markdmac's Enterprise Scripts
I was doing a VBScript/WMI query of a Windows 2008 server. While querying the Win32_QuickFixEngineering class and grabbing the InstalledOn property for hotfixes I encountered a glitch. The same code that worked on Windows XP, 2003 and even Windows 7 to return a date was returning a long string that appeared to be Hex. I confirmed this to be a problem on both Vista and Server 2008.
This is what I was seeing:
01c9c5ce4b48e5fd
However when I compared that to the data I see in the GUI via Add/Remove Programs the real date for that hotfix is:
4/25/2009
I started to research this, hoping to find a function that would convert this for me but after several hours hit a brick wall, don't worry I only bruised my hand. Anyway after a good nights sleep I guess my brain had digested and processed some of my research and I was able to come up with the following function. I hope it helps others.
Code:
hDate = "01c9c5ce4b48e5fd"[green]
'The above should resolve to 4/25/2009[/green]
WScript.Echo HexDateToDate(hDate)
Function HexDateToDate(hDate)
highPart = CDbl("&h" & Left(hDate,8))
lowPart = CDbl("&h" & Right(hDate,8))
intInstalledOn = highPart * (2^32) + lowPart
intInstalledOn = intInstalledOn / (60 * 10000000)
intInstalledOn = intInstalledOn / 1440
HexDateToDate = intInstalledOn + #1/1/1601#
End Function
Breaking down the code:
The secret was to break apart the number into two parts and then convert those numbers from Hex to decimal. So we will separate our number into two eight digit number. Then we convert those from Hex to decimal.
We then use the properties of the IADsLargeInteger to work with this. I won't even pretend to comprehend the math behind this, but you need to raise the first half to 2 to the 32nd power. Then add that to the second part. This will yield a rather large decimal number that represents the number of nanoseconds since Jan 1, 1601 and the event that logged our time.
Once we have nonoseconds, the rest of the code is used to convert to years, months, days, hours, minutes & seconds.
We then add that time to Jan 1, 1601 to get the time we had recorded.