How to Fix Time Drift for Off-Prem Domain PCs

The world is becoming more adjusted to what a modern workplace is due to many factors, including the COVID-19 pandemic response.  One of the many new problems that has come up for my organization is the issue of “Time Drift” for devices not on premises.  Some users are reporting a few minutes to a few hours difference to reality mainly causing meeting reminders to appear extremely late.  This caused me to delve into the realm of Time Servers and how/when devices communicate with them.  The following post provides background information on the issue and how to address it with a creative solution.

Background

When a Domain Controller is set up, it is often configured to be a Time Server as well, acting as a “known good” source of time and date for managed devices.  This is important as underlying systems depend on consistency to function (such as Kerberos).  When a device is taken out of the box, with a factory installed copy of Windows, it will normally have time information being obtained from the Microsoft Time Server: time.microsoft.com.  However, when a device is joined to a domain, it now looks to the Domain Controller(s) as the time source (instead of Microsoft) and the Internet Time tab is removed from the Date and Time window!

Missing internet time tab
Internet Time tab is missing

If your devices are on premises, this is generally not an issue; but when devices move off premises, and many of them don’t require the user to connect to the organization’s VPN to do their work, this can become a problem.

Time Drift can occur for several reasons, and many tickets that I have seen over the years have come back to CMOS batteries being weak.  When devices are in the office spaces, this problem can be hidden because time is being updated by the DCs.  While replacing a CMOS battery is an easy fix for a tech when a device is onsite, it becomes extremely difficult when office spaces have been vastly vacated due to a pandemic response and asking remote users to come on premises and maintain social distancing is frowned upon.  I will leave the hardware repair part of discussion to what it is and continue as it can easily go way off topic of this post.

Solution

So, if there are a multitude of devices that are not talking to a DC to get updated time information, what do you, as an admin or engineer, do?  My investigation led me down several paths involving Microsoft docs and blog posts; here is how my organization resolved things.

There is a GPO that can be set to configure an alternate Time Server.  I know what you are thinking,

“Uh, if the device isn’t talking to the DC, it isn’t going to get a GPO, dude.  Duh!”

And you are 100% correct!  But what does a GPO do when it is applied to a device?  It sets registry keys.  I configured the GPO on a test device to use time.nist.gov as the alternate Time Server and then extracted the registry keys that were set.  I then created a Configuration Baseline that will apply those registry keys to the fleet through Config Manager internet-based client management (IBCM) as we are not using Azure at this point for device management.  Since doing this several weeks ago, our fleet had the Baseline successfully applied and our support staff has reported no more calls about Time Drift.

The GPO related registry keys are documented by Microsoft.  The main subkey here is “NtpServer” and it was sent to “time.nist.gov,0x2”.  The addition of “0x2” to the end means it will be used as a fallback server only.  Another important subkey is “Type” being sent to “AllSync” which will use all available sources to update time.  It is quite neat how it works…  If the device can communicate with the DC, it will use the DC as the time source.  If a device cannot communicate with the DC, it will use the server specified in this setting.  The computer will switch between the DC and the alternate automatically if the DC is available or not.  No action needs to be taken by the user; it just works and the switch happens (literally) within a minute or so.

Deploy the Configuration Baseline to the desired collection, the devices will get the registry keys, and the support staff will get less calls!

Scripts and Stuff

Configuration Item – Discovery Script:

  • Setting type: Script
  • Data type:  Boolean
$NtpServerVal = (Get-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\W32time\Parameters -Name NtpServer -ErrorAction SilentlyContinue).NtpServer
If ($NtpServerVal -eq "time.nist.gov,0x2") {
    Write-Output $True
} Else {
    Write-Output $False
}

Configuration Item – Compliance Rule:

$TimePath = "HKLM:\SOFTWARE\Policies\Microsoft\W32time"
$ParamPath = "$TimePath\Parameters"
$ClientPath = "$TimePath\TimeProviders\NtpClient"

# Create NtpServer Registry Keys
New-Item -Path $ParamPath -ItemType Key -Force | Out-Null
New-ItemProperty -Path $ParamPath -PropertyType String -Name "NtpServer" -Value "time.nist.gov,0x2" -Force | Out-Null
New-ItemProperty -Path $ParamPath -PropertyType String -Name "Type" -Value "AllSync" -Force | Out-Null
New-Item -Path $ClientPath -ItemType Key -Force | Out-Null
New-ItemProperty -Path $ClientPath -PropertyType DWord -Name "CrossSiteSyncFlags" -Value "0x00000002" -Force | Out-Null
New-ItemProperty -Path $ClientPath -PropertyType DWord -Name "ResolvePeerBackoffMinutes" -Value "0x0000000f" -Force | Out-Null
New-ItemProperty -Path $ClientPath -PropertyType DWord -Name "ResolvePeerBackoffMaxTimes" -Value "0x00000007" -Force | Out-Null
New-ItemProperty -Path $ClientPath -PropertyType DWord -Name "SpecialPollInterval" -Value "0x00000400" -Force | Out-Null
New-ItemProperty -Path $ClientPath -PropertyType DWord -Name "EventLogFlags" -Value "0x00000000" -Force | Out-Null

# Restart time service to use settings
Restart-Service -Name w32time -Force
  • Rule type: Value
  • The value returned by the specified script: Equals True
  • Run the specified remediation script when the setting is noncompliant: Check
  • Report noncompliance if this setting instance is not found: Check
  • Noncompliance severity for reports: None
  • Supported Platforms: Windows 10 – All Windows 10 (64-bit), All Windows 10 (32-bit)

I did not test this on Windows 10 ARM, Windows 7, or Windows 8.x but they will probably work fine as this is not a unique set of registry keys.

If you want to know where a device is getting its time information from, run the following command from an elevated command prompt:  w32tm /query /source
You can also right-click the clock in the system tray and select “Adjust date/time”.

Date & time information window showing time server source
Showing time server source

If you want to know the options of where a device will be getting time information, run the following command from an elevated command prompt:  w32tm /query /peers

If you want to know general time status information, run the following command from an elevated command prompt:  w32tm /query /status

Examples of the w32tm commands
Examples of the w32tm commands

Please let me know if you found this useful. I don’t post often as I try to keep the information I share worthwhile.

As always, test any code you get from the internet in a test environment (or on a test device at least) before using in production. If you break something, that’s on you!