functions/New-AdmfContextModule.ps1
function New-AdmfContextModule { <# .SYNOPSIS Create an ADMF Client PowerShell module. .DESCRIPTION Create an ADMF Client PowerShell module. Specify which contexts to use from a repository to which they have previously been published. It will then dynamically create a PowerShell module containing all contexts and their dependencies and publish them under its own Context store once imported. .PARAMETER Name Name of the contexts to include. Supports plain "Name" or the PowerShell module notation. Examples: "Default" @{ ModuleName = 'SecBaseline' } @{ ModuleName = 'SecBaseline'; ModuleVersion = '2.0.0' } @{ ModuleName = 'SecBaseline'; RequiredVersion = '2.3.1' } .PARAMETER Repository Name of the repository to download from. .PARAMETER Path Path where to write the finished module to. .PARAMETER ModuleName Name of the module to generate. .PARAMETER ModuleOption Additional options to include in the module code when generating the module. Confirm: Injects all ADMF component modules with the requirement to confirm all changes. .PARAMETER AliasPrefix Create aliases for the common ADMF commands. This simplifies guiding users into loading the module containing their configuration settings. Rather than having them run Test-ADMFDomain, you could have them run Test-ConDomain, which would then implicitly load the generated module and make the contexts available, without having to first manually import the module generated. .PARAMETER ModuleVersion The version of the module to generate. Defaults to 1.0.0 .PARAMETER Credential Credentials to use for accessing the powershell repository. .PARAMETER ModuleCode Additional code to iunclude in the module generated .PARAMETER GetV3 Use PowerShellGet V3 or later. Defaults to the configuration setting of ADMF.PowerShellGet.UseV3. .EXAMPLE PS C:\> New-AdmfContextModule -Name Default -Repository Contoso -Path . -ModuleName Whatever -ModuleOption Confirm -AliasPrefix WE Retrieves the "Default" context from the "Contoso" repository. It will then wrap it into a module named "Whatever", injecting a requirement to confirm all changes and include aliases for the common ADMF commands with the WE prefix (e.g. Test-WEDomain) #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [Parameter(Mandatory = $true)] $Name, [Parameter(Mandatory = $true)] [string] $Repository, [Parameter(Mandatory = $true)] [string] $Path, [Parameter(Mandatory = $true)] [string] $ModuleName, [ValidateSet('Confirm')] [string[]] $ModuleOption = 'Confirm', [string] $AliasPrefix, [version] $ModuleVersion = '1.0.0', [PSCredential] $Credential, [ScriptBlock] $ModuleCode, [switch] $GetV3 ) trap { Remove-PSFTempItem -ModuleName ADMF -Name * throw $_ } # Resolve Target Module Names / Versions $modules = foreach ($entry in $Name) { if ($entry -is [string]) { @{ Name = $entry } } else { $entry | ConvertTo-PSFHashtable Name, ModuleVersion, RequiredVersion } } foreach ($module in $modules) { if ($module.Name -notlike 'ADMF.Context.*') { $module.Name = "ADMF.Context.$($module.Name)" } if ($GetV3) { $module.Remove('ModuleVersion') if ($module.RequiredVersion) { $module.Version = $module.RequiredVersion $module.Remove('RequiredVersion') } } else { if ($module.ModuleVersion) { $module.MinimumVersion = $module.ModuleVersion $module.Remove('ModuleVersion') } } } # Create TEMP folder and deploy them from repository $folder = New-PSFTempDirectory -Name contextpath -ModuleName ADMF $moduleParam = $PSBoundParameters | ConvertTo-PSFHashtable -Include Repository, Credential foreach ($module in $modules) { if ($GetV3) { Save-PSResource @moduleParam @module -Path $folder } else { Save-Module @moduleParam @module -Path $folder } } # Create Module & Copy Contexts $moduleRoot = New-PSFTempDirectory -Name moduleroot -ModuleName ADMF -DirectoryName $ModuleName $manifest = @{ Path = "$moduleRoot\$ModuleName.psd1" ModuleVersion = $ModuleVersion RootModule = "$ModuleName.psm1" FunctionsToExport = @() CmdletsToExport = @() AliasesToExport = @() VariablesToExport = @() } if ($AliasPrefix) { $manifest.AliasesToExport = "Invoke-$($aliasPrefix)Forest", "Invoke-$($aliasPrefix)Domain", "Invoke-$($aliasPrefix)DC", "Invoke-$($aliasPrefix)Item", "Test-$($aliasPrefix)Domain", "Test-$($aliasPrefix)DC", "Test-$($aliasPrefix)Forest" } New-ModuleManifest @manifest $null = New-Item -Path $moduleRoot -Name "$ModuleName.psm1" -ItemType File $contextRoot = New-Item -Path $moduleRoot -Name Contexts -ItemType Directory $contextConfig = Get-Item -Path "$folder/*/*/*/*/context.json" $contextPaths = $contextConfig.FullName | Split-Path | Split-Path | Sort-Object -Unique foreach ($contextPath in $contextPaths) { Copy-Item -Path $contextPath -Destination $contextRoot.FullName -Recurse -Force } # Add module content $content = @() ## Register Context Store $content += "Set-PSFConfig -FullName 'ADMF.Context.Store.$ModuleName' -Value `"`$PSScriptRoot\Contexts`"" ## Confirm Preference if ($ModuleOption -contains 'Confirm') { $content += @' # Confirm by default & (Get-Module DCManagement) { $script:ConfirmPreference = 'Low' } & (Get-Module DomainManagement) { $script:ConfirmPreference = 'Low' } & (Get-Module ForestManagement) { $script:ConfirmPreference = 'Low' } '@ } ## Add Alias for the ADMF Commands if ($AliasPrefix) { $content += "`$aliasPrefix = '$aliasPrefix'" $content += @' # Set Aliases for module $aliases = @{ 'Invoke-AdmfDC' = "Invoke-$($aliasPrefix)DC" 'Invoke-AdmfDomain' = "Invoke-$($aliasPrefix)Domain" 'Invoke-AdmfForest' = "Invoke-$($aliasPrefix)Forest" 'Invoke-AdmfItem' = "Invoke-$($aliasPrefix)Item" 'Test-AdmfDC' = "Test-$($aliasPrefix)DC" 'Test-AdmfDomain' = "Test-$($aliasPrefix)Domain" 'Test-AdmfForest' = "Test-$($aliasPrefix)Forest" } foreach ($pair in $aliases.GetEnumerator()) { Set-Alias -Name $pair.Value -Value $pair.Key } '@ } ## Add Custom Code if ($ModuleCode) { $content += $ModuleCode.ToString() } $content | Set-Content -Path "$moduleRoot\$ModuleName.psm1" # Copy to destination Copy-Item -Path $moduleRoot -Destination $Path -Recurse Remove-PSFTempItem -ModuleName ADMF -Name * } |