Reputation: 1
I have problems to execute a batch file on a remote server via PowerShell. The user can choose several opinions in a pop-up window like Servername, starting or killing process and Servicename. The chosen items will be saved in variables.
If all items are chosen, I want to merge the strings to one string and execute the batch script which is named like this result string. I try to do it as described in this post, but the batch script won't be executed.
Example:
[String]$scriptpath="C:\tmp\"
[String]$Servername = "xx040"
[String]$actionprefix = "kill_process"
[String]$action = $($actionprefix) + "-"
[String]$Servicename = "service1"
[String]$ServiceFullname = $($action) + $($Servicename) + ".bat"
$batchPath = $("`"$scriptpath + $ServiceFullname `"")
Invoke-Command -ComputerName $Servername -ScriptBlock {
cmd.exe /c "`"$batchPath`""
}
Upvotes: 0
Views: 2149
Reputation: 200483
Simply use the call operator (&
) and put the variable with the path to your batch file in double quotes.
& "$batchPath"
You also need to make the variable $batchPath
known inside your scriptblock via the using:
scope modifier, otherwise $batchPath
inside the scriptblock would be a different (empty) variable than $batchPath
outside the scriptblock.
Invoke-Command -Computer $Servername -ScriptBlock {
& "$using:batchPath"
}
An alternative would be to pass the variable into the scriptblock as an argument:
Invoke-Command -Computer $Servername -ScriptBlock {
Param($BatchPath)
& "$BatchPath"
} -ArgumentList $batchPath
Use Join-Path
for building paths, so you don't need to deal with leading/trailing path separators yourself. Also, PowerShell expands variables in double-quoted strings, allowing you to avoid excess concatenations. In single-quoted strings variables are not expanded, so I normally use double quotes for strings with, and single quotes for strings without variables in them.
Modified code:
$Servername = 'xx040'
$scriptpath = 'C:\tmp'
$actionprefix = 'kill_process'
$Servicename = 'service1'
$batchPath = Join-Path $scriptpath "$actionprefix-$Servicename.bat"
Invoke-Command -ComputerName $Servername -ScriptBlock {
& "$using:batchPath"
}
Upvotes: 1
Reputation: 500
In your code you are not passing in anything to your invoke-command, so when it's running remotely it doesn't know what $batchPath
is. Take a look at this SO answer How do I pass named parameters with Invoke-Command?
Invoke-Command -ComputerName $Servername -ScriptBlock {param($batchPath) cmd.exe /c "`"$batchPath`"" } -ArgumentList $batchPath
Is how you would want to make your call.
Upvotes: 1
Reputation: 10973
One alternative to avoid paths with spaces in them is to use the 8.3 short notation.
Open a command line in Windows and use the /x
parameter of dir. To find the shortname of the program files dir you would use dir C:\prog* /x
. This is the result:
21.10.2015 14:46 <DIR> PROGRA~1 Program Files
21.10.2015 12:47 <DIR> PROGRA~2 Program Files (x86)
04.09.2014 18:25 <DIR> PR6AFF~1 Programs16Bit
If you were to address C:\Program Files
you could write C:\PROGRA~1
too.
Upvotes: 0