#PowerShell: Splatting a Local Hash Table in a Remote Session
I'm sure that most people who use PowerShell on a regular basis are familiar with the Using
variable scope modifier which allows for the use of local variables in a remote session. This
functionality was introduced with PowerShell version 3:
1$MyVar = 'Bits', 'W32time'
2
3Invoke-Command -ComputerName DC01 {
4 Get-Service -Name $Using:MyVar
5}
A fairly simple concept, right? But wait a minute, did you know that you can also define a local hash table to be used with splatting in a remote session using this same concept?
1$MyParams = @{
2 ClassName = 'Win32_Service'
3 Filter = "Name = 'bits' or Name = 'W32time'"
4}
5
6Invoke-Command -ComputerName DC01 {
7 Get-CimInstance @Using:MyParams
8}
The previous example is a simple one, but this concept comes in handy when writing an advanced
function where you've wrapped your function around PowerShell remoting like in the following example
where I use a hash table from the local session to control the PassThru
, WhatIf
, and Confirm
parameters that are taking place in the remote session:
1#Requires -Version 3.0
2function Start-MrAutoStoppedService {
3
4<#
5.SYNOPSIS
6 Starts services that are set to start automatically, are not currently running,
7 excluding the services that are set to delayed start.
8
9.DESCRIPTION
10 Start-MrAutoStoppedService is a function that starts services on the specified
11 remote computer(s) that are set to start automatically, are not currently running,
12 and it excludes the services that are set to start automatically with a delayed
13 startup. This function requires PowerShell version 3 or higher on the machine it
14 is being run from, PowerShell version 2 or higher on the remote machine that it is
15 being run against, and PowerShell remoting to be enabled on the remote computer.
16
17.PARAMETER ComputerName
18 The remote computer(s) to check the status and start the services on.
19
20.PARAMETER Credential
21 Specifies a user account that has permission to perform this action. The default
22 is the current user.
23
24.PARAMETER PassThru
25 Returns an object representing the service. By default, this function does not
26 generate any output.
27
28.EXAMPLE
29 Start-MrAutoStoppedService -ComputerName 'Server1', 'Server2'
30
31.EXAMPLE
32 Start-MrAutoStoppedService -ComputerName 'Server1', 'Server2' -PassThru
33
34.EXAMPLE
35 'Server1', 'Server2' | Start-MrAutoStoppedService
36
37.EXAMPLE
38 Start-MrAutoStoppedService -ComputerName 'Server1', 'Server2' -Credential (Get-Credential)
39
40.INPUTS
41 String
42
43.OUTPUTS
44 None or ServiceController
45
46.NOTES
47 Author: Mike F Robbins
48 Website: http://mikefrobbins.com
49 Twitter: @mikefrobbins
50#>
51
52 [CmdletBinding(SupportsShouldProcess)]
53 param (
54 [Parameter(Mandatory,
55 ValueFromPipeline,
56 ValueFromPipelineByPropertyName)]
57 [string[]]$ComputerName,
58
59 [System.Management.Automation.Credential()]$Credential = [System.Management.Automation.PSCredential]::Empty,
60
61 [switch]$PassThru
62 )
63
64 BEGIN {
65 $Params = @{}
66 $RemoteParams = @{}
67
68 switch ($PSBoundParameters) {
69 {$_.keys -contains 'Credential'} {$Params.Credential = $Credential}
70 {$_.keys -contains 'PassThru'} {$RemoteParams.PassThru = $true}
71 {$_.keys -contains 'Confirm'} {$RemoteParams.Confirm = $true}
72 {$_.keys -contains 'WhatIf'} {$RemoteParams.WhatIf = $true}
73 }
74
75 }
76
77 PROCESS {
78 $Params.ComputerName = $ComputerName
79
80 Invoke-Command @Params {
81 $Services = Get-WmiObject -Class Win32_Service -Filter {
82 State != 'Running' and StartMode = 'Auto'
83 }
84
85 foreach ($Service in $Services.Name) {
86 Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\$Service" |
87 Where-Object {$_.Start -eq 2 -and $_.DelayedAutoStart -ne 1} |
88 Select-Object -Property @{label='ServiceName';expression={$_.PSChildName}} |
89 Start-Service @Using:RemoteParams
90 }
91 }
92 }
93}
The Start-MrAutoStoppedService
function shown in the previous code example can be downloaded from
my PowerShell repository on GitHub.
µ