diff --git a/ADMF/functions/Set-AdmfContext.ps1 b/ADMF/functions/Set-AdmfContext.ps1 index a6cdba7..f817ad7 100644 --- a/ADMF/functions/Set-AdmfContext.ps1 +++ b/ADMF/functions/Set-AdmfContext.ps1 @@ -2,54 +2,54 @@ <# .SYNOPSIS Applies a set of configuration contexts. - + .DESCRIPTION Applies a set of configuration contexts. This merges the settings from all selected contexts into one configuration set. - + .PARAMETER Context Name of context or full context object to apply. - + .PARAMETER Interactive Show an interactive context selection prompt. This is designed for greater convenience when managing many forests. The system automatically uses Set-AdmfContext with this parameter when directly testing or invoking against a new domain without first selecting a context to apply. - + .PARAMETER ReUse ADMF remembers the last contexts assigned to a specific server/domain. By setting this parameter, it will re-use those contexts, rather than show the prompt again. This parameter is used by the system to prevent prompting automatically on each call. - + .PARAMETER DefineOnly Do not actually switch configuration sets. Just register the selected Contexts to the target domain, after validating the selection. - + .PARAMETER Server The server / domain to work with. - + .PARAMETER Credential The credentials to use for this operation. - + .PARAMETER NoDomain If used against a target without a domain, it will skip AD connect and instead use the server name for Context caching purposes. - + .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions. This is less user friendly, but allows catching exceptions in calling scripts. - + .EXAMPLE PS C:\> Set-AdmfContext -Interactive - + Interactively pick to select the contexts to apply to the user's own domain. - + .EXAMPLE PS C:\> Set-AdmfContext -Interactive -Server contoso.com - + Interactively pick to select the contexts to apply to the contoso.com domain. - + .EXAMPLE PS C:\> Set-AdmfContext -Context Default, Production, Europe -Server eu.contoso.com - + Configures the contexts Default, Production and Europe to be applied to eu.contoso.com. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] @@ -59,51 +59,51 @@ [Alias('Name')] [object[]] $Context, - + [Parameter(ParameterSetName = 'interactive')] [switch] $Interactive, - + [switch] $ReUse, - + [switch] $DefineOnly, - + [PSFComputer] $Server = $env:USERDNSDOMAIN, - + [System.Management.Automation.PSCredential] $Credential, - + [Parameter(DontShow = $true)] [switch] $NoDomain, - + [switch] $EnableException ) - + begin { #region Utility Functions function Set-Context { [CmdletBinding()] param ( $ContextObject, - + [string] $Server, - + [System.Management.Automation.PSCredential] $Credential, - + [System.Management.Automation.PSCmdlet] $Cmdlet, - + [bool] $EnableException ) - + Write-PSFMessage -String 'Set-AdmfContext.Context.Applying' -StringValues $ContextObject.Name -Target $ContextObject $parameters = $PSBoundParameters | ConvertTo-PSFHashtable -Include Server, Credential $stopParam = @{ @@ -112,7 +112,7 @@ Target = $ContextObject StepsUpward = 1 } - + #region PreImport if (Test-Path "$($ContextObject.Path)\preImport.ps1") { try { $null = & "$($ContextObject.Path)\preImport.ps1" @parameters } @@ -124,7 +124,7 @@ } } #endregion PreImport - + #region Forest $forestFields = @{ 'exchangeschema' = Get-Command Register-FMExchangeSchema @@ -134,10 +134,10 @@ 'sites' = Get-Command Register-FMSite 'subnets' = Get-Command Register-FMSubnet } - + foreach ($key in $forestFields.Keys) { if (-not (Test-Path "$($ContextObject.Path)\forest\$key")) { continue } - + foreach ($file in (Get-ChildItem "$($ContextObject.Path)\forest\$key\" -Recurse -Filter "*.json")) { Write-PSFMessage -Level Debug -String 'Set-AdmfContext.Context.Loading' -StringValues $ContextObject.Name, $key, $file.FullName try { @@ -156,7 +156,7 @@ } } } - + if (Test-Path "$($ContextObject.Path)\forest\schemaldif") { $filesProcessed = @() @@ -201,7 +201,7 @@ foreach ($file in (Get-ChildItem "$($ContextObject.Path)\forest\schemaldif\" -Recurse -Filter "*.ldf")) { # Skip files already defined in json if ($filesProcessed -contains $file.FullName) { continue } - + try { Register-FMSchemaLdif -Name $file.BaseName -Path $file.FullName -ContextName $ContextObject.Name -ErrorAction Stop } catch { @@ -212,7 +212,7 @@ } #endregion Process Ldif Files without configuration } - + # Forest Level if (Test-Path "$($ContextObject.Path)\forest\forest_level.json") { @@ -230,7 +230,7 @@ return } } - + #region NTAuthStore if (Test-Path "$($ContextObject.Path)\forest\ntAuthStore") { @@ -276,7 +276,7 @@ } #endregion NTAuthStore #endregion Forest - + #region Domain $domainFields = @{ 'accessrules' = (Get-Command Register-DMAccessRule) @@ -295,10 +295,10 @@ 'psos' = (Get-Command Register-DMPasswordPolicy) 'users' = (Get-Command Register-DMUser) } - + foreach ($key in $domainFields.Keys) { if (-not (Test-Path "$($ContextObject.Path)\domain\$key")) { continue } - + foreach ($file in (Get-ChildItem "$($ContextObject.Path)\domain\$key\" -Recurse -Filter "*.json")) { Write-PSFMessage -Level Debug -String 'Set-AdmfContext.Context.Loading' -StringValues $ContextObject.Name, $key, $file.FullName try { @@ -365,7 +365,7 @@ return } } - + # Domain Level if (Test-Path "$($ContextObject.Path)\domain\domain_level.json") { @@ -383,7 +383,7 @@ return } } - + # Content Mode if (Test-Path "$($ContextObject.Path)\domain\content_mode.json") { $file = Get-Item "$($ContextObject.Path)\domain\content_mode.json" @@ -415,7 +415,27 @@ } } #endregion Domain - + + #region WinRMMode + + + if (Test-Path "$($ContextObject.Path)\domain\WinRM_mode.json") { + $file = Get-Item "$($ContextObject.Path)\domain\WinRM_mode.json" + Write-PSFMessage -Level Debug -String 'Set-AdmfContext.Context.Loading' -StringValues $ContextObject.Name, 'WinRMMode', $file.FullName + try { + $dataSet = Get-Content $file.FullName -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop | Write-Output | ConvertTo-PSFHashtable -Include ([string[]](Get-Command Set-DMWinRMMode).Parameters.Keys) + Set-DMWinRMMode @dataSet + } + catch + { + Clear-AdcConfiguration + Stop-PSFFunction @stopParam -String 'Set-AdmfContext.Context.Error.DomainConfig' -StringValues $ContextObject.Name, 'WinRMMode', $file.FullName -ErrorRecord $_ + return + } + } + + #endregon WinRMMode + #region DC if (Test-Path "$($ContextObject.Path)\dc\dc_config.json") { try { $dcData = Get-Content "$($ContextObject.Path)\dc\dc_config.json" -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop } @@ -425,23 +445,23 @@ Stop-PSFFunction @stopParam -String 'Set-AdmfContext.Context.Error.DCConfig' -StringValues $ContextObject.Name -ErrorRecord $_ return } - + if ($null -ne $dcData.NoDNS) { Set-PSFConfig -FullName 'DCManagement.Defaults.NoDNS' -Value $dcData.NoDNS } if ($null -ne $dcData.NoReboot) { Set-PSFConfig -FullName 'DCManagement.Defaults.NoReboot' -Value $dcData.NoReboot } if ($dcData.DatabasePath) { Set-PSFConfig -FullName 'DCManagement.Defaults.DatabasePath' -Value $dcData.DatabasePath } if ($dcData.LogPath) { Set-PSFConfig -FullName 'DCManagement.Defaults.LogPath' -Value $dcData.LogPath } if ($dcData.SysvolPath) { Set-PSFConfig -FullName 'DCManagement.Defaults.SysvolPath' -Value $dcData.SysvolPath } } - + $dcFields = @{ 'shares' = Get-Command Register-DCShare 'fsaccessrules' = Get-Command Register-DCAccessRule } - + foreach ($key in $dcFields.Keys) { if (-not (Test-Path "$($ContextObject.Path)\dc\$key")) { continue } - + foreach ($file in (Get-ChildItem "$($ContextObject.Path)\dc\$key\" -Recurse -Filter "*.json")) { Write-PSFMessage -Level Debug -String 'Set-AdmfContext.Context.Loading' -StringValues $ContextObject.Name, $key, $file.FullName @@ -465,7 +485,7 @@ } } #endregion DC - + #region PostImport if (Test-Path "$($ContextObject.Path)\postImport.ps1") { try { $null = & "$($ContextObject.Path)\postImport.ps1" @parameters } @@ -479,16 +499,16 @@ #endregion PostImport } #endregion Utility Functions - + $parameters = $PSBoundParameters | ConvertTo-PSFHashtable -Include Server, Credential - + $selectedContexts = @{ } # Common parameters for Stop-PSFFunction $commonParam = @{ EnableException = $EnableException Continue = $true } - + if ($NoDomain) { $domain = [pscustomobject]@{ DNSRoot = $Server } @@ -506,7 +526,7 @@ process { if (Test-PSFFunctionInterrupt) { return } - + #region Explicitly specified contexts foreach ($contextObject in $Context) { if ($contextObject -is [string]) { @@ -545,7 +565,7 @@ } end { if (Test-PSFFunctionInterrupt) { return } - + #region Handle errors in selection $missingPrerequisites = $selectedContexts.Values.Prerequisites | Where-Object { $_ -notin $selectedContexts.Values.Name } if ($missingPrerequisites) { @@ -558,7 +578,7 @@ return } #endregion Handle errors in selection - + # Do nothing if the currently loaded contexts are equal to the selected ones if ( $script:loadedContexts.Name -and @@ -570,20 +590,20 @@ if (-not $script:assignedContexts["$($domain.DNSRoot)"]) { $script:assignedContexts["$($domain.DNSRoot)"] = $selectedContexts.Values } return } - + # In Define Only Mode: Register Context to domain and terminate peacefully if ($DefineOnly) { $script:assignedContexts["$($domain.DNSRoot)"] = $selectedContexts.Values | Sort-Object Weight return } - + # Kill previous configuration $script:loadedContexts = @() Clear-AdcConfiguration - + Set-PSFTaskEngineCache -Module ADMF -Name currentlyImportingContexts -Value $selectedContexts.Values - + foreach ($contextObject in ($selectedContexts.Values | Sort-Object Weight)) { if (Test-PSFFunctionInterrupt) { return } Set-Context @parameters -ContextObject $contextObject -Cmdlet $PSCmdlet -EnableException $EnableException