One-time time synchronization in Windows

UPDATE: While the script outlined below works well enough, I have taken a different approach in LiteTouch/WinPE. You can see the final script here:
https://blog.uvm.edu/jgm/2010/10/14/time-sync-in-mdt-2010winpe-take-3/

Recently our clients have started to complain about Windows product activation errors. I think this is less likely caused by an increased per-capita error rate, and more by an upswing in deployment of KMS-dependent operating systems (such as Windows 7).

Some investigation reveals that the root cause is incorrect system time on the Windows clients that are requesting KMS licenses. I am not sure how much time skew the KMS can tolerate between itself and license-requesting clients, but I do know that it is less than 24 hours.

Unfortunately, the license activation errors are not overly helpful in explaining to client machines that time synchronization is the problem. I plan to reduce the occurrence of this problem by scripting a one-time time sync in out LiteTouch task sequences.

How?
Easy… sort of.

' SetTime.vbs script
' J. Greg Mackinnon, 2010-10-04
' Actions: Syncs local system clock to "ntp.pool.org" time using the NTP protocol.
'          Will change registry values for maximum time skew correction If necessary, Then revert to original values
'          ReSets the w32time service during execution, but NOT at the End of the script.  An manual restart is required to 
'            revert Domain-joined systems to defaults.
' Requires: w32tm.exe, net.exe.  Both should be present on all Vista/Win7 systems.
' Tested on: WinDows 7.  Should work on Vista as well... NOT intEnded for XP systems.

Option explicit

Dim oShell, oExec
Dim iPosRegVal, iNegRegVal
Dim strKeyPath, strPosValueName, strNegValueName

strKeyPath = "HKLM\SYSTEM\CurrentControlSet\services\W32Time\Config"
strPosValueName = "MaxPosPhaseCorrection"
strNegValueName = "MaxNegPhaseCorrection"

Set oShell = WScript.CreateObject("WScript.Shell") 

WScript.Echo "Current Time is: " & Date & " " & Time

'This works, If you can understand the screwball interger value that gets returned.  
'Everything over hex 0x0fffffff is listed as a negative interger.
'0xffffffff returns -1.
iPosRegVal = oShell.RegRead(strKeyPath & "\" & strPosValueName)
iNegRegVal = oShell.RegRead(strKeyPath & "\" & strNegValueName)
WScript.Echo "strNegValueName value is: " & iNegRegVal
WScript.Echo "StrPosValueName value is: " & iPosRegVal

If iPosRegVal  -1 Then
	WScript.Echo "Maximum allowed clock skew correction is NOT large enough... Setting to maximum value."
	'Setting the Max Phase Correction registry values to "-1" (or 0xffffffff in hex), 
	'which will allow correction of local time by any amount.
	oShell.RegWrite strKeyPath & "\" & strPosValueName, -1, "REG_DWORD"
	oShell.RegWrite strKeyPath & "\" & strNegValueName, -1, "REG_DWORD"
	WScript.Echo strPosValueName & " is now Set to: " & oShell.RegRead(strKeyPath & "\" & strPosValueName)
	WScript.Echo strNegValueName & " is now Set to: " & oShell.RegRead(strKeyPath & "\" & strNegValueName)
Else
	WScript.Echo "This system already already is configured to allow large clock skew corrections."
End If 

WScript.Echo "Setting WinDows Time service Manual-sync NTP Server to ""pool.ntp.org"""
' Pool.ntp.org is a collection of Internet NTP time servers.  
' It is the default time source for stand-alone RedHat installs,
' and apparently it is a but more reliable than "time.winDows.com"
Set oExec = oShell.Exec("w32tm.exe /config /manualpeerlist:pool.ntp.org /update")
Do While oExec.Status = 0
     WScript.Sleep 100
Loop
Do While NOT oExec.StdOut.AtEndOfStream
	WScript.Echo oExec.StdOut.ReadLine
Loop

'Stopping the w32time service.  
'Necessary because changes to the w32time service will NOT take effect until service restart.
Set oExec = oShell.Exec("net.exe stop w32time")
Do While oExec.Status = 0
     WScript.Sleep 100
Loop
Do While NOT oExec.StdOut.AtEndOfStream
	WScript.Echo oExec.StdOut.ReadLine
Loop

'Starting the w32time service
Set oExec = oShell.Exec("net start w32time")
Do While oExec.Status = 0
     WScript.Sleep 100
Loop
Do While NOT oExec.StdOut.AtEndOfStream
	WScript.Echo oExec.StdOut.ReadLine
Loop

'Forcing a time service resync
'Time would resync on its own soon enough, but we are impatient and want to see results immediately.
Set oExec = oShell.Exec("w32tm.exe /resync")
Do While oExec.Status = 0
     WScript.Sleep 100
Loop
Do While NOT oExec.StdOut.AtEndOfStream
	WScript.Echo oExec.StdOut.ReadLine
Loop

WScript.Echo "Current Time is: " & Date & " " & Time

If iPosRegVal  -1 Then
	WScript.Echo "ReSetting registry maximum allowed clock skew correction Settings to their original values..."
	oShell.RegWrite strKeyPath & "\" & strPosValueName, iPosRegVal, "REG_DWORD"
	oShell.RegWrite strKeyPath & "\" & strNegValueName, iNegRegVal, "REG_DWORD"
	WScript.Echo strPosValueName & " is now Set to: " & oShell.RegRead(strKeyPath & "\" & strPosValueName)
	WScript.Echo strNegValueName & " is now Set to: " & oShell.RegRead(strKeyPath & "\" & strNegValueName)
End If

Comments are closed.