Posts Tagged ‘mdt’

Time Sync Scripts… updated for MDT 2010/LiteTouch

Update: Although the scripts in this post work, a correction is required for time to sync properly in the winPE environment. An updated WinPE script can be found here:
http://blog.uvm.edu/jgm/2010/10/14/time-sync-in-mdt-2010winpe-take-3/

With some help from the indispensable MDT Debugger, I have managed to get my quick Time Sync VBScript into MDT 2010: http://blogs.technet.com/b/deploymentguys/archive/2010/03/22/mdt-debugger.aspx

The script I posted previously needed a few quick adjustments to enable proper logging to the “MININT” deployment directories. Here is the updated version. If you want to use it, give it a name starting with “Z” and drop it in the “Scripts” directory of your deployment share:


   
   

Option Explicit
RunNewInstance

'//—————————————————————————-
'//  Global Constants
'//—————————————————————————-

'//—————————————————————————-
'//  Main Class
'//—————————————————————————-

Class ZUVMsetTime

    '//—————————————————————————-
    '//  Global constant and variable declarations
    '//—————————————————————————-

    Dim iRetVal

    '//—————————————————————————-
    '//  Constructor to initialize needed global objects
    '//—————————————————————————-

    Private Sub Class_Initialize

    End Sub
    '//—————————————————————————-
    '//  Main routine
    '//—————————————————————————-

    Function Main

	' 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.

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

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

		oLogging.CreateEntry "setTime> " &  "Current Time is: " & Date & " " & Time, LogTypeInfo

		'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)
		oLogging.CreateEntry "setTime> " &  "strNegValueName value is: " & iNegRegVal, LogTypeInfo
		oLogging.CreateEntry "setTime> " &  "StrPosValueName value is: " & iPosRegVal, LogTypeInfo

		If iPosRegVal  -1 Then
			oLogging.CreateEntry "setTime> " &  "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"
			oLogging.CreateEntry "setTime> " &  strPosValueName & " is now Set to: " & oShell.RegRead(strKeyPath & "\" & strPosValueName), LogTypeInfo
			oLogging.CreateEntry "setTime> " &  strNegValueName & " is now Set to: " & oShell.RegRead(strKeyPath & "\" & strNegValueName), LogTypeInfo
		Else
			oLogging.CreateEntry "setTime> " &  "This system already already is configured to allow large clock skew corrections.", LogTypeInfo
		End If 

		oLogging.CreateEntry "setTime> " &  "Setting WinDows Time service Manual-sync NTP Server to ""pool.ntp.org""", LogTypeInfo
		' 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
			oLogging.CreateEntry "setTime> " &  oExec.StdOut.ReadLine, LogTypeInfo
		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
			oLogging.CreateEntry "setTime> " &  oExec.StdOut.ReadLine, LogTypeInfo
		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
			oLogging.CreateEntry "setTime> " &  oExec.StdOut.ReadLine, LogTypeInfo
		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
			oLogging.CreateEntry "setTime> " &  oExec.StdOut.ReadLine, LogTypeInfo
		Loop

		oLogging.CreateEntry "setTime> " &  "Current Time is: " & Date & " " & Time, LogTypeInfo

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

End Class

   

But wait! This does not really work very… Time only gets fixed after the computer logs in after mini-setup completes. By this time, the initial Windows Activation attempt will have failed. Let’s take care of time synchronization in the WinPE environment, before we even lay down the Windows OS image. The following script is added as a custom action during the “pre-install” phase of LiteTouch deployment:


   
   

Option Explicit
RunNewInstance

'//—————————————————————————-
'//  Global Constants
'//—————————————————————————-

'const DEPLOY_SERVER = "\\sysimg3.campus.ad.uvm.edu"

'//—————————————————————————-
'//  Main Class
'//—————————————————————————-

Class ZUVMsetTimePE

    '//—————————————————————————-
    '//  Global constant and variable declarations
    '//—————————————————————————-
	
    Dim iRetVal

    '//—————————————————————————-
    '//  Constructor to initialize needed global objects
    '//—————————————————————————-

    Private Sub Class_Initialize
    End Sub
	
	Function RegExpFind(patrn, strng)
	  Dim regEx, oMatch, oMatches, iPos

	  ' Create the regular expression.
	  Set regEx = New RegExp
	  regEx.Pattern = patrn
	  regEx.IgnoreCase = False
	  regEx.Global = False

	  ' Do the search.
	  Set oMatches = regEx.Execute(strng)
	  
	  iPos = "0"
	  
	  For Each oMatch in oMatches
		iPos = oMatch.FirstIndex
	  Next
	  
	  RegExpFind = iPos
	End Function

    '//—————————————————————————-
    '//  Main routine
    '//—————————————————————————-

    Function Main
	
		' setTimePE.vbs
		' J. Greg Mackinnon, 2010-10-07
		' Sets time from within a WinPE 3.0 environment.
		
		Dim sDATESEARCH
		Dim sTIMESEARCH
		
		Dim oExec
		Dim sDSTime, sExecOut, sDate, sTime, sDateTime, sCmd, sDPServ
		Dim iPos1, iPos2, iLength
		
		sDATESEARCH = "[0-9]*/"
		sTIMESEARCH = "[0-9]*:"
		
		sDPServ = oEnvironment.Item("SMSDP")
		'sDPServ = "sysimg3.campus.ad.uvm.edu"

		oLogging.CreateEntry "Current Time on localhost is: " & Date & " " & Time, LogTypeInfo

		set oExec = oShell.Exec("net.exe time \\" & sDPServ)
		Do While oExec.Status = 0
			 WScript.Sleep 100
		Loop
		Do Until oExec.StdOut.AtEndOfStream
			sExecOut = oExec.StdOut.ReadLine
			oLogging.CreateEntry "setTime> Output from net time: " & sExecOut, LogTypeInfo
			iPos1 = RegExpFind(sDATESEARCH, sExecOut)
			If iPos1  0 then
				sDateTime = Mid(sExecOut,iPos1)
				iPos2 = RegExpFind(sTIMESEARCH, sDateTime)
				If  iPos2  0 then
					sTime = Mid(sDateTime, iPos2)
					sDate = Left(sDateTime, iPos2)
					Exit Do
				End If
			End If
		Loop

		oLogging.CreateEntry "Current Time on " & sDPServ & " is: " & sDateTime, LogTypeInfo


		REM set oExec = oShell.Exec("%comspec% /c time " & sTime)
		sCMD = """time " & sTime & """"
		oShell.Run "%comspec% /c " & sCMD

		sCMD = """date " & sDate & """"
		oShell.Run "%comspec% /c " & sCMD

		oLogging.CreateEntry "Current Time on localhost now is: " & Date & " " & Time, LogTypeInfo

	End Function

End Class

   


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