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.

    .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()]
    param
    (
        [Parameter(Mandatory = $true)]
        [string]
        $ConfigurationName,

        [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 = '.\'
    )

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

    $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
}