Out-Config.ps1
function Out-Config { <# .Synopsis Generates a configuration from any input object .Description Generates a PowerShell DSC configuration based off of a series of input objects or hashtables. The properties Node, ResourceName, and SetttingName are used to define their corresponding parts in a DSC configuration. .Example @{ ResourceName = 'WindowsFeature' SettingName = 'IIS' Ensure = 'Present' Name = 'Web-Server' }, @{ ResourceName = 'Package' SettingName = 'UrlRewrite' Ensure = "Present" Name = "IIS URL Rewrite Module 2" Path = "http://download.microsoft.com/download/6/7/D/67D80164-7DD0-48AF-86E3-DE7A182D6815/rewrite_2.0_rtw_x64.msi" Arguments = "/quiet" ProductId = "EB675D0A-2C95-405B-BEE8-B42A65D23E11" } | Out-Config -Name IISInstall .Link Split-Config .Link Join-Config #> param( [Parameter(Mandatory=$true,ValueFromPipeline=$true)] [PSObject[]] $InputObject, # The name of the new configuration. If this is not provided, the name 'NewConfiguration' will be used. [Parameter(Position=1)] [string] $Name ) begin { $allConfigParts = New-Object Collections.ArrayList $Accumulate = New-Object Collections.ArrayList if (-not $script:LastAskedForDscResources -or ([DateTime]::Now - $script:LastAskedForDscResources) -gt [TimeSpan]"00:05:00") { $script:LastAskedForDscResources = [DateTime]::Now $script:CachedDSCResources = Get-DscResource } $AllDscResources = $script:CachedDSCResources } process { $Accumulate.AddRange($InputObject) } end { $nodeName = '' $ResourceName = '' $allConfigParts = foreach ($obj in $Accumulate) { $objHt = if ($obj -isnot [Hashtable]) { $ht = @{} foreach($prop in $obj.psobject.properties) { $ht+=@{$prop.Name=$prop.Value} } $ht } else { $obj } if ($objHt.Node) { $nodeName = $objHt.Node } if ($objHt.ResourceName) { $ResourceName = $objHt.ResourceName } elseif ($objHt.Resource) { $ResourceName = $objHt.Resource } if ($objHt.SettingName) { $SettingName = $objHt.SettingName } if (-not $ResourceName) { continue } $MatchingResource = $AllDscResources | Where-Object { $_.Name -eq $ResourceName } if (-not $MatchingResource) { continue } $MandatoryFound = $true $ResourceSettings = @{} foreach ($prop in $MatchingResource.Properties) { $propType = $prop.PropertyType.Substring(1,$prop.PropertyType.Length - 2) -as [type] if ($ObjHt[$prop.Name] -and $objhT[$prop.Name] -as $propType) { $ResourceSettings[$prop.Name] = $objHt[$prop.Name] if ($prop.IsMandatory) { $MandatoryFound = $true } } } if ($MandatoryFound) { $configurationSettingsBlock = New-Object Text.StringBuilder $null = $configurationSettingsBlock.AppendLine("{") foreach ($kv in $ResourceSettings.GetEnumerator() | Sort-Object Key) { if ($nodeName) { $null = $configurationSettingsBlock.Append(" " * 12) } else { $null = $configurationSettingsBlock.Append(" " * 8) } $null = $configurationSettingsBlock.Append($kv.Key) $null = $configurationSettingsBlock.Append(" = ") if ($kv.Value -is [bool]) { $null = $configurationSettingsBlock.Append("`$$($kv.Value)") } elseif ($kv.Value -as [float] -ne $null) { $null = $configurationSettingsBlock.Append("$($kv.Value)") } else { $null = $configurationSettingsBlock.Append("'$($kv.Value)'") } $null = $configurationSettingsBlock.AppendLine("") } if ($nodeName) { $null = $configurationSettingsBlock.Append(" " * 8) } else { $null = $configurationSettingsBlock.Append(" " * 4) } $null = $configurationSettingsBlock.AppendLine("}") " $ResourceName $SettingName $configurationSettingsBlock " | Add-Member NoteProperty Node $nodeName -PassThru | Add-Member NoteProperty ResourceName "$ResourceName" -PassThru | Add-Member NoteProperty SettingName $SettingName -PassThru } } if (-not $name) { $name = "NewConfiguration" } $configBuilder = New-Object Text.StringBuilder $null = $configBuilder.AppendLine("configuration $name {") if ($allVariablesUsed) { $paramBody = @(foreach ($variableName in $allVariablesUsed) { if (-not $variableName) { continue } $paramBlocks[$variableName] }) -join (',' + [Environment]::NewLine + (" " * 4)) $null = $configBuilder.AppendLine(" " * 4 + "param($($paramBody.Trim("()").Trim()))") } if ($allModulesImported) { $null = $configBuilder.AppendLine(" " * 4 + "Import-DSCResource -Module '$(($allModulesImported | Select-Object -Unique | Sort-Object) -join "','")'") } foreach ($resourceName in $ExplicitResourceNames) { $null = $configBuilder.AppendLine(" " * 4 + "Import-DSCResource -Name '$resourceName'") } foreach ($partsByNode in $allConfigParts | Group-Object Node) { $indentSize = if ($partsByNode.Name) { 8 $null = $configBuilder.AppendLine(" " * 4 + "node $($partsByNode.Name) {") } else { 4 } foreach ($part in $partsByNode.Group) { $null = $configBuilder.AppendLine(" " * $indentSize + $part.Trim()) } if ($indentSize -eq 8) { $null = $configBuilder.AppendLine(" " * 4 + "}") } } $null = $configBuilder.AppendLine("}") [ScriptBlock]::Create("$configBuilder") } } |