Open utterances-bot opened 3 years ago
This article saved me hours of work. Thank you for posting this! I did however add the below code to the DNS cleanup as the current code did not remove the NS entries:
{$_ -eq "NS"} { If ($Record.RecordData.NameServer -like "$($AD_DC_Name_To_Remove)") { Write-Host "Removing DNS record" -ForegroundColor Yellow $Record $Record | Remove-DnsServerResourceRecord -ZoneName $ZoneName -ComputerName $($env:ComputerName) -Confirm:$false -Force } ;break }
Glad I could help!
I added your suggestion to the blog post for others as well. Good catch
Forgive me for being noob but why am i getting an error for #GettingtheForest
The error im getting for #GettingtheForest is
Get-ADForest : Cannot validate argument on parameter 'Identity'. The argument is null. Provide a valid value for the argument, and then try running the command again. At line:31 char:34
+ CategoryInfo : InvalidData: (:) [Get-ADForest], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADForest
Sorry for mutiple post
Hi,
It seems like you may have forgotten to fill in all the parameters.
Check out the parameters section of this page.
Hi,Eric "$Forest_Fully_Qualified_Domain_Name = "Forest.com" Does the variable "$Forest_Fully_Qualified_Domain_Name" need to modify as "$Forest_Domain_Name" ? Otherwise I get the same error as @mickdubs .
It's been a while since i've had to use this. It looks like I may have some values out of order. I'll need to lab this up to know for sure. That said, The idea here is to dynamically populate the variables. If you know the answers, then you can hard code them to get around it.
Thanks, Eric. This is a huge help here. I have made some changes to adapt to my lab. I will post later, tomorrow maybe, and it works like a charm with 0 error. Great script anyway.
https://kaedeleo.top/f84c4b07-6c48-4228-bd0c-4aa6179d67fc
$ip="10.1.1.57"
If ($All_Roles_To_Move_Count -gt 0) { foreach ($role in $All_Roles_To_Move ) { Move-ADDirectoryServerOperationMasterRole -Identity $AD_DC_Replacement_Name -OperationMasterRole $role -Force -confirm:$false } }
I will delete the article later on my blog. Thanks a lot!
I know this post is super old, but I wanted to say thanks. It saved me a massive amount of time by providing the bulk of a function I was creating. To say thanks I wanted to share that function as well as two other functions I had previously created for moving fsmo, and cleaning out DNS. Hope these help someone
Function Invoke-MetaDataCleanup{ <# .SYNOPSIS Removes a Domain Controller from Active Directory
.DESCRIPTION
Performs a complete metadata cleanup of a domain controller.
Make sure to seize any roles
.PARAMETER DcToRemove
.EXAMPLE
Remove-DCFromAD -DcToRemove DC01
Performs a metadata cleanup of DC01
#>
[CmdletBinding()]
param(
$DcToRemove
)
Begin {
#Gather Domain info
$FullyQualifiedDomainName = (Get-ADDomain).DNSRoot
$DomainDistinguishedName = (Get-ADDomain).DistinguishedName
#Get all AD Sites
$AllADSites = Get-ADReplicationSite -Filter "*"
#Formulate the FQDN of the DC
#$DCToRemoveFQDN = "$($ADDCNameToRemove).$($FullyQualifiedDomainName)"
}
Process {
:AllADSites Foreach ($AdSite in $AllADSites) {
Write-Host "Working on site $($AdSite.Name)"
Write-Host "Checking if site $($AdSite.Name) contains $($DcToRemove)"
$DC_In_Site = $null
$DC_In_Site = Get-ADObject -Identity "cn=$($DcToRemove),cn=servers,$($AdSite.DistinguishedName)" -Partition "CN=Configuration,$($DomainDistinguishedName)" -Properties * -ErrorAction SilentlyContinue
If ($null -ne $DC_In_Site) {
Write-Host "Site $($AdSite.Name) contains $($DcToRemove)" -ForegroundColor Cyan
$StandardOut = New-TemporaryFile
$ErrorOut = New-TemporaryFile
Write-Host "Attempting to cleanup NTDS for $($DcToRemove)" -ForegroundColor Yellow
$NTDS = $null
$NTDS = Start-process -FilePath ntdsutil -argumentList """metadata cleanup"" ""remove selected server cn=$($DcToRemove),cn=servers,$($AdSite.DistinguishedName)"" q q" -wait -nonewwindow -RedirectStandardOutput $StandardOut.FullName -RedirectStandardError $ErrorOut -PassThru
Get-Content -Path $StandardOut -Raw
Remove-Item -Path $StandardOut -Confirm:$false -Force
If ($NTDS.ExitCode -gt 0){
Get-Content -Path $ErrorOut -Raw
Remove-Item -Path $ErrorOut -Confirm:$false -Force
Throw "NTDS exit code was $($NTDS.ExitCode)"
}
Write-Host "Cleaned up NTDS for $($DcToRemove)" -ForegroundColor Green
Write-Host "Attempting to cleanup site object for $($DcToRemove)" -ForegroundColor Yellow
$DC_In_Site = Get-ADObject -Identity "cn=$($DcToRemove),cn=servers,$($AdSite.DistinguishedName)" -Partition "CN=Configuration,$($DomainDistinguishedName)" -Properties * -ErrorAction SilentlyContinue
$DC_In_Site | Remove-ADObject -Recursive -Confirm:$false
Write-Host "Cleaned up site object for $($DcToRemove)" -ForegroundColor Green
Write-Host "Attempting to cleanup other AD objects with this DC name" -ForegroundColor Yellow
$All_AD_Objects = Get-ADObject -Filter "*"
Foreach ($AD_Object in $All_AD_Objects) {
If ($AD_Object.DistinguishedName -like "*$($DcToRemove)*") {
Write-Host "Attempting to remove AD object $($AD_Object.DistinguishedName)" -ForegroundColor Yellow
$AD_Object | Remove-ADObject -Recursive -Confirm:$false
Write-Host "Removed AD object $($AD_Object.DistinguishedName)" -ForegroundColor Green
}
}
break AllADSites
}
}
}
}
Function Purge-DNSEntries { <# .SYNOPSIS Purge DNS of stale entries
.DESCRIPTION
Finds all DNS Zones. Then searches for all entries that contain the string provided and purges them. This searches this searches Hostname and Data fields. It also removes all name servers with the string in the name.
.PARAMETER PurgeThis
.EXAMPLE
Purge-DNSEntries -PurgeThis "DC-01"
Finds and removes all entries containing DC-01
#>
[CmdletBinding()]
Param
(
[parameter(ValueFromPipeline=$True)]
[String]$PurgeThis
)
PROCESS
{
$DNSZones = Get-dnsServerZone
ForEach ($Zone in $DNSZones)
{
$records = Get-DnsServerResourceRecord -ZoneName $Zone.ZoneName | Where-Object {
$_.HostName -match "$PurgeThis" -or
$_.RecordData.PtrDomainName -match "$PurgeThis" -or
$_.RecordData.NameServer -match "$PurgeThis"
}
foreach ($record in $records) {
# Remove the resource record
Remove-DnsServerResourceRecord -ZoneName $zone.ZoneName -InputObject $record -Force
Write-Host "Removed record with Hostname: $($record.hostname) and Data: $($record.RecordData.NameServer) from zone: $($zone.ZoneName)"
}
}
Write-Host "Completed removal of all instances of $PurgeThis."
}
}
function Move-FSMO { <# .SYNOPSIS Moves FSMO roles to selected computer
.DESCRIPTION
Moves FSMO roles to selected computer
.PARAMETER DestDir
.EXAMPLE
Move-FSMO
Moves all the FSMO roles to the computer the command is being executed on
.EXAMPLE
Move-FSMO -DestServer DC02
Moves all FSMO roles to DC02
.EXAMPLE
Move-FSMO -DestServer DC02 -Force
Seizes all FSMO roles to DC02
#>
[CmdletBinding()]
Param (
[string]$DestServer
)
Begin {
if ([string]::isnullorempty($DestServer)) {
$DestServer = hostname
}
}
Process {
Move-ADDirectoryServerOperationMasterRole -Identity $DestServer -OperationMasterRole DomainNamingMaster,InfrastructureMaster,PDCEmulator,RIDMaster,SchemaMaster
}
}
Oops posted and old version of move fsmo. Can't see a way to delete my last post.
function Move-FSMO { <# .SYNOPSIS Moves FSMO roles to selected computer
.DESCRIPTION
Moves FSMO roles to selected computer
.PARAMETER DestDir
.PARAMETER Force
.EXAMPLE
Move-FSMO
Moves all the FSMO roles to the computer the command is being executed on
.EXAMPLE
Move-FSMO -DestServer DC02
Moves all FSMO roles to DC02
.EXAMPLE
Move-FSMO -DestServer DC02 -Force
Seizes all FSMO roles to DC02
#>
[CmdletBinding()]
Param (
[string]$DestServer
[switch]$Force
)
Begin {
if ([string]::isnullorempty($DestServer)) {
$DestServer = hostname
}
}
Process {
If(!($Force)){
Move-ADDirectoryServerOperationMasterRole -Identity $DestServer -OperationMasterRole DomainNamingMaster,InfrastructureMaster,PDCEmulator,RIDMaster,SchemaMaster
}
Else{
Move-ADDirectoryServerOperationMasterRole -Identity $DestServer -OperationMasterRole DomainNamingMaster,InfrastructureMaster,PDCEmulator,RIDMaster,SchemaMaster -Force
}
}
End {
$FSMO = New-Object PSObject -Property @{
SchemaMaster = (Get-ADForest).SchemaMaster
DomainNamingMaster = (Get-ADForest).DomainNamingMaster
PDCEmulator = (Get-ADDomain).PDCEmulator
RIDMaster = (Get-ADDomain).RIDMaster
InfrastructureMaster = (Get-ADDomain).InfrastructureMaster
}
$FSMO
Return $FSMO
}
}
You are welcome Protheophage, glad it helped!
PowerShell: Remove a failed domain controller | Eric C. Singers Blog
Just another IT blog
https://ericcsinger.com/PowerShell-Remove-a-failed-domain-controller