There is an excellent post on getting and setting the TimeZone done by Pat Richard using Powershell and TZUtil which I thought was absolutely cool.

The only thing I noticed was the Script had a defined list for the Time Zones.   Knowing much of this information is contained directly in Windows I was wondering if there was a way to pull the list in and use it as the master.

Within .NET there is System.TimeZoneInfo which has a nice simple method called (are you ready?) GetSystemTimeZones

So to leverage this method in Windows Powershell all we need to do it

[System.TimeZoneInfo]::GetSystemTimeZones()

Poof! now we have a big funky list on our screen! But now to make it more useful as no ITPro likes to keep typing in .NET (Well some of us do, but we’re more classified as half dev/half itpro hobbits)

So we can make this a nice simple advanced Function

function get-timezone
{
[cmdletbinding()]
param([string]$Name)
([system.timezoneinfo]::GetSystemTimeZones() | where { $_.ID –like "*$Name*” }) 
}

or possibly a Function to only pull up a matching one?

function get-timezonematch
{
[cmdletbinding()]
param([string]$Name)
if ([system.timezoneinfo]::GetSystemTimeZones() | where { $_.ID -eq $Name })
{ Return $TRUE }
else
{ Return $FALSE }
 
}

Now I can do something like THIS

GET-TIMEZONE | Format-table –autosize

or

GET-TIMEZONE *EAST*

or

GET-TIMEZONEMATCH “Eastern Standard Time”

Now we can take Pat’s original script and give it a slight improvement to pull from the Internal list from Windows.  If we have already defined the “GET-TimeZone” Advanced function and executed it first, we can do this Pat’s function.

function Set-TimeZone {
[CmdletBinding(SupportsShouldProcess = $True)]
param(
    [Parameter(ValueFromPipeline = $False, ValueFromPipelineByPropertyName = $True, Mandatory = $False)]
    [ValidateNotNullOrEmpty()]
    [string]$TimeZone = "Eastern Standard Time"
  )

If (GET-TIMEZONEMATCH $TimeZone) {  
  $process = New-Object System.Diagnostics.Process
  $process.StartInfo.WindowStyle = "Hidden"
  $process.StartInfo.FileName = "tzutil.exe"
  $process.StartInfo.Arguments = "/s `"$TimeZone`""
  $process.Start() | Out-Null }

ELSE { WRITE-ERROR “InvalidTimeZone” }

} # end function Set-TimeZone

Pretty cool what you can do with Powershell and .NET and STILL be classified as an ITPro.  Also Thanks to Pat Richard, Lync MVP Extraordinaire for writing this cool Powershell Script Smile

There is an excellent post on getting and setting the TimeZone done by Pat Richard using Powershell and TZUtil which I thought was absolutely cool.

The only thing I noticed was the Script had a defined list for the Time Zones.   Knowing much of this information is contained directly in Windows I was wondering if there was a way to pull the list in and use it as the master.

Within .NET there is System.TimeZoneInfo which has a nice simple method called (are you ready?) GetSystemTimeZones

So to leverage this method in Windows Powershell all we need to do it

[System.TimeZoneInfo]::GetSystemTimeZones()

Poof! now we have a big funky list on our screen! But now to make it more useful as no ITPro likes to keep typing in .NET (Well some of us do, but we’re more classified as half dev/half itpro hobbits)

So we can make this a nice simple advanced Function

function get-timezone
{
[cmdletbinding()]
param([string]$Name)
([system.timezoneinfo]::GetSystemTimeZones() | where { $_.ID –like "*$Name*” }) 
}

or possibly a Function to only pull up a matching one?

function get-timezonematch
{
[cmdletbinding()]
param([string]$Name)
if ([system.timezoneinfo]::GetSystemTimeZones() | where { $_.ID -eq $Name })
{ Return $TRUE }
else
{ Return $FALSE }
 
}

Now I can do something like THIS

GET-TIMEZONE | Format-table –autosize

or

GET-TIMEZONE *EAST*

or

GET-TIMEZONEMATCH “Eastern Standard Time”

Now we can take Pat’s original script and give it a slight improvement to pull from the Internal list from Windows.  If we have already defined the “GET-TimeZone” Advanced function and executed it first, we can do this Pat’s function.

function Set-TimeZone {
[CmdletBinding(SupportsShouldProcess = $True)]
param(
    [Parameter(ValueFromPipeline = $False, ValueFromPipelineByPropertyName = $True, Mandatory = $False)]
    [ValidateNotNullOrEmpty()]
    [string]$TimeZone = "Eastern Standard Time"
  )

If (GET-TIMEZONEMATCH $TimeZone) {  
  $process = New-Object System.Diagnostics.Process
  $process.StartInfo.WindowStyle = "Hidden"
  $process.StartInfo.FileName = "tzutil.exe"
  $process.StartInfo.Arguments = "/s `"$TimeZone`""
  $process.Start() | Out-Null }

ELSE { WRITE-ERROR “InvalidTimeZone” }

} # end function Set-TimeZone

Pretty cool what you can do with Powershell and .NET and STILL be classified as an ITPro.  Also Thanks to Pat Richard, Lync MVP Extraordinaire for writing this cool Powershell Script Smile

SET-RANT $TRUE

This is actually pretty easy if you’re going to deploy modules in Windows Module but it is CRITICAL to FOLLOW THE RULES.  I know some people either a) don’t follow them and are rebelling against Society as a whole or b) honestly don’t know them.  I’ll opt for b) because By and Large most Developers and Product Teams are pretty decent people. Smile

RULE 1

No exceptions or an Angry Gru will reach down from within Microsoft and force you to write “I will not do this” 1000 times in pure Binary using only an Abacus, a box of broken crayons (melted) on wet toilet paper.  Or perhaps I will cast a D20 to determine if a Yeti goes free.   Or a massive release of Tribbles.  We will look at this in BIG Bold Letters so NOBODY forgets

DO NOT PUT ANY MODULES IN “%SYSTEMROOT%\system32\WindowsPowerShell\v1.0\Modules”

This area is verboten.  It belongs to Windows O/S only.  If you put things here there is a GOOD chance it will get wiped out some time or possibly you will hear a big booming voice echoing throughout the skies.  Or Sean The Energized Tech might write a horrible song about you doing it.

Ok …. just don’t do it.   This will avoid a certain Tribble/Yeti invasion bursting forth.

Just make your own folder under Maybe %ProgramFiles% or possibly even under %PUBLIC% and we’ll all be a lot happier

RULE 2

DO update the Modules Path variable with the location of your new module.   There is an environment variable called %PSModulePath% – It is JUST like %PATH% to add information to.   If you add the Path to your new module to THIS variable people will be able to find it by doing GET-MODULE.  So again let’s remember this in BIG BOLD LETTERS.

UPDATE %PSMODULEPATH% with the Path of your Module…. *P*L*E*A*S*E*

If you do NOT do this you will not only make life more difficult for Systems Administrators using Windows Powershell, you will also make many Many MANY Windows Powershell MVP’s VERY ANGRY (And we’re usually a pretty happy bunch)

So if you have a product and you’re creating a Windows Powershell module, please follow these two small steps to make our lives easier and your modules so that your Cmdlets can be AutoDiscovered in Powershell Version 3.

So if you have a Product with a module and you are not following this… put in a freaking hotfix or something to just do this.   It makes your stuff so much easier to work with…. and lessens the chance of me writing some horrid parody music about it NOT being there.

*Nuff said* I shall jump off my Soapbox now

SET-RANT $FALSE