Public/ConvertTo-DSC.ps1
function ConvertTo-Dsc { <# .SYNOPSIS Converts json DSL files to PSCustomObject .DESCRIPTION Converts json DSL files to PSCustomObjects that Invoke-DSCResource can consume. All property objects will be converted to hashtables for the property cmdlet of Invoke-DSCResource. ModuleName is discovered dynamically from the resource name provided in the json. .PARAMETER Path Specifies the path to a .json file. .PARAMETER InputObject Specifies an InputObject containing json synatx .EXAMPLE ConvertTo-Dsc -Path 'c:\json\example.json' #> [CmdletBinding()] param( [Parameter(Mandatory = $true, ParameterSetName = 'Path', Position = 0)] [string]$Path, [Parameter(Mandatory = $true, ParameterSetName = 'InputObject', Position = 1)] [object[]]$InputObject ) begin { if ($PSBoundParameters.ContainsKey('Path')) { $data = Get-Content -Path $path -Raw | ConvertFrom-Json } else { $data = $InputObject | ConvertFrom-Json } $alldscObj = @() } process { $dscResourceProperties = $data.DSCResourcesToExecute.PSObject.Properties | Where-Object { $_.MemberType -eq "NoteProperty"; }; foreach ($dscResourceProperty in $dscResourceProperties) { $dscResource = $dscResourceProperty.Value $dscObj = New-Object psobject if ($dscResource.dscResourceName) { $resource = (Get-DscResource -Name $dscResource.dscResourceName | Sort-Object Version -Descending)[0] } else { throw "dscResourceName property is null for [$($dscResourceProperty.Name)]" } if ($dscResource.dscResourceName -eq 'file') { $module = 'PSDesiredStateConfiguration' } else { $module = $resource.ModuleName } if ($null -ne $data.Modules.$module -and $data.Modules -match $module) { $moduleVersion = ($data.Modules).$module if ($resource.Version -notmatch $moduleVersion) { $resource = Get-DscResource -Name $dscResource.dscResourceName | Where-Object Version -Match $moduleVersion } } $Config = @{ Name = ($dscResource.dscResourceName) Property = @{ } } $configkeys = ($dscResource.psobject.Properties -notmatch '(dsc)?ResourceName') foreach ($configKey in $configKeys) { $prop = $resource.Properties | Where-Object {$_.Name -eq $configKey.Name} if ($ConfigKey.Value -is [array] -and $prop.PropertyType -eq '[string]'){ $ConfigKey.Value = $configKey.Value | Out-String } if ($ConfigKey.Value -is [array]) { foreach ($key in $ConfigKey.Value) { if ($key.psobject.Properties['CimType']) { #Create new CIM object $cimhash = @{} $key.Properties.psobject.Properties | ForEach-Object { $cimhash[$_.Name] = $_.Value } if ($prop.PropertyType -match '\[\w+\[\]\]') { [ciminstance[]]$value += New-CimInstance -ClassName $key.CimType -Property $cimhash -ClientOnly } else { [ciminstance]$value = New-CimInstance -ClassName $key.CimType -Property $cimhash -ClientOnly } } else { $value = $configKey.Value } } $config.Property.Add($configKey.Name, $value) Remove-Variable -Name Value -Force } elseif ($prop.PropertyType -eq '[PSCredential]') { $credSplit = $configKey.Value -split '\\' $cred = New-Object System.Management.Automation.PSCredential ($credSplit[0], ($credSplit[1] | ConvertTo-SecureString -AsPlainText -Force)) [System.Management.Automation.PSCredential]$value = $cred $config.Property.Add($configKey.Name, $value) Remove-Variable -Name Value -Force } else { $config.Property.Add($configKey.Name, $configKey.Value) } } $dscObj | Add-Member -MemberType NoteProperty -Name resourceName -Value $dscResourceProperty.Name $dscObj | Add-Member -MemberType NoteProperty -Name dscResourceName -Value $dscResource.dscResourceName $dscObj | Add-Member -MemberType NoteProperty -Name ModuleName -Value $module if ($null -ne $data.Modules.$module -and $data.Modules -match $module) { $dscObj | Add-Member -MemberType NoteProperty -Name ModuleVersion -Value $moduleVersion } else { $dscObj | Add-Member -MemberType NoteProperty -Name ModuleVersion -Value $null } $dscObj | Add-Member -MemberType NoteProperty -Name Property -Value $Config.Property $alldscObj += $dscObj } } end { return $alldscObj } } |