Hey, Scripting Guy! How can I set the date and time on a computer?
— KM
Hey, KM. Well, it’s true: today is the last day of TechEd IT Forum. That also means that, for the Scripting Guys, the party is over: tomorrow morning they hop on a plane and head back for home. And, needless to say, back to the real world: jobs, car payments, mortgages, families, the whole nine yards.
Gee, we can hardly wait.
Anyway, we decide to celebrate our last day in Barcelona the only way the Scripting Guys know how to celebrate: by writing a script that can set the date and time on a computer. Stand back, everyone; it’s time for the Scripting Guys to party:
dtmNewDateTime = “20071115132000.000000-480”strComputer = “.”
Set objWMIService = GetObject(“winmgmts:{(Systemtime)}\\” & strComputer & “\root\cimv2”)
Set colOSes = objWMIService.ExecQuery(“Select * From Win32_OperatingSystem”)
For Each objOS In colOSes objOS.SetDateTime dtmNewDateTime Next
A word or two of caution before we explain how this script works. This script will, indeed, change the time on the computer, and that could be a problem if the computer is a member of an Active Directory domain. Active Directory relies on computer times being synchronized; if a computer’s time strays too far from the domain controller time you won’t be able to log on to the network. (However, you’ll still be able to log on to the computer itself.) Likewise, Active Directory does its best to keep computer times in synch; even if you can log on to the domain there’s a good chance that, sooner or later, Active Directory will update the time for you. That might not be a problem for you, and it won’t be a problem at all if your computer isn’t part of an Active Directory domain. Just something you should keep in mind.
Note. That said, changing computer times like this is often used for testing purposes, even within an Active directory domain. |
So how does the script work? Well, step 1 is to assign a new date and time to a variable named dtmNewDateTime; that’s what we do in the very first line of code:
dtmNewDateTime = “20071115130000.000000-480”
And you know what? You’re right: that doesn’t look very much like a date-time value, does it? That’s because WMI uses the so-called Universal Time Coordinate (UTC) format. As strange as a UTC value might look, it really is a date-time value:
• |
The first four characters (2007) represent the year. |
• |
The next two characters (11) represent the month. |
• |
The next two characters (15) represent the day. |
• |
The next two characters (13) represent the hour in 24-hour format. For you Americans out there, “13 o’clock” is the same as 1:00 PM. |
• |
The next two characters (00) represent the seconds. |
• |
The .000000 represents the milliseconds. |
• |
The -480 represents the “offset” from Greenwich Mean Time. -480 means that the time zone this computer lives in is 8 hours (480 minutes) earlier than Greenwich Mean Time. In other words, if it’s 12:00 noon in Redmond, WA (where this computer lives) then it must be 8:00 PM (20:00) in Greenwich, England. |
Note. How the heck are you supposed to know your offset from Greenwich Mean Time? Take a peek at the Microsoft Windows 2000 Scripting Guide for the answer. |
As you can probably see, we created our own UTC value for this script; we did that so that this script would work on versions of Windows prior to Windows XP. If you’re running Windows XP or a later version of Windows you can use the WbemScripting.SWbemDateTime object to create a UTC value for you:
Set objSWbemDateTime = CreateObject(“WbemScripting.SWbemDateTime”)objSWbemDateTime.SetVarDate #11/15/2007 1:20 PM#, True dtmDateTime = objSWbemDateTime.Value
Wscript.Echo dtmDateTime
For more information, see the Hey, Scripting Guy! column It’s About Time (Oh, and About Dates, Too) in TechNet Magazine.
Getting a proper UTC value is actually the difficult part of this script. Once we have this value we then connect to the WMI service on the local computer. (Although we could also run this script against a remote machine; just assign the name of that remote computer to the variable strComputer.) After that we use this line of code to retrieve a collection of all the operating systems currently in use on the computer:
Set colOSes = objWMIService.ExecQuery(“Select * From Win32_OperatingSystem”)
Note. Why did we say “currently in use” rather than installed? That’s easy: that’s how the Win32_OperatingSystem class works. This class only returns information about the operating system currently in use; it does not return information about any other operating systems that might be installed on a multi-boot system. |
From there we set up a For Each loop to through each item in the collection (although there will never be more than one item in that collection). Inside that loop all we have to do is call the SetDateTime method, passing SetDateTime the UTC value we created:
objOS.SetDateTime dtmNewDateTime
Just like that, the time will get changed on the computer. And everyone will live happily ever after.
We hope that answers your question, KM. As for the Scripting Guys, we have one final day of booth duty, and then one final chance to eat churros with a cup of melted chocolate and whipped cream. One final chance to – sigh. If you happen to be at IT Forum today, swing by booth 22 and say hi to the Scripting Guys. They could use a little cheering up.
0 comments