Private/Confirm-ADSOrganizationalStructureGPO.ps1
Function Confirm-ADSOrganizationalStructureGPO { [CmdLetBinding(SupportsShouldProcess = $True)] Param ( [Parameter(Mandatory = $True)] [String] $DistinguishedName, [Parameter(Mandatory = $True)] [String] $ADServer, [Parameter(Mandatory = $True)] $OUStructure, [Parameter(Mandatory = $True)] $Variables ) Begin { Write-Verbose "[$($DistinguishedName)] Start $($MyInvocation.InvocationName)" [Bool]$YesToAllGPLink = $False [Bool]$NoToAllGPLink = $False } Process { Write-Verbose "[$($DistinguishedName)] Processing GPOs" # Clone node so to not overwrite settings in the template node $OUStructure = $OUStructure.CloneNode($True) If ($Null -ne $OUStructure.GPOGroup) { Write-Verbose "[$($DistinguishedName)] Processing GPO groups" ForEach ($group in $OUStructure.GPOGroup) { Write-Verbose "[$($DistinguishedName)] Importing $($group.GroupName)" $groupGPOs = Get-ADSGPOsFromGPOGroup -GroupName $($group.GroupName) $node = $OUStructure.OwnerDocument.ImportNode($groupGPOs, $True) ForEach ($childNode in $node.GPO) { # Write-Verbose "Importing $($childNode.OuterXml)" $OUStructure.AppendChild($childNode) | Out-Null } # Write-Verbose "$($OUStructure.OuterXml)" } } # BlockInheritance $Inheritance = Get-GPInheritance -Target $DistinguishedName -Server $ADServer $RequstedInheritanceStatus = $False If (-not [String]::IsNullOrEmpty($OUStructure.BlockInheritance)) { $RequstedInheritanceStatus = [Bool]$OUStructure.BlockInheritance } If ($Inheritance.GpoInheritanceBlocked -ne $RequstedInheritanceStatus) { Write-Verbose "[$($DistinguishedName)] Setting inheritance to '$($RequstedInheritanceStatus)'" If ($RequstedInheritanceStatus) { Set-GPInheritance -Target $DistinguishedName -IsBlocked 'Yes' -Confirm:$False -Server $ADServer | Out-Null } Else { Set-GPInheritance -Target $DistinguishedName -IsBlocked 'No' -Confirm:$False -Server $ADServer | Out-Null } } $LinkedGPOs = $Inheritance.GpoLinks # Sort by Order as INTEGER otherwise ASCII order will take preference (e.g, 1,10,100 then 2,20,200 and so on) $OrderedGPOs = $OUStructure.GPO | Sort-Object { [Int]$_.Order } $Order = 1 $ProcessedGPOs = @() ForEach ($gpo in $OrderedGPOs) { If (-not (Test-ADSGPOFilter -DistinguishedName $DistinguishedName -XML $gpo -OUStructure $OUStructure)) { Continue } $name = $gpo.DisplayName If ([String]::IsNullOrEmpty($name)) { If (-not [String]::IsNullOrEmpty($gpo.FormattedName)) { If ($DistinguishedName -match 'OU=([A-Z]{3}),OU=([A-Z]{2})') { $name = $gpo.FormattedName -replace '@COUNTRY@', $Matches[2] } Else { Write-Error "[$($DistinguishedName)] Failed to format name" } } Else { Write-Warning "[$($DistinguishedName)] No GPO Name set. Skipping processing" Continue } } If (-not [String]::IsNullOrEmpty($gpo.Order)) { $gpo.Order = ($Order++).ToString() } Else { $gpo.SetAttribute('Order', $Order++) | Out-Null } Write-Verbose "[$($DistinguishedName)]->[$($name)] Calculated order is $($gpo.Order) " $linkedGPO = $LinkedGPOs | Where-Object { $_.DisplayName -eq $name } # GPO is not linked but should be If (-not $DeleteOnly.IsPresent -and $Null -eq $linkedGPO) { If ($Null -eq ($AllGPOs | Where-Object { $_.DisplayName -eq $name })) { $Order-- Write-Host "[$($DistinguishedName)] Expected GPO '$($name)' in '$($DistinguishedName)' but did not find any matching GPO" -ForegroundColor Yellow Continue } Write-Host "[$($DistinguishedName)] Linking '$($name)' to '$($DistinguishedName)'" -ForegroundColor Green If ($PSCmdlet.ShouldProcess("-Name '$($name)' -Target '$($DistinguishedName)' -Order $($gpo.Order)", 'New-GPLink')) { New-GPLink -Name $($name) -Target $($DistinguishedName) -Order $($gpo.Order) -Server $ADServer | Out-Null } } # GPO is already linked but order is wrong ElseIf (-not $DeleteOnly.IsPresent -and ($linkedGPO.Order -ne $gpo.Order -or $ForceSetOUOrder.IsPresent)) { Write-Host "[$($DistinguishedName)] " -NoNewline -ForegroundColor Green If ($ForceSetOUOrder.IsPresent -and $linkedGPO.Order -eq $gpo.Order) { Write-Host 'FORCE ' -ForegroundColor Yellow -NoNewline } Write-Host "Setting order of '$($name)' in '$($DistinguishedName)' to $($gpo.Order)" -ForegroundColor Green If ($PSCmdlet.ShouldProcess("-Name '$($name)' -Target '$($DistinguishedName)' -Order $($gpo.Order)", 'Set-GPLink')) { Set-GPLink -Name $($name) -Target $($DistinguishedName) -Order $($gpo.Order) -Server $ADServer | Out-Null } } $ProcessedGPOs += $name } If (-not $CreateOnly.IsPresent) { $additionalGPOs = $LinkedGPOs | Where-Object { $_.DisplayName -notin $ProcessedGPOs } ForEach ($gpo in $additionalGPOs) { If ($gpo.DisplayName -like 'TEMP_*') { Write-Host "[$($DistinguishedName)] NOT deleting Link '$($gpo.DisplayName)' from '$($DistinguishedName)' as it's marked as temporary GPO" -ForegroundColor Yellow Continue } Write-Host "[$($DistinguishedName)] Deleting Link '$($gpo.DisplayName)' from '$($DistinguishedName)'" -ForegroundColor Red If ($PSCmdlet.ShouldProcess("-Name '$($gpo.DisplayName)' -Target '$($DistinguishedName)'", 'Remove-GPLink')) { If ($Force -or $PSCmdlet.ShouldContinue("Delete link of GPO '$($gpo.DisplayName)' from '$($DistinguishedName)'", "Are you sure you want to delete link of GPO '$($gpo.DisplayName)' from '$($DistinguishedName)'?", $False, [Ref]$YesToAllGPLink, [Ref]$NoToAllGPLink)) { Remove-GPLink -Name $($gpo.DisplayName) -Target $($DistinguishedName) -Server $ADServer | Out-Null } } } } } End { Write-Verbose "[$($DistinguishedName)] End $($MyInvocation.InvocationName)" } } |