Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xWebConfigPropertyCollection: Adding system.webServer/security/authorization fails Test-TargetResource #590

Open
General-Fault opened this issue Dec 15, 2020 · 3 comments
Labels
bug The issue is a bug. help wanted The issue is up for grabs for anyone in the community.

Comments

@General-Fault
Copy link

Details of the scenario you tried and the problem that is occurring

I am using xWebConfigPropertyCollection to configure the authorization for an IIS server. In this case, I am attempting to add an 'Allow' accessType for the 'Administrators' group (see example configuration below). The 'Set-TargetResource' completes successfully. However the Test-TargetResource always fails.

This really appears to be caused by a peculiarity (failure?) in how Get-WebConfigurationProperty works.

The Test-TargetResource method calls Get-ItemValues, which in turn constructs a filter and calls Get-WebConfigurationProperty. Get-WebConfigurationProperty returns an object with an 'Attributes' property. For attribute values that represent an enum, the numeric value is returned rather than the enum value name. So $item.Attributes['accessType'] = 0. This would probably be ok if the TypeName of the 'accessType' attribute was the name of the attribute.
Interestingly the object returned from Get-WebConfigurationProperty also has properties pulled from the attributes that have the string 'name' of the enum value. In this case $item.accessType = 'Allowed'.

See also https://docs.microsoft.com/en-us/previous-versions/iis/settings-schema/aa965015(v=vs.90)

Verbose logs showing the problem


> Invoke-DscResource -ModuleName 'xWebAdministration' -Name 'xWebConfigPropertyCollection' -Property @{
>>     WebsitePath = 'MACHINE/WEBROOT/APPHOST'
>>     Filter = 'system.webServer/security'
>>     CollectionName = 'authorization'
>>     ItemName = 'add'
>>     ItemKeyName = 'users'
>>     ItemKeyValue = 'Administrator'
>>     ItemPropertyName = 'accessType'
>>     ItemPropertyValue ='Allow'
>> } -Verbose -Method 'Set'

VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = ResourceSet,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' =
root/Microsoft/Windows/DesiredStateConfiguration'.
VERBOSE: An LCM method call arrived from computer [obfuscated] with user sid S-1-5-21-4059549603-1526190832-587935432-1000.
VERBOSE: [[obfuscated]]: LCM:  [ Start  Set      ]  [[xWebConfigPropertyCollection]DirectResourceAccess]
VERBOSE: [[obfuscated]]:                            [[xWebConfigPropertyCollection]DirectResourceAccess] Checking for the existence of property "accessType" in collection item "authorization/add" with key
"users=Administrator" using filter "system.webServer/security" located at "MACHINE/WEBROOT/APPHOST".
VERBOSE: [[obfuscated]]:                            [[xWebConfigPropertyCollection]DirectResourceAccess] Collection item "authorization/add" with key "users=Administrator" exists, editing property
"accessType".
VERBOSE: [[obfuscated]]: LCM:  [ End    Set      ]  [[xWebConfigPropertyCollection]DirectResourceAccess]  in 1.7030 seconds.
VERBOSE: [[obfuscated]]: LCM:  [ End    Set      ]    in  4.9840 seconds.
VERBOSE: Operation 'Invoke CimMethod' complete.

RebootRequired
--------------
False
VERBOSE: Time taken for configuration job to complete is 5.171 seconds

> Invoke-DscResource -ModuleName 'xWebAdministration' -Name 'xWebConfigPropertyCollection' -Property @{
>>     WebsitePath = 'MACHINE/WEBROOT/APPHOST'
>>     Filter = 'system.webServer/security'
>>     CollectionName = 'authorization'
>>     ItemName = 'add'
>>     ItemKeyName = 'users'
>>     ItemKeyValue = 'Administrator'
>>     ItemPropertyName = 'accessType'
>>     ItemPropertyValue ='Allow'
>> } -Verbose -Method 'Test'
VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = ResourceTest,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' =
root/Microsoft/Windows/DesiredStateConfiguration'.
VERBOSE: An LCM method call arrived from computer [obfuscated] with user sid S-1-5-21-4059549603-1526190832-587935432-1000.
VERBOSE: [[obfuscated]]: LCM:  [ Start  Test     ]  [[xWebConfigPropertyCollection]DirectResourceAccess]
VERBOSE: [[obfuscated]]:                            [[xWebConfigPropertyCollection]DirectResourceAccess] Checking for the existence of property "accessType" in collection item "authorization/add" with key
"users=Administrator" using filter "system.webServer/security" located at "MACHINE/WEBROOT/APPHOST".
VERBOSE: [[obfuscated]]:                            [[xWebConfigPropertyCollection]DirectResourceAccess] Property "accessType" has not been found with expected value.
VERBOSE: [[obfuscated]]: LCM:  [ End    Test     ]  [[xWebConfigPropertyCollection]DirectResourceAccess] False in 0.4370 seconds.
VERBOSE: [[obfuscated]]: LCM:  [ End    Set      ]    in  0.4840 seconds.
VERBOSE: Operation 'Invoke CimMethod' complete.

