CompositeResource.psm1
<# .SYNOPSIS Converts a PowerShell Desired State Configuration configuration to a composite resources. .DESCRIPTION Converts a PowerShell Desired State Configuration configuration to a composite resources. It is possible to convert several configuration to composite resource to the same resource module. Use the same ModuleName, ModuleVersion and OutputPath for all the configurations that are converted. .PARAMETER ConfigurationName The configuration name to convert into a composite resource. The configuration name must exist in the session. If this is used, then the parameter Script cannot be used. .PARAMETER Script A script block containing the configuration to convert into a composite resource. If this is used, then the parameter ConfigurationName cannot be used. .PARAMETER ResourceName The name of the composite resource that will be created. Defaults to the same name as the configuration name. .PARAMETER ModuleName The name of the resource module that will contain the new composite resource. Defaults to the same name as the configuration name, suffixed with DSC, e.g. ModuleNameDSC. .PARAMETER ModuleVersion The version number of the resource module being created. .PARAMETER Author The name of the author of the resource module. This will be added to the module manifest. Defaults to $env:USERNAME. .PARAMETER Description The description of the resource module. This will be added to the module manifest. Defaults to 'Automatically generated by the Composite Resource module.' .PARAMETER OutputPath The path to where the new resource module will be created. Defaults to the current folder. If there are already a resource module with the same name at the output path, that module will be updated. .OUTPUTS No command output returned when successful. .NOTES Get more information, and how to contribute, at https://github.com/Microsoft/CompositeResource. .EXAMPLE ConvertTo-CompositeResource -ConfigurationName 'Test' -Author 'Name' -Description 'Text' #> function ConvertTo-CompositeResource { [CmdletBinding(DefaultParameterSetName = 'ByConfiguration')] param ( [Parameter(Mandatory = $true, ParameterSetName = 'ByConfigurationName')] [string] $ConfigurationName, [Parameter(Mandatory = $true, ParameterSetName = 'ByScript')] [string] $Script, [Parameter()] [string] $ResourceName = $ConfigurationName, [Parameter()] [string] $ModuleName = "$($ConfigurationName)DSC", [Parameter(Mandatory = $true)] [version] $ModuleVersion, [Parameter()] [string] $Author = $env:USERNAME, [Parameter()] [string] $Description = 'Automatically generated by the Composite Resource module. http://github.com/microsoft/compositeresource', [Parameter()] [string] $OutputPath = '.\' ) switch ($PsCmdlet.ParameterSetName) { "ByConfigurationName" { $configuration = Get-Command -Name $ConfigurationName -CommandType 'Configuration' -ErrorAction SilentlyContinue if (-not $configuration) { throw ('Could not find a configuration ''{0}'' loaded in the session.' -f $ConfigurationName) } } "ByScript" { # Get the configuration definition ast. $parseErrors = $null $definitionAst = [System.Management.Automation.Language.Parser]::ParseInput($Script, [ref] $null, [ref] $parseErrors) if ($parseErrors) { throw $parseErrors } $astFilter = { $args[0] -is [System.Management.Automation.Language.ConfigurationDefinitionAst] } $configurationDefinitionAst = $definitionAst.Find($astFilter, $false) # Get the script block definition ast, from the result of the configuration definition ast. $parseErrors = $null $definitionAst = [System.Management.Automation.Language.Parser]::ParseInput($configurationDefinitionAst.Body.Extent.Text, [ref] $null, [ref] $parseErrors) if ($parseErrors) { throw $parseErrors } $astFilter = { $args[0] -is [System.Management.Automation.Language.ScriptBlockAst] } $configurationContentDefinitionAst = $definitionAst.Find($astFilter, $false) # Removes the beginning open brace an ending closing brace of the script block. $configurationDefinition = $configurationContentDefinitionAst.Extent.Text $configurationDefinition = ` $configurationDefinition.Remove($configurationContentDefinitionAst.Extent.EndScriptPosition.Offset - 1, 1) $configurationDefinition = ` $configurationDefinition.Remove($configurationContentDefinitionAst.Extent.StartScriptPosition.Offset, 1) # Build the correct configuration values. $configuration = @{ Definition = $configurationDefinition } $ConfigurationName = $configurationDefinitionAst.InstanceName.Value # Set default values if they are not set. if (-not $PSBoundParameters.ContainsKey('ResourceName')) { $ResourceName = $ConfigurationName } if (-not $PSBoundParameters.ContainsKey('ModuleName')) { $ModuleName = "$($ConfigurationName)DSC" } } } $moduleFolder = Join-Path -Path $OutputPath -ChildPath $ModuleName $versionFolder = Join-Path -Path $moduleFolder -ChildPath $ModuleVersion.ToString() $dscResourcesFolder = Join-Path -Path $versionFolder -ChildPath 'DSCResources' $configurationFolder = Join-Path -Path $dscResourcesFolder -ChildPath $ResourceName # Creates the folder structure if any folder does not exist. if (-not (Resolve-Path -Path $configurationFolder -ErrorAction 'SilentlyContinue')) { New-Item -Path $configurationFolder -ItemType Directory -Force -ErrorAction Stop | Out-Null } $resourcePsm1 = Join-Path -Path $configurationFolder -ChildPath "$ResourceName.schema.psm1" $resourcePsd1 = Join-Path -Path $configurationFolder -ChildPath "$ResourceName.psd1" $modulePsd1 = Join-Path -Path $versionFolder -ChildPath "$ModuleName.psd1" Set-Content -Path $resourcePsm1 -Value @" Configuration $ResourceName { $($configuration.Definition) } "@ $resourceNames = @() # If we already got a module manifest, then pick up any existing resource names. if (Test-Path -Path $modulePsd1) { $moduleManifest = Import-PowerShellDataFile -Path $modulePsd1 $resourceNames = @($moduleManifest.DscResourcesToExport) } if ($resourceNames -notcontains $ResourceName) { $resourceNames += $ResourceName } New-ModuleManifest -Path $modulePsd1 ` -Guid (New-Guid).Guid ` -Author $Author ` -Description $Description ` -ModuleVersion $ModuleVersion ` -DscResourcesToExport $resourceNames New-ModuleManifest -Path $resourcePsd1 ` -RootModule "$ResourceName.schema.psm1" ` -Guid (New-Guid).Guid } |