Configuring a Windows Domain Controller to synchronize its clock with an external time source

Kerberos authentication requires correct time on all clients participating in authentication. If the clocks on two machines trying to authenticate to each other are too far apart, Kerberos authentication will fail. Since Kerberos is used extensively in Windows a mechanism to ensure correct clocks throughout the forest was also implemented. This is the Windows Time Service (w32time), a service which runs on all Windows machines since Windows 2000. The protocol used for synchronizing clocks is the Network Time Protocol (NTP). Every member computer, be it server or workstation, synchronize their clocks with the Domain Controller holding the PDC emulator FSMO role for its domain. The PDC emulator for a domain, in turn, synchronizes with the PDC emulator DC in the forest root domain. The PDC emulator in the root domain, therefore, is authoritative for the time throughout the forest, since all machines will inherit its clock. For this reason the PDC emulator DC in the forest root domain should be configured to obtain exact time from a dependable time server on the Internet. Microsoft has published information about doing this in KB816042. I have created a VBScript which implements the registry changes specified in that article:

 1: ' Configures the PDC Emulator in the root of a forest to be an authoritative time server
 2: ' and sync time from several NTP time servers on the Internet
 3: ' Info gathered from KB816042 How to configure an authoritative time server in
 4: ' Windows Server 2003 (http://support.microsoft.com/kb/816042)
 5: '
 6: ' On a PDC Emulator the settings changed from the default settings are:
 7: ' Type (From NT5DS to NTP)
 8: ' AnnounceFlags (From 10 to 5)
 9: ' NTPServer (From time.windows.com,0x1 to contents of strTimeServers)
 10: ' SpecialPollInterval (From 3600 to 900)
 11: ' MaxPosPhaseCorrection (From 4294967295 to 1800)
 12: ' MaxNegPhaseCorrection (From 4294967295 to 1800)
 13: '
 14: ' A useful command line command is:
 15: ' w32tm /config /manualpeerlist:"time-a.nist.gov time-b.nist.gov time.nist.gov time-nw.nist.gov" /syncfromflags:manual /reliable:yes /update
 16: ' This command sets AnnounceFlags to 5, NTPServer to the server list and Type to NTP
 17: ' Command found here:
 18: ' http://technet2.microsoft.com/windowsserver/en/library/ce8890cf-ef46-4931-8e4a-2fc5b4ddb0471033.mspx?mfr=true
 19: '
 20: ' A list of the NIST time server can be found here:
 21: ' http://tf.nist.gov/service/time-servers.html
 22: '
 23: ' Microsoft's list of (S)NTP servers is here:
 24: ' http://support.microsoft.com/kb/262680/en-us 
 25:
 26: const HKEY_CURRENT_USER = &H80000001
 27: const HKEY_LOCAL_MACHINE = &H80000002
 28: strKeyPath = "SYSTEMCurrentControlSetServicesW32Time"
 29:
 30: strTimeServers = "time-a.nist.gov,0x1 time-b.nist.gov,0x1 time-a.timefreq.bldrdoc.gov,0x1 time-b.timefreq.bldrdoc.gov,0x1 time-c.timefreq.bldrdoc.gov,0x1 utcnist.colorado.edu,0x1 time.nist.gov,0x1 time-nw.nist.gov,0x1 nist1.dc.certifiedtime.com,0x1 nist1.datum.com,0x1 nist1.nyc.certifiedtime.com,0x1 nist1.sjc.certifiedtime.com,0x1"
 31: strComputer = "."
 32: Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\" & strComputer & "rootdefault:StdRegProv")
 33:
 34: 'Change the server type to NTP (KB Step 1)
 35: objReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath & "Parameters","Type","NTP"
 36: 'Set AnnounceFlags to 5 (KB Step 2)
 37: objReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath & "Config","AnnounceFlags",5
 38: 'Enable NTPServer (KB Step 3)
 39: objReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath & "TimeProvidersNtpServer","Enabled",1
 40: 'Specify the time sources (KB Step 4)
 41: objReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath & "Parameters","NtpServer",strTimeServers
 42: 'Select the poll interval (KB Step 5)
 43: objReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath & "TimeProvidersNtpClient","SpecialPollInterval",900
 44: 'Configure the time correction settings (KB Step 6)
 45: objReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath & "Config","MaxPosPhaseCorrection",1800
 46: objReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath & "Config","MaxNegPhaseCorrection",1800
 47:
 48: Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\" & strComputer & "rootcimv2")
 49: Set colListOfServices = objWMIService.ExecQuery ("Select * from Win32_Service Where Name ='W32Time'")
 50: For Each objService in colListOfServices
 51:     retVal = objService.StopService()
 52:     If retVal = 0 Then
 53:         'WScript.Echo "Service stopped"
 54:     Else
 55:         WScript.Echo "Service stop failed (" & retVal & ")"
 56:     End If
 57:     WScript.Sleep 5000
 58:     retVal = objService.StartService()
 59:     If retVal = 0 Then
 60:         'WScript.Echo "Service started"
 61:     Else
 62:         WScript.Echo "Service start failed (" & retVal & ")"
 63:     End If
 64: Next
 65:
 66: WScript.Echo "Done!"

