Trying to create a powershell script to install a program on a remote computer on the same network

128 Views Asked by At

I'm very new to Powershell and I am trying to create a script whereby I copy a folder from one computer to another computer on the same network, and then run a batch file as an admin on the remote computer when a regular user is logged in.

Here is what I have so, issue is, I can't get Powershell to run the batch file with admin rights.

The reason I want to run the batch file is the exe in the batch file needs parameters to run, and Powershell doesn't recognize them.

$Session = New-PSSession -ComputerName "computer Name" -Credential "Admin creds"
Copy-Item -Path "\Local computer folder\*" -Destination "\\computer Name\C$\Temp" -Recurse -Force
Invoke-Command -ComputerName "computer" -Credential "Admin creds" -ScriptBlock {  
  Start-Process c:\temp\Install.bat -wait  
}
Remove-Item –path \\computer Name\C$\Temp –recurse
Remove-PSSession $session  

I have tried several different commands, with no luck.

1

There are 1 best solutions below

0
mklement0 On

tl;dr, based on your own feedback:

Replacing { Start-Process c:\temp\Install.bat -wait } as the -ScriptBlock argument with:

{ c:\temp\Install.bat -wait } 

fixes your problem; it ensures:

  • synchronous (blocking) execution of the batch file...

    • As an aside: While you're always free to use &, the call operator in direct invocation (& c:\temp\Install.bat -wait), it is only required if the executable path is quoted (usually due to containing spaces) and/or is expressed in terms of variables.
  • ... with -wait being passed as an argument to c:\temp\Install.bat.


Background information:

Your problem boiled down to this:

Start-Process c:\temp\Install.bat -wait

You expected -wait to be a pass-through argument, i.e. to be passed to c:\temp\Install.bat

However, -wait was interpreted by Start-Process as its -Wait switch, so that it synchronously ran your batch file, but without passing it any arguments.

The immediate fix would have been:

  • Quote your pass-through argument(s), which is a must if it looks like a parameter name.

  • Also pass Start-Process' -Wait switch, which is a must in a remote call with Invoke-Command that creates an ad hoc remote session due to using the -ComputerName parameter:

    • The session is closed when Invoke-Command returns, and if a remotely and asynchronously Start-Process-launched process hasn't completed yet at that point, it will be killed.
Invoke-Command -ComputerName "computer Name" -Credential "Admin creds" -ScriptBlock {  
  # Note the use of -Wait for Start-Process and '-wait' as the pass-through argument.
  Start-Process -Wait c:\temp\Install.bat '-wait' 
}

However, except in special cases there's no good reason to use Start-Process to synchronously invoke console applications (such as batch files), so the direct invocation solution at the top is preferable:

  • Direct invocation, in addition to being invariably synchronous with console applications, also allows you to capture their output directly and to later query their exit code via automatic $LASTEXITCODE variable.

  • GitHub docs issue #6239 provides guidance on when use of Start-Process is and isn't appropriate.


As for your concern about running with elevation (administrative privileges):

  • If the calling user is an administrator, the remote command invariably runs with elevation, and by default it is only administrators that are permitted to perform PowerShell remoting operations.

  • The remote command will run with the caller's user identity (which by default is the user identity of the calling session, but can be overridden with the -Credential parameter), which is unrelated to whether or which user happens to be logged on at the target machine.

    • In other words: you cannot use a remoting call to perform an installation for a different user.