Active Directory Group Policy Health Check items: Is your time configuration correct?

Time configuration on domain controllers needs to be correct throughout the Active Directory forest. You need to ensure that all Active Directory domain controllers are configured to sync time using the default time synchronization hierarchy unless there is a need to configure domain controllers to sync time from a different time source. In the default time synchronization configuration, all domain controllers of a child domain sync time from the PDC Emulator of that domain, PDC Emulator of child domain syncs time from a domain controller in the root domain, and PDC Emulator of root domain syncs time from an external source to ensure it receives accurate time configuration.

PDC Emulator of root domain is always considered as a reliable time source. You need to ensure all Active Directory domain controllers and PDC Emulator of root domain are configured correctly. This is where this article comes handy. We will provide you a PowerShell script that you can use to check time configuration on all domain controllers, including PDC Emulator of root domain and then take any actions to rectify the time configuration.

Requirements

Before you can use the script, please ensure you meet the requirements mentioned below:

  • PowerShell script must be executed from a Windows Server 2012 or later operating systems.
  • Ensure W32tm.exe is working correctly on the computer from where you will run the PowerShell script. PowerShell script uses W32Tm.exe to collect time configuration from domain controllers.
  • PDC Emulator of Active Directory forest root must be reachable in order to collect time configuration from the PDC emulator of the root domain.

What does the script do?

The script performs the following functions:

  • Retrieves all domain controllers from current Active Directory forest and exports the domain controller names in C:\Temp\GDCList.TXT file. The script uses “C:\Temp\GDCList.TXT” file to check time configuration on all domain controllers.
  • Connects to Active Directory forest specified in the $CurForestName variable and then gets the name of the PDC Emulator. Checks time configuration of PDC Emulator and reports the status in the CSV file. Current forest that we use in the script is “TechGenix.com”.
  • Script executes W32Tm.exe against each domain controller specified in “C:\Temp\GDCList.txt” and collects the time configuration data.
  • Script output is generated in “C:\Temp\ADTimeConfiguration.CSV” file.

Script Contents

[code lang=”ps”]
### Script Starts Here ###

$TotNo=0

$ItemCount=0

$TestText = ""

$TestStatus= ""

$SumVal = ""

$AnyGap = "No"

$ErrorOrNot = "No"

$AnyOneOk = "No"

$TotDCsInError = 0

$CurForestName="TechGenix.com"

$TestCSVFile = "C:\Temp\ADTimeConfiguration.CSV"

remove-item $TestCSVFile -ErrorAction SilentlyContinue

$ThisString="Domain Controller,Connection,Command Status, Controller Type, Sync Setting,Sync From,Final Status"

Add-Content "$TestCSVFile" $ThisString

$GDCList = "C:\Temp\DCList.TXT"

remove-item $GDCList -ErrorAction SilentlyContinue

DSQuery Server -O RDN > $GDCList

$Error.Clear()

$PDCInForest =Get-ADForest $CurForestName | Select-Object -ExpandProperty RootDomain | Get-ADDomain | Select-Object -Property PDCEmulator

IF ($Error.Count -eq 0)

{

$PDCServer = $PDCInForest.PDCEmulator

$RMNow=w32tm /query /configuration /computer:$PDCServer

$SyncSettingNow = ""

$SyncFrom = ""

$FinStatus ="Ok"

Foreach ($Item in $RMNow)

{

$T1, $T2 = $Item.Split(":")

IF ($T1 -eq "Type")

{

IF ($T2 -eq " NTP (Local)")

{

}

else

{

$AnyGap = "Yes"

$FinStatus = "WARNING: Root PDC must sync its time from an External NTP Server by specifying NTP (Local) value in Type Registry entry. It is not recommended to use NT5DS and AllSync(Local) for PDC."

}

$SyncSettingNow = $T2

}

IF ($T1 -eq "NtpServer")

{

$SyncFrom = $T2

}

}

$FinalSTR = $PDCServer+",Ok,Ok,PDC,"+$SyncSettingNow+","+’"’+$SyncFrom+’"’+","+$FinStatus

Add-Content "$TestCSVFile" $FinalStr

}

else

{

$ComConError = $Error[0].Exception.Message

$FinalSTR = $ItemName+",$DCConError,"+$ComConError

Add-Content "$TestCSVFile" $FinalSTR

}

Foreach ($ItemName in Get-Content "$GDCList")

