I have developed a function to promote domain controllers in an existing forest then moves the DC from the standard Domain Controller OU to a sub OU. The function works however sometimes when running the function the server being promoted will reboot within ~10 minutes of running the function, other times it waits ~85 minutes before rebooting. The function accepts a CSV for promoting multiple DC's sequentially.
The problem is when the function waits ~85 minutes before rebooting it delays the promotion of the next DC in the CSV. All the Domain Controllers are in the same Data Center on the same network. The initial AD replication continues after the reboot - so it's not waiting for the initial replication to complete before the reboot.
In order to ensure DC promotions occur in a timely manor for my customers, I need to understand what the process for reboots is.
My question is: What dictates when a server will reboot during dc promotion?
My function is as follows:
function New-PSATDomainController {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string] $VMName,
[Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string] $Domain,
[Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string] $ADSite,
[Parameter(Mandatory = $true)][string] $SafeModeAdministratorPassword,
[Parameter(Mandatory = $true)][System.Management.Automation.PSCredential] $GuestCredential,
[Parameter(Mandatory = $true)][System.Management.Automation.PSCredential] $Credential
)
begin {
}
process {
# Set required variables
$FQDN = ("$vmname"+"."+"$Domain")
$DefaultDomainControllerOUPath = (Get-PSATDefaultDomainControllerOUPath -Domain "$Domain")
# Install AD Domain Services
Write-verbose "Installing the following windows features - AD-Domain-Services,RSAT-AD-AdminCenter,RSAT-ADDS-Tools" -Verbose
$InstallDomainServices = "Add-WindowsFeature AD-Domain-Services,RSAT-AD-AdminCenter,RSAT-ADDS-Tools -Restart"
Invoke-VMScript `
-VM "$VMName" `
-ScriptText $InstallDomainServices `
-GuestCredential $GuestCredential `
-Confirm:$false
start-sleep -Seconds 60
Wait-Tools -VM "$VMName" -TimeoutSeconds 300
Start-Sleep -Seconds 20
# Promote Virtual Machine to Domain Controller.
Write-Verbose "Promoting `"$VMName`" to be a Domain Controller of the `"$Domain`" Domain." -Verbose
$PromoteToDomainControllerScript = "
`$CredentialPassword = ConvertTo-SecureString -String '$($Credential.GetNetworkCredential().Password)' -AsPlainText -Force
`$Credential = New-Object System.Management.Automation.PSCredential (`"$($Credential.Username)`", `$CredentialPassword)
`$SafeModeAdministratorPassword = ConvertTo-SecureString -String '$SafeModeAdministratorPassword' -AsPlainText -Force
New-Item -Path e:\NTDS -ItemType directory
New-Item -Path e:\SYSVOL -ItemType directory
Import-Module ADDSDeployment
Install-ADDSDomainController ``
-NoGlobalCatalog:`$false ``
-CriticalReplicationOnly:`$false ``
-DatabasePath 'e:\NTDS' ``
-DnsDelegationCredential `$Credential ``
-DomainName $Domain ``
-InstallDns:`$true ``
-LogPath 'e:\NTDS' ``
-NoRebootOnCompletion:`$false ``
-SiteName $ADSite ``
-SysvolPath 'e:\SYSVOL' ``
-Force:`$true ``
-SafeModeAdministratorPassword `$SafeModeAdministratorPassword ``
-ADPrepCredential `$Credential ``
-Credential `$Credential"
Invoke-VMScript `
-ScriptText $PromoteToDomainControllerScript `
-VM "$VMName" `
-GuestCredential $GuestCredential `
-Confirm:$false `
-ScriptType:Powershell `
-ErrorAction SilentlyContinue
# Wait for the VM to finalise it's Domain Controller promotion and reboot
Write-Verbose "Waiting up to 60 minutes for `"$FQDN`" to finalise it's Domain Controller promotion and reboot" -Verbose
$StartDate = Get-Date
$DCServices = "adws","dns","kdc","netlogon"
do {
$DCServicesStatus = (invoke-command -ComputerName "$FQDN" -Credential $Credential -ScriptBlock {get-service -Name $Using:DCServices} -ErrorAction SilentlyContinue)
} while ($DCServicesStatus.status -ne "Running" -and $startDate.AddMinutes(120) -gt (Get-Date))
Write-Verbose "$VMName has rebooted" -Verbose
Wait-Tools -VM "$VMName"
Start-Sleep -Seconds 60
# Move New Domain Controller into Correct AD OU.
Write-verbose "Moving new Domain Controller `"$VMName`" into correct AD OU, `"$DefaultDomainControllerOUPath`"." -Verbose
Invoke-Command `
-ComputerName $Domain `
-ScriptBlock {get-adcomputer "$Using:VMName" | Move-ADObject -TargetPath "$Using:DefaultDomainControllerOUPath"} `
-Credential $Credential
Write-Verbose "Completed promoting `"$VMName`" to be a Domain Controller of the `"$Domain`" Domain." -Verbose
}
end {
}
}