While scanning the PowerShell forums this evening I ran accross this question. Cruisader03 had already answered the question. The solution.. just…. looked too complicated. After three years of using PowerShell everyday as my primary means of administration… I offer this simple mantra.
If it looks complex your doing it wrong!… And you’re the second person to read it.
I just made that up, but I like it! Seriously though, this is something I’ve started to notice in my own code. I believe it is an interesting side effect of the Admin Development Model.
We cut and paste, one line at a time. Until we get it to work. By the time we finish a script we know that code not as a script, but as a series of lines. (Pay attention, I bet you still read it like a series of one liners). In that context it looks fine, but wait 24hr’s and look again… not the same is it. Now that you’re looking at a finished script. You will start to find all sorts of inefficiencies and poor grammar usage. So you polish it up a little… rinse and repeat 100 times, and post to PoshCode! So goes the Admin Development Model. With that in mind I offer this simple snip it, more a refactor of Cruisader03 post than a solution.
$name = '.' Get-WmiObject Win32_NetworkLoginProfile -ComputerName $name| #Filter out any non valid DTG Where-Object {$_.LastLogon -match "(?<dtg>\d{14}\.\d{6}\S)(?<offset>\d+)$"}| #Foreach valid entry find the last logon dtg ForEach-Object { # Win32_NetworkLoginProfile formats the utc offset in seconds this # Breaks the DateTime parser. We reformat the string converting # the offset back to hours $CorrectedDTG = "{0}{1:00}" -f $matches.dtg, ($matches.offset/60) New-Object PSObject -Property @{ Name=$_.Name LogonTime=[datetime]::ParseExact($CorrectedDTG, "yyyyMMddhhmmss.ffffffzz", $null) } } | Sort-Object -Descending LogonTime | Select-Object -First 1
~Glenn
Steven Murawski | 07-Mar-10 at 11:20 am | Permalink
Great post. I like the use of the Admin Development Model in your description. Its sounds classier than REPL (read, evaluate, print, loop).
JKavanagh58 | 08-Mar-10 at 9:06 am | Permalink
Great post but I can’t get the script to work, and not sure why. The error response line number would indicate it’s this line:
LogonTime=[datetime]::ParseExact($CorrectedDTG, “yyyyMMddhhmmss.ffffffzz”, $null)
Exception calling “ParseExact” with “3″ argument(s): “String was not recognized as a valid DateTime.”
At line:15 char:45
+ LogonTime=[datetime]::ParseExact <<<< ($CorrectedDTG, "yyyyMMddhhmmss.ffffffzz", $null)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
glnsize | 27-Mar-10 at 9:47 am | Permalink
JKavanagh58, Your system is returning a dtg format that my parser doesn’t understand. I would suggest looking at the raw dtg, and go from there.
Sorry, I couldn’t be more help, but this is the problem with text. It is just too unpredictable to get 100%.
~Glenn