0

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`""
}
0

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

You're right! Now the batch script is running successfully. I'd found a mistake in my code: Changed $batchPath = $(""$scriptpath + $ServiceFullname "") to $batchPath = $(""$scriptpath\$ServiceFullname "")
1

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"
}

Comments

0

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.

2 Comments

I don't think it's a good idea as creating 8dot3 NTFS filenames could be disabled (per volume or even per system). See fsutil.exe behavior set Disable8dot3 /? and Disable short file name creation. Some admins do this because they believe that disabling 8.3 file name creation increases file performance under Windows, so for performance reasons they disable it on their file servers.
@JosefZ I would say "it depends" ;-) We can only hope that never one of those "bored administrators" sets DisableCMD=1 (see technet.microsoft.com/en-us/library/cc787344(v=ws.10).aspx).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.