{

$DCConError = "Ok"

$DCConStatus = "Ok"

$ProceedOrNot = "Yes"

$Error.Clear()

$AllServices = Get-WMIObject Win32_Service -computer $ItemName

IF ($Error.Count -ne 0)

{

$ProceedOrNot = "No"

$TotDCsInError++

$DCConError = $Error[0].Exception.Message

$FinalSTR = $ItemName+",Not OK: Error: $DCConError"

Add-Content "$TestCSVFile" $FinalSTR

}

IF ($ProceedOrNot -eq "Yes")

{

$ComConError="Ok"

$Error.Clear()

$RMNow=w32tm /query /configuration /computer:$ItemName

IF ($Error.count -eq 0)

{

$AnyOneOk="Yes"

$SyncSettingNow = ""

$SyncFrom = ""

$FinStatus ="Ok"

Foreach ($Item in $RMNow)

{

$T1, $T2 = $Item.Split(":")

IF ($T1 -eq "Type")

{

IF ($T2 -eq " NT5DS (Local)" -or $T2 -eq $Null -or $T2 -eq "")

{

}

else

{

$AnyGap = "Yes"

$FinStatus = "WARNING: Domain Controller must use NT5DS value in Type registry entry. It is not recommended to use AllSync(Local) registry value for domain controllers."

}

$SyncSettingNow = $T2

}

IF ($T1 -eq "NtpServer")

{

$SyncFrom = $T2

}

}

IF ($ItemName.ToLower() -eq $PDCServer.ToLower())

{

$FinStatus=""

}

$FinalSTR = $ItemName+","+$DCConError+","+$ComConError+",Domain Controller,"+$SyncSettingNow+","+’"’+$SyncFrom+’"’+","+$FinStatus

Add-Content "$TestCSVFile" $FinalStr

}

else

{

$ComConError = $Error[0].Exception.Message

$FinalSTR = $ItemName+",$DCConError,"+$ComConError

Add-Content "$TestCSVFile" $FinalSTR

}

}

else

{

$ComConError = $Error[0].Exception.Message

$FinalSTR = $ItemName+",$DCConError,"+$ComConError

Add-Content "$TestCSVFile" $FinalSTR

}

}

$OthText = ""

IF ($TotDCsInError -ne 0)

{

$OthText = "Some Domain Controllers have not been checked due to connectivity or command issues."

}

IF ($AnyGap -eq "Yes")

{

$TestText = "Domain Controller Time Synchronization is not correct. Please ensure PDC syncs its time from an External NTP Server and other domain controllers sync using the default Time Synchronization settings. All other Domain Controllers must be using NT5DS registry entry. $OthText"

$SumVal = $TotNo

$TestStatus="Critical"

}

IF ($AnyGap -eq "No")

{

$TestText = "Time Synchronization is configured correctly in Active Directory Forest. $OthText"

$SumVal = ""

$TestStatus="Passed"

IF ($AnyOneOk -eq "No")

{

$TestText = "Error Executing Dynamic Pack."

$SumVal = ""

$TestStatus="Completed with Errors."

}

}

$STR = $ADTestName +","+$TestStartTime+","+$TestStatus+","+$SumVal +","+$TestText

### Script Ends Here ###
[/code]

Once the script has finished executing for all domain controllers in the Active Directory forest, a report with time configuration of all domain controllers will be generated in the CSV file as shown in the screenshot below.

Time Configuration of Domain Controllers

As you can see in the screenshot, the script reported time configuration of all domain controllers, including PDC Emulator of the root domain. As it indicates with a warning in the first line of the CSV report, PDC Emulator is not configured to sync time from an external time source, which is against the recommendation. Since PDC Emulator of root domain is always considered as a reliable time source, it must be configured to sync its time from a reliable external time source. All other domain controllers are configured with correct time settings except the DC3.TechGenix.com domain controller. DC3.TechGenix.com must use “NT5DS” setting in order to use default time synchronization hierarchy. If you are using Active Directory Health Profiler, you can execute the AD Domain Controller Time Configuration Test Dynamic Pack against an Active Directory forest or a domain and then show the output of the Dynamic Pack in Active Directory Health Profiler console as shown in the screenshot below.

Time Configuration of Domain Controllers in AD Health Profiler

It is recommended that you use the default time configuration on all Active Directory domain controllers to avoid any authentication issues. We provided a PowerShell script that can help you collect time configuration from PDC Emulator as well as domain controllers in an Active Directory forest. You can include the above PowerShell script in your Active Directory health procedure and execute it once in a month to ensure time configuration on all domain controllers are configured correctly.

To download the script as a .txt file: click here

About The Author

10 thoughts on “Active Directory Group Policy Health Check items: Is your time configuration correct?”

  1. Hi – Good script. Wish you had uploaded the script. Copy and paste to notepad screws up all the “” function.

  2. Hi – Your code block still screws up the function. Will it be possible to upload the script elsewhere (like one drive or google drive or by email)

    1. I have sent the script to you via email. Please also check your spam folder if you don’t receive it shortly. In any case, the script block in the post is now also updated to display proper quotation marks, I did not realize initially that some page formatting messed those up. Let me know if it works now!

  3. Hi – Thanks for sharing the script. Tried the script – Below is the error

    PS C:\Users\Administrator\Downloads> .\ad-time-config-script.ps1
    At C:\Users\Administrator\Downloads\ad-time-config-script.ps1:35 char:23
    + DSQuery Server -O RDN > $GDCList
    + ~
    The ampersand (&) character is not allowed. The & operator is reserved for future use; wrap an ampersand in double
    quotation marks (“&”) to pass it as part of a string.
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : AmpersandNotAllowed

    1. You are right, the & gt; is another encoding problem. The line:

      DSQuery Server -O RDN & gt; $GDCList

      should be:

      DSQuery Server -O RDN > $GDCList

      instead.

    1. Hi,

      I have sent it to you via email.

      There is also a download link now at the bottom of the article with the full script in a txt file.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Scroll to Top