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")
    }
}