Authoritative Restore of SYSVOL after Deallocation of Azure DCs

The Problem

If you run an isolated lab in Azure IaaS with more than one Domain Controller and are in the habit of shutting down and de-allocating the VMs to save money, you may have found that SYSVOL doesn’t replicate when you start them back up.

The Cause

De-allocation/re-allocation of a VM changes the VM generation ID and Active Directory forces a safe recovery on restart. The problem with safe recovery in an isolated Azure IaaS lab is that no DC is authoritative.

The Solution

A manual authoritative restore of DFSR SYSVOL is required using steps outlined in KB2218556.

The Whinge

I’m fed up with doing this so wrote a PowerShell script

The Script

 # Get the list of all DCs in the local domain
$domainControllers = Get-ADDomainController -Filter *

# Use the first DC in the list as the primary member for DFSR
# If a specific DC is preferred, use Get-ADDomainController -Identity <DC_Hostname>
$primaryDC = $domainControllers[0]

# Stop DFSR on all DCs
foreach ($dc in $domainControllers)
{
    Invoke-Command -ComputerName $dc.HostName -ScriptBlock {Stop-Service DFSR}
}

# Modify DFSR subscription object to disable the SYSVOL replica in AD and replicate it
foreach ($dc in $domainControllers)
{
    $sysvolSubscriptionObject = "CN=SYSVOL Subscription,CN=Domain System Volume,CN=DFSR-LocalSettings," + $dc.ComputerObjectDN
    Get-ADObject -Identity $sysvolSubscriptionObject | Set-ADObject -Server $primaryDC -Replace @{"msDFSR-Enabled"=$false}
    Get-ADDomainController -filter * | foreach {Sync-ADObject -Object $sysvolSubscriptionObject -Source $primaryDC -Destination $_.hostname}
}

# Start and then stop DFSR on all DCs
foreach ($dc in $domainControllers)
{
    Invoke-Command -ComputerName $dc.HostName -ScriptBlock {Start-Service DFSR}
    Start-Sleep -Seconds 20
    Invoke-Command -ComputerName $dc.HostName -ScriptBlock {Stop-Service DFSR}
}

# Modify DFSR subscription to enable the SYSVOL replica in AD and set the primary
# Force replication of these changes
$sysvolSubscriptionObject = "CN=SYSVOL Subscription,CN=Domain System Volume,CN=DFSR-LocalSettings," + $primaryDC.ComputerObjectDN
Get-ADObject -Identity $sysvolSubscriptionObject | Set-ADObject -Server $primaryDC -Replace @{"msDFSR-Options"=1}

foreach ($dc in $domainControllers)
{
    $sysvolSubscriptionObject = "CN=SYSVOL Subscription,CN=Domain System Volume,CN=DFSR-LocalSettings," + $dc.ComputerObjectDN
    Get-ADObject -Identity $sysvolSubscriptionObject | Set-ADObject -Server $primaryDC -Replace @{"msDFSR-Enabled"=$true}
    Get-ADDomainController -filter * | foreach {Sync-ADObject -Object $sysvolSubscriptionObject -Source $primaryDC -Destination $_.hostname}
}

# Start DFSR on all DCs
foreach ($dc in $domainControllers)
{
    Invoke-Command -ComputerName $dc.HostName -ScriptBlock {Start-Service DFSR}
}

The Warning

I’d caution against setting this as a scheduled task or anything too creative. You really do want all DCs booted and running before you do this

The Conclusion

Hopefully it’s useful to some