CommonTasks icon indicating copy to clipboard operation
CommonTasks copied to clipboard

WebSites: Binding infos not supported

Open psdgal opened this issue 3 years ago • 2 comments

Problem description

Specifying the binding infos for a website, the MOF compilation fails.

Verbose logs

Write-NodeMOFFile : Invalid MOF definition for node 'localhost_WebSites': Exception calling "ValidateInstanceText" with "1" argument(s): "Convert property 'BindingInfo' value from type 
'STRING[]' to type 'INSTANCE[]' failed

DSC configuration

Items:
  - Name: TestSite1
    ApplicationPool: TestAppPool1
    BindingInfo:
      Protocol: HTTPS
      Port: 443
      HostName: test.com
      CertificateThumbprint: 466CD26A6E2F346A3A813D12E2BAAD0E886E7BBF
  - Name: TestSite2
    ApplicationPool: TestAppPool2
  # Remove IIS Default WebSite
  - Name: Default Web Site
    Ensure: Absent

Operating system the target node is running

OsName               : Microsoft Windows 10 Enterprise
OsOperatingSystemSKU : EnterpriseEdition
OsArchitecture       : 64-bit
WindowsVersion       : 2009
WindowsBuildLabEx    : 19041.1.amd64fre.vb_release.191206-1406
OsLanguage           : en-US
OsMuiLanguages       : {en-US}

PowerShell version and build the target node is running

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

CommonTasks version

0.4

psdgal avatar Mar 10 '22 06:03 psdgal

Assuming you're using the Website composite resource, and given its simple code here: https://github.com/dsccommunity/CommonTasks/blob/main/source/DSCResources/WebSites/Websites.schema.psm1#L23

I think the problem comes with Get-DscSplattedResource because it does not support MOF subtypes: https://github.com/dsccommunity/xWebAdministration/blob/main/source/DSCResources/MSFT_xWebSite/MSFT_xWebSite.schema.mof#L30

I think this problem does not happen with Class-based resources when the constructor of the nested type supports hashtable as parameter (which is and should be the default).

I appreciate that does not help solving the issue, but helps pin-pointing it.

gaelcolas avatar Mar 10 '22 09:03 gaelcolas

Thank you Gael!

I got to manage it working in this way:


function Global:Get-DscSplattedResource {
    [CmdletBinding()]
    Param(
        [String]
        $ResourceName,

        [String]
        $ExecutionName,

        [hashtable]
        $Properties,

        [switch]
        $NoInvoke
    )
    # Remove Case Sensitivity of ordered Dictionary or Hashtables
    $Properties = @{}+$Properties

    $stringBuilder = [System.Text.StringBuilder]::new()
    $null = $stringBuilder.AppendLine("Param([hashtable]`$Parameters)")
    $null = $stringBuilder.AppendLine()

    if($ExecutionName) {
        $null = $stringBuilder.AppendLine(" $ResourceName '$ExecutionName' {")
    }
    else {
        $null = $stringBuilder.AppendLine(" $ResourceName {")
    }

    foreach($PropertyName in $Properties.keys) {
        $null = $stringBuilder.AppendLine("$PropertyName = `$(`$Parameters['$PropertyName'])")
    }
    $null = $stringBuilder.AppendLine("}")
    Write-Debug ("Generated Resource Block = {0}" -f $stringBuilder.ToString())
    
    if($NoInvoke) {
        [scriptblock]::Create($stringBuilder.ToString())
    }
    else {
        [scriptblock]::Create($stringBuilder.ToString()).Invoke($Properties)
    }
}
Set-Alias -Name x -Value Get-DscSplattedResource -scope Global


configuration WebSites {
    param (
        [Parameter(Mandatory = $true)]
        [hashtable[]]
        $Items
    )

    Import-DscResource -ModuleName PSDesiredStateConfiguration
    Import-DscResource -ModuleName xWebAdministration

    foreach ($item in $Items)
    {
        # Remove Case Sensitivity of ordered Dictionary or Hashtables
        $item = @{} + $item

        if (-not $item.ContainsKey('Ensure'))
        {
            $item.Ensure = 'Present'
        }

        if ($item.ContainsKey('BindingInfo'))
        {
            $bindingInfo = $item.BindingInfo
            $item.BindingInfo = (Get-DscSplattedResource -ResourceName MSFT_xWebBindingInformation -Properties $bindingInfo -NoInvoke).Invoke($bindingInfo)
        }

        $executionName = "website_$($item.Name -replace '[{}#\-\s]','_')"
        (Get-DscSplattedResource -ResourceName xWebSite -ExecutionName $executionName -Properties $item -NoInvoke).Invoke($item)
    }
}

Would you accept such modifications as PR for Get-DscSplattedResource in DscBuildHelpers module? Or is there something you think that needs to be better look at?

if($ExecutionName) {
    $null = $stringBuilder.AppendLine(" $ResourceName '$ExecutionName' {")
}
else {
    $null = $stringBuilder.AppendLine(" $ResourceName {")
}

psdgal avatar Mar 12 '22 13:03 psdgal