Manipulating Dates Returned by Windows Management Instrumentation (WMI)

Manipulating Dates Returned by Windows Management Instrumentation (WMI)

  • Comments 3
  • Likes

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! I need to understand how to work with dates that I receive from Windows Management Instrumentation (WMI). I remember in VBScript I had to use a function I got from the Scripting Guys that did string manipulation to convert the WMI date to a “normal” date. I guess that is okay, but I had no idea how that function worked or how to correct things when it did not work properly. I have been reading your Hey, Scripting Guy! Blog posts this week about dates, and I have yet to see you address this issue. Is it because it is too hard, and you are going to do the old two-step shuffle?

-- EA

 

Hey, Scripting Guy! Answer

Hello EA,

Microsoft Scripting Guy Ed Wilson here. As a famous twentieth century philosopher once said, “I can't dance”; therefore, I do not know how to do the old two-step shuffle. Or the Ickey Shuffle. I’m not too bad with the Corgi Shuffle though.

I can do a pretty effective string shuffle. It is string shuffling that is required to make sense of the date string that is returned by WMI. This is because WMI dates are returned as strings and not as datetime objects. These strings are compliant with the Distributed Management Task Force (DMTF) Common Information Model (CIM) standards. In VBScript days, most scripters used a version of the function found in the Convert WMI Date-Time Values script in the Scripting Guys Script Repository. EA, you are probably talking about this VBScript function in your email. It was a brilliant piece of code and is shown here:

Function WMIDateStringToDate(dtmInstallDate)
WMIDateStringToDate = CDate(Mid(dtmInstallDate, 5, 2) & "/" & _
Mid(dtmInstallDate, 7, 2) & "/" & Left(dtmInstallDate, 4) _
& " " & Mid (dtmInstallDate, 9, 2) & ":" & _
Mid(dtmInstallDate, 11, 2) & ":" & Mid(dtmInstallDate, _
13, 2))
End Function

Interestingly enough, in Windows XP a new COM object was introduced to WMI—the SwbemDateTime object. This object obsoleted the WMIDateStringToDate function. This object is discussed in a Hey, Scripting Guy! TechNet Magazine article called It’s About Time (Oh, and About Dates, Too). To use the SwbemDateTime object, I wrote the FunDate function, which is much easier to understand and is more reliable—and perhaps fun!

Function funDate(wmiDate)
Dim objSWbemDateTime
Set objSWbemDateTime = CreateObject("WbemScripting.SWbemDateTime")
objSWbemDateTime.value = wmiDate
funDate = objSWbemDateTime.GetVarDate
End function

An example of a WMI UTC date is seen here from the InstallDate property of the Win32_OperatingSystem WMI class.

PS C:\> $os = Get-WmiObject win32_operatingsystem
PS C:\> $os.InstallDate
20091024192037.000000-240
PS C:\>

Either of these approaches can be leveraged in Windows PowerShell. To use the SwbemDateTime object, use the New-Object cmdlet to create an instance of the object. Use the Get-WmiObject cmdlet to perform the WMI query of the Win32_OperatingSystem class, supply the InstallDate value to the value property of the SwbemDateTime object, and call the GetVarDate method from the same object. This technique is illustrated here:

PS C:\> $swbem = New-Object -ComObject wbemscripting.swbemdatetime
PS C:\> $os = Get-WmiObject win32_operatingsystem
PS C:\> $swbem.Value = $os.InstallDate
PS C:\> $swbem.GetVarDate()
Saturday, October 24, 2009 7:20:37 PM
PS C:\>

But the System.Management.ManagementDateTimeConverter .NET Framework class contains a number of static methods that are useful for working with WMI Dates. The static methods are shown here:

PS C:\> [management.managementDateTimeConverter] | gm -s


   TypeName: System.Management.ManagementDateTimeConverter

