Querying a WMi object on the
$colItems = Get-WmiObject Win32_NetworkLoginProfile -Namespace "root\CIMV2"
| Where-Object {$_.name -match "Name"} | Select-Object name,PasswordAge
according to MSDN
PasswordAge
Data type: datetime
Access type: Read-only
Length of time a password has been in effect. This value is measured from the number of seconds elapsed since the password was last changed.
Example: 00001201000230.000000 000
I am getting
00000068235223.000000:000
So I have tried casting this to TimeSpan
and DateTime
no luck.
what does the colon represent how to get number hours it represent.
Thanks Adding the WMI class name to title for the next poor soul that get confused by documentation wording.
here is what works
That worked perfectly $str = "00000068235223.000000:000" $ts = [System.Management.ManagementDateTimeConverter]::ToTimeSpan($str)
Days : 68 Hours : 23 Minutes : 52 Seconds : 23 Milliseconds : 0 Ticks : 59611430000000 TotalDays : 68.9947106481481 TotalHours : 1655.87305555556 TotalMinutes : 99352.3833333333 TotalSeconds : 5961143 TotalMilliseconds : 5961143000
This is the DMTF time interval format which is documented here. Basically it is string that encodes a time span in the form ddddddddHHMMSS.mmmmmm:000
. Note that for time intervals, the ending is always :000
.
From the docs:
The following example shows the format of a date-time interval. ddddddddHHMMSS.mmmmmm:000
The following table lists the fields of the date-time interval.
Field Description
dddddddd Eight digits that represent a number of days (00000000 through 99999999).
HH Two-digit hour of the day that uses the 24-hour clock (00 through 23).
MM Two-digit minute in the hour (00 through 59).
SS Two-digit number of seconds in the minute (00 through 59).
mmmmmm Six-digit number of microseconds in the second (000000 through 999999).
I believe the documentation is somewhat misleading for this field, since it is implying the whole numbers are full seconds, but in fact it is a string format representing days, hours, minutes, seconds, etc.
You should use [System.Management.ManagementDateTimeConverter]::ToTimeSpan
to convert this string to a .NET Timespan, however, for whatever reason I actually received an array instead of a string for PasswordAge, so I had to use this:
$p = gwmi Win32_NetworkLoginProfile
[System.Management.ManagementDateTimeConverter]::ToTimeSpan($p.PasswordAge[1])
To add to all the previous answers, the proper routine to make something out of this type of strings is call [System.Management.ManagementDateTimeConverter]::ToTimeSpan($string)
. This will produce a [System.TimeSpan]
object, which you can then parse in a better way.
Credit for class to do conversion goes to this answer.
Those are CIM_DATETIME
values or Interval values. The format is defined by the CIM standard that WMI is built upon.
With normal datetime values, the WMI object provides a converter function. For example:
$_.ConvertToDateTime($_.PasswordExpires);
But that doesn't work for intervals, which is what PasswordAge
is.
The MS doc you point to says the value is the number of seconds, but I believe that means the precision is to the second, not that the value is literally in seconds. My current password says it's 43 years old if that were the case, for example, and that's not possible. So it must use the Interval format.
I would do this:
$PasswordAge = New-TimeSpan -Days $_.PasswordAge.Substring(0,8) `
-Hours $_.PasswordAge.Substring(8,2) `
-Minutes $_.PasswordAge.Substring(10,2) `
-Seconds $_.PasswordAge.Substring(12,2);
Remember to use $PasswordAge.TotalHours
and not just $PasswordAge.Hours
if you want the actual age value expressed in hours and not just the hour value of the timespan.
Edit: @Vesper is right. You can just use:
[System.Management.ManagementDateTimeConverter]::ToTimeSpan($_.PasswordAge);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With