dlwyatt / PolicyFileEditor

PowerShell functions and DSC resource wrappers around the TJX.PolFileEditor.PolFile .NET class.
Apache License 2.0
189 stars 33 forks source link

Errors in Invoke-DSCResource due to SINT type #5

Closed ricardogaspar2 closed 7 years ago

ricardogaspar2 commented 7 years ago

Hi, I would like to report some issues I found in order to improve this module.

I was trying to use this DSC resource but I had a few issues when using it with Invoke-DSCResource command.

Although, as I described in a previous issue (https://github.com/dlwyatt/PolicyFileEditor/issues/4), using a DSC configuration script works:

Configuration LocalGPO
{
    param
    (
        [string[]] $NodeName = 'localhost'
    )

    Import-DSCResource -ModuleName PolicyFileEditor

    Node $NodeName
    {
        cAdministrativeTemplateSetting RDPLicensing
        {
            KeyValueName = "SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services\LicenseServers"
            PolicyType = "Machine"
            Data = ("server.test.localgpo.dsc.com")
            Ensure = "Present"
            Type = "String"
        }

      ## The next 3 resources are to change the GPO Setting "Set Remote Desktop Services User Home Directory"
        cAdministrativeTemplateSetting "RDP Users Home Directory Path"
        {
        #    SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services!WFHomeDirUNC 
        #    SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services!WFHomeDir
        #    SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services!WFHomeDirDrive
            KeyValueName = "SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services\WFHomeDir"
            PolicyType = "Machine"
            Data = "\\servershare\test"
            Ensure = "Present"
            Type = "String"
        }

        cAdministrativeTemplateSetting "RDP Users Home Directory Letter"
        {
            KeyValueName = "SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services\WFHomeDirDrive"
            PolicyType = "Machine"
            Data = "X:"
            Ensure = "Present"
            Type = "String"
        }

        cAdministrativeTemplateSetting "RDP Users Home Directory UNC boolean"
        {
            KeyValueName = "SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services\WFHomeDirUNC"
            PolicyType = "Machine"
            Data = "1"
            Ensure = "Present"
            Type = "Dword"
        }
    }
}
LocalGPO
Start-DscConfiguration -Path .\LocalGPO -Wait -Force -Verbose

When one needs to remotely call this resource or use other configuration management tools like Puppet or Ansible that rely on the Invoke-DSCResource command it doesn't work properly.

You can check the reported issues submitted by me in the corresponding issue trackers:

It's possible to confirm that there is a problem when passing the Type property as a string.

Tests:

This does NOT work

$DscParams = @{}
$DscParams.Add("Ensure", "Present")
$DscParams.Add("KeyValueName", "'SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services\LicenseServers")
$DscParams.Add("PolicyType", "Machine")
$DscParams.Add("Data", @("something.contoso.com"))
$DscParams.Add("Type", "String")
Invoke-DscResource -Name cAdministrativeTemplateSetting -ModuleName "PolicyFileEditor" -Method Test -Property $dscparams 

Output:

Convert property 'Type' value from type 'STRING' to type 'SINT32' failed
 At line:12, char:2
 Buffer:
irectResourceAccess";
};^
insta
    + CategoryInfo          : SyntaxError: (root/Microsoft/...gurationManager:String) [], CimException
    + FullyQualifiedErrorId : MiClientApiError_Failed
    + PSComputerName        : localhost

This WORKS

$DscParams2 = @{}
$DscParams2.Add("Ensure", "Present")
$DscParams2.Add("KeyValueName", "'SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services\LicenseServers")
$DscParams2.Add("PolicyType", "Machine")
$DscParams2.Add("Data", @("something.contoso.com"))
$DscParams2.Add("Type", 1) 
Invoke-DscResource -Name cAdministrativeTemplateSetting -ModuleName "PolicyFileEditor" -Method Test -Property $dscparams2

Output:

InDesiredState
--------------
False

With any type the resource only works passing an integer, as defined in the mof file: https://github.com/dlwyatt/PolicyFileEditor/blob/master/DscResources/PshOrg_AccountAdminTemplateSetting/PshOrg_AccountAdminTemplateSetting.schema.mof#L8

Possible solutions

So, the solutions could be on of the two:

1. [Preferable] Change the type to String.

Like the Registry resource from Microsoft, it is possible to use a string instead of sint32: https://github.com/PowerShell/PSDscResources/blob/2c33e69634aa9c641ab27427d457fe9f49884e7c/DscResources/MSFT_RegistryResource/MSFT_RegistryResource.schema.mof#L7

2. Change the map in the type property to use only integers int or sint32.

[ClassVersion("1"), FriendlyName("cAccountAdministrativeTemplateSetting")]
class PshOrg_AccountAdminTemplateSetting : OMI_BaseResource
{
[Key] string Account;
[Key] string KeyValueName;
[write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure;
[write] string Data[];
[write,ValueMap{"0","1","2","3","4","7","11","-1"},Values"0","1","2","3","4","7","11","-1"}] sint32 Type;
};

In this solution, the user has to know the mappings from the different types in order to use the correct integer. So it has to be in the documentation somewhere.

It would be great to have a fix for this.

dlwyatt commented 7 years ago

Out of curiosity, what happens if you call Invoke-DscResource with [Microsoft.Win32.RegistryValueKind]::String as the argument instead of "String"? The String-to-Int mapping in the schema file is what happens when you declare a function argument as an enum type in the tooling that I use to auto-generate schema.mof files.

ricardogaspar2 commented 7 years ago

Testing with [Microsoft.Win32.RegistryValueKind]::String

Test 1


$DscParams3 = @{}
$DscParams3.Add("Ensure", "Present")
$DscParams3.Add("KeyValueName", "'SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services\LicenseServers")
$DscParams3.Add("PolicyType", "Machine")
$DscParams3.Add("Data", @("something.contoso.com"))
$DscParams3.Add("Type", [Microsoft.Win32.RegistryValueKind]::String)
Invoke-DscResource -Name cAdministrativeTemplateSetting -ModuleName "PolicyFileEditor" -Method Test -Property $dscparams3

Output:

Invoke-DscResource : Failed to serialize properties into CimInstance.
At line:1 char:1
+ Invoke-DscResource -Name cAdministrativeTemplateSetting -ModuleName " ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Invoke-DscResource], SerializationException
    + FullyQualifiedErrorId : System.Runtime.Serialization.SerializationException,Microsoft.PowerShell.DesiredStateConfiguration.Commands.InvokeDscRe
   sourceMethodCommand

Test 2

$DscParams4 = @{}
$DscParams4.Add("Ensure", "Present")
$DscParams4.Add("KeyValueName", "'SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services\LicenseServers")
$DscParams4.Add("PolicyType", "Machine")
$DscParams4.Add("Data", @("something.contoso.com"))
$DscParams4.Add("Type", "[Microsoft.Win32.RegistryValueKind]::String") 
Invoke-DscResource -Name cAdministrativeTemplateSetting -ModuleName "PolicyFileEditor" -Method Test -Property $dscparams4

Output:

Convert property 'Type' value from type 'STRING' to type 'SINT32' failed
 At line:12, char:2
 Buffer:
irectResourceAccess";
};^
insta
    + CategoryInfo          : SyntaxError: (root/Microsoft/...gurationManager:String) [], CimException
    + FullyQualifiedErrorId : MiClientApiError_Failed
    + PSComputerName        : localhost
erwinwildenburg commented 7 years ago

Added a pull request. The sint32 conversion didn't really make sense indeed.

@dlwyatt if you have time could you push a new version to PSGallery?

dlwyatt commented 7 years ago

V3.0 has been published. Thanks! :)