Below is a comparison of the changes in the registry before and after the changes:

Before

 1: PS C:Usersadministrator> w32tm /query /configuration
 2: [Configuration]
 3:
 4: EventLogFlags: 2 (Local)
 5: AnnounceFlags: 10 (Local)
 6: TimeJumpAuditOffset: 28800 (Local)
 7: MinPollInterval: 6 (Local)
 8: MaxPollInterval: 10 (Local)
 9: MaxNegPhaseCorrection: 172800 (Local)
 10: MaxPosPhaseCorrection: 172800 (Local)
 11: MaxAllowedPhaseOffset: 300 (Local)
 12:
 13: FrequencyCorrectRate: 4 (Local)
 14: PollAdjustFactor: 5 (Local)
 15: LargePhaseOffset: 50000000 (Local)
 16: SpikeWatchPeriod: 900 (Local)
 17: LocalClockDispersion: 10 (Local)
 18: HoldPeriod: 5 (Local)
 19: PhaseCorrectRate: 7 (Local)
 20: UpdateInterval: 100 (Local)
 21:
 22:
 23: [TimeProviders]
 24:
 25: NtpClient (Local)
 26: DllName: C:Windowssystem32w32time.dll (Local)
 27: Enabled: 1 (Local)
 28: InputProvider: 1 (Local)
 29: CrossSiteSyncFlags: 2 (Local)
 30: AllowNonstandardModeCombinations: 1 (Local)
 31: ResolvePeerBackoffMinutes: 15 (Local)
 32: ResolvePeerBackoffMaxTimes: 7 (Local)
 33: CompatibilityFlags: 2147483648 (Local)
 34: EventLogFlags: 1 (Local)
 35: LargeSampleSkew: 3 (Local)
 36: SpecialPollInterval: 3600 (Local)
 37:
 38:
 39:
 40:
 41: Type: NT5DS (Local)
 42:
 43: NtpServer (Local)
 44: DllName: C:Windowssystem32w32time.dll (Local)
 45: Enabled: 1 (Local)
 46: InputProvider: 0 (Local)
 47: AllowNonstandardModeCombinations: 1 (Local)
 48:
 49: VMICTimeProvider (Local)
 50: DllName: C:WindowsSystem32vmictimeprovider.dll (Local)
 51: Enabled: 1 (Local)
 52: InputProvider: 1 (Local)
 53:

