Proxy Cmdlets is a new feature introduced in Windows PowerShell v2. You can read more about this feature in this article on the Microsoft PowerShell Team blog. This article will show how we can combine this feature with another feature called object events. Using the Register-ObjectEvent cmdlet we can subscribe to events generated by a Microsoft .Net Framework object. In this article we`re using a PowerShell job-object as an example.
To accomplish this a Cmdlet Proxy for Start-Job is created, available on the Microsoft Script Center Gallery. The following is a description on how this Cmdlet Proxy are built:
1) A desription of the Cmdlet Proxy are defined at the top using block comments: <# #>. 2) On line 13 we define a new function with the same name as the original cmdlet Start-Job. The function code are generated using the metadata exposed by PowerShell:
[Management.Automation.ProxyCommand]::Create((New-Object Management.Automation.CommandMetaData (Get-Command Start-Job)))
The output from the above command are inserted to the Start-Job function.
3) In the parameter-section we define the OnCompletionAction parameter (line 48-49): [System.Management.Automation.ScriptBlock] ${OnCompletionAction}, The first line defines the data type the parameter accepts. A script block type is chosen to let the user be able to run as much PowerShell code as needed. A script block is defined by using braces, in example {Get-Service}. The second line defines the name of the parameter.
4) The next section customized is between line 70-89:
#region Initialize helper variable to create command $scriptCmdPipeline = '' #endregion
# add new parameter handling #region Process and remove the OnCompletionAction parameter if it is present if ($OnCompletionAction) { $PSBoundParameters.Remove('OnCompletionAction') | Out-Null $scriptCmdPipeline += " | foreach-object{ `$job = Register-ObjectEvent -InputObject `$_ -EventName StateChanged -SourceIdentifier JobEndAlert -Action { if(`$sender.State -eq 'Completed') { `& { $OnCompletionAction } Unregister-Event -SourceIdentifier JobEndAlert -Force } } }" }
First we define a helper variable to create the command to be run.
Due to the if-statement the following section is only run if the OnCompletionAction parameter is provided. Next the OnCompletionAction are remove, this is necessary if we are replacing builtin parameters to the Start-Job cmdlet. Next, we add custom code to the helper variable. This is where we define the actual code for the nCompletionParameter. Key points:
Using the same technique it`s also possible to add a OnFailedAction if you want some custom action to be run if the job fails. Jan Egil Ring has written an article describing a practical usage scenario for the new Start-Job Cmdlet Proxy.