Home arrow Howto's arrow Howto - Scripting Solutions arrow Improving Upon Microsoft's Daylight Saving Time Patch
Home
Tools
Knowledge Center
Howto's
Latest Jobs
Latest jobs from IT Contractor Jobs
The latest jobs registered on the IT Contractor Jobs web site.
  • Business Analyst

    - Business Analyst (New Zealand, Wellington - Wellington CBD)

    Business Analyst Intermediate to senior level Business Analyst 6 months initial term Start ASAP..... Major financial services organisation requires an intermediate to senior level Business...

  • Desktop Engineer

    - Desktop Engineer (New Zealand, Auckland - Auckland CBD)

    Desktop Engineer We are looking for an experienced Desktop Engineer to provide on-site technical PC support.   The successful candidate will demonstrate the following experience and...

  • IT Support/ Helpdesk

    - IT Support/ Helpdesk (New Zealand, Christchurch - Christchu5rch CBD)

    IT Support/ Helpdesk - Contract Roles   My client is searching for a highly skilled allrounder to join their team at a time when...


Improving Upon Microsoft's Daylight Saving Time Patch PDF Print E-mail
Like the original scripts, the new scripts work on all the Windows platforms mentioned in the article. However, with the new scripts, machines that have been updated once don't need to be updated again if the users move to a different time zone. All the users need to do is to select the new time zone in the machine's Date and Time Properties dialog box and they're covered.

 

By now, most IT professionals are aware of the daylight saving time changes that will take effect starting this year as a result of the Energy Policy Act passed by the U.S. government in August 2005. The Energy Policy Act changes the start and end dates of daylight saving time. This year, daylight saving time starts three weeks earlier (2 A.M. on March 11) and ends one week later (2 A.M. on November 4) compared with last year.