After

 1: PS C:Usersadministrator> w32tm /query /configuration
 2: [Configuration]
 3:
 4: EventLogFlags: 2 (Local)
 5: AnnounceFlags: 5 (Local)
 6: TimeJumpAuditOffset: 28800 (Local)
 7: MinPollInterval: 6 (Local)
 8: MaxPollInterval: 10 (Local)
 9: MaxNegPhaseCorrection: 1800 (Local)
 10: MaxPosPhaseCorrection: 1800 (Local)
 11: MaxAllowedPhaseOffset: 300 (Local)
 12:
 13: FrequencyCorrectRate: 4 (Local)
 14: PollAdjustFactor: 5 (Local)
 15: LargePhaseOffset: 50000000 (Local)
 16: SpikeWatchPeriod: 900 (Local)
 17: LocalClockDispersion: 10 (Local)
 18: HoldPeriod: 5 (Local)
 19: PhaseCorrectRate: 7 (Local)
 20: UpdateInterval: 100 (Local)
 21:
 22:
 23: [TimeProviders]
 24:
 25: NtpClient (Local)
 26: DllName: C:Windowssystem32w32time.dll (Local)
 27: Enabled: 1 (Local)
 28: InputProvider: 1 (Local)
 29:
 30: AllowNonstandardModeCombinations: 1 (Local)
 31: ResolvePeerBackoffMinutes: 15 (Local)
 32: ResolvePeerBackoffMaxTimes: 7 (Local)
 33: CompatibilityFlags: 2147483648 (Local)
 34: EventLogFlags: 1 (Local)
 35: LargeSampleSkew: 3 (Local)
 36: SpecialPollInterval: 900 (Local)
 37: Type: NTP (Local)
 38: NtpServer: time-a.nist.gov,0x1 time-b.nist.gov,0x1 time-a.timefreq.bldrdoc.gov,0x1 time-b.timefreq.bldrdoc.gov,0x1 time-
 39: c.timefreq.bldrdoc.gov,0x1 utcnist.colorado.edu,0x1 time.nist.gov,0x1 time-nw.nist.gov,0x1 nist1.dc.certifiedtime.com,0x
 40: 1 nist1.datum.com,0x1 nist1.nyc.certifiedtime.com,0x1 nist1.sjc.certifiedtime.com,0x1 (Local)
 41:
 42:
 43: NtpServer (Local)
 44: DllName: C:Windowssystem32w32time.dll (Local)
 45: Enabled: 1 (Local)
 46: InputProvider: 0 (Local)
 47: AllowNonstandardModeCombinations: 1 (Local)
 48:
 49: VMICTimeProvider (Local)
 50: DllName: C:WindowsSystem32vmictimeprovider.dll (Local)
 51: Enabled: 1 (Local)
 52: InputProvider: 1 (Local)

The most notable change is the Type value for the NTP client, which changes from NT5DS to NTP. The Type value is documented here.

Using w32tm.exe

The Windows Time Service can be configured using a complimentary utility called w32tm.exe. The following sets AnnounceFlags to 5, NTPServer to the server list and Type to NTP:

w32tm.exe /config /manualpeerlist:”time-a.nist.gov time-b.nist.gov time.nist.gov time-nw.nist.gov” /syncfromflags:manual /reliable:yes /update

Note that the settings for poll interval (SpecialPollInterval) and time correction (MaxPosPhaseCorrection/MaxNegPhaseCorrection) must be set in the registry.

Although the script uses the NIST time servers, I would recommend looking at the NTP Pool Project as well.

Also, to clear up a common misunderstanding, Windows does not need any third party software to synchronize its clock with an external time source, as long as the protocol used is NTP. This, of course, does not apply if you are using a special piece of hardware, such as a hardware clock, to keep correct time on your forest root PDC emulator DC. Furthermore, it is absolutely not necessary to include net time /sync or the like in logon scripts for clients to ensure they have the correct time, the Windows Time Service handles this.

If the DC holding the PDC Emulator FSMO role in the forest root domain is not set to sync its time from a reliable or external time source, the Windows Time service will log a warning in the System log with event ID 12:

