Last active
May 29, 2024 15:53
-
-
Save realslacker/98ca8e767bbb282ca2d7eac876aec370 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.SYNOPSIS | |
Converts top level Users and Computers containers into OUs allowing you to attach policy | |
.PARAMETER Server | |
Domain controller to use for all operations, defaults to PDC Emulator | |
.PARAMETER Credential | |
Domain Admin level credential to use for operations, defaults to current user | |
#> | |
[CmdletBinding()] | |
param( | |
[string] | |
$Server, | |
[pscredential] | |
$Credential | |
) | |
#Requires -Modules ActiveDirectory | |
#Requires -RunAsAdministrator | |
if ( -not $PSBoundParameters.ContainsKey('Server') ) { | |
$PSBoundParameters.Server = $Server = Get-ADDomainController -Discover -Service PrimaryDC | Select-Object -ExpandProperty HostName | |
} | |
$Domain = Get-ADDomain @PSBoundParameters | |
'Users', 'Computers' | ForEach-Object { | |
Write-Host ( 'Processing ''{0}'' container...' -f $_ ) | |
$ContainerObject = Get-ADObject -Filter ( 'DistinguishedName -eq "CN={0},{1}" -and ObjectClass -eq "container"' -f $_, $Domain.DistinguishedName ) @PSBoundParameters | |
if ( $ContainerObject ) { | |
$TempOU = Get-ADObject -Filter ( 'DistinguishedName -eq "OU=Temp{0},{1}" -and ObjectClass -eq "organizationalUnit"' -f $_, $Domain.DistinguishedName ) @PSBoundParameters | |
if ( -not $TempOU ) { | |
Write-Host ( 'Creating temporary OU ''Temp{0}''...' -f $_ ) | |
$TempOU = New-ADOrganizationalUnit -Name ( 'Temp{0}' -f $_ ) -Path $Domain.DistinguishedName @PSBoundParameters -PassThru | |
} | |
[object[]] $DecendantObjects = Get-ADObject -Filter * -SearchScope OneLevel -SearchBase $ContainerObject.DistinguishedName -Properties ProtectedFromAccidentalDeletion @PSBoundParameters | |
if ( $DecendantObjects ) { | |
Write-Host ( 'Moving {0} objects to the temporary OU...' -f $DecendantObjects.Count ) | |
$DecendantObjects | Set-ADObject -ProtectedFromAccidentalDeletion:$false -PassThru @PSBoundParameters | Move-ADObject -TargetPath $TempOU.DistinguishedName -Confirm:$false @PSBoundParameters | |
$DecendantObjects | Where-Object { $_.ProtectedFromAccidentalDeletion -eq $true } | ForEach-Object { Set-ADObject -Identity $_.ObjectGuid -ProtectedFromAccidentalDeletion:$true @PSBoundParameters } | |
} | |
$OldWellKnownObject = Get-ADObject -Identity $Domain.DistinguishedName -Properties WellKnownObjects | Select-Object -ExpandProperty WellKnownObjects | Where-Object { $_.Split(':')[-1] -eq $ContainerObject.DistinguishedName } | |
if ( $OldWellKnownObject ) { | |
Write-Host ( 'Updating {0} redirection to the temporary OU...' -f $_ ) | |
$WKOParts = $OldWellKnownObject.Split(':') | |
$WKOParts[-1] = $TempOU.DistinguishedName | |
$NewWellKnownObject = $WKOParts -join ':' | |
Set-ADObject -Identity $Domain.DistinguishedName -Remove @{ wellKnownObjects = $OldWellKnownObject } -Add @{ wellKnownObjects = $NewWellKnownObject } @PSBoundParameters | |
} | |
Write-Host ( 'Removing {0} container...' -f $_ ) | |
$ContainerObject | Set-ADObject -ProtectedFromAccidentalDeletion:$false -PassThru @PSBoundParameters | Remove-ADObject -Confirm:$false @PSBoundParameters | |
} | |
$FinalOU = Get-ADObject -Filter ( 'DistinguishedName -eq "OU={0},{1}" -and ObjectClass -eq "organizationalUnit"' -f $_, $Domain.DistinguishedName ) @PSBoundParameters | |
if ( -not $FinalOU ) { | |
$FinalOU = New-ADOrganizationalUnit -Name $_ -Path $Domain.DistinguishedName @PSBoundParameters -PassThru | |
} | |
$TempOU = Get-ADObject -Filter ( 'DistinguishedName -eq "OU=Temp{0},{1}" -and ObjectClass -eq "organizationalUnit"' -f $_, $Domain.DistinguishedName ) @PSBoundParameters | |
if ( $TempOU ) { | |
[object[]] $DecendantObjects = Get-ADObject -Filter * -SearchScope OneLevel -SearchBase $TempOU.DistinguishedName -Properties ProtectedFromAccidentalDeletion @PSBoundParameters | |
if ( $DecendantObjects ) { | |
Write-Host ( 'Moving {0} objects to the final OU...' -f $DecendantObjects.Count ) | |
$DecendantObjects | Set-ADObject -ProtectedFromAccidentalDeletion:$false -PassThru @PSBoundParameters | Move-ADObject -TargetPath $FinalOU.DistinguishedName -Confirm:$false @PSBoundParameters | |
$DecendantObjects | Where-Object { $_.ProtectedFromAccidentalDeletion -eq $true } | ForEach-Object { Set-ADObject -Identity $_.ObjectGuid -ProtectedFromAccidentalDeletion:$true @PSBoundParameters } | |
} | |
$OldWellKnownObject = Get-ADObject -Identity $Domain.DistinguishedName -Properties WellKnownObjects | Select-Object -ExpandProperty WellKnownObjects | Where-Object { $_.Split(':')[-1] -eq $TempOU.DistinguishedName } | |
if ( $OldWellKnownObject ) { | |
Write-Host ( 'Updating {0} redirection to the final OU...' -f $_ ) | |
$WKOParts = $OldWellKnownObject.Split(':') | |
$WKOParts[-1] = $FinalOU.DistinguishedName | |
$NewWellKnownObject = $WKOParts -join ':' | |
Set-ADObject -Identity $Domain.DistinguishedName -Remove @{ wellKnownObjects = $OldWellKnownObject } -Add @{ wellKnownObjects = $NewWellKnownObject } @PSBoundParameters | |
} | |
$TempOU | Set-ADObject -ProtectedFromAccidentalDeletion:$false -PassThru @PSBoundParameters | Remove-ADOrganizationalUnit -Confirm:$false @PSBoundParameters | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment