How is it possible to use the parameters collected in a hash table for use with ArgumentList
on Invoke-Command
?
$CopyParams = @{
Source = 'E:\DEPARTMENTS\CBR\SHARE\Target'
Destination = 'E:\DEPARTMENTS\CBR\SHARE\Target 2'
Structure = 'yyyy-MM-dd'
}
Invoke-Command -Credential $Cred -ComputerName 'SERVER' -ScriptBlock ${Function:Copy-FilesHC} -ArgumentList @CopyParams
Whatever I try, it's always complaining about the 'Source':
Cannot validate argument on parameter 'Source'. The "Test-Path $_" validation script for the argument with
value "System.Collections.Hashtable" did not return true. Determine why the validation script failed
This blog talks about a similar problem, but I can't get it to work.
The same is true for a simple Copy-Item
within Invoke-Command
, example:
Invoke-Command -Credential $Cred -ComputerName 'SERVER' -ScriptBlock {Copy-Item} -ArgumentList @CopyParams
Invoke-Command : Missing an argument for parameter 'ArgumentList'. Specify a parameter of type 'System.Obj
ect[]' and try again.
At line:11 char:89
+ ... ck {Copy-Item} -ArgumentList @CopyParams
Thank you for your help.
Here is the basic syntax for using splatting. You use the regular PowerShell command ( <CommandName> ) followed by the variable name indicating the splatted values ( @<SplattedValues> ). Not all parameters need to be included in the splat. You can pass other parameters ( <parameters> ) before or after the splat.
The Invoke-Command cmdlet runs commands on a local or remote computer and returns all output from the commands, including errors. Using a single Invoke-Command command, you can run commands on multiple computers. To run a single command on a remote computer, use the ComputerName parameter.
-ArgumentListSpecifies parameters or parameter values to use when this cmdlet starts the process. Arguments can be accepted as a single string with the arguments separated by spaces, or as an array of strings separated by commas.
To run a script on one or many remote computers, use the FilePath parameter of the Invoke-Command cmdlet. The script must be on or accessible to your local computer. The results are returned to your local computer. For example, the following command runs the DiskCollect.
One-liner, to convert a remote script to accept named parameters from a hash.
Given a scriptblock which you wish to call like this:
$Options = @{
Parameter1 = "foo"
Parameter2 = "bar"
}
Invoke-Command -ComputerName REMOTESERVER -ArgumentList $Options -ScriptBlock {
param(
$Parameter1,
$Parameter2
)
#Script goes here, this is just a sample
"ComputerName: $ENV:COMPUTERNAME"
"Parameter1: $Parameter1"
"Parameter2: $Parameter2"
}
You can convert it like so
Invoke-Command -Computername REMOTESERVER -ArgumentList $Options -ScriptBlock {param($Options)&{
param(
$Parameter1,
$Parameter2
)
#Script goes here, this is just a sample
"ComputerName: $ENV:COMPUTERNAME"
"Parameter1: $Parameter1"
"Parameter2: $Parameter2"
} @Options}
What's going on? Essentially we've wrapped the original script block like so:
{param($Options)& <# Original script block (including {} braces)#> @options }
This makes the original script block an anonymous function, and creates the outer script block which has a parameter $Options
, which does nothing but call the inner script block, passing @options
to splat the hash.
Here's one way to approach passing named parameters:
function Copy-FilesHC
{
param ($Source,$Destination,$Structure)
"Source is $Source"
"Desintation is $Destination"
"Structure is $Structure"
}
$CopyParams = @{
Source = 'E:\DEPARTMENTS\CBR\SHARE\Target'
Destination = "'E:\DEPARTMENTS\CBR\SHARE\Target 2'" #Nested quotes required due to embedded space in value.
Structure = 'yyyy-MM-dd'
}
$SB = [scriptblock]::Create(".{${Function:Copy-FilesHC}} $(&{$args}@CopyParams)")
Invoke-Command -Credential $Cred -ComputerName 'SERVER' -ScriptBlock $SB
Basically, you create a new script block from your invoked script, with the parameters splatted to that from the hash table. Everything is already in the script block with the values expanded, so there's no argument list to pass.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With