Running Batch Script on remote Server via PowerShe

2019-01-20 16:00发布

问题:

I need to connect to some remote servers from a client (same domain as the servers) once connected, I need to run a batch file:

I've done so with this code:

$Username = 'USER'
$Password = 'PASSWORD'
$pass = ConvertTo-SecureString -AsPlainText $Password -Force
$Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass

try {
    Invoke-Command -ComputerName "SERVER1" -Credential $Cred -ScriptBlock -ErrorAction Stop {
        Start-Process "C:\Users\nithi.sundar\Desktop\Test.bat"
    }
} catch {
    Write-Host "error"
}

This script does not give any errors, but it doesn't seem to be executing the batch script.

any input on this would be greatly appreciated.

回答1:

Try replacing

invoke-command -computername "SERVER1" -credential $Cred -ScriptBlock -ErrorAction stop { Start-Process "C:\Users\nithi.sundar\Desktop\Test.bat" }

with

Invoke-Command -ComputerName "Server1" -credential $cred -ErrorAction Stop -ScriptBlock {Invoke-Expression -Command:"cmd.exe /c 'C:\Users\nithi.sund
ar\Desktop\Test.bat'"}


回答2:

It's not possible that the code you posted ran without errors, because you messed up the order of the argument to Invoke-Command. This:

Invoke-Command ... -ScriptBlock -ErrorAction Stop { ... }

should actually look like this:

Invoke-Command ... -ErrorAction Stop -ScriptBlock { ... }

Also, DO NOT use Invoke-Expression for this. It's practically always the wrong tool for whatever you need to accomplish. You also don't need Start-Process since PowerShell can run batch scripts directly:

Invoke-Command -ComputerName "SERVER1" -ScriptBlock {
    C:\Users\nithi.sundar\Desktop\Test.bat
} -Credential $Cred -ErrorAction Stop

If the command is a string rather than a bare word you need to use the call operator, though:

Invoke-Command -ComputerName "SERVER1" -ScriptBlock {
    & "C:\Users\nithi.sundar\Desktop\Test.bat"
} -Credential $Cred -ErrorAction Stop

You could also invoke the batch file with cmd.exe:

Invoke-Command -ComputerName "SERVER1" -ScriptBlock {
    cmd /c "C:\Users\nithi.sundar\Desktop\Test.bat"
} -Credential $Cred -ErrorAction Stop

If for some reason you must use Start-Process you should add the parameters -NoNewWindow and -Wait.

Invoke-Command -ComputerName "SERVER1" -ScriptBlock {
    Start-Process 'C:\Users\nithi.sundar\Desktop\Test.bat' -NoNewWindow -Wait
} -Credential $Cred -ErrorAction Stop

By default Start-Process runs the invoked process asynchronously (i.e. the call returns immediately) and in a separate window. That is most likely the reason why your code didn't work as intended.