These daylight saving time changes will affect more than just U.S. organizations because Canada has adopted the changes as well. In addition, the changes can affect organizations with worldwide operations. On the "Daylight Saving Time Help and Support Center" Web page (http://www.microsoft.com/windows/timezone/dst2007.mspx), Microsoft states that, "While the change in daylight saving time applies to U.S. and Canada, the change may impact customers based outside North America. Companies or organizations with operations, customers or vendors based in North America may be affected. In addition customers who interact or integrate with systems that are based in North America or rely on date/time calculations may be impacted."

Although the daylight saving time changes don't pose as much a threat as the Y2K changes seven years ago, some IT professionals have already raised concerns about the negative impact the daylight saving time changes will have, especially on those organizations that still have a large number of computers running Windows 2000 Server and Windows 2000 Professional. This concern stems from the fact that Microsoft released a daylight saving time patch for Windows Server 2003 and Windows XP (http://support.microsoft.com/kb/928388) but not for Win2K because Microsoft ended mainstream support for it.

The Microsoft article “How to configure daylight saving time for the United States in 2007” (http://support.microsoft.com/kb/914387) provides workaround methods for updating the daylight saving time dates of those OSs excluded from mainstream support. These methods involve either using the Time Zone Editor (tzedit.exe) or scripts that use registry imports. However, for large environments with hundreds of Win2K servers and workstations in use, these methods aren't feasible. Using the Time Zone Editor isn't practical because you must be physically at the machine. And using a registry import script isn't practical because the registry import may pose a security risk for large enterprise environments. Some companies disable the regfile association on all their servers because of such security risks.

My company has a large, mixed environment of Windows OSs, so I wrote my own script, SetDSTDates.vbs, to automate the daylight saving time changes. Unlike the Microsoft patch, SetDSTDates.vbs applies the daylight saving time changes to Win2K as well as Windows 2003 and XP machines. Specifically, you can use the script on the following platforms:

  • Windows 2003 x64 Editions
  • Windows 2003
  • XP 64-Bit Edition
  • XP
  • Win2K Server
  • Win2K Pro

You can download SetDSTDates.vbs from the Scripting Pro VIP Web site. Before I tell you how to use and test SetDSTDates.vbs, let's explore how this script works.

Exploring SetDSTDates.vbs
The main function in SetDSTDates.vbs is setDSTValue. This function relies on three other functions: getTimeZoneName, compareDSTDate and setDSTDate. Here's how these four functions work together to update the daylight saving time dates on a machine.

As Listing 1 (bottom of the page) shows, the setDSTValue function begins by declaring all its variables, then calls the getTimeZoneName function. When I was writing SetDSTDates.vbs, I discovered that three binary values in the registry had to be updated. However, the path to one of those values is based on the time zone set for the target computer. So, the getTimeZoneName function obtains the name of the time zone for the target computer. As Listing 2 (bottom of the page) shows, the function obtains the time-zone name by querying Windows Management Instrumentation's (WMI's) Win32_TimeZone class.

After the setDSTValue function has the time-zone name, it appends this name to the registry path HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\ and sets the resulting registry key to the strKeyPath1 variable, as callout A in Listing 1(bottom of the page) shows. With this setup, you can launch the script from a machine that has a different time zone than that of the target machine, assuming you pass in the remote computer's name as an input parameter to the function. (More information about using the script on remote computers appears in the "Using the Script" section.)

The value name for the registry key in strKeyPath1 is TZI. In the registry, TZI is a REG_BINARY value. Because SetDSTDates.vbs uses WMI's StdRegProv class to manipulate the target computer's registry, the script uses the WMI data type of uint8 array (i.e., an array of hexadecimal values that don't exceed 255, or hex FF) to specify the TZI value. (For information about how registry data types map to the WMI data types used by StdRegProv, see the Microsoft article "Mapping a Registry Data Type to a WMI Data Type" at http://msdn2.microsoft.com/en-us/library/aa392326.aspx.) As callout B in Listing 1 shows, the array value is set to the arrDSTTZValue variable.

The value in arrDSTTZValue defines the new dates for daylight saving time. Changing the TZI value alone will change the daylight saving time dates. However, in order for the daylight saving time changes to update automatically, you need to update two other binary values—StandardStart and DaylightStart—in the registry. Both binary values are part of the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation key. The setDSTValue function defines the StandardStart and DaylightStart values in uint8 array format and sets to them to the arrDSTSSValue and arrDSTDSValue variables, respectively. The value in arrDSTSSValue updates the date when standard time starts, whereas the value in arrDSTDSValue updates the date when daylight saving time begins.

With the correct registry keys and binary values defined in their respective variables, the compareDSTDate function, which Listing 3 shows, takes center stage. The setDSTValue function calls the compareDSTDate function three times to compare the target machine's current TZI, StandardStart, and DaylightStart binary values with the values in the arrDSTTZValue, arrDSTSSValue, and arrDSTDSValue variables, respectively. The compareDSTDate function returns the value "Updated" when the corresponding values match and "NotUpdated" when they don't match, as callout A in Listing 3 shows.

The setDSTValue function stores the returned values from the three compareDSTDate function calls in the variables named strDSTTZComp, strDSTSSComp, and strDSTDSComp. When the strDSTTZComp, strDSTSSComp, and strDSTDSComp values all read "Updated", the setDSTValue function returns the value “Already updated,” as callout C in Listing 1 shows. This value prompts the script's RuntheScript subroutine to display a message that the machine has already been updated, and the script ends.

When one or more of the strDSTTZComp, strDSTSSComp, and strDSTDSComp values read "NotUpdated", the setDSTValue function calls the setDSTDate function three times (once for each binary value), as callout D in Listing 1 shows. The setDSTDate function, which Listing 4 shows, performs the actual registry modifications. As callout A in Listing 4 shows, if the setDSTDate function fails to make a registry modification, the returned value for that particular function call is "Error". Otherwise, the returned value is "Success".

The setDSTValue function stores the returned values from the three setDSTDate function calls in the strSetDST1, strSetDST2 and strSetDST3 variables. The setDSTValue function then checks the values in these variables to see whether all three setDSTDate function calls were successful. If so, the script displays a screen message that reports the daylight saving time operation was successful. Otherwise, the message reports that the operation failed. The script then ends.

Using the Script
To run SetDSTDates.vbs on a local computer, you simply need to double-click it or use SetDSTDates.exe (a self-executable that's included in the download package for this article) to launch it. You don't need to customize SetDSTDates.vbs at all, and you don't need to restart the computer after the script runs. However, the computer on which you run SetDSTDates.vbs must have Windows Script Host (WSH) 5.6 and the standard WMI components installed.

Also included in this article's download package is the SetDSTDates_Cmd.vbs script, which you can use to update daylight saving time on a remote machine from a command line. (SetDSTDates_Cmd.vbs will only run from the command line. Double-clicking this script will generate an error message.) Because SetDSTDates_Cmd.vbs uses WMI to update the registry, you can run the script against multiple machines from a single location. In this case, you'd need to integrate SetDSTDates_Cmd.vbs into another script, such as a script that can query computers in an Active Directory (AD) domain. When the daylight saving time update is deployed in this manner, there's no need to restart the machines for the changes to take effect.

Before you use SetDSTDates_Cmd.vbs in this manner, though, remember that the daylight saving time dates in other countries likely differ from the new daylight saving time dates in the United States and Canada. (The Microsoft article "How to configure daylight saving time for the United States in 2007" contains information about the countries adopting the new daylight saving time standard and the countries that use different daylight saving time dates.) In addition, two states (Arizona and Hawaii) and five U.S. territories (American Samoa, Guam, the Northern Marianas, Puerto Rico, and the Virgin Islands) have chosen not to observe daylight saving time. If you update multiple machines in a domain but some of the machines in that domain are in areas that don't follow the new daylight saving time standard, you'll be creating problems for those machines. One way to avoid this problem is to group computers in AD domains into organizational units (OUs), then have the script target only those machines in certain OUs.

Another way you can make the daylight saving time changes on multiple machines is to use Group Policy to deploy SetDSTDates_Silent.exe as a single startup script. SetDSTDates_Silent.exe is a self-executable program and is encrypted, so the deployment of this script with Group Policy will be more secure than a script that uses a registry import. You'll find SetDSTDates_Silent.exe in this article's download package. In this case, each target computer will require a restart.

Because SetDSTDates_Silent.exe runs in silent mode, it writes two application event log entries to let you know the script's results:

  • "Success (Event ID 0, Source WSH), which will have an event description that reads something like, "Daylight Saving Time dates on computerA have been updated successfully."
  • Failed (Event ID 1, Source WSH), which will have an event description that reads something like, "Daylight Saving Time update failed on computerA."

Testing the Script and Validating Its Results
It's always a good practice to test a script and validate its results before you run the script in a production environment. So, you should test SetDSTDates.vbs on each type of OS you have in your network, then validate the results to see whether the daylight saving time changes actually occurred.

You can validate the results by following these steps:

  1. Open the Date and Time Properties dialog box.
  2. In the month drop-down list, select March.
  3. Click any date before March 11 and click Apply.
  4. Select the date of March 11, set the system clock to 1:59:30 A.M., and click Apply. Watch to see whether the system clock moves one hour forward immediately after the second counter reaches 60. The clock should read 3:00:00 A.M.
  5. In the month drop-down list, select November.
  6. Click any date before November 4 and click Apply.
  7. Select the date of November 4, set the system clock to 1:59:30 A.M., and click Apply. Watch to see whether the system clock moves one hour backward immediately after the second counter reaches 60. The clock should read 1:00:00 A.M.
  8. Set the date and time back to the correct setting.

After you update the machines in your network, you'll likely want to keep SetDSTDates.vbs and the other scripts handy. You should apply the daylight saving time update to any newly built machine (with the exception of Windows Vista) or rebuilt machine you later install in your network. You can easily accomplish this by using SetDSTDates_Silent.exe and Group Policy.

Script Can Help Alleviate Mixed Platform Problems
Not implementing the daylight saving time changes on those computers that should be updated can negatively impact anyone who uses applications that rely on the OS timestamp. For system administrators, the consequences can be more serious because daylight saving time dates can affect domain operations, such as AD replication and network authentication. (By default, Kerberos requires that any two computers authenticating over the network be within five minutes of each other.) With this in mind, it's easy to imagine the complications that might arise in organizations that have a mixture of Windows platforms, some of which can be updated by the available Microsoft patch and some of which can't be. Fortunately, the information and the script provided here should go a long way in helping the systems administrators in these organizations who apply the daylight saving time changes across their entire network.







 


Listing 1

' Listing 1: The setDSTValue Function  Private Function setDSTValue(ByVal strComputer)   Dim strTimeZoneName, strKeyPath1, strValueName1, strKeyPath2, strValueName2   Dim strKeyPath3, strValueName3, arrDSTTZValue, arrDSTSSValue, arrDSTDSValue   Dim strDSTTZComp, strDSTSSComp, strDSTDSComp, strSetDST1, strSetDST2, strSetDST3    ' Get the name of the time zone for the target computer.   strTimeZoneName = getTimeZoneName(strComputer)    ' Define variables for the registry key and value names.  ' ******* BEGIN CALLOUT A *******    strKeyPath1 = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\" & _      strTimeZoneName  ' ******* END CALLOUT A *******    strValueName1 = "TZI"   strKeyPath2 = "SYSTEM\CurrentControlSet\Control\TimeZoneInformation"   strValueName2 = "StandardStart"   strKeyPath3 = "SYSTEM\CurrentControlSet\Control\TimeZoneInformation"   strValueName3 = "DaylightStart"    ' Define the variables for the three registry settings.  ' ******* BEGIN CALLOUT B *******    arrDSTTZValue = Array(&H68,&H01,&H00,&H00,&H00,&H00,&H00,&H00, _     &HC4,&HFF,&HFF,&HFF,&H00,&H00,&H0B,&H00,&H00,_     &H00,&H01,&H00,&H02,&H00,&H00,&H00,&H00,&H00, _     &H00,&H00,&H00,&H00,&H03,&H00,&H00,&H00,&H02, _     &H00,&H02,&H00,&H00,&H00,&H00,&H00,&H00,&H00)  ' ******* END CALLOUT B *******    arrDSTSSValue = Array(&H00,&H00,&H0B,&H00,&H01,&H00,&H02,&H00, _     &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00)   arrDSTDSValue = Array(&H00,&H00,&H03,&H00,&H02,&H00,&H02,&H00, _     &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00)    ' Check the current daylight saving time dates to see whether they've already been updated.   strDSTTZComp = compareDSTDate(strComputer, strKeyPath1, strValueName1, arrDSTTZValue)   strDSTSSComp = compareDSTDate(strComputer, strKeyPath2, strValueName2, arrDSTSSValue)   strDSTDSComp = compareDSTDate(strComputer, strKeyPath3, strValueName3, arrDSTDSValue)  ' ******* BEGIN CALLOUT C *******    ' If the current daylight saving time dates have been updated, skip the update routines below.   If strDSTTZComp = "Updated" And strDSTSSComp = "Updated" _     And strDSTDSComp = "Updated" Then       setDSTValue = "Already updated"       Exit Function  ' ******* END CALLOUT C *******    Else  ' ******* BEGIN CALLOUT D *******      ' Set daylight saving time for the current time zone.     strSetDST1 = setDSTDate(strComputer, strKeyPath1, strValueName1, arrDSTTZValue)     ' Set the start date of standard time.     strSetDST2 = setDSTDate(strComputer, strKeyPath2, strValueName2, arrDSTSSValue)     ' Set the start date of daylight saving time.     strSetDST3 = setDSTDate(strComputer, strKeyPath3, strValueName3, arrDSTDSValue)  ' ******* END CALLOUT D *******      ' Check to see whether all the setDSTDate function calls were successful. If so, report     ' that the daylight saving time operation was a success. Otherwise, report that it failed.     If strSetDST1 = "Success" And strSetDST2 = "Success" And strSetDST3 = "Success" Then       setDSTValue = "Success"     Else       setDSTValue = "Failed"     End If   End If  End Function  


 



Listing 2

' Listing 2: The getTimeZoneName Function  Private Function getTimeZoneName(ByVal strComputer)   Dim objWMIService, colTimeZone, objItem   Set objWMIService = GetObject("winmgmts:" _     & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")   Set colTimeZone = objWMIService.ExecQuery("Select * from Win32_TimeZone")   For Each objItem In colTimeZone     getTimeZoneName = objItem.StandardName   Next   Set objWMIService = Nothing: Set colTimeZone = Nothing End Function   


 



Listing 3

' Listing 3: The compareDSTDate Function  Private Function compareDSTDate(strComputer, strKeyPath, strValueName, arrBinValue)   Const HKEY_LOCAL_MACHINE = &H80000002   Dim objRegistry, arrCurrentValue, objItem, strBinValue1, strBinValue2     Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}//" & _       strComputer & "/root/default:StdRegProv")     objRegistry.GetBinaryValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,arrCurrentValue     If Not IsNull(arrCurrentValue) Then       For Each objItem In arrCurrentValue         strBinValue1 = strBinValue1 & objItem       Next       For Each objItem In arrBinValue         strBinValue2 = strBinValue2 & objItem       Next  ' ******* BEGIN CALLOUT A *******        If strBinValue1 = strBinValue2 Then         compareDSTDate = "Updated"       Else         compareDSTDate = "NotUpdated"       End If  ' ******* END CALLOUT A *******      End If   Set objRegistry = Nothing End Function  


 



Listing 4

' Listing 4: The setDSTDate Function  Private Function setDSTDate(strComputer, strKeyPath, strValueName, arrBinValue)   Const HKEY_LOCAL_MACHINE = &H80000002   Dim objRegistry     Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}//" & _       strComputer & "/root/default:StdRegProv")     On Error Resume Next     objRegistry.SetBinaryValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,arrBinValue  ' ******* BEGIN CALLOUT A *******      If Err Then       setDSTDate = "Error"     Else       setDSTDate = "Success"     End If  ' ******* END CALLOUT A *******      Err.Clear     On Error Goto 0   Set objRegistry = Nothing End Function  
 
< Prev   Next >
Powered by IT CONTRACTORS and designed by EZPrinting web hosting