PowerShell – using Proxy Cmdlets in combination with object events

PowerShell v2 introduced a new feature called Proxy Cmdlets. An explanation of this feature is available in this blog-post on the Windows PowerShell team s blog.

Using the Windows PowerShell Customer Connection on Microsoft Connect you can suggest new features (and submit bugs), and your suggestion may or may not be added to the next version. Another option is to add the functionality yourself by leveraging Proxy Cmdlets. Essentially this makes it possible to add or remove functionality to PowerShell cmdlets.

Two examples on how to leverage this functionality:

  • Kirk Munro shows how to add more functionality to Import-Csv.
  • Dmitry Sotnikov shows how to add more functionality to ConvertTo-HTML.

Register-ObjectEvent is another cmdlet introduced in PowerShell v2, which I want to show how you can leverage in combination with Proxy Cmdlets.

The best way to explain how this can be leveraged is to show an example:

Were using the Start-Job cmdlet which is a part of the Background Jobs feature in PowerShell to start a job that we expect will take some time to complete.

001
Start-Job -ScriptBlock {Start-Sleep 600}

Here were using Start-Sleep to simulate a long-running task. To wait for the job to complete we could use the Wait-Job cmdlet, however, we want to perform a custom action when the job completes:

001
002
003
004
005
006
$job = Start-Job -ScriptBlock {Start-Sleep 600} 

Register-ObjectEvent -InputObject $job -EventName StateChanged
-SourceIdentifier JobEndAlert -Action {Send-MailMessage -To
user@domain.com -From ps@domain.com -Subject "Job Completed"

-Body “Job State Changed” -Body “Job $($Sender.Id) $($Sender.JobStateInfo)”}

 

In this example an e-mail will be sent when the job completes.

Wouldnt it be nice if the Start-Job cmdlet contained an OnCompletionAction parameter where we could specify a custom action to run when the job is complete? In example like this:

001
002
003
004
Start-Job -ScriptBlock {start-sleep 3} -OnCompletionAction {
Send-MailMessage -To
user@domain.com -From ps@domain.com -Subject “Job Completed” `
-Body “Job State Changed” -Body “Job $($Sender.Id) $($Sender.JobStateInfo)”}

The above example would actually work when using a proxy cmdlet that leverages Register-ObjectEvent. An example on how to do this is available here. You could paste this code directly in your PowerShell session, save it to a ps1-file and dotsource it or save it to your PowerShell-profile. A complete walkthrough of the example Cmdlet Proxy are available in this article on the Microsoft TechNet Wiki.

I would like to thank Kirk Munro and Shay Levy for assistance in creating this example.