ExportedFunctions/Set-DryADConfiguration.ps1
Using Namespace System.IO Using Namespace System.Collections.Generic # DryActiveDirectory is an AD config module for use with DryDeploy, or by itself. # # Copyright (C) 2021 Bjørn Henrik Formo (bjornhenrikformo@gmail.com) # LICENSE: https://raw.githubusercontent.com/bjoernf73/DryActiveDirectory/main/LICENSE # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Function Set-DryADConfiguration { [CmdLetBinding(DefaultParameterSetName='Local')] Param ( [Parameter(HelpMessage="Variables are used for replacements in configs and GPOs")] [List[PSObject]] $Variables, [Parameter(Mandatory,HelpMessage="Path of the configuration directory")] [DirectoryInfo] $ConfigurationPath, [Parameter(HelpMessage="Shortname (not IP!) of the computer for which the configuration is run")] [String] $ComputerName, [Parameter(HelpMessage="Active Directory site name for which the configuration is done")] [String] $ADSite, [Parameter(HelpMessage="Array of one or more components to process; OUs, RightsGroups, RoleGroups, GroupMembers (or 'Groups' for all the previous 3), Rights, GPOImports, GPOLinks (or 'GPOs' for both), WMIFilterImports, WMIFilterLinks (or just 'WMIFilters' for both), ADSchema, NETLOGON, AdmTemplates, Users, UserGroupMembers. By default, all are processed. Only specify during development to limit the scope")] [ValidateSet('OUs','RightsGroups','RoleGroups','GroupMembers','Groups','Rights','GPOImports','GPOLinks','GPOs','WMIFilters', 'WMIFilterImports','WMIFilterLinks','ADSchema','NETLOGON','AdmTemplates','Users','UserGroupMembers')] [String[]] $Components, [Parameter(Mandatory,ParameterSetName='Remote',HelpMessage="Specify a resolvable name or IP to a Domain Controller to remote into")] [Parameter(Mandatory,ParameterSetName='Local',HelpMessage="Specify a resolvable name or IP to a Domain Controller to perform AD actions on")] [String] $DomainController, [Parameter(Mandatory,ParameterSetName='Remote')] [PSSession] $PSSession, [Parameter(HelpMessage="Should only be `$True when called from DryDeploy. Will allow autogenerated passwords for users that are created to be stored in DryDeploy's Credentials store. If you're running standalone (not as part of DryDeploy, hence `$DryDeploy = `$False), then passwords of users that are configured with the property .password.get_or_generate = 'generate', are autogenerated, but lost. You will have to reset the passwords of the created users to access those accounts. Use instead .password.get_or_generate = 'get' to be prompted for the credentials.")] [Switch]$DryDeploy ) Try { [String]$ExecutionType = $PSCmdlet.ParameterSetName If ($ExecutionType -eq 'Remote') { $ConfigurationPublicCertificatePath = Join-Path -Path $ConfigurationPath -ChildPath "RemoteSystemPublicCertificate.cer" $DomainDN = Get-DryADDomainProperty -Property 'DistinguishedName' -PSSession $PSSession $DomainFQDN = Get-DryADDomainProperty -Property 'DNSRoot' -PSSession $PSSession $DomainNB = Get-DryADDomainProperty -Property 'NetBIOSName' -PSSession $PSSession } Else { $DomainDN = Get-DryADDomainProperty -Property 'DistinguishedName' -DomainController $DomainController $DomainFQDN = Get-DryADDomainProperty -Property 'DNSRoot' -DomainController $DomainController $DomainNB = Get-DryADDomainProperty -Property 'NetBIOSName' -DomainController $DomainController } ol i 'Set-DryADConfiguration started' -sh ol i 'Execution Type', "$ExecutionType" ol i 'ConfigurationPath', "$ConfigurationPath" ol i 'Domain scope', "$DomainFQDN" ol i 'Site scope', "$ADSite" ol i 'Computer scope', "$ComputerName" $SourceGPOsPath = Join-Path -Path $ConfigurationPath -ChildPath "GPOs" # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # REPLACEMENT HASH # The Replacement Hash is mainly used for string replacement in the module # 'GPOManagement', which is not part of DryDeploy or DryActiveDirectory. Only # in use if you have access to that module and use 'jsonified' GPOs. # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ReplacementHash = @{} ForEach ($Var in $Variables) { $ReplacementHash.Add("###$($Var.Name)###",$Var.Value) } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ROLE CONFIGURATION OBJECT # Pick up all jsons (*.json) and commented jsons (*.jsonc) in # $ConfigurationPath, and merge into the $RoleConfiguration # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Remove-Variable -Name RoleConfiguration,ADConfObject,ConfigurationPathFiles -ErrorAction Ignore $RoleConfiguration = New-Object -TypeName PSObject $ConfigurationPathFiles = @(Get-ChildItem -Path "$ConfigurationPath\*" -Include "*.jsonc","*.json" -ErrorAction Stop) ForEach ($ADConfFile in $ConfigurationPathFiles) { $ADConfObject = Get-DryADCommentedJson -Path $ADConfFile.FullName -ErrorAction Stop $RoleConfiguration = (Merge-DryADPSObjects -FirstObject $RoleConfiguration -SecondObject $ADConfObject) } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # CASING # Variables that specifies case modification of OUs, GPOs, groups and users. # Valid values are 'upper', lower', 'capitalized' and 'ignore'. Defaults # to ignore # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # [String]$OUCase = 'ignore' [String]$GPOCase = 'ignore' [String]$GroupCase = 'ignore' [String]$UserCase = 'ignore' If ($RoleConfiguration.casing.ad_organizational_unit_case) { [String]$OUCase = $RoleConfiguration.casing.ad_organizational_unit_case } If ($RoleConfiguration.casing.ad_gpo_case) { [String]$GPOCase = $RoleConfiguration.casing.ad_gpo_case } If ($RoleConfiguration.casing.ad_group_case) { [String]$GroupCase = $RoleConfiguration.casing.ad_group_case } If ($RoleConfiguration.casing.ad_user_case) { [String]$UserCase = $RoleConfiguration.casing.ad_user_case } ol v 'Casing - OUs', "$OUCase" ol v 'Casing - GPOs', "$GPOCase" ol v 'Casing - Groups', "$GroupCase" ol v 'Casing - Users', "$UserCase" # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # PROGRESS COUNTERS # Counts configurations to process before start, to show # a progress bar during configuration # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # [int]$ElementsCounter = 0 [int]$NumberOfElementsToProcess = 0 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # AD SCHEMA # Action: Get and Count # Dataset: $RoleConfiguration # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If (Test-Path -Path "$ConfigurationPath\ADSchema" -ErrorAction Ignore) { If ( ($Components -icontains 'ADSchema') -or ($Null -eq $Components) ) { $ProcessADSchema = $True # [Array]$ADSchemaExtensions = $RoleConfiguration.active_directory_schema_updates $ADSchemaExtensions = @(Get-ChildItem -Path "$ConfigurationPath\ADSchema\*" -Include "*.LDF") $NumberOfElementsToProcess += $ADSchemaExtensions.Count } $NumberOfADSchemaExtensions = $ADSchemaExtensions.Count } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # NETLOGON # Action: Count # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If (Test-Path -Path "$ConfigurationPath\NETLOGON" -ErrorAction Ignore) { If ( ($Components -icontains 'NETLOGON') -or ($Null -eq $Components) ) { $ProcessNETLOGON = $True $NumberOfElementsToProcess++ $NumberOfNETLOGONs = 1 } } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # AdmTemplates # Action: Count # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If (Test-Path -Path "$ConfigurationPath\AdmTemplates" -ErrorAction Ignore) { If ( ($Components -icontains 'AdmTemplates') -or ($Null -eq $Components) ) { $ProcessAdmTemplates = $True $NumberOfElementsToProcess++ } } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ORGANIZATIONAL UNITS # Action: Get, Count and String Replacement # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ($RoleConfiguration.active_directory_ou_schema) { # Elements have a scope; domain, site or computer. [Array]$DomainOUs += @($RoleConfiguration.active_directory_ou_schema | Where-Object { $_.scope -contains 'domain' } ) [Array]$SiteOUs += @($RoleConfiguration.active_directory_ou_schema | Where-Object { $_.scope -contains 'site' } ) [Array]$ComputerOUs += @($RoleConfiguration.active_directory_ou_schema | Where-Object { $_.scope -contains 'computer' } ) If (($Components -icontains 'OUs') -or ($Null -eq $Components)) { $ProcessOUs = $True $NumberOfElementsToProcess += ( $DomainOUs.Count + $SiteOUs.Count + $ComputerOUs.Count ) } } # Replace all replacement patterns If ($DomainOUs) { $DomainOUs = Resolve-DryADReplacementPatterns -inputobject $DomainOUs -Variables $Variables } If ($SiteOUs) { $SiteOUs = Resolve-DryADReplacementPatterns -inputobject $SiteOUs -Variables $Variables } If ($ComputerOUs) { $ComputerOUs = Resolve-DryADReplacementPatterns -inputobject $ComputerOUs -Variables $Variables } $NumberOfOUs = $DomainOUs.Count + $SiteOUs.Count + $ComputerOUs.Count # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ORGANIZATIONAL UNITS PATHS # Action: Resolve Path from Paths # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # DomainOUs that are missing 'path'-property must resolve it from 'paths' ForEach ($OU in $DomainOUs | Where-Object { ($Null -eq $_.Path) -and ($Null -ne $_.Paths) }) { Remove-Variable -Name Path -ErrorAction Ignore $Path = $OU.paths.domain If ($Null -eq $Path) { ol e "Unable to find `$OU.paths.domain on '$($OU.Tag)'" Throw "Unable to find `$OU.paths.domain on '$($OU.Tag)'" } ElseIf ($Path -is [Array]) { ol e "Multiple definitions `$OU.paths.domain on '$($OU.Tag)'" Throw "Multiple definitions `$OU.paths.domain on '$($OU.Tag)'" } # Add Path property, then remove .paths $OU | Add-Member -MemberType NoteProperty -Name 'Path' -Value $Path -Force $OU.PSObject.Properties.Remove('paths') Remove-Variable -Name Path -ErrorAction Ignore } # SiteOUs that are missing 'path'-property must resolve it from 'paths' ForEach ($OU in $SiteOUs | Where-Object { ($Null -eq $_.Path) -and ($Null -ne $_.Paths) }) { Remove-Variable -Name Path -ErrorAction Ignore $Path = $OU.paths.site If ($Null -eq $Path) { ol e "Unable to find `$OU.paths.Site on '$($OU.Tag)'" Throw "Unable to find `$OU.paths.Site on '$($OU.Tag)'" } ElseIf ($Path -is [Array]) { ol e "Multiple definitions `$OU.paths.Site on '$($OU.Tag)'" Throw "Multiple definitions `$OU.paths.Site on '$($OU.Tag)'" } # Add Path property, then remove .paths $OU | Add-Member -MemberType NoteProperty -Name 'Path' -Value $Path -Force $OU.PSObject.Properties.Remove('paths') Remove-Variable -Name Path -ErrorAction Ignore } # ComputerOUs that are missing 'path'-property must resolve it from 'paths' ForEach ($OU in $ComputerOUs | Where-Object { ($Null -eq $_.Path) -and ($Null -ne $_.Paths) }) { Remove-Variable -Name Path -ErrorAction Ignore $Path = $OU.paths.computer If ($Null -eq $Path) { ol e "Unable to find `$OU.paths.computer on '$($OU.Tag)'" Throw "Unable to find `$OU.paths.computer on '$($OU.Tag)'" } ElseIf ($Path -is [Array]) { ol e "Multiple definitions `$OU.paths.computer on '$($OU.Tag)'" Throw "Multiple definitions `$OU.paths.computer on '$($OU.Tag)'" } # Add Path property, then remove .paths $OU | Add-Member -MemberType NoteProperty -Name 'Path' -Value $Path -Force $OU.PSObject.Properties.Remove('paths') Remove-Variable -Name Path -ErrorAction Ignore } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ORGANIZATIONAL UNITS PATHS # Action: Resolve Child Paths from Parents # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $AnOUWasResolved = $True Do { $AnOUWasResolved = $False # Loop through DomainOUs that already have a path ForEach ($ResolvedOU in $DomainOUs | Where-Object { $null -ne $_.path }) { # Loop through DomainOUs that do not have a path ForEach ($UnresolvedOU in $DomainOUs | Where-Object { $null -eq $_.path }) { Try { Remove-Variable -Name Parent -ErrorAction Ignore $Parent = $UnresolvedOU.parents | Where-Object { ($_.parentscope -eq 'domain') -and ($_.scope -eq 'domain') -and ($_.tag -eq $ResolvedOU.tag) } If ($Parent) { $Path = Get-DryADOUPathFromTag -Tag $Parent.tag -OUs $DomainOUs -Scope 'domain' -Child $Parent.child $AnOUWasResolved = $True # Add Path property $UnresolvedOU | Add-Member -MemberType NoteProperty -Name 'Path' -Value $Path -Force # Once resolved, remove parents $UnresolvedOU.PSObject.Properties.Remove('parents') } } Catch { $PSCmdLet.ThrowTerminatingError($_) } Finally { Remove-Variable -Name Path,Parent -ErrorAction Ignore } } # Loop through SiteOUs that do not have a path ForEach ($UnresolvedOU in $SiteOUs | Where-Object { $null -eq $_.path }) { Try { Remove-Variable -Name Parent -ErrorAction Ignore $Parent = $UnresolvedOU.parents | Where-Object { ($_.parentscope -eq 'domain') -and ($_.scope -eq 'site') -and ($_.tag -eq $ResolvedOU.tag) } If ($Parent) { $Path = Get-DryADOUPathFromTag -Tag $Parent.tag -OUs $DomainOUs -Scope 'site' -Child $Parent.child $AnOUWasResolved = $True # Add Path property $UnresolvedOU | Add-Member -MemberType NoteProperty -Name 'Path' -Value $Path -Force # Once resolved, remove parents $UnresolvedOU.PSObject.Properties.Remove('parents') } } Catch { $PSCmdLet.ThrowTerminatingError($_) } Finally { Remove-Variable -Name Path,Parent -ErrorAction Ignore } } # Loop through ComputerOUs that do not have a path ForEach ($UnresolvedOU in $ComputerOUs | Where-Object { $null -eq $_.path }) { Try { Remove-Variable -Name Parent -ErrorAction Ignore $Parent = $UnresolvedOU.parents | Where-Object { ($_.parentscope -eq 'domain') -and ($_.scope -eq 'computer') -and ($_.tag -eq $ResolvedOU.tag) } If ($Parent) { $Path = Get-DryADOUPathFromTag -Tag $Parent.tag -OUs $DomainOUs -Scope 'computer' -Child $Parent.child $AnOUWasResolved = $True # Add Path property $UnresolvedOU | Add-Member -MemberType NoteProperty -Name 'Path' -Value $Path -Force # Once resolved, remove parents $UnresolvedOU.PSObject.Properties.Remove('parents') } } Catch { $PSCmdLet.ThrowTerminatingError($_) } Finally { Remove-Variable -Name Path,Parent -ErrorAction Ignore } } } # Loop through SiteOUs that already have a path ForEach ($ResolvedOU in $SiteOUs | Where-Object { $null -ne $_.Path }) { # Loop through SiteOUs that do not have a path ForEach ($UnresolvedOU in $SiteOUs | Where-Object { $null -eq $_.path }) { Try { Remove-Variable -Name Parent -ErrorAction Ignore $Parent = $UnresolvedOU.parents | Where-Object { ($_.parentscope -eq 'site') -and ($_.scope -eq 'site') -and ($_.tag -eq $ResolvedOU.tag) } If ($Parent) { $Path = Get-DryADOUPathFromTag -Tag $Parent.tag -OUs $SiteOUs -Scope 'site' -Child $Parent.child $AnOUWasResolved = $True # Add Path property $UnresolvedOU | Add-Member -MemberType NoteProperty -Name 'Path' -Value $Path -Force # Once resolved, remove parents $UnresolvedOU.PSObject.Properties.Remove('parents') } } Catch { $PSCmdLet.ThrowTerminatingError($_) } Finally { Remove-Variable -Name Path,Parent -ErrorAction Ignore } } # Loop through ComputerOUs that do not have a path ForEach ($UnresolvedOU in $ComputerOUs | Where-Object { $null -eq $_.path }) { Try { Remove-Variable -Name Parent -ErrorAction Ignore $Parent = $UnresolvedOU.parents | Where-Object { ($_.parentscope -eq 'site') -and ($_.scope -eq 'computer') -and ($_.tag -eq $ResolvedOU.tag) } If ($Parent) { $Path = Get-DryADOUPathFromTag -Tag $Parent.tag -OUs $SiteOUs -Scope 'computer' -Child $Parent.child $AnOUWasResolved = $True # Add Path property $UnresolvedOU | Add-Member -MemberType NoteProperty -Name 'Path' -Value $Path -Force # Once resolved, remove parents $UnresolvedOU.PSObject.Properties.Remove('parents') } } Catch { $PSCmdLet.ThrowTerminatingError($_) } Finally { Remove-Variable -Name Path,Parent -ErrorAction Ignore } } } # Loop through ComputerOUs that already have a path ForEach ($ResolvedOU in $ComputerOUs | Where-Object { $null -ne $_.Path }) { # Loop through ComputerOUs that do not have a path ForEach ($UnresolvedOU in $ComputerOUs | Where-Object { $null -eq $_.path }) { Try { Remove-Variable -Name Parent -ErrorAction Ignore $Parent = $UnresolvedOU.parents | Where-Object { ($_.parentscope -eq 'computer') -and ($_.scope -eq 'computer') -and ($_.tag -eq $ResolvedOU.tag) } If ($Parent) { $Path = Get-DryADOUPathFromTag -Tag $Parent.tag -OUs $ComputerOUs -Scope 'computer' -Child $Parent.child $AnOUWasResolved = $True # Add Path property $UnresolvedOU | Add-Member -MemberType NoteProperty -Name 'Path' -Value $Path -Force # Once resolved, remove parents $UnresolvedOU.PSObject.Properties.Remove('parents') } } Catch { $PSCmdLet.ThrowTerminatingError($_) } Finally { Remove-Variable -Name Path,Parent -ErrorAction Ignore } } } } While ($AnOUWasResolved) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ORGANIZATIONAL UNITS PATHS # Action: Display resolved paths # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ($DomainOUs.count -gt 0) { ol i "Resolved Domain OU Tags" -sh ForEach ($OU in $DomainOUs) { ol i "$($OU.Tag)","$($OU.Path)" } } If ($SiteOUs.count -gt 0) { ol i "Resolved Site OU Tags" -sh ForEach ($OU in $SiteOUs) { ol i "$($OU.Tag)","$($OU.Path)" } } If ($ComputerOUs.count -gt 0) { ol i "Resolved Computer OU Tags" -sh ForEach ($OU in $ComputerOUs) { ol i "$($OU.Tag)","$($OU.Path)" } } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ORGANIZATIONAL UNITS PATHS # Action: Convert To 'distinguishedName' and Correct Case # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ForEach ($OU in $DomainOUs) { $OU.Path = ConvertTo-DryADDistinguishedName -Name $OU.Path -Case $OUcase ol d "Domain OU dN for $($OU.Tag) is: '$($OU.Path)'" } ForEach ($OU in $SiteOUs) { $OU.Path = ConvertTo-DryADDistinguishedName -Name $OU.Path -Case $OUcase ol d "Site OU dN for $($OU.Tag) is: '$($OU.Path)'" } ForEach ($OU in $ComputerOUs) { $OU.Path = ConvertTo-DryADDistinguishedName -Name $OU.Path -Case $OUcase ol d "Site OU dN for $($OU.Tag) is: '$($OU.Path)'" } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # WMI Filter Imports and Links # Action: Get, Count and String Replacement # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ( ($Components -icontains 'WMIFilters') -or ($Components -icontains 'WMIFilterImports') -or ($Components -icontains 'WMIFilterLinks') -or ($Null -eq $Components) ) { If ($RoleConfiguration.wmifilters) { # Get the elements [Array]$DomainWMIFilters += @($RoleConfiguration.wmifilters | Where-Object { $_.scope -eq 'domain' } ) [Array]$SiteWMIFilters += @($RoleConfiguration.wmifilters | Where-Object { $_.scope -eq 'site' } ) [Array]$ComputerWMIFilters += @($RoleConfiguration.wmifilters | Where-Object { $_.scope -eq 'computer' } ) # Replace any replacement pattern $DomainWMIFilters = Resolve-DryADReplacementPatterns -inputobject $DomainWMIFilters -Variables $Variables $SiteWMIFilters = Resolve-DryADReplacementPatterns -inputobject $SiteWMIFilters -Variables $Variables $ComputerWMIFilters = Resolve-DryADReplacementPatterns -inputobject $ComputerWMIFilters -Variables $Variables # Count the WMIFilters, but only if we're actually importing them If ( ($Components -icontains 'WMIFilters') -or ($Components -icontains 'WMIFilterImports') -or ($Null -eq $Components) ) { $ProcessWMIFilterImports = $True $NumberOfElementsToProcess += ($DomainWMIFilters.Count + $SiteWMIFilters.Count + $ComputerWMIFilters.Count) $NumberOfWMIFilters += ($DomainWMIFilters.Count + $SiteWMIFilters.Count + $ComputerWMIFilters.Count) } If ( ($Components -icontains 'WMIFilters') -or ($Components -icontains 'WMIFilterLinks') -or ($Null -eq $Components) ) { $ProcessWMIFilterLinks = $True $DomainWmiFilterLinksCount = 0 $DomainWMIFilters.ForEach({ $_.links.ForEach({ $DomainWmiFilterLinksCount++ }) }) $SiteWmiFilterLinksCount = 0 $SiteWMIFilters.ForEach({ $_.links.ForEach({ $SiteWmiFilterLinksCount++ }) }) $ComputerWmiFilterLinksCount = 0 $ComputerWMIFilters.ForEach({ $_.links.ForEach({ $ComputerWmiFilterLinksCount++ }) }) $NumberOfWMIFilterLinks = $DomainWmiFilterLinksCount + $SiteWmiFilterLinksCount + $ComputerWmiFilterLinksCount $NumberOfElementsToProcess += $NumberOfWMIFilterLinks } } } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # RIGHTS GROUPS # Action: Get, Count, String Replacement, Resolve Paths and Convert Case # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ($RoleConfiguration.rights_groups) { # Get domain scoped rights groups $DomainRightsGroups = @($RoleConfiguration.rights_groups | Where-Object { $_.scope -eq 'domain' } ) # Get site scoped rights groups $SiteRightsGroups = @($RoleConfiguration.rights_groups | Where-Object { $_.scope -eq 'site' } ) # Get computer scoped rights groups $ComputerRightsGroups = @($RoleConfiguration.rights_groups | Where-Object { $_.scope -eq 'computer' } ) # Count If ( ($Components -icontains 'RightsGroups') -or ($Components -icontains 'Groups') -or ($Null -eq $Components) ) { $ProcessRightsGroups = $True $NumberOfElementsToProcess += ($DomainRightsGroups.Count + $SiteRightsGroups.Count + $ComputerRightsGroups.Count) $NumberOfRightsGroups = ($DomainRightsGroups.Count + $SiteRightsGroups.Count + $ComputerRightsGroups.Count) } # Replace any replacement pattern # Replace regardless of $Components -icontains 'RightsGroups', since RightsGroups are referenced by Rights, GroupMembers and GPOImports $DomainRightsGroups = Resolve-DryADReplacementPatterns -inputobject $DomainRightsGroups -Variables $Variables $SiteRightsGroups = Resolve-DryADReplacementPatterns -inputobject $SiteRightsGroups -Variables $Variables $ComputerRightsGroups = Resolve-DryADReplacementPatterns -inputobject $ComputerRightsGroups -Variables $Variables # Resolve Domain OU Paths from schema ForEach ($RightsGroup in $DomainRightsGroups) { If ($NULL -eq $RightsGroup.path) { # Resolve domain paths from OU schema $Path = Get-DryADOUPathFromTag -Tag $RightsGroup.Tag -OUs $DomainOUs -Scope 'domain' $RightsGroup | Add-Member -MemberType NoteProperty -Name Path -Value $Path } # Convert to $GroupCase $RightsGroup.groupname = ConvertTo-DryADCase -Name $RightsGroup.groupname -Case $Groupcase } # Resolve Site OU Paths from schema ForEach ($RightsGroup in $SiteRightsGroups) { If ($NULL -eq $RightsGroup.path) { # Resolve domain paths from OU schema $Path = Get-DryADOUPathFromTag -Tag $RightsGroup.Tag -OUs $SiteOUs -Scope 'site' $RightsGroup | Add-Member -MemberType NoteProperty -Name Path -Value $Path } # Convert to $GroupCase $RightsGroup.groupname = ConvertTo-DryADCase -Name $RightsGroup.groupname -Case $Groupcase } # Resolve Site OU Paths from schema ForEach ($RightsGroup in $ComputerRightsGroups) { If ($NULL -eq $RightsGroup.path) { # Resolve domain paths from OU schema $Path = Get-DryADOUPathFromTag -Tag $RightsGroup.Tag -OUs $ComputerOUs -Scope 'computer' $RightsGroup | Add-Member -MemberType NoteProperty -Name Path -Value $Path } # Convert to $GroupCase $RightsGroup.groupname = ConvertTo-DryADCase -Name $RightsGroup.groupname -Case $Groupcase } } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ROLE GROUPS # Action: Count and String replacement # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ($RoleConfiguration.role_groups) { # Get domain scoped rights groups $DomainRoleGroups = @($RoleConfiguration.role_groups | Where-Object { $_.scope -eq 'domain' } ) # Get site scoped rights groups $SiteRoleGroups = @($RoleConfiguration.role_groups | Where-Object { $_.scope -eq 'site' } ) # Get computer scoped rights groups $ComputerRoleGroups = @($RoleConfiguration.role_groups | Where-Object { $_.scope -eq 'computer' } ) # Count If ( ($Components -icontains 'RoleGroups') -or ($Components -icontains 'Groups') -or ($Null -eq $Components) ) { $ProcessRoleGroups = $True $NumberOfElementsToProcess += ($DomainRoleGroups.Count + $SiteRoleGroups.Count + $ComputerRoleGroups.Count) $NumberOfRoleGroups = ($DomainRoleGroups.Count + $SiteRoleGroups.Count + $ComputerRoleGroups.Count) } # Replace any replacement pattern # Replace regardless of $Components -icontains 'RightsGroups', since groups are referenced by -component GroupMembers $DomainRoleGroups = @(Resolve-DryADReplacementPatterns -inputobject $DomainRoleGroups -Variables $Variables) $SiteRoleGroups = @(Resolve-DryADReplacementPatterns -inputobject $SiteRoleGroups -Variables $Variables) $ComputerRoleGroups = @(Resolve-DryADReplacementPatterns -inputobject $ComputerRoleGroups -Variables $Variables) # Resolve domain OU paths from schema ForEach ($RoleGroup in $DomainRoleGroups) { If ($NULL -eq $RoleGroup.path) { # Resolve domain paths from OU schema $Path = Get-DryADOUPathFromTag -Tag $RoleGroup.Tag -OUs $DomainOUs -Scope 'domain' $RoleGroup | Add-Member -MemberType NoteProperty -Name Path -Value $Path } # Convert to $GroupCase $RoleGroup.groupname = ConvertTo-DryADCase -Name $RoleGroup.groupname -Case $Groupcase } # Resolve site OU paths from schema ForEach ($RoleGroup in $SiteRoleGroups) { If ($NULL -eq $RoleGroup.path) { # Resolve site paths from OU schema $Path = Get-DryADOUPathFromTag -Tag $RoleGroup.Tag -OUs $SiteOUs -Scope 'site' $RoleGroup | Add-Member -MemberType NoteProperty -Name Path -Value $Path } # Convert to $GroupCase $RoleGroup.groupname = ConvertTo-DryADCase -Name $RoleGroup.groupname -Case $Groupcase } # Resolve computer OU paths from schema ForEach ($RoleGroup in $ComputerRoleGroups) { If ($NULL -eq $RoleGroup.path) { # Resolve site paths from OU schema $Path = Get-DryADOUPathFromTag -Tag $RoleGroup.Tag -OUs $ComputerOUs -Scope 'computer' $RoleGroup | Add-Member -MemberType NoteProperty -Name Path -Value $Path } # Convert to $GroupCase $RoleGroup.groupname = ConvertTo-DryADCase -Name $RoleGroup.groupname -Case $Groupcase } } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # GROUP MEMBERS # Action: Count # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Count Members and MemberOfs $NumberOfMemberAndMemberOf = 0 $NumberOfDomainMemberAndMemberOf = 0 $NumberOfSiteMemberAndMemberOf = 0 $NumberOfComputerMemberAndMemberOf = 0 If ( ($Components -icontains 'GroupMembers') -or ($Components -icontains 'Groups') -or ($Null -eq $Components) ) { $ProcessGroupMembers = $True # Domain Scope - Both Role and Rights groups may have .member and .memberof ForEach ($DomainRoleGroup in $DomainRoleGroups) { $NumberOfDomainMemberAndMemberOf += $DomainRoleGroup.Member.Count $NumberOfDomainMemberAndMemberOf += $DomainRoleGroup.MemberOf.Count } ForEach ($DomainRightsGroup in $DomainRightsGroups) { $NumberOfDomainMemberAndMemberOf += $DomainRightsGroup.Member.Count $NumberOfDomainMemberAndMemberOf += $DomainRightsGroup.MemberOf.Count } $NumberOfElementsToProcess += $NumberOfDomainMemberAndMemberOf $NumberOfMemberAndMemberOf += $NumberOfDomainMemberAndMemberOf # Site Scope - Both Role and Rights groups may have .member and .memberof ForEach ($SiteRoleGroup in $SiteRoleGroups) { $NumberOfSiteMemberAndMemberOf += $SiteRoleGroup.Member.Count $NumberOfSiteMemberAndMemberOf += $SiteRoleGroup.MemberOf.Count } ForEach ($SiteRightsGroup in $SiteRightsGroups) { $NumberOfSiteMemberAndMemberOf += $SiteRightsroup.Member.Count $NumberOfSiteMemberAndMemberOf += $SiteRightsGroup.MemberOf.Count } $NumberOfElementsToProcess += $NumberOfSiteMemberAndMemberOf $NumberOfMemberAndMemberOf += $NumberOfSiteMemberAndMemberOf # Computer Scope - Both Role and Rights groups may have .member and .memberof ForEach ($ComputerRoleGroup in $ComputerRoleGroups) { $NumberOfComputerMemberAndMemberOf += $ComputerRoleGroup.Member.Count $NumberOfComputerMemberAndMemberOf += $ComputerRoleGroup.MemberOf.Count } ForEach ($ComputerRightsGroup in $ComputerRightsGroups) { $NumberOfComputerMemberAndMemberOf += $ComputerRightsGroup.Member.Count $NumberOfComputerMemberAndMemberOf += $ComputerRightsGroup.MemberOf.Count } $NumberOfElementsToProcess += $NumberOfComputerMemberAndMemberOf $NumberOfMemberAndMemberOf += $NumberOfComputerMemberAndMemberOf } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # RIGHTS # Action: Count and Resolve Paths # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ( ($Components -icontains 'Rights') -or ($Null -eq $Components) ) { $ProcessRights = $True # Count and resolve domain Path $NumberOfRights = 0 $NumberOfDomainRights = 0 $NumberOfSiteRights = 0 $NumberOfComputerRights = 0 ForEach ($DomainRightsGroup in $DomainRightsGroups) { ForEach ($DomainRight in $DomainRightsGroup.Rights) { $NumberOfElementsToProcess++ # Update the debug counter as well $NumberOfRights++ $NumberOfDomainRights++ # Resolve Path If ($Null -eq $DomainRight.Path) { # Resolve paths from OU schema. It is possible to set a domain right # at a site- or computer-scoped OU Switch ($DomainRight.Scope) { 'domain' { $Path = Get-DryADOUPathFromTag -Tag $DomainRight.Tag -OUs $DomainOUs -Scope 'domain' } 'site' { $Path = Get-DryADOUPathFromTag -Tag $DomainRight.Tag -OUs $SiteOUs -Scope 'site' } 'computer' { $Path = Get-DryADOUPathFromTag -Tag $DomainRight.Tag -OUs $ComputerOUs -Scope 'computer' } } $DomainRight | Add-Member -MemberType NoteProperty -Name Path -Value $Path # Once resolved, remove Tag. Keep scope - we need that to determine if the target scope, or # IdentityReeference, is a site or domain path $DomainRight.PSObject.Properties.Remove('Tag') } } } # Count and resolve site Path ForEach ($SiteRightsGroup in $SiteRightsGroups) { ForEach ($SiteRight in $SiteRightsGroup.Rights) { $NumberOfElementsToProcess++ $NumberOfRights++ $NumberOfSiteRights++ # Resolve Path If ($Null -eq $SiteRight.Path) { # Resolve domain paths from OU schema. A right for a site group may # reference an OU in the domain scope, site scope or computer scope Switch ($SiteRight.Scope) { 'domain' { $Path = Get-DryADOUPathFromTag -Tag $SiteRight.Tag -OUs $DomainOUs -Scope 'domain' } 'site' { $Path = Get-DryADOUPathFromTag -Tag $SiteRight.Tag -OUs $SiteOUs -Scope 'site' } 'computer' { $Path = Get-DryADOUPathFromTag -Tag $SiteRight.Tag -OUs $ComputerOUs -Scope 'computer' } } $SiteRight | Add-Member -MemberType NoteProperty -Name Path -Value $Path # Once resolved, remove Tag. Leave Scope, we may need that $SiteRight.PSObject.Properties.Remove('Tag') } } } # Count and resolve computer Path ForEach ($ComputerRightsGroup in $ComputerRightsGroups) { ForEach ($ComputerRight in $ComputerRightsGroup.Rights) { $NumberOfElementsToProcess++ $NumberOfRights++ $NumberOfComputerRights++ # Resolve Path If ($Null -eq $ComputerRight.Path) { # Resolve domain paths from OU schema. A right for a computer group may # reference an OU in the domain scope, or in the site scope Switch ($ComputerRight.Scope) { 'domain' { $Path = Get-DryADOUPathFromTag -Tag $ComputerRight.Tag -OUs $DomainOUs -Scope 'domain' } 'site' { $Path = Get-DryADOUPathFromTag -Tag $ComputerRight.Tag -OUs $SiteOUs -Scope 'site' } 'computer' { $Path = Get-DryADOUPathFromTag -Tag $ComputerRight.Tag -OUs $ComputerOUs -Scope 'computer' } } $ComputerRight | Add-Member -MemberType NoteProperty -Name Path -Value $Path # Once resolved, remove Tag. Leave Scope, we may need that $ComputerRight.PSObject.Properties.Remove('Tag') } } } } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # GROUP POLICY IMPORTS # Action: Count and String replacement # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ( ($Components -icontains 'GPOImports') -or ($Components -icontains 'GPOs') -or ($Null -eq $Components) ){ If ($RoleConfiguration.gpo_imports){ $ProcessGPOImports = $True $DomainGPOImports = @($RoleConfiguration.gpo_imports | Where-Object { $_.scope -eq 'domain' }) $SiteGPOImports = @($RoleConfiguration.gpo_imports | Where-Object { $_.scope -eq 'site' }) $ComputerGPOImports = @($RoleConfiguration.gpo_imports | Where-Object { $_.scope -eq 'computer' }) # If the configuration set contains json-gpos, $JsonGPOImports = @($RoleConfiguration.gpo_imports | Where-Object { $_.type -eq 'json' }) $RequiresAccessToGPOManagement = $False If ($JsonGPOImports.count -gt 0) { $RequiresAccessToGPOManagement = $True } $NumberOfElementsToProcess += ($DomainGPOImports.Count + $SiteGPOImports.Count + $ComputerGPOImports.Count) $NumberOfGPOImports += ($DomainGPOImports.Count + $SiteGPOImports.Count + $ComputerGPOImports.Count) $DomainGPOImports = Resolve-DryADReplacementPatterns -inputobject $DomainGPOImports -Variables $Variables $SiteGPOImports = Resolve-DryADReplacementPatterns -inputobject $SiteGPOImports -Variables $Variables $ComputerGPOImports = Resolve-DryADReplacementPatterns -inputobject $ComputerGPOImports -Variables $Variables } } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # GROUP POLICY LINKS # Action: Count, String replacement and Resolve paths from tags # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ( ($Components -icontains 'GPOLinks') -or ($Components -icontains 'GPOs') -or ($Null -eq $Components) ){ If ($RoleConfiguration.gpo_links) { $ProcessGPOLinks = $True $DomainGPOLinks = @($RoleConfiguration.gpo_links | Where-Object { $_.scope -eq 'domain' } ) $SiteGPOLinks = @($RoleConfiguration.gpo_links | Where-Object { $_.scope -eq 'site' } ) $ComputerGPOLinks = @($RoleConfiguration.gpo_links | Where-Object { $_.scope -eq 'computer' } ) $NumberOfElementsToProcess += ($DomainGPOLinks.Count + $SiteGPOLinks.Count + $ComputerGPOLinks.Count) $NumberOfGPOLinks = ($DomainGPOLinks.Count + $SiteGPOLinks.Count + $ComputerGPOLinks.Count) # String Replacements $DomainGPOLinks = Resolve-DryADReplacementPatterns -inputobject $DomainGPOLinks -Variables $Variables $SiteGPOLinks = Resolve-DryADReplacementPatterns -inputobject $SiteGPOLinks -Variables $Variables $ComputerGPOLinks = Resolve-DryADReplacementPatterns -inputobject $ComputerGPOLinks -Variables $Variables # Resolve Domain Paths from OU schema ForEach ($DomainGPOLink in $DomainGPOLinks) { If ($NULL -eq $DomainGPOLink.path) { $Path = Get-DryADOUPathFromTag -Tag $DomainGPOLink.Tag -OUs $DomainOUs -Scope 'domain' $DomainGPOLink | Add-Member -MemberType NoteProperty -Name Path -Value $Path } } # Resolve Site Paths from OU schema ForEach ($SiteGPOLink in $SiteGPOLinks) { If ($NULL -eq $SiteGPOLink.path) { $Path = Get-DryADOUPathFromTag -Tag $SiteGPOLink.Tag -OUs $SiteOUs -Scope 'site' $SiteGPOLink | Add-Member -MemberType NoteProperty -Name Path -Value $Path } } # Resolve Computer Paths from OU schema ForEach ($ComputerGPOLink in $ComputerGPOLinks) { If ($NULL -eq $ComputerGPOLink.path) { $Path = Get-DryADOUPathFromTag -Tag $ComputerGPOLink.Tag -OUs $ComputerOUs -Scope 'computer' $ComputerGPOLink | Add-Member -MemberType NoteProperty -Name Path -Value $Path } } } } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # USERS # Action: Count, String replacement, resolve OUs # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ( ($Components -icontains 'Users') -or ($Null -eq $Components) ){ If ($RoleConfiguration.users) { # Get domain scoped users $DomainUsers = @($RoleConfiguration.users | Where-Object { $_.scope -eq 'domain' } ) # Get site scoped users $SiteUsers = @($RoleConfiguration.users | Where-Object { $_.scope -eq 'site' } ) # Get computer scoped users $ComputerUsers = @($RoleConfiguration.users | Where-Object { $_.scope -eq 'computer' } ) # Count If ( ($Components -icontains 'Users') -or ($Null -eq $Components) ) { $ProcessUsers = $True $NumberOfElementsToProcess += ($DomainUsers.Count + $SiteUsers.Count + $ComputerUsers.Count) $NumberOfUsers = ($DomainUsers.Count + $SiteUsers.Count + $ComputerUsers.Count) } # Replace any replacement pattern If ($DomainUsers.count -gt 0) { $DomainUsers = @(Resolve-DryADReplacementPatterns -inputobject $DomainUsers -Variables $Variables) } If ($SiteUsers.count -gt 0) { $SiteUsers = @(Resolve-DryADReplacementPatterns -inputobject $SiteUsers -Variables $Variables) } If ($ComputerUsers.count -gt 0) { $ComputerUsers = @(Resolve-DryADReplacementPatterns -inputobject $ComputerUsers -Variables $Variables) } # Resolve domain OU paths from schema ForEach ($User in $DomainUsers) { If ($NULL -eq $User.path) { # Resolve domain paths from OU schema $Path = Get-DryADOUPathFromTag -Tag $User.Tag -OUs $DomainOUs -Scope 'domain' $User | Add-Member -MemberType NoteProperty -Name Path -Value $Path } # Convert to $GroupCase $User.name = ConvertTo-DryADCase -Name $User.name -Case $UserCase } # Resolve site OU paths from schema ForEach ($User in $SiteUsers) { If ($NULL -eq $User.path) { # Resolve site paths from OU schema $Path = Get-DryADOUPathFromTag -Tag $User.Tag -OUs $SiteOUs -Scope 'site' $User | Add-Member -MemberType NoteProperty -Name Path -Value $Path } # Convert to $GroupCase $User.name = ConvertTo-DryADCase -Name $User.name -Case $UserCase } # Resolve computer OU paths from schema ForEach ($User in $ComputerUsers) { If ($NULL -eq $User.path) { # Resolve site paths from OU schema $Path = Get-DryADOUPathFromTag -Tag $User.Tag -OUs $ComputerOUs -Scope 'computer' $User | Add-Member -MemberType NoteProperty -Name Path -Value $Path } # Convert to $GroupCase $User.name = ConvertTo-DryADCase -Name $User.name -Case $UserCase } } } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # USER'S GROUP MEMBERSHIPS # Action: Count # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ( ($Components -icontains 'UserGroupMembers') -or ($Null -eq $Components) ){ $ProcessUserMemberOf = $True # Count User's MemberOfs $NumberOfDomainUserMemberOf = 0 $NumberOfSiteUserMemberOf = 0 $NumberOfComputerUserMemberOf = 0 # Domain Scope ForEach ($DomainUser in $DomainUsers) { $NumberOfDomainUserMemberOf += $DomainUser.MemberOf.Count } $NumberOfElementsToProcess += $NumberOfDomainUserMemberOf # Site Scope ForEach ($SiteUser in $SiteUsers) { $NumberOfSiteUserMemberOf += $SiteUser.MemberOf.Count } $NumberOfElementsToProcess += $NumberOfSiteUserMemberOf # Computer Scope ForEach ($ComputerUser in $ComputerUsers) { $NumberOfComputerUserMemberOf += $ComputerUser.MemberOf.Count } $NumberOfElementsToProcess += $NumberOfComputerUserMemberOf $NumberOfUserMemberOf = $NumberOfDomainUserMemberOf + $NumberOfSiteUserMemberOf + $NumberOfComputerUserMemberOf } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # AD DRIVE # Action: Make sure the AD Drive on the executing system is created when # importing the ActiveDirectory module, and that it points to the correct # Domain Controller. # - If Remote execution, we remote into a Domain Controller, and the AD # drive should be pointed to localhost. # - If Local execution, the AD Drive should point to $DomainController # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Switch ($ExecutionType) { 'Remote' { ol i "Configuring AD Drive on $DomainController" -sh Set-DryADDrive -PSSession $PSSession } 'Local' { ol i "Configuring AD Drive on local system" -sh Set-DryADDrive -DomainController $DomainController } } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # AD WEB SERVICES ON DOMAIN CONTROLLER # Action: Test, and wait for the service to become available # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ($ExecutionType -eq 'Remote') { ol i "Testing and Waiting for AD Availability" -sh Wait-DryADForADWebServices -DomainDN $DomainDN -PSSession $PSSession } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # SCHEMA UPDATES # Action: Invoke/Update. Will only work when 'Remote' and $DomainController # is the Schema Master # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ($ProcessADSchema) { ol i "AD Schema Extensions ($($ADSchemaExtensions.count))" -sh ForEach ($ADSchemaExtension in $ADSchemaExtensions) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Schema extension: $($ADSchemaExtension.BaseName)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters $ADSchemaExtJson = Get-Content -Path (Join-Path -Path (Split-Path -Path $ADSchemaExtension.FullName) -ChildPath "$($ADSchemaExtension.BaseName).json") | ConvertFrom-Json -ErrorAction 'Stop' $ADSchemaExtContent = Get-Content -Path $ADSchemaExtension.FullName -Raw -ErrorAction 'Stop' $ExtendDryADSchemaParams = @{ Type = $ADSchemaExtension.BaseName SuccessCount = $ADSchemaExtJson.success_string_match_count Content = $ADSchemaExtContent Variables = $Variables Server = $DomainController } If ($ExecutionType -eq 'Remote') { $ExtendDryADSchemaParams += @{ PSSession = $PSSession } } ol i 'Extending AD Schema, type',"$($ADSchemaExtension.BaseName)" Set-DryADSchemaExtension @ExtendDryADSchemaParams } $DebugCounter = $NumberOfADSchemaExtensions If ($ElementsCounter -ne $DebugCounter) { Throw "Elementscounter is $ElementsCounter, but was supposed to be $DebugCounter" } } # If ($ProcessSchema) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # NETLOGON # Action: Configure # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ($ProcessNETLOGON) { ol i "NETLOGON File Copy" -sh # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): NETLOGON" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters $NETLOGONSourcePath = Join-Path -Path $ConfigurationPath -ChildPath 'NETLOGON' If ($ExecutionType -eq 'Remote') { } Switch ($ExecutionType) { 'Local' { $NETLOGONTargetPath = "$DomainFQDN\NETLOGON\" } 'Remote' { $NETLOGONTargetPath = "C:\Windows\SYSVOL\domain\scripts\" } } ol i "NETLOGON source path","$NETLOGONSourcePath\*" ol i "NETLOGON target path","$NETLOGONTargetPath" $CopyNETLOGONParams = @{ Path = "$NETLOGONSourcePath\*" Destination = "$NETLOGONTargetPath" Recurse = $True Force = $True ErrorAction = 'Stop' } If ($ExecutionType -eq 'Remote') { $CopyNETLOGONParams += @{ ToSession = $PSSession } } Copy-Item @CopyNETLOGONParams $DebugCounter += $NumberOfNETLOGONs If ($ElementsCounter -ne $DebugCounter) { Throw "Elementscounter is $ElementsCounter, but was supposed to be $DebugCounter" } } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # AdmTemplates # Action: Configure # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ($ProcessAdmTemplates) { ol i "AdmTemplates File Copy" -sh # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Administrative Templates" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters $AdmTemplatesSourcePath = "$ConfigurationPath\AdmTemplates\*" Switch ($ExecutionType) { 'Local' { $AdmTemplatesTargetPath = "\\\\$DomainFQDN\\SYSVOL\\$DomainFQDN\\Policies\\PolicyDefinitions\\" } 'Remote' { $AdmTemplatesTargetPath = "C:\\Windows\\SYSVOL\\domain\\Policies\\PolicyDefinitions\\" } } ol i "AdmTemplates source path",$AdmTemplatesSourcePath ol i "AdmTemplates target path",$AdmTemplatesTargetPath $CopyDryFilesToRemoteTargetParams = @{ SourcePath = "$AdmTemplatesSourcePath" TargetPath = "$AdmTemplatesTargetPath" } If ($PSSession) { $CopyDryFilesToRemoteTargetParams += @{ PSSession = $PSSession } } Copy-DryADFilesToRemoteTarget @CopyDryFilesToRemoteTargetParams | Out-Null $DebugCounter += 1 If ($ElementsCounter -ne $DebugCounter) { Throw "Elementscounter is $ElementsCounter, but was supposed to be $DebugCounter" } } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ORGANIZATIONAL UNITS # Action: Create # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ($ProcessOUs) { ol i "OUs - Domain scope ($($DomainOUs.count))" -sh ForEach ($OU in $DomainOUs) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Creating OU: $($OU.Path)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Create instance of class OU and invoke method CreateOU() ol i "Creating OU (domain '$DomainFQDN')","$($OU.path)" Switch ($ExecutionType) { 'Local' { [OU]$OUObject = [OU]::new("$($OU.path)","$DomainFQDN",$DomainController) } 'Remote' { [OU]$OUObject = [OU]::new("$($OU.path)","$DomainFQDN",$PSSession) } } $OUObject.CreateOU() Remove-Variable -Name OUObject -ErrorAction Ignore } # loop through site OUs ol i "OUs - Site scope ($($SiteOUs.count))" -sh ForEach ($OU in $SiteOUs){ # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Creating OU: $($OU.Path)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters ol i "Creating OU (site '$adsite')","$($OU.Path)" Switch ($ExecutionType) { 'Local' { [OU]$OUObject = [OU]::new("$($OU.path)","$DomainFQDN",$DomainController) } 'Remote' { [OU]$OUObject = [OU]::new("$($OU.path)","$DomainFQDN",$PSSession) } } $OUObject.CreateOU() # clean up Remove-Variable -name CopyOU -ErrorAction Ignore } # loop through site OUs ol i "OUs - Computer scope ($($ComputerOUs.count))" -sh ForEach ($OU in $ComputerOUs){ # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Creating OU: $($OU.Path)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters ol i "Creating OU (computer '$ComputerName')","$($OU.Path)" Switch ($ExecutionType) { 'Local' { [OU]$OUObject = [OU]::new("$($OU.path)","$DomainFQDN",$DomainController) } 'Remote' { [OU]$OUObject = [OU]::new("$($OU.path)","$DomainFQDN",$PSSession) } } $OUObject.CreateOU() # clean up Remove-Variable -name CopyOU -ErrorAction Ignore } $DebugCounter += $NumberOfOUs If ($ElementsCounter -ne $DebugCounter) { Throw "Elementscounter is $ElementsCounter, but was supposed to be $DebugCounter" } } # If ($ProcessOU) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # WMI FILTERS # Action: Create # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ($ProcessWMIFilterImports) { # WMIfilters. Log some info, then loop through each ol i "WMIFilters - Domain scope ($($DomainWMIfilters.count))" -sh # Make sure 'Allow System Only Change' in registry on domain controller is 1 # If it isn't, WMIFilter creation will fail with access denied ol d "Calling 'Set-DryADRemoteRegistry' to set 'Allow System Only Change' to 1" $AllowSystemOnlyChangeParameters = @{ BaseKey = 'HKEY_LOCAL_MACHINE' LeafKey = 'System\\CurrentControlSet\\Services\\NTDS\\Parameters' ValueName = 'Allow System Only Change' ValueData = 1 ValueType = 'DWORD' PSSession = $PSSession ErrorAction = 'Stop' } Set-DryADRemoteRegistry @AllowSystemOnlyChangeParameters # $DomainWMIfilters ForEach ($GPOWMIFilter in $DomainWMIfilters) { # Progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Importing WMIFilter '$($GPOWMIFilter.Name)'" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Any GPMC command must run in a remote session, since the cmdlets lack the -credentials parameter $NewDryWmiFilterParameters = @{ Name = $GPOWMIFilter.Name Description = $GPOWMIFilter.Description Query = [Array]$GPOWMIFilter.Queries } Switch ($ExecutionType) { 'Local' { $NewDryWmiFilterParameters += @{ DomainController = $DomainController } } 'Remote' { $NewDryWmiFilterParameters += @{ PSSession = $PSSession } } } ol i "Importing WMI Filter (domain '$DomainFQDN')","$($GPOWMIFilter.Name)" New-DryADWmiFilter @NewDryWmiFilterParameters } # $SiteWMIfilters ol i "WMIFilters - Site scope ($($SiteWMIfilters.count))" -sh ForEach ($GPOWMIFilter in $SiteWMIfilters) { # Progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Importing WMIFilter '$($GPOWMIFilter.Name)'" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Any GPMC command must run in a remote session, since the cmdlets lack the -credentials parameter $NewDryWmiFilterParameters = @{ Name = $GPOWMIFilter.Name Description = $GPOWMIFilter.Description Query = [Array]$GPOWMIFilter.Queries } Switch ($ExecutionType) { 'Local' { $NewDryWmiFilterParameters += @{ DomainController = $DomainController } } 'Remote' { $NewDryWmiFilterParameters += @{ PSSession = $PSSession } } } ol i "Importing WMI Filter (site '$adsite')","$($GPOWMIFilter.Name)" New-DryADWmiFilter @NewDryWmiFilterParameters } # $ComputerWMIfilters ol i "WMIFilters - Computer scope ($($ComputerWMIfilters.count))" -sh ForEach ($GPOWMIFilter in $ComputerWMIfilters) { # Progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Importing WMIFilter '$($GPOWMIFilter.Name)'" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters $NewDryWmiFilterParameters = @{ Name = $GPOWMIFilter.Name Description = $GPOWMIFilter.Description Query = [Array]$GPOWMIFilter.Queries } Switch ($ExecutionType) { 'Local' { $NewDryWmiFilterParameters += @{ DomainController = $DomainController } } 'Remote' { $NewDryWmiFilterParameters += @{ PSSession = $PSSession } } } ol i "Importing WMI Filter (computer '$ComputerName')","$($GPOWMIFilter.Name)" New-DryADWmiFilter @NewDryWmiFilterParameters } $DebugCounter += $NumberOfWMIFilters If ($ElementsCounter -ne $DebugCounter) { Throw "Elementscounter is $ElementsCounter, but was supposed to be $DebugCounter" } } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # RIGHTS GROUPS # Action: Create # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ($ProcessRightsGroups) { ol i "Rights Groups - Domain scope ($($DomainRightsGroups.count))" -sh # loop through domain Rights ForEach ($RightsGroup in $DomainRightsGroups) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Rights Group: $($RightsGroup.groupname)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters $NewDryADSecurityGroupParams = @{ Name = $RightsGroup.groupname Path = $RightsGroup.path Description = $RightsGroup.groupdescription Type = $RightsGroup.grouptype } Switch ($ExecutionType) { 'Local' { $NewDryADSecurityGroupParams += @{ DomainController = $DomainController } } 'Remote' { $NewDryADSecurityGroupParams += @{ PSSession = $PSSession } } } ol i "Creating Rights Group (domain '$DomainFQDN')","$($RightsGroup.groupname)" New-DryADSecurityGroup @NewDryADSecurityGroupParams } # loop through site Rights ol i "Rights Groups - Site scope ($($SiteRightsGroups.count))" -sh ForEach ($RightsGroup in $SiteRightsGroups) { # Add site to the description $RightsGroup.groupdescription = $RightsGroup.groupdescription + " (site '$adsite')" # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Rights Group: $($RightsGroup.groupname)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters $NewDryADSecurityGroupParams=@{ Name = $RightsGroup.groupname Path = $RightsGroup.path Description = $RightsGroup.groupdescription Type = $RightsGroup.grouptype } Switch ($ExecutionType) { 'Local' { $NewDryADSecurityGroupParams += @{ DomainController = $DomainController } } 'Remote' { $NewDryADSecurityGroupParams += @{ PSSession = $PSSession } } } ol i "Creating Rights Group (site '$adsite')","$($RightsGroup.groupname)" New-DryADSecurityGroup @NewDryADSecurityGroupParams } # loop through site Rights ol i "Rights Groups - Computer scope ($($ComputerRightsGroups.count))" -sh ForEach ($RightsGroup in $ComputerRightsGroups) { # Add site to the description $RightsGroup.groupdescription = $RightsGroup.groupdescription + " (computer '$ComputerName')" # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Rights Group: $($RightsGroup.groupname)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters $NewDryADSecurityGroupParams=@{ Name = $RightsGroup.groupname Path = $RightsGroup.path Description = $RightsGroup.groupdescription Type = $RightsGroup.grouptype } Switch ($ExecutionType) { 'Local' { $NewDryADSecurityGroupParams += @{ DomainController = $DomainController } } 'Remote' { $NewDryADSecurityGroupParams += @{ PSSession = $PSSession } } } ol i "Creating Rights Group (computer '$ComputerName')","$($RightsGroup.groupname)" New-DryADSecurityGroup @NewDryADSecurityGroupParams } $DebugCounter += $NumberOfRightsGroups If ($ElementsCounter -ne $DebugCounter) { Throw "Elementscounter is $ElementsCounter, but was supposed to be $DebugCounter" } } # If ($ProcessRightsGroups) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ROLE GROUPS # Action: Create # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ($ProcessRoleGroups) { ol i "Role Groups - Domain scope ($($DomainRoleGroups.count))" -sh # loop through domain Role Groups ForEach ($RoleGroup in $DomainRoleGroups) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Role Group: $($RoleGroup.groupname)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters $NewDryADSecurityGroupParams = @{ Name = $RoleGroup.groupname Path = $RoleGroup.path Description = $RoleGroup.groupdescription Type = $RoleGroup.grouptype } Switch ($ExecutionType) { 'Local' { $NewDryADSecurityGroupParams += @{ DomainController = $DomainController } } 'Remote' { $NewDryADSecurityGroupParams += @{ PSSession = $PSSession } } } ol i "Creating Role Group (domain '$DomainFQDN')","$($RoleGroup.groupname)" New-DryADSecurityGroup @NewDryADSecurityGroupParams } # loop through site Role Groups ol i "Role Groups - Site scope ($($SiteRoleGroups.count))" -sh ForEach ($RoleGroup in $SiteRoleGroups) { # Add site to the description $RoleGroup.groupdescription = $RoleGroup.groupdescription + " (site '$adsite')" # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Role Group: $($RoleGroup.groupname)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters $NewDryADSecurityGroupParams = @{ Name = $RoleGroup.groupname Path = $RoleGroup.path Description = $RoleGroup.groupdescription Type = $RoleGroup.grouptype } Switch ($ExecutionType) { 'Local' { $NewDryADSecurityGroupParams += @{ DomainController = $DomainController } } 'Remote' { $NewDryADSecurityGroupParams += @{ PSSession = $PSSession } } } ol i "Creating Role Group (site '$adsite')","$($RoleGroup.groupname)" New-DryADSecurityGroup @NewDryADSecurityGroupParams } # loop through site Role Groups ol i "Role Groups - Computer scope ($($ComputerRoleGroups.count))" -sh ForEach ($RoleGroup in $ComputerRoleGroups) { # Add computername to the description $RoleGroup.groupdescription = $RoleGroup.groupdescription + " (computer '$ComputerName')" # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Role Group: $($RoleGroup.groupname)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters $NewDryADSecurityGroupParams = @{ Name = $RoleGroup.groupname Path = $RoleGroup.path Description = $RoleGroup.groupdescription Type = $RoleGroup.grouptype } Switch ($ExecutionType) { 'Local' { $NewDryADSecurityGroupParams += @{ DomainController = $DomainController } } 'Remote' { $NewDryADSecurityGroupParams += @{ PSSession = $PSSession } } } ol i "Creating Role Group (computer '$ComputerName')","$($RoleGroup.groupname)" New-DryADSecurityGroup @NewDryADSecurityGroupParams } $DebugCounter += $NumberOfRoleGroups If ($ElementsCounter -ne $DebugCounter) { Throw "Elementscounter is $ElementsCounter, but was supposed to be $DebugCounter" } } # If ($ProcessRoleGroups) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # GROUP'S GROUP MEMBERS # Action: Add Role Groups to RightsGroups # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ($ProcessGroupMembers) { ol i "Group Members - Domain scope ($NumberOfDomainMemberAndMemberOf)" -sh # Both Role and Rights groups may have .member and .memberof ForEach ($DomainRoleGroup in $DomainRoleGroups) { ForEach ($DomainRoleGroupMember in $DomainRoleGroup.Member) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Group Member: $($DomainRoleGroup.groupname)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Add Members to $DomainRoleGroup $AddDryADGroupMemberParams = @{ Group = $DomainRoleGroup.groupname Member = $DomainRoleGroupMember } Switch ($ExecutionType) { 'Local' { $AddDryADGroupMemberParams += @{ DomainController = $DomainController } } 'Remote' { $AddDryADGroupMemberParams += @{ PSSession = $PSSession } } } ol i "Group Members (domain '$DomainFQDN')","Adding '$DomainRoleGroupMember' to '$($DomainRoleGroup.groupname)'" Add-DryADGroupMember @AddDryADGroupMemberParams Remove-Variable -Name AddDryADGroupMemberParams -ErrorAction Ignore } ForEach ($DomainRoleGroupMemberOf in $DomainRoleGroup.MemberOf) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Group Member Of: $($DomainRoleGroup.groupname)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Add $DomainRoleGroup to each MemberOf $AddDryADGroupMemberParams = @{ Group = $DomainRoleGroupMemberOf Member = $DomainRoleGroup.groupname } Switch ($ExecutionType) { 'Local' { $AddDryADGroupMemberParams += @{ DomainController = $DomainController } } 'Remote' { $AddDryADGroupMemberParams += @{ PSSession = $PSSession } } } ol i "Group Members (domain '$DomainFQDN')","Adding '$($DomainRoleGroup.groupname)' to '$DomainRoleGroupMemberOf'" Add-DryADGroupMember @AddDryADGroupMemberParams Remove-Variable -Name AddDryADGroupMemberParams -ErrorAction Ignore } } ForEach ($DomainRightsGroup in $DomainRightsGroups) { ForEach ($DomainRightsGroupMember in $DomainRightsGroup.Member) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Group Member: $($DomainRightsGroup.groupname)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Add Members to $DomainRightsGroup $AddDryADGroupMemberParams = @{ Group = $DomainRightsGroup.groupname Member = $DomainRightsGroupMember } Switch ($ExecutionType) { 'Local' { $AddDryADGroupMemberParams += @{ DomainController = $DomainController } } 'Remote' { $AddDryADGroupMemberParams += @{ PSSession = $PSSession } } } ol i "Group Members (domain '$DomainFQDN')","Adding '$DomainRightsGroupMember' to '$($DomainRightsGroup.groupname)'" Add-DryADGroupMember @AddDryADGroupMemberParams Remove-Variable -Name AddDryADGroupMemberParams -ErrorAction Ignore } ForEach ($DomainRightsGroupMemberOf in $DomainRightsGroup.MemberOf) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Group Member Of: $($DomainRightsGroup.groupname)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Add $DomainRightsGroup to each MemberOf $AddDryADGroupMemberParams = @{ Group = $DomainRightsGroupMemberOf Member = $DomainRightsGroup.groupname } Switch ($ExecutionType) { 'Local' { $AddDryADGroupMemberParams += @{ DomainController = $DomainController } } 'Remote' { $AddDryADGroupMemberParams += @{ PSSession = $PSSession } } } ol i "Group Members (domain '$DomainFQDN')","Adding '$($DomainRightsGroup.groupname)' to '$DomainRightsGroupMemberOf'" Add-DryADGroupMember @AddDryADGroupMemberParams Remove-Variable -Name AddDryADGroupMemberParams -ErrorAction Ignore } } ol i "Group Members - Site scope ($NumberOfSiteMemberAndMemberOf)" -sh ForEach ($SiteRoleGroup in $SiteRoleGroups) { ForEach ($SiteRoleGroupMember in $SiteRoleGroup.Member) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Group Member: $($SiteRoleGroup.groupname)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Add Members to $SiteRoleGroup $AddDryADGroupMemberParams = @{ Group = $SiteRoleGroup.groupname Member = $SiteRoleGroupMember } Switch ($ExecutionType) { 'Local' { $AddDryADGroupMemberParams += @{ DomainController = $DomainController } } 'Remote' { $AddDryADGroupMemberParams += @{ PSSession = $PSSession } } } ol i "Group Members (site '$adsite')","Adding '$SiteRoleGroupMember' to '$($SiteRoleGroup.groupname)'" Add-DryADGroupMember @AddDryADGroupMemberParams Remove-Variable -Name AddDryADGroupMemberParams -ErrorAction Ignore } ForEach ($SiteRoleGroupMemberOf in $SiteRoleGroup.MemberOf) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Group Member Of: $($SiteRoleGroup.groupname)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Add $SiteRoleGroup to each MemberOf $AddDryADGroupMemberParams = @{ Group = $SiteRoleGroupMemberOf Member = $SiteRoleGroup.groupname } Switch ($ExecutionType) { 'Local' { $AddDryADGroupMemberParams += @{ DomainController = $DomainController } } 'Remote' { $AddDryADGroupMemberParams += @{ PSSession = $PSSession } } } ol i "Group Members (site '$adsite')","Adding '$($SiteRoleGroup.groupname)' to '$SiteRoleGroupMemberOf'" Add-DryADGroupMember @AddDryADGroupMemberParams Remove-Variable -Name AddDryADGroupMemberParams -ErrorAction Ignore } } ForEach ($SiteRightsGroup in $SiteRightsGroups) { ForEach ($SiteRightsGroupMember in $SiteRightsGroup.Member) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Group Member: $($SiteRightsGroup.groupname)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Add Members to $SiteRightsGroup $AddDryADGroupMemberParams = @{ Group = $SiteRightsGroup.groupname Member = $SiteRightsGroupMember } Switch ($ExecutionType) { 'Local' { $AddDryADGroupMemberParams += @{ DomainController = $DomainController } } 'Remote' { $AddDryADGroupMemberParams += @{ PSSession = $PSSession } } } ol i "Group Members (site '$adsite')","Add '$SiteRightsGroupMember' to '$($SiteRightsGroup.groupname)'" Add-DryADGroupMember @AddDryADGroupMemberParams Remove-Variable -Name AddDryADGroupMemberParams -ErrorAction Ignore } ForEach ($SiteRightsGroupMemberOf in $SiteRightsGroup.MemberOf) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Group Member Of: $($SiteRightsGroup.groupname)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Add $SiteRightsGroup to each MemberOf $AddDryADGroupMemberParams = @{ Group = $SiteRightsGroupMemberOf Member = $SiteRightsGroup.groupname } Switch ($ExecutionType) { 'Local' { $AddDryADGroupMemberParams += @{ DomainController = $DomainController } } 'Remote' { $AddDryADGroupMemberParams += @{ PSSession = $PSSession } } } ol i "Group Members (site '$adsite')","Add '$($SiteRightsGroup.groupname)' to '$SiteRightsGroupMemberOf'" Add-DryADGroupMember @AddDryADGroupMemberParams Remove-Variable -Name AddDryADGroupMemberParams -ErrorAction Ignore } } ol i "Group Members - Computer scope ($NumberOfComputerMemberAndMemberOf)" -sh ForEach ($ComputerRoleGroup in $ComputerRoleGroups) { ForEach ($ComputerRoleGroupMember in $ComputerRoleGroup.Member) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Group Member: $($ComputerRoleGroup.groupname)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Add Members to $ComputerRoleGroup $AddDryADGroupMemberParams = @{ Group = $ComputerRoleGroup.groupname Member = $ComputerRoleGroupMember } Switch ($ExecutionType) { 'Local' { $AddDryADGroupMemberParams += @{ DomainController = $DomainController } } 'Remote' { $AddDryADGroupMemberParams += @{ PSSession = $PSSession } } } ol i "Group Members (Computer '$ComputerName')","Add '$ComputerRoleGroupMember' to '$($ComputerRoleGroup.groupname)'" Add-DryADGroupMember @AddDryADGroupMemberParams Remove-Variable -Name AddDryADGroupMemberParams -ErrorAction Ignore } ForEach ($ComputerRoleGroupMemberOf in $ComputerRoleGroup.MemberOf) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Group Member Of: $($ComputerRoleGroup.groupname)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Add $ComputerRoleGroup to each MemberOf $AddDryADGroupMemberParams = @{ Group = $ComputerRoleGroupMemberOf Member = $ComputerRoleGroup.groupname } Switch ($ExecutionType) { 'Local' { $AddDryADGroupMemberParams += @{ DomainController = $DomainController } } 'Remote' { $AddDryADGroupMemberParams += @{ PSSession = $PSSession } } } ol i "Group Members (Computer '$ComputerName')","Add '$($ComputerRoleGroup.groupname)' to '$ComputerRoleGroupMemberOf'" Add-DryADGroupMember @AddDryADGroupMemberParams Remove-Variable -Name AddDryADGroupMemberParams -ErrorAction Ignore } } ForEach ($ComputerRightsGroup in $ComputerRightsGroups) { ForEach ($ComputerRightsGroupMember in $ComputerRightsGroup.Member) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Group Member: $($ComputerRightsGroup.groupname)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Add Members to $ComputerRightsGroup $AddDryADGroupMemberParams = @{ Group = $ComputerRightsGroup.groupname Member = $ComputerRightsGroupMember } Switch ($ExecutionType) { 'Local' { $AddDryADGroupMemberParams += @{ DomainController = $DomainController } } 'Remote' { $AddDryADGroupMemberParams += @{ PSSession = $PSSession } } } ol i "Group Members (Computer '$ComputerName'): Add '$ComputerRightsGroupMember' to '$($ComputerRightsGroup.groupname)'" Add-DryADGroupMember @AddDryADGroupMemberParams Remove-Variable -Name AddDryADGroupMemberParams -ErrorAction Ignore } ForEach ($ComputerRightsGroupMemberOf in $ComputerRightsGroup.MemberOf) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Group Member Of: $($ComputerRightsGroup.groupname)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Add $ComputerRightsGroup to each MemberOf $AddDryADGroupMemberParams = @{ Group = $ComputerRightsGroupMemberOf Member = $ComputerRightsGroup.groupname } Switch ($ExecutionType) { 'Local' { $AddDryADGroupMemberParams += @{ DomainController = $DomainController } } 'Remote' { $AddDryADGroupMemberParams += @{ PSSession = $PSSession } } } ol i "Group Members (Computer '$CompterName')","Add '$($ComputerRightsGroup.groupname)' to '$ComputerRightsGroupMemberOf'" Add-DryADGroupMember @AddDryADGroupMemberParams Remove-Variable -Name AddDryADGroupMemberParams -ErrorAction Ignore } } $DebugCounter += $NumberOfMemberAndMemberOf If ($ElementsCounter -ne $DebugCounter) { Throw "Elementscounter is $ElementsCounter, but was supposed to be $DebugCounter" } } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # USERS # Action: Getting the connection point's public certificate. # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ($ProcessUsers) { If ( ($NumberOfUsers.Count -gt 0) -and ($ExecutionType -eq 'Remote') ) { ol i "Users - Getting the Connection Point's public certificate" -sh Try { Get-DryADRemotePublicCertificate -PSSession $PSSession -CertificateFile $ConfigurationPublicCertificatePath } Catch { $PSCmdLet.ThrowTerminatingError($_) } } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # USERS # Action: Create # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ol i "Users - Domain scope ($($DomainUsers.count))" -sh # loop through domain Users ForEach ($User in $DomainUsers) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): User: $($User.name)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters $NewDryADUserParams = @{ User = $User DomainNB = $DomainNB DryDeploy = $DryDeploy } Switch ($ExecutionType) { 'Local' { $NewDryADUserParams += @{ DomainController = $DomainController } } 'Remote' { $NewDryADUserParams += @{ PSSession = $PSSession DCPublicCertificateFilePath = $ConfigurationPublicCertificatePath } } } ol i "Creating User (domain '$DomainFQDN')","$($User.name)" New-DryADUser @NewDryADUserParams } # loop through site Users ol i "Users - Site scope ($($SiteUsers.count))" -sh ForEach ($User in $SiteUsers) { # Add site to the description $User.description = $User.description + " (site '$adsite')" # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): User: $($User.name)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters $NewDryADUserParams = @{ User = $User DomainNB = $DomainNB DryDeploy = $DryDeploy } Switch ($ExecutionType) { 'Local' { $NewDryADUserParams += @{ DomainController = $DomainController } } 'Remote' { $NewDryADUserParams += @{ PSSession = $PSSession DCPublicCertificateFilePath = $ConfigurationPublicCertificatePath } } } ol i "Creating User (site '$adsite')","$($User.name)" New-DryADUser @NewDryADUserParams } # loop through site Users ol i "Users - Computer scope ($($ComputerUsers.count))" -sh ForEach ($User in $ComputerUsers) { # Add site to the description $User.description = $User.description + " (computer '$ComputerName')" # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): User: $($User.name)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters $NewDryADUserParams = @{ User = $User DomainNB = $DomainNB DryDeploy = $DryDeploy } Switch ($ExecutionType) { 'Local' { $NewDryADUserParams += @{ DomainController = $DomainController } } 'Remote' { $NewDryADUserParams += @{ PSSession = $PSSession DCPublicCertificateFilePath = $ConfigurationPublicCertificatePath } } } ol i "Creating User (computer '$ComputerName')","$($User.name)" New-DryADUser @NewDryADUserParams } $DebugCounter += $NumberOfUsers If ($ElementsCounter -ne $DebugCounter) { Throw "Elementscounter is $ElementsCounter, but was supposed to be $DebugCounter" } } # If ($ProcessUsers) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # USER'S GROUP MEMBERSHIPS # Action: Add Users to Groups # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ($ProcessUserMemberOf) { ol i "User Group Memberships Domain scope ($NumberOfDomainUserMemberOf)" -sh # Both Role and Rights groups may have .member and .memberof ForEach ($DomainUser in $DomainUsers) { ForEach ($DomainUserMemberOf in $DomainUser.MemberOf) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): $($DomainUser.name) member of: $DomainUserMemberOf" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Add $DomainUser to each MemberOf $AddDryADGroupMemberParams = @{ Group = $DomainUserMemberOf Member = $DomainUser.name } Switch ($ExecutionType) { 'Local' { $AddDryADGroupMemberParams += @{ DomainController = $DomainController } } 'Remote' { $AddDryADGroupMemberParams += @{ PSSession = $PSSession } } } ol i "Group Members (domain '$DomainFQDN')","Adding '$($DomainUser.name)' to '$DomainUserMemberOf'" Add-DryADGroupMember @AddDryADGroupMemberParams Remove-Variable -Name AddDryADGroupMemberParams -ErrorAction Ignore } } ol i "User Group Memberships Site scope ($NumberOfSiteUserMemberOf)" -sh ForEach ($SiteUser in $SiteUsers) { ForEach ($SiteUserMemberOf in $SiteUser.MemberOf) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): $($SiteUser.name) member of: $SiteUserMemberOf" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Add $SiteUser to each MemberOf $AddDryADGroupMemberParams = @{ Group = $SiteUserMemberOf Member = $SiteUser.name } Switch ($ExecutionType) { 'Local' { $AddDryADGroupMemberParams += @{ DomainController = $DomainController } } 'Remote' { $AddDryADGroupMemberParams += @{ PSSession = $PSSession } } } ol i "Group Members (site '$adsite')","Adding '$($SiteUser.name)' to '$SiteUserMemberOf'" Add-DryADGroupMember @AddDryADGroupMemberParams Remove-Variable -Name AddDryADGroupMemberParams -ErrorAction Ignore } } ol i "User Group Memberships Computer scope ($NumberOfComputerUserMemberOf)" -sh ForEach ($ComputerUser in $ComputerUsers) { ForEach ($ComputerUserMemberOf in $ComputerUser.MemberOf) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): $($ComputerUser.name) member of: $ComputerUserMemberOf" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Add $ComputerUser to each MemberOf $AddDryADGroupMemberParams = @{ Group = $ComputerUserMemberOf Member = $ComputerUser.name } Switch ($ExecutionType) { 'Local' { $AddDryADGroupMemberParams += @{ DomainController = $DomainController } } 'Remote' { $AddDryADGroupMemberParams += @{ PSSession = $PSSession } } } ol i "Group Members (computer '$ComputerName')","Add '$($ComputerUser.name)' to '$ComputerUserMemberOf'" Add-DryADGroupMember @AddDryADGroupMemberParams Remove-Variable -Name AddDryADGroupMemberParams -ErrorAction Ignore } } $DebugCounter += $NumberOfUserMemberOf If ($ElementsCounter -ne $DebugCounter) { Throw "Elementscounter is $ElementsCounter, but was supposed to be $DebugCounter" } } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ACTIVE DIRECTORY RIGHTS # Action: Delegate Rights in AD # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ($ProcessRights) { ol i "Rights - Domain scope ($NumberOfDomainRights)" -sh # Domain Rights ForEach ($DomainRightsGroup in $DomainRightsGroups) { ForEach ($DomainRight in $DomainRightsGroup.Rights) { ol v "Setting rights for group '$($DomainRightsGroup.groupname)'" # create hash from properties of the object Remove-Variable -Name SetDryADAccessRuleParams -ErrorAction Ignore $SetDryADAccessRuleParams = @{} # Add all properties but site and scope to the rights hash $DomainRight.PSObject.Properties | ForEach-Object { If ($_.Name -notin @('scope')) { $SetDryADAccessRuleParams.Add($_.Name,$_.Value) } } # Add the groupname as 'Group' - the owner of the right $SetDryADAccessRuleParams.Add('Group',$DomainRightsGroup.groupname) Switch ($ExecutionType) { 'Local' { $SetDryADAccessRuleParams += @{ DomainController = $DomainController } } 'Remote' { $SetDryADAccessRuleParams += @{ PSSession = $PSSession } } } # Debug logging ol d -hash $SetDryADAccessRuleParams # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Domain Right: $($DomainRight.Path)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Set the right ol i "Rights (domain '$DomainFQDN')","Group '$($DomainRightsGroup.groupname)'" ol i "Rights (domain '$DomainFQDN')","Target '$($DomainRight.Path)'" If ((Set-DryADAccessRule @SetDryADAccessRuleParams) -eq $True) { ol i "Rights (domain '$DomainFQDN')",'' } Else { ol e @("Rights (domain '$DomainFQDN')","Group '$($DomainRightsGroup.groupname)', Target '$($DomainRight.Path)'") Throw "Failed: domain '$DomainFQDN'): Group '$($DomainRightsGroup.groupname)', Target '$($DomainRight.Path)'" } # Clean up Remove-Variable -Name SetDryADAccessRuleParams,WriteProgressParameters -ErrorAction Ignore } } # Site Rights ol i "Rights - Site scope ($NumberOfSiteRights)" -sh ForEach ($SiteRightsGroup in $SiteRightsGroups) { ForEach ($SiteRight in $SiteRightsGroup.Rights) { # create hash from properties of the object Remove-Variable -Name SetDryADAccessRuleParams -ErrorAction Ignore $SetDryADAccessRuleParams = @{} # Add all properties but site and scope to the rights hash $SiteRight.PSObject.Properties | ForEach-Object { If ($_.Name -notin @('scope')) { $SetDryADAccessRuleParams.Add($_.Name,$_.Value) } } # Add the groupname as 'Group' - the owner of the right $SetDryADAccessRuleParams.Add('Group',$SiteRightsGroup.groupname) Switch ($ExecutionType) { 'Local' { $SetDryADAccessRuleParams += @{ DomainController = $DomainController } } 'Remote' { $SetDryADAccessRuleParams += @{ PSSession = $PSSession } } } # Debug logging ol d -hash $SetDryADAccessRuleParams # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Site Right: $($SiteRight.Path)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Set the right ol i "Rights (site '$adsite')","Group '$($SiteRightsGroup.groupname)'" ol i "Rights (site '$adsite')","Target '$($SiteRight.Path)'" If ((Set-DryADAccessRule @SetDryADAccessRuleParams) -eq $True) { ol i "Rights (site '$adsite')",'' } Else { ol e @("Rights (site '$adsite')","Group '$($SiteRightsGroup.groupname)', Target '$($SiteRight.Path)'") Throw "Failed: Rights (site '$adsite'): Group '$($SiteRightsGroup.groupname)', Target '$($SiteRight.Path)'" } # Clean up Remove-Variable -Name SetDryADAccessRuleParams,WriteProgressParameters -ErrorAction Ignore } } # Computer scoped Rights ol i "Rights - Computer scope ($NumberOfComputerRights)" -sh ForEach ($ComputerRightsGroup in $ComputerRightsGroups) { ForEach ($ComputerRight in $ComputerRightsGroup.Rights) { # create hash from properties of the object Remove-Variable -Name SetDryADAccessRuleParams -ErrorAction Ignore $SetDryADAccessRuleParams = @{} # Add all properties but site and scope to the rights hash $ComputerRight.PSObject.Properties | ForEach-Object { If ($_.Name -notin @('scope')) { $SetDryADAccessRuleParams.Add($_.Name,$_.Value) } } # Add the groupname as 'Group' - the owner of the right $SetDryADAccessRuleParams.Add('Group',$ComputerRightsGroup.groupname) Switch ($ExecutionType) { 'Local' { $SetDryADAccessRuleParams += @{ DomainController = $DomainController } } 'Remote' { $SetDryADAccessRuleParams += @{ PSSession = $PSSession } } } # Debug logging ol d -hash $SetDryADAccessRuleParams # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Computer Right: $($ComputerRight.Path)" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Set the right ol i "Rights (Computer '$ComputerName')","Group '$($ComputerRightsGroup.groupname)' =>" ol i "Rights (Computer '$ComputerName')","Target '$($ComputerRight.Path)'" If ((Set-DryADAccessRule @SetDryADAccessRuleParams) -eq $True) { ol i "Rights (Computer '$ComputerName')",'' } Else { ol e @("Rights (Computer '$ComputerName')","Group '$($ComputerRightsGroup.groupname)', Target '$($ComputerRight.Path)'") Throw "Failed: Rights (Computer '$ComputerName')","Group '$($ComputerRightsGroup.groupname)', Target '$($ComputerRight.Path)'" } # Clean up Remove-Variable -Name SetDryADAccessRuleParams,WriteProgressParameters -ErrorAction Ignore } } $DebugCounter += $NumberOfRights If ($ElementsCounter -ne $DebugCounter) { Throw "Elementscounter is $ElementsCounter, but was supposed to be $DebugCounter" } } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # GROUP POLICIES # Action: Define paths, copy helper modules and GPOs to remote target if # ExecutionType 'Remote' # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ($ProcessGPOImports) { Switch ($ExecutionType) { 'Remote' { [String]$RemoteRootPath = "C:\DryDeploy\$ComputerName\" [String]$GPOsPath = Join-Path -Path $RemoteRootPath -ChildPath 'GPOs' # Only invoke if json-gpos in configuration If ($RequiresAccessToGPOManagement) { ol i "GPO Imports - Copying helper module to remote target" -sh Copy-DryADModulesToRemoteTarget -PSSession $PSSession -RemoteRootPath $RemoteRootPath -Modules @('GPOManagement') | Out-Null } ol i "GPO Imports - Copying GPOs to remote target" -sh Copy-DryADFilesToRemoteTarget -PSSession $PSSession -TargetPath $RemoteRootPath -SourcePath $SourceGPOsPath | Out-Null } 'Local' { [String]$GPOsPath = $SourceGPOsPath } } # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # GROUP POLICIES # Action: Import # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ol i "GPO Imports - Domain scope ($($DomainGPOImports.count))" -sh ForEach ($GPO in $DomainGPOImports) { # Ensure TargetName exists, and is converted to the desired case If ($Null -eq $GPO.TargetName) { $GPO | Add-Member -MemberType NoteProperty -Name 'TargetName' -Value $(ConvertTo-DryADCase -Name $GPO.Name -Case $GPOcase) } Else { $GPO.TargetName = ConvertTo-DryADCase -Name $GPO.TargetName -Case $GPOcase } # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Importing GPO '$($GPO.TargetName)'" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters $ImportDryADGPOParams = @{ GPO = $GPO GPOsPath = $GPOsPath Scope = 'domain' ReplacementHash = $ReplacementHash } Switch ($ExecutionType) { 'Local' { $ImportDryADGPOParams += @{ DomainController = $DomainController } } 'Remote' { $ImportDryADGPOParams += @{ PSSession = $PSSession } } } ol i "GPO Import (domain '$DomainFQDN')","Importing '$($GPO.Name)'" Import-DryADGPO @ImportDryADGPOParams } ol i "GPO Imports - Site scope ($($SiteGPOImports.count))" -sh ForEach ($GPO in $SiteGPOImports) { # Ensure TargetName exists, and is converted to the desired case If ($Null -eq $GPO.TargetName) { $GPO | Add-Member -MemberType NoteProperty -Name 'TargetName' -Value $(ConvertTo-DryADCase -Name $GPO.Name -Case $GPOcase) } Else { $GPO.TargetName = ConvertTo-DryADCase -Name $GPO.TargetName -Case $GPOcase } # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Importing GPO '$($GPO.Name)'" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters $ImportDryADGPOParams = @{ GPO = $GPO GPOsPath = $GPOsPath Scope = 'site' ReplacementHash = $ReplacementHash } Switch ($ExecutionType) { 'Local' { $ImportDryADGPOParams += @{ DomainController = $DomainController } } 'Remote' { $ImportDryADGPOParams += @{ PSSession = $PSSession } } } ol i "GPO Import (site '$ADSite')","Importing '$($GPO.Name)'" Import-DryADGPO @ImportDryADGPOParams } ol i "GPO Imports - Computer scope ($($ComputerGPOImports.count))" -sh ForEach ($GPO in $ComputerGPOImports) { # Ensure TargetName exists, and is converted to the desired case If ($Null -eq $GPO.TargetName) { $GPO | Add-Member -MemberType NoteProperty -Name 'TargetName' -Value $(ConvertTo-DryADCase -Name $GPO.Name -Case $GPOcase) } Else { $GPO.TargetName = ConvertTo-DryADCase -Name $GPO.TargetName -Case $GPOcase } # Increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Importing GPO '$($GPO.Name)'" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters $ImportDryADGPOParams = @{ GPO = $GPO GPOsPath = $GPOsPath Scope = 'computer' ReplacementHash = $ReplacementHash } Switch ($ExecutionType) { 'Local' { $ImportDryADGPOParams += @{ DomainController = $DomainController } } 'Remote' { $ImportDryADGPOParams += @{ PSSession = $PSSession } } } ol i "GPO Import (Computer '$ComputerName')","Importing '$($GPO.Name)'" Import-DryADGPO @ImportDryADGPOParams } $DebugCounter += $NumberOfGPOImports If ($ElementsCounter -ne $DebugCounter) { Throw "Elementscounter is $ElementsCounter, but was supposed to be $DebugCounter" } } # If ($ProcessGPO) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # GROUP POLICIES # Action: Links # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ($ProcessGPOLinks) { ol i "GPO Links - Domain scope ($($DomainGPOLinks.count))" -sh ForEach ($DomainGPOLink in $DomainGPOLinks | Where-Object { $_.defined_in -eq 'OS'}) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Linking GPOs to '$($DomainGPOLink.Path)'" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Call Set-DryADGPLink. Let that function do the Information Logging $SetDryGPLinkParams = @{ GPOLinkObject = $DomainGPOLink DomainDN = $DomainDN DomainFQDN = $DomainFQDN } Switch ($ExecutionType) { 'Local' { $SetDryGPLinkParams += @{ DomainController = $DomainController } } 'Remote' { $SetDryGPLinkParams += @{ PSSession = $PSSession } } } If (($DomainGPOLink.Path).Trim() -eq '') { ol i "Link GPOs (domain '$DomainFQDN') to","(Domain Root)" } Else { ol i "Link GPOs (domain '$DomainFQDN') to","$($DomainGPOLink.Path)" } Set-DryADGPLink @SetDryGPLinkParams } ForEach ($DomainGPOLink in $DomainGPOLinks | Where-Object { $_.defined_in -ne 'OS'}) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Linking GPOs to '$($DomainGPOLink.Path)'" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Call Set-DryADGPLink. Let that function do the Information Logging $SetDryGPLinkParams = @{ GPOLinkObject = $DomainGPOLink DomainDN = $DomainDN DomainFQDN = $DomainFQDN } Switch ($ExecutionType) { 'Local' { $SetDryGPLinkParams += @{ DomainController = $DomainController } } 'Remote' { $SetDryGPLinkParams += @{ PSSession = $PSSession } } } If (($DomainGPOLink.Path).Trim() -eq '') { ol i "Link GPOs (domain '$DomainFQDN') to","(Domain Root)" } Else { ol i "Link GPOs (domain '$DomainFQDN') to","$($DomainGPOLink.Path)" } Set-DryADGPLink @SetDryGPLinkParams } ol i "GPO Links - Site scope ($($SiteGPOLinks.count))" -sh # loop through Site GPOLinks defined by the OS Config ForEach ($SiteGPOLink in $SiteGPOLinks | Where-Object { $_.defined_in -eq 'OS'}) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Linking GPOs to '$($SiteGPOLink.Path)'" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Call Set-DryADGPLink. Let that function do the Information Logging $SetDryGPLinkParams = @{ GPOLinkObject = $SiteGPOLink DomainDN = $DomainDN DomainFQDN = $DomainFQDN } Switch ($ExecutionType) { 'Local' { $SetDryGPLinkParams += @{ DomainController = $DomainController } } 'Remote' { $SetDryGPLinkParams += @{ PSSession = $PSSession } } } If (($SiteGPOLink.Path).Trim() -eq '') { ol i "Link GPOs (site '$adsite') to","(Root of Domain)" } Else { ol i "Link GPOs (site '$adsite') to","$($SiteGPOLink.Path)" } Set-DryADGPLink @SetDryGPLinkParams } # loop through Site GPOLinks defined by the Role ForEach ($SiteGPOLink in $SiteGPOLinks | Where-Object { $_.defined_in -ne 'OS'}) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Linking GPOs to '$($SiteGPOLink.Path)'" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Call Set-DryADGPLink. Let that function do the Information Logging $SetDryGPLinkParams = @{ GPOLinkObject = $SiteGPOLink DomainDN = $DomainDN DomainFQDN = $DomainFQDN } Switch ($ExecutionType) { 'Local' { $SetDryGPLinkParams += @{ DomainController = $DomainController } } 'Remote' { $SetDryGPLinkParams += @{ PSSession = $PSSession } } } If (($SiteGPOLink.Path).Trim() -eq '') { ol i "Link GPOs (site '$adsite') to","(Root of Domain)" } Else { ol i "Link GPOs (site '$adsite') to","$($SiteGPOLink.Path)" } Set-DryADGPLink @SetDryGPLinkParams } ol i "GPO Links - Computer scope ($($ComputerGPOLinks.count))" -sh # loop through Computer GPOLinks defined by the OS Config ForEach ($ComputerGPOLink in $ComputerGPOLinks | Where-Object { $_.defined_in -eq 'OS'}) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Linking GPOs to '$($ComputerGPOLink.Path)'" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Call Set-DryADGPLink. Let that function do the Information Logging $SetDryGPLinkParams = @{ GPOLinkObject = $ComputerGPOLink DomainDN = $DomainDN DomainFQDN = $DomainFQDN } Switch ($ExecutionType) { 'Local' { $SetDryGPLinkParams += @{ DomainController = $DomainController } } 'Remote' { $SetDryGPLinkParams += @{ PSSession = $PSSession } } } If (($ComputerGPOLink.Path).Trim() -eq '') { ol i "Link GPOs (Computer '$ComputerName') to","(Root of Domain)" } Else { ol i "Link GPOs (Computer '$ComputerName') to","$($ComputerGPOLink.Path)" } Set-DryADGPLink @SetDryGPLinkParams } # loop through Computer GPOLinks defined by the Role ForEach ($ComputerGPOLink in $ComputerGPOLinks | Where-Object { $_.defined_in -ne 'OS'}) { # increment the element counter and update progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Linking GPOs to '$($ComputerGPOLink.Path)'" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters # Call Set-DryADGPLink. Let that function do the Information Logging $SetDryGPLinkParams = @{ GPOLinkObject = $ComputerGPOLink DomainDN = $DomainDN DomainFQDN = $DomainFQDN } Switch ($ExecutionType) { 'Local' { $SetDryGPLinkParams += @{ DomainController = $DomainController } } 'Remote' { $SetDryGPLinkParams += @{ PSSession = $PSSession } } } If (($ComputerGPOLink.Path).Trim() -eq '') { ol i "Link GPOs (Computer '$ComputerName') to","(Root of Domain)" } Else { ol i "Link GPOs (Computer '$ComputerName') to","$($ComputerGPOLink.Path)" } Set-DryADGPLink @SetDryGPLinkParams } $DebugCounter += $NumberOfGPOLinks If ($ElementsCounter -ne $DebugCounter) { Throw "Elementscounter is $ElementsCounter, but was supposed to be $DebugCounter" } } # If ($ProcessGPOLinks) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Wmi Filter Links # Action: Link to GPOs # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # If ($ProcessWMIFilterLinks) { ol i "WMIFilterLinks - Domain scope ($DomainWmiFilterLinksCount)" -sh ForEach ($GPOWMIFilter in $DomainWMIFilters) { ForEach ($GPOWMIFilterLink in $GPOWMIFilter.links) { # Progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Linking WMIFilter '$($GPOWMIFilter.Name)'" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters $SetDryWmiFilterLinkParams = @{ GPOName = $GPOWMIFilterLink WMIFilterName = $GPOWMIFilter.Name } Switch ($ExecutionType) { 'Local' { $SetDryWmiFilterLinkParams += @{ DomainController = $DomainController } } 'Remote' { $SetDryWmiFilterLinkParams += @{ PSSession = $PSSession } } } ol i "Linking WMI Filter (domain '$DomainFQDN')","$($GPOWMIFilter.Name)" Set-DryADWmiFilterLink @SetDryWmiFilterLinkParams } } ol i "WMIFilters - Site scope ($SiteWmiFilterLinksCount)" -sh ForEach ($GPOWMIFilter in $SiteWMIFilters) { ForEach ($GPOWMIFilterLink in $GPOWMIFilter.links) { # Progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Linking WMIFilter '$($GPOWMIFilter.Name)'" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters $SetDryWmiFilterLinkParams = @{ GPOName = $GPOWMIFilterLink WMIFilterName = $GPOWMIFilter.Name } Switch ($ExecutionType) { 'Local' { $SetDryWmiFilterLinkParams += @{ DomainController = $DomainController } } 'Remote' { $SetDryWmiFilterLinkParams += @{ PSSession = $PSSession } } } ol i "Linking WMI Filter (site '$adsite')","$($GPOWMIFilter.Name)" Set-DryADWmiFilterLink @SetDryWmiFilterLinkParams } } ol i "WMIFilters - Computer scope ($ComputerWmiFilterLinksCount)" -sh ForEach ($GPOWMIFilter in $ComputerWMIFilters) { ForEach ($GPOWMIFilterLink in $GPOWMIFilter.links) { # Progress $ElementsCounter++ $WriteProgressParameters = @{ Activity = 'Configuring Active Directory' Status = "Item ($ElementsCounter / $NumberOfElementsToProcess): Linking WMIFilter '$($GPOWMIFilter.Name)'" PercentComplete = (($ElementsCounter / $NumberOfElementsToProcess) * 100 ) } Write-Progress @WriteProgressParameters $SetDryWmiFilterLinkParams = @{ GPOName = $GPOWMIFilterLink WMIFilterName = $GPOWMIFilter.Name } Switch ($ExecutionType) { 'Local' { $SetDryWmiFilterLinkParams += @{ DomainController = $DomainController } } 'Remote' { $SetDryWmiFilterLinkParams += @{ PSSession = $PSSession } } } ol i "Linking WMI Filter (computer '$ComputerName')","$($GPOWMIFilter.Name)" Set-DryADWmiFilterLink @SetDryWmiFilterLinkParams } } $DebugCounter += $NumberOfWMIFilterLinks If ($ElementsCounter -ne $DebugCounter) { Throw "Elementscounter is $ElementsCounter, but was supposed to be $DebugCounter" } } ol i "ConfigAD ran successfully" -sh } Catch { $PSCmdLet.ThrowTerminatingError($_) } Finally { $PSSession | Remove-PSSession -ErrorAction SilentlyContinue # End the progress bar Write-Progress -Completed -Activity "Configuring AD objects" ol i "Set-DryADConfiguration ended" -sh } } |