Time Provider NtpClient: This machine is configured to use the domain hierarchy to determine its time source, but it is the AD PDC emulator for the domain at the root of the forest, so there is no machine above it in the domain hierarchy to use as a time source. It is recommended that you either configure a reliable time service in the root domain, or manually configure the AD PDC to synchronize with an external time source. Otherwise, this machine will function as the authoritative time source in the domain hierarchy. If an external time source is not configured or used for this computer, you may choose to disable the NtpClient.

Resetting configuration

In some cases you need to reset the configuration of the Windows Time Service. The easiest way I have found is to unregister and the register the service. Do this:

  1. Stop the Windows Time Service
    net stop w32time
  2. Unregister the service:
    w32tm /unregister
  3. Register the service:
    w32tm /register
  4. Start the Windows Time Service
    net start w32time

These steps will reset the service back to the defaults, usually to sync from the Domain Hierachy for a domain joined machine.

Configuring time synchornication on a non-domain computer

Some machines are not part of a domain hierarchy and therefore do not automatically use it to set their clocks. For Windows Vista and later there is a schedules task (Task Scheduler LibraryMicrosoftWindowsTime SynchronizationSynchronizeTime) that is set to run every Sunday at 01:00 by default. The Windows Time serivce is set to manual startup on workgroup computers by default and is started by the scheduled task. The command in the schedule task is %windir%system32sc.exe start w32time task_started. The start of the service, in turn, triggers a synchronizations agains the configured time server; time.windows.com, by default. Which server that is used to syncronize time is specified on the Internet Time tab of the Date and Time Control Panel applet (timedate.cpl). The Internet Time tab is missing on domian joined computers.

When you press Update now it seems to perform a regular synchronization with the Windows Time service, starting the service first if it is not running. This is evident by the events in the System log:

EntryType          : Information
Message            : The time service is now synchronizing the system time with the time source no.pool.ntp.org,0x9 (ntp.m|0x9|0.0.0.0:123->139.117.2.21:123).
Source             : Microsoft-Windows-Time-Service
UserName           : NT AUTHORITYLOCAL SERVICE

EntryType          : Information
Message            : The time provider NtpClient is currently receiving valid time data from no.pool.ntp.org,0x9 (ntp.m|0x9|0.0.0.0:123->139.117.2.21:123).
Source             : Microsoft-Windows-Time-Service
UserName           : NT AUTHORITYLOCAL SERVICE

EntryType          : Information
Message            : The system time has changed to ‎2011‎-‎10‎-‎12T10:05:28.640000000Z from ‎2011‎-‎10‎-‎12T10:05:28.640606800Z.
Source             : Microsoft-Windows-Kernel-General
UserName           : NT AUTHORITYLOCAL SERVICE

If you want to dump the SynchronizeTime task you can use this command:

schtasks.exe /query /TN “MicrosoftWindowsTime SynchronizationSynchronizeTime” /v /FO List

If you try to issue any w32tm.exe command before the Windows Time service is started you will receive an error:

The following error occurred: The service has not been started. (0x80070426)

After either starting the service yourself, or by pressing the Update now button in the Date and Time applet (which starts the service), you can issue commands with w32tm.exe normally. To configure which server(s) the computer syncs with you can either use the applet and enter a server FQDN (only one), or use w32tm.exe (multiple servers). With w32tm.exe you would use a sligtly different version of the command used on a forest root PDC Emulator domain controller:

w32tm.exe /config /manualpeerlist:”0.no.pool.ntp.org 1.no.pool.ntp.org 2.no.pool.ntp.org 3.no.pool.ntp.org” /syncfromflags:manual /update

As you can see, the reliable flag is missing from this command since it is only applicable on Domain Controllers.

One thought on “Configuring a Windows Domain Controller to synchronize its clock with an external time source”

Leave a Reply

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