Parsing lists to objects in PowerShell – Tzutil
Last week I taught a PowerShell class – the first time in ages I’d gone back to my old role as a trainer, and of the first things we do explaining PowerShell is explain that
(a) When PowerShell’s own commands are piped together they pass object with properties – not a text representation of the objects which we’ve been used to in other shells. So when we get the contents of a directory, instead of a line of text for each item we get a file object with a name, a size and so on.
(b) PowerShell can still run command line executables intended for the CMD shell. Output from these will be formatted text.
So… this throws up another point, the need to parse text and turn it back into an object…
Over on the server core blog there is post about the command line Time Zone Utility (TZutil) – which is also present in Windows 7 (so I’m guessing the whole product family), and this links to another article about it, with some PowerShell script.
I thought I’d try another approach. TzUtil /L gives a list of the time zone names and codes like this
(UTC-12:00) International Date Line West
Dateline Standard Time
(UTC-11:00) Midway Island, Samoa
Samoa Standard Time
…
(UTC+12:00) Fiji, Kamchatka, Marshall Is.
Fiji Standard Time
(UTC+13:00) Nuku'alofa
Tonga Standard Time
So I wanted to convert it to Powershell objects and the code I came up was this
$tzlist=(tzutil.exe /l) ; 0..[int]($tzlist.count/3) | select -property @{name="TzID"; expression={$tzList[$_ * 3]}} ,
@{name="TzName";expression={$tzList[$_ * 3 + 1]}}
The first part is simple enough – run Tzutil /l and store the result. Since the lines are grouped in 3 the next bit just counts from zero to 1/3 of the count of lines and pipes the results into select-object. This is a corruption of what I think of as the Noble method. Jonathan Noble was the first person I saw to create a custom object by adding properties to an empty string, using select. I did the same thing and then thought “Does it have to be an empty string” ? No, it can be an integer, and it doesn’t matter if is empty or not – the number part is discarded. So what comes out is:
TzID TzName
---- ------
(UTC-12:00) International Date Line West Dateline Standard Time
(UTC-11:00) Midway Island, Samoa Samoa Standard Time
…(UTC+12:00) Fiji, Kamchatka, Marshall Is. Fiji Standard Time
(UTC+13:00) Nuku'alofa Tonga Standard Time
Which can be used anywhere else I need it - for example in making a selection to set the time zone with Tzutil /s.
The configuration tool which I have nearly finished for server 2008 R2 Core and Hyper-V server R2 will probably get the time zone to display it on the menu using a one line PowerShell function
Function Get-TimeZone { Tzutil.exe /g}