InDesiredState
--------------
False
VERBOSE: Time taken for configuration job to complete is 0.553 seconds

Attempting to set the raw value:


> Invoke-DscResource -ModuleName 'xWebAdministration' -Name 'xWebConfigPropertyCollection' -Property @{
>>     WebsitePath = 'MACHINE/WEBROOT/APPHOST'
>>     Filter = 'system.webServer/security'
>>     CollectionName = 'authorization'
>>     ItemName = 'add'
>>     ItemKeyName = 'users'
>>     ItemKeyValue = 'Administrator'
>>     ItemPropertyName = 'accessType'
>>     ItemPropertyValue ='0'
>> } -Verbose -Method 'Set'
VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = ResourceSet,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' =
root/Microsoft/Windows/DesiredStateConfiguration'.
VERBOSE: An LCM method call arrived from computer [obfuscated] with user sid S-1-5-21-4059549603-1526190832-587935432-1000.
VERBOSE: [[obfuscated]]: LCM:  [ Start  Set      ]  [[xWebConfigPropertyCollection]DirectResourceAccess]
VERBOSE: [[obfuscated]]:                            [[xWebConfigPropertyCollection]DirectResourceAccess] Checking for the existence of property "accessType" in collection item "authorization/add" with key
"users=Administrator" using filter "system.webServer/security" located at "MACHINE/WEBROOT/APPHOST".
VERBOSE: [[obfuscated]]:                            [[xWebConfigPropertyCollection]DirectResourceAccess] Collection item "authorization/add" with key "users=Administrator" does not exist, adding with property
"accessType".
Enum must be one of Allow, Deny
    + CategoryInfo          : NotSpecified: (:) [], CimException
    + FullyQualifiedErrorId : System.Runtime.InteropServices.COMException,Microsoft.IIs.PowerShell.Provider.AddConfigurationPropertyCommand
    + PSComputerName        : localhost

VERBOSE: [[obfuscated]]: LCM:  [ End    Set      ]  [[xWebConfigPropertyCollection]DirectResourceAccess]  in 0.3280 seconds.
The PowerShell DSC resource '[xWebConfigPropertyCollection]DirectResourceAccess' with SourceInfo '' threw one or more non-terminating errors while running the Set-TargetResource functionality. These errors
are logged to the ETW channel called Microsoft-Windows-DSC/Operational. Refer to this channel for more details.
    + CategoryInfo          : InvalidOperation: (root/Microsoft/...gurationManager:String) [], CimException
    + FullyQualifiedErrorId : NonTerminatingErrorFromProvider
    + PSComputerName        : localhost

VERBOSE: Operation 'Invoke CimMethod' complete.
VERBOSE: Time taken for configuration job to complete is 0.445 seconds

Suggested solution to the issue

The property object returned from Get-AddElementSchema has all of the information needed to convert the Attribute value to a string. The 'Type' member is 'enum' and $property.GetEnumValues() returns a list of the possible string enum values as strings and numeric values.

function Get-CollectionItemPropertyType
{
    [CmdletBinding()]
    [OutputType([System.String])]
    param
    (
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $WebsitePath,

        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Filter,

        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $PropertyName,

        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $AddElement
    )

    $webConfiguration = Get-WebConfiguration -Filter $Filter -PsPath $WebsitePath

    $addElementSchema = Get-AddElementSchema -AddElement $AddElement -WebConfiguration $webConfiguration

    $property = $addElementSchema | Where-Object -FilterScript {$_.Name -eq $PropertyName}
    if ($property.Type -eq 'enum')
    {
        return $property.Type
    }
    else 
    {
        return $property.ClrType.Name
    }
}


