I need to run a ps1 script on a remote computer. The script will be passed a single parameter representing a file name. I have tried many, many different combinations and approaches to passing the parameters to the script block, but I am always getting one error or another when trying to support spaces in the script name and/or file name.
Note: The end result will be running a script on a REMOTE computer using the -ComputerName
parameter to Invoke-Command, but for simplicity and testing all the examples run locally.
Given the sample "remote" script
#processFile.ps1
$args[0] # Just outputs the first parameter passed
The following works when there are no spaces in the name
$cmd = ".\processFile.ps1"
$fn = "someFile.csv"
$sb = [ScriptBlock]::Create("$cmd $fn")
Invoke-Command -ScriptBlock $sb
# Outputs the correct
someFile.csv
However, the following does not work
$cmd = ".\processFile.ps1"
$fn = "some File.csv"
$sb = [ScriptBlock]::Create("$cmd $fn")
Invoke-Command -ScriptBlock $sb
# Outputs the incorrect
some
Obviously, the file name parameter needs to be escaped and passed as "some File.csv". And this can be done with the following:
$cmd = ".\processFile.ps1"
$fn = "some File.csv"
$sb = [ScriptBlock]::Create("$cmd `"$fn`"") # Notice the escape $fn parameter
Invoke-Command -ScriptBlock $sb
# Outputs the correct
some File.csv
BUT, when I try to extended this space support to the script name, everything falls apart. The following fails
$cmd = ".\processFile.ps1"
$fn = "some File.csv"
$sb = [ScriptBlock]::Create("`"$cmd`" `"$fn`"") # Notice the attempt to escape both parameters
with the following exception
Exception calling "Create" with "1" argument(s): "Unexpected token 'some File.csv' in expression or statement."
Everything I have tried, and there have been many, many different approaches, have resulted in something similar. I just cannot seem to get both parameters to be escaped. (Actually, the problem is more than I cannot escape the first parameter. Some of my attempts have included nested quotes, single quotes, [ScriptBlock]::Create, { }, $executionContext, etc.
Try this:
$sb = [ScriptBlock]::Create(@"
&'$cmd' '$fn'
"@)
For anyone puzzling over the accepted answer by mjolinor, you need to add:
. $sb
For it to actually run the script block.
Additionally, a simpler syntax which seems more readable to me is:
$cmd = @"
&'$cmd' '$fn'
"@
Invoke-Expression $cmd
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