Name               MemberType Definition
----               ---------- ----------
Equals             Method     static bool Equals(System.Object objA, System.Objec...
ReferenceEquals    Method     static bool ReferenceEquals(System.Object objA, Sys...
ToDateTime         Method     static System.DateTime ToDateTime(string dmtfDate)
ToDmtfDateTime     Method     static string ToDmtfDateTime(System.DateTime date)
ToDmtfTimeInterval Method     static string ToDmtfTimeInterval(System.TimeSpan ti...
ToTimeSpan         Method     static System.TimeSpan ToTimeSpan(string dmtfTimespan)


PS C:\>

To parse the InstallDate property from the Win32_OperatingSystem WMI class, you would use the ToDateTime static method as illustrated here:

PS C:\> $os = Get-WmiObject win32_operatingsystem
PS C:\> [management.managementDateTimeConverter]::ToDateTime($os.InstallDate)
Saturday, October 24, 2009 7:20:37 PM
PS C:\>

This can be accomplished in one line, by retrieving both the WMI class and selecting the property at the same time.

Image of retrieving WMI class and selecting property at same time

There is only one problem with using the management.managementDateTimeConverter .NET Framework class—it is waaaaaaaaaaay toooooooooooo loooooong for me to type reliably on a regular basis. Therefore, this makes a great candidate to add to one’s profile. Before I add anything to a profile, I like to test the command first to ensure it works. Here is the command and the “test”:

PS C:\> New-Variable -Name dteConv -Value $("management.managementDateTimeConverter"
-as [type]) -Description MrEd_Variable
PS C:\> $dteConv::ToDateTime((gwmi win32_operatingSystem).InstallDate)
Saturday, October 24, 2009 7:20:37 PM
PS C:\>

I can edit a Windows PowerShell profile in Notepad, as shown in the following image. (Windows PowerShell profiles were discussed in Hey, Scripting Guy! Blog posts during Profile Week.)

?Image of editing Windows PowerShell profile in Notepad

There is another way to deal with WMI dates and times, and that is to use a ScriptMethod that is added by the Windows PowerShell team to WMI objects. Two ScriptMethods are added, as shown via the Get-Member cmdlet:

PS C:\> Get-WmiObject win32_OperatingSystem | Get-Member -MemberType ScriptMethod


   TypeName: System.Management.ManagementObject#root\cimv2\Win32_OperatingSystem

Name                MemberType   Definition
----                ----------   ----------
ConvertFromDateTime ScriptMethod System.Object ConvertFromDateTime();
ConvertToDateTime   ScriptMethod System.Object ConvertToDateTime();


PS C:\>

Because the ScriptMethods are added directly to instances of the WMI class, they can be accessed directly:

PS C:\> $os = Get-WmiObject win32_OperatingSystem
PS C:\> $os.ConvertToDateTime($os.InstallDate)
Saturday, October 24, 2009 7:20:37 PM
PS C:\>

Using the ScriptMethod always involves two steps: creating an instance of the WMI object, and passing an instance with the property to the ScriptMethod. The only way to perform this on a single line is to use the semicolon to create two logical commands on a single physical line. This is shown here:

PS C:\> $os = Get-WmiObject win32_OperatingSystem ; $os.ConvertToDateTime($os.Install
Date)
Saturday, October 24, 2009 7:20:37 PM
PS C:\>

The advantage of always having access to the ConvertToDateTime ScriptMethod on an instance of a WMI class can be seen here. The gwmi alias for the Get-WmiObject cmdlet and the ft alias for the Format-Table cmdlet are used. A custom label is created for the table called “Installed”. The value of the installed date is created by using the ConvertToDateTime ScriptMethod. The results can be compared to creating a table with the version and the installdate without parsing the date:

PS C:\> gwmi win32_operatingsystem | ft version, @{LABEL="Installed"; EXPRESSION = {$
_.convertToDateTime($_.InstallDate)}}

version                                    Installed
-------                                    ---------
6.1.7600                                   10/24/2009 7:20:37 PM


PS C:\> gwmi win32_operatingsystem | ft version, installDate

version                                    installDate
-------                                    -----------
6.1.7600                                   20091024192037.000000-240


PS C:\>


EA, that is all there is to using dates when working with Windows Management Instrumentation (WMI). That also brings Date Week to a close. Join us tomorrow for Quick-Hits Friday.

We invite you to follow us on Twitter or Facebook. If you have any questions, send email to us at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Great. Thanks for this post, I was struggling with converting an old vbs script to PowerShell because of the DateTime object.

  • I am running a vbs to retrieve the date created, date last accessed and date last modified of a folder.  The results then are put into an Excel spreadsheet.  How do I convert the WMI date/time to a regular date format?

  • Thank you for another "as always perfectly explained" tutorial on this ScriptMethod.