Five PowerShell 3.0 Tips & Tricks

PowerShell 3.0 includes a wealth of new functionality. In fact, it may be a bit overwhelming to know where to begin. So allow me to share five of my favorite PowerShell 3.0 tips and tricks. These are items that I think can make you more productive or are just plain fun to use. They may also finally convince you to jump to the latest version if you’ve been sitting on the fence.

1. Default Parameter Values

If you find yourself always using the same parameter value for a given cmdlet, you can now set it as a default, reducing the amount of typing you need at the console. For example, you might run a command like this because you always want to set Format-Wide to 3 columns.

PS C:\> get-process | format-wide –column 3

Or perhaps you always like to use –Autosize with Format-Table.

PS C:\> get-service m* | format-table Name,Displayname,Status -AutoSize

Now you can store these default values in a new variable called PSDefaultParameterValues. The variable doesn’t exist by default but PowerShell will look for it. To use, create a hashtable where the key is the name uses the form “<cmdlet name>:<parameter>”.

PS C:\> $PSDefaultParameterValues = @{'Format-Wide:Column'=3 ; 'Format-Table:Autosize'=$True}
PS C:\> $PSDefaultParameterValues
Name                           Value
----                           -----
Format-Wide:Column             3
Format-Table:Autosize          True

Now you can run the commands again and they will automatically use these values.

PS C:\> get-process | format-wide
PS C:\> get-service m* | format-table Name,Displayname,Status

If you want to use a different value, simply specify the parameter.

PS C:\> get-service | format-wide –col 4

You can also add and remove values to an existing variable.

PS C:\> $PSDefaultParameterValues.Remove('Format-Wide:Column')
PS C:\> $PSDefaultParameterValues.add("Get-Eventlog:Logname","System")

The variable is per session so use your PowerShell profile to configure it.

2. Disconnected Sessions

PowerShell 3.0 remoting has been enhanced. We can now establish a remote session, disconnect from it, and reconnect later, even from a different computer. One way to use this feature is with Invoke-Command. You can kick off a long running command on a remote computer and tell PowerShell to use a disconnected session.

PS C:\> invoke-command {get-eventlog system} -computername Server01 -InDisconnectedSession

Later, you can receive the results of the session.

PS C:\> $data = Receive-PSSession -ComputerName Server01

I recommend saving results to a variable because once you receive them they are cleared from the session. The remote computer must be running PowerShell 3.0 with remoting enabled.

3. Download Web Data

PowerShell 3.0 ships with some new cmdlets for working with web data and services. Look how easy it is to get an RSS feed in PowerShell:

PS C:\> $url = "http://mcpmag.com/rss-feeds/prof-powershell.aspx"
PS C:\> Invoke-RestMethod $url

In the past we had to mess with .NET classes and some gnarly parsing. Now, PowerShell does it all for us as you can see below.
PowerShell 3.0 tips
But because this is an object we can work with. Here’s a variation that turns the pubDate into a DateTime value.

PS C:\> Invoke-RestMethod $url | Select Title,Description,@{Name="Date";Expression={$_.PubDate -as [datetime]}}

PowerShell 3.0 tips

4. Pass Objects through Out-GridView

One of my favorite PowerShell 3.0 tricks is to use Out-Gridview as an object picker. We can now tell Out-Gridview to pass objects back to the pipeline. I can run a command like this:

PS C:\> Get-Process | Out-GridView -PassThru -Title "Select a process"

Which sends data to Out-Gridview
PowerShell 3.0 tips
I can select one or more objects and press OK, which will pass the object back to the pipeline.
PowerShell 3.0 tips
Because the object is written to the pipeline, I can pipe the results to other cmdlets.

PS C:\scripts> get-service | where {$_.status -eq "Stopped"} | out-gridview -Title "Pick a service to start" -PassThru | start-service –passthru

This will get all stopped services, display them in Out-Gridview. I can select the ones I want and start them.

5. WMI Objects with Formatted DateTime Values

My last item is really an example of something new in PowerShell 3.0 that, while a minor change, is something that I find tremendously useful. When using Get-WmiObject, any object that had a datetime value was formatted with a decidedly unfriendly format.

PS C:\scripts> $OS = Get-WmiObject win32_operatingsystem -comp NOVO8
PS C:\scripts> $OS.LastbootUptime
20130221101226.498098-300

We had to convert this value.

PS C:\scripts> (Get-Date) - ($OS.ConvertToDateTime($OS.LastBootUptime)) -as [string]
1.01:38:20.1156751

We ended up with some complicated-looking code. But PowerShell 3.0 introduces us to the world of CIM cmdlets. These cmdlets work with WMI information but use PowerShell remoting. This is the future of systems management in PowerShell. One benefit is that we no longer need to reformat datetime values.

PS C:\scripts> Get-CimInstance Win32_OperatingSystem -comp NOVO8 |
>> Select LocalDateTime,InstallDate
>>
LocalDateTime                                     InstallDate
-------------                                     -----------
2/22/2013 11:54:34 AM                             9/7/2012 1:17:33 PM

Now, it is much easier to write an expression like this:

PS C:\scripts> Get-CimInstance Win32_OperatingSystem -comp NOVO8 |
>> Select PSComputername,LocalDateTime,InstallDate, LastBootUpTime,
>> @{Name="Uptime";Expression={(Get-Date) - $_.LastBootUpTime}}
>>
PSComputerName : NOVO8
LocalDateTime  : 2/22/2013 11:55:30 AM
InstallDate    : 9/7/2012 1:17:33 PM
LastBootUpTime : 2/21/2013 10:12:26 AM
Uptime         : 1.01:42:00.6587855

As you might expect there is much more to everything I’ve shown you. If you have other PowerShell 3.0 tips to offer, please add them in the comments section.