Get-EnumString 
{
    [CmdletBinding()]
    [OutputType([System.String])]
    param
    (
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $WebsitePath,

        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Filter,

        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $PropertyName,

        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $AddElement,
        
        [Parameter(Mandatory = $true)]
        [Int32]
        $InputValue
    )

    $webConfiguration = Get-WebConfiguration -Filter $Filter -PsPath $WebsitePath

    $addElementSchema = Get-AddElementSchema -AddElement $AddElement -WebConfiguration $webConfiguration

    $property = $addElementSchema | Where-Object -FilterScript {$_.Name -eq $PropertyName}
    
    $enumValues = $property.GetEnumValues()
    
    $strValue = ($enumValues | where-object {$_.Value -eq $InputValue}).Name
    
    return $enumValues.GetEnum
}

Then rework Get-ItemValues to get the type and do the conversion rather than making the Get/Set/Test-TargetResource do it.

The DSC configuration that is used to reproduce the issue (as detailed as possible)

Configuration TestConfiguration
{
    Import-DscResource -ModuleName xWebAdministration

    Node localhost
    {
        xWebConfigPropertyCollection 'AllowAdministratorAuth'
        {
            WebsitePath = 'MACHINE/WEBROOT/APPHOST'
            Filter = 'system.webServer/security'
            CollectionName = 'authorization'
            ItemName = 'add'
            ItemKeyName = 'users'
            ItemKeyValue = 'Administrator'
            ItemPropertyName = 'accessType'
            ItemPropertyValue = 'Allow'
            Ensure = 'Present'
        }
    }
}

The operating system the target node is running

OsName : Microsoft Windows 10 Enterprise LTSC
OsOperatingSystemSKU : 125
OsArchitecture : 64-bit
WindowsVersion : 1809
WindowsBuildLabEx : 17763.1.amd64fre.rs5_release.180914-1434
OsLanguage : en-US
OsMuiLanguages : {en-US}

Version and build of PowerShell the target node is running

Name Value
PSVersion 5.1.17763.1490
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.17763.1490
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1

Version of the DSC module that was used

3.2.0

@johlju johlju added bug The issue is a bug. help wanted The issue is up for grabs for anyone in the community. labels Dec 15, 2020
@General-Fault
Copy link
Author

General-Fault commented Dec 15, 2020

The conversion should probably handle flag enums as well.

if ($property.Type -eq 'flags' -and $InputValue -ne 0) 
{
    $strValue = ($enumValues | where-object {$_.Value -ne 0 -and ($_.Value -band $InputValue) -eq $_.Value}).Name
}
else
{
    $strValue = ($enumValues | where-object {$_.Value -eq $InputValue}).Name
}

/untested

@quillypowers
Copy link

I've been able to get apphost level auth working via passing in params like below
("adminauth","MACHINE/WEBROOT/APPHOST","system.webServer/security/authorization",".","add","accessType","Allow","users","Administrator","Present"),

    $ConfigurationData.NonNodeData.Roles.([String]($Node.Role -eq "WEBSMTP")).ConfigColls.foreach({
        WebConfigPropertyCollection $_[0]
        {
            WebsitePath       = $_[1]
            Filter            = $_[2]
            CollectionName    = $_[3]
            ItemName          = $_[4]
            ItemKeyName       = $_[5]
            ItemKeyValue      = $_[6]
            ItemPropertyName  = $_[7]
            ItemPropertyValue = $_[8]
            Ensure            = $_[9]
        }
    })

@quillypowers
Copy link

quillypowers commented May 26, 2023

I did verify above works. Test seemed to work, but need to sift through still. I'm on webadministration 4.1.0 too.
The same should work for doing site level auth with params like below into the same, but that errors everytime with err below that. Any help there from anyone that reads this would be great, but this one being dead for 3 years doesn't give much hope.
("userauth",'MACHINE/WEBROOT',"system.webServer/security/authorization",".","add","accessType","Allow","users","*","Present"),

Cannot bind argument to parameter 'WebConfiguration' because it is null.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug The issue is a bug. help wanted The issue is up for grabs for anyone in the community.
Projects
None yet
Development

No branches or pull requests

3 participants