Last active
June 20, 2024 09:23
-
-
Save bentman/7c0ff8f837b97dc0ef562a01e9661ce5 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
function Wait-UntilAdComputerDeleted { | |
<# | |
.SYNOPSIS | |
Waits until a specified computer object is deleted from all domain controllers. | |
.DESCRIPTION | |
This function checks the deletion status of a specified computer object across all discovered domain controllers. It waits until the object is confirmed deleted on all domain controllers or identifies any inaccessible controllers after a specified number of failures. | |
.PARAMETER computerName | |
The name of the computer object to check for deletion. Required. | |
.PARAMETER sleepInterval | |
The number of seconds to wait between checks. Default is 5 seconds. | |
.PARAMETER failureThreshold | |
The number of failures before a domain controller is considered inaccessible. Default is 5 failures. | |
.EXAMPLE | |
Wait-UntilAdComputerDeleted -computerName "Computer1" | |
.EXAMPLE | |
Wait-UntilAdComputerDeleted -computerName "Computer1" -sleepInterval 10 -failureThreshold 3 | |
#> | |
param ( | |
[Parameter(Mandatory = $true)] [string]$computerName, | |
[Parameter()] [int]$sleepInterval = 5, # Default sleep interval of 5 seconds | |
[Parameter()] [int]$failureThreshold = 5 # Number of failures before considering a DC as inaccessible | |
) | |
# Import the Active Directory module | |
try { Import-Module ActiveDirectory -ErrorAction Stop } | |
catch { Write-Output "Error importing Active Directory module: $($_.Exception.Message)"; return } | |
# Get the distinguished name of the computer object | |
try { $computer = Get-ADComputer -Identity $computerName -ErrorAction Stop } | |
catch { Write-Output "Error retrieving computer object '$computerName': $($_.Exception.Message)"; return } | |
if ($null -eq $computer) { Write-Output "Computer object '$computerName' not found in Active Directory."; return } | |
$objectDN = $computer.DistinguishedName | |
# Dynamically discover domain controllers | |
try { $domainControllers = (Get-ADDomainController -Discover -Service PrimaryDC).HostName } | |
catch { Write-Output "Error retrieving domain controllers: $($_.Exception.Message)"; return } | |
$failureCount = @{}; $inaccessibleDCs = @() | |
foreach ($dc in $domainControllers) { $failureCount[$dc] = 0 } | |
do { | |
$remainingDCs = @($domainControllers | Where-Object { $inaccessibleDCs -notcontains $_ }) | |
foreach ($dc in $remainingDCs) { | |
try { | |
$replicationMetadata = Get-ADReplicationAttributeMetadata -Object $objectDN -Server $dc -Properties "isDeleted" -ErrorAction Stop | |
if ($null -eq $replicationMetadata -or $replicationMetadata.AttributeMetaData.isDeleted -ne $true) { Write-Output "Object $objectDN is not deleted on $dc." } | |
else { | |
Write-Output "Object $objectDN is confirmed deleted on $dc." | |
$domainControllers = $domainControllers -ne $dc # Remove the DC from future checks | |
} | |
$failureCount[$dc] = 0 # Reset failure count on successful contact | |
} | |
catch { | |
Write-Output "Error checking deletion status on $($dc): $($_.Exception.Message)" | |
$failureCount[$dc]++ | |
if ($failureCount[$dc] -ge $failureThreshold) { Write-Output "Marking $dc as inaccessible after $failureThreshold failures."; $inaccessibleDCs += $dc } | |
} | |
} | |
if ($domainControllers.Count -gt 0) { | |
Write-Output "$($domainControllers.Count) domain controller(s) remaining. Waiting for $sleepInterval seconds before rechecking..." | |
Start-Sleep -Seconds $sleepInterval | |
} | |
} | |
while ($domainControllers.Count -gt 0) | |
if ($inaccessibleDCs.Count -gt 0) { Write-Output "The following domain controller(s) were inaccessible:"; $inaccessibleDCs | ForEach-Object { Write-Output "- $_" } } | |
if ($domainControllers.Count -eq 0) { | |
if ($inaccessibleDCs.Count -gt 0) { Write-Output "Object $objectDN is deleted on all accessible domain controllers, but some were inaccessible." } | |
else { Write-Output "Object $objectDN is deleted on all domain controllers." } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment