Power shell Invoke remote script is not working - powershell

I am trying to invoke a remote bat file from my local machine that should start and run the bat in a remote machine terminal. My script is able to connect and show me the output. However, it is invoking the remote bat file but waiting on my screen with bat file output. and my idea is the bat file should invoke and running in the remote machine rather than showing the output on my terminal local terminal. What should be the way here?
loop{
Invoke-Command -ComputerName $computer -credential $cred -ErrorAction Stop -ScriptBlock { Invoke-Expression -Command:"cmd.exe /c 'C:\apacheserver.bat'" }
}

From what I understand you want the .bat file to not show you the result. If so, you should do it with the Out-Null or by redirecting STDOUT and STDERR to NULL.
IE: Invoke-Expression -Command:"cmd.exe /c 'C:\apacheserver.bat'" | Out-Null

If I'm understanding correctly, you want to suppress the output from the .bat file inside your local console? If so, redirecting to some form of $null is the way to go. You also shouldn't need Invoke-Expression as Invoke-Command can run the file directly:
Invoke-Command -ComputerName $computer -Credential $cred -ErrorAction Stop -Scriptblock {
cmd.exe /c 'C:\apacheserver.bat' | Out-Null
}
You could also use > $null instead of Out-Null if you prefer.
If you want to redirect the output of the Invoke-Command call to the remote console instead, that kind of defeats the purpose of the cmdlet. You could try redirecting the console output to a file on the remote computer if you want a local record:
$remoteFile = '\\server\C$\Path\To\Output.txt'
Invoke-Command -ComputerName $computer -Credential $cred -ErrorAction Stop -Scriptblock {
cmd.exe /c 'C:\apacheserver.bat' > $remoteFile
}

If I understand you, you want to run the script in the background and not wait for it:
Invoke-Command $computer -Credential $cred { start-process C:\apacheserver.bat }

Related

Invoke-Command executes on remote machine without having an effect

I'm trying to run a command on a VM using Invoke-Command. The command should stop a program that processes jobs after it finishes its current job. It works if I run it in the terminal using RDC.
& 'C:\Program Files\Autodesk\Vault Client 2021\Explorer\JobProcessor.exe' /stop
But if I run it from a different machine using Invoke-Command nothing seems to happen.
$session = New-PSSession -ComputerName 'hostname' -Credential (Get-Credential)
Invoke-Command -Session $session -ScriptBlock {
& 'C:\Program Files\Autodesk\Vault Client 2021\Explorer\JobProcessor.exe' /stop
}
However Process Monitor shows the command come in for both cases, but the program is still running.
I have also tried using Start-Process with the same result, i.e. it works in the terminal on the VM but not using Invoke-Command.
Start-Process -FilePath 'C:\Program Files\Autodesk\Vault Client 2021\Explorer\JobProcessor.exe' -ArgumentList '/stop'
I've been stuck for many days and I've exhausted my googlable knowledge for this problem.
Are you sure that file exists on the remote computer?
For simplicity, I rewrote your command to a known executable that is always there in Windows and returns unique info for any given computer.
C:\> & 'C:\Windows\system32\HOSTNAME.EXE'
server1
C:\> icm {& 'C:\Windows\system32\HOSTNAME.EXE'}
server1
C:\> icm {& 'C:\Windows\system32\HOSTNAME.EXE'} -ComputerName server2
server2
Here's your script with some error handling.
$session = New-PSSession -ComputerName 'hostname' -Credential (Get-Credential)
Invoke-Command -Session $session -ScriptBlock {
$exe = 'C:\Program Files\Autodesk\Vault Client 2021\Explorer\JobProcessor.exe'
$ok = Test-Path $exe
if ($ok) {& $exe /stop} else {
Write-Warning "EXE not present on $($env:COMPUTERNAME)!"
}
}
Learn how to add error handling and you'll be well on your way to solving your problems faster and getting more stuff done.

How to make powershell wait for a batch file to complete the execution of all comand on remote-server

$storesess = New-PSSession -ComputerName marshy -Credential marshy001
Enter-PSSession -Session $storesess
Invoke-Command -ScriptBlock {start-process C:\Users\marshmellow\Documents\Some\xyz.bat }
Exit-PSSession
Above is the script which calls a bat file saved on remote server C:\Users\marshmellow\Documents\Some\xyz.bat
The bat file has two commands one which sets the working directory using "pushd" and another which stops a application process. The second command takes a couple of minutes to complete. I have found that the Start-Process doesn't wait for the second command to complete successfully, it just fires the command and closes the process.
Is there any way to make the Start-Process wait for the command to get completed successfully as I have already tried using -Wait which doesn't work.
If there's a way to even open a cmd session on the remote server and pass few commands in it saved in variables and that output is relayed to my PowerShell script even that is fine. can anyone please help?
Using cmd.exe might work?
Invoke-Command -ScriptBlock {
cmd /k "C:\Users\marshmellow\Documents\Some\xyz.bat"
} -ErrorAction Stop
If not, you could probably Start-Process -Wait on cmd.exe, then supply the batch commands as an -ArgumentList
What do you get if you try this?
Invoke-Command -FilePath $PathToBatchFile
You do not need the Invoke-Command cmdlet. Just use Start-Process with the -Wait parameter and pass the correct parameters to cmd:
$storesess = New-PSSession -ComputerName marshy -Credential marshy001
Enter-PSSession -Session $storesess
Start-Process cmd -ArgumentList "/C C:\Users\marshmellow\Documents\Some\xyz.bat" -Wait
Exit-PSSession

How do I display the output of a remote exe locally when using Invoke-Command in Powershell?

I have the following script block:
$scriptBlock = {Start-Process ping.exe -ArgumentList localhost -Wait -NoNewWindow -PassThru}
Note: I am using a process as I want to be able to set the working directory the exe is executed in.
If I invoke it locally like this:
Invoke-Command -ScriptBlock $scriptBlock
I get the full ping output displayed. But when I invoke it remotely like this:
Invoke-Command -ComputerName RemoteComputerName -ScriptBlock $scriptBlock
I don't see any of the ping output. How can I get the remote output to display locally?
Drop the Start-Process and invoke the command directly:
$scriptBlock = {ping.exe localhost}
or via the call operator:
$scriptBlock = {& ping.exe localhost}
If you need to run the command from a particular directory, simply change to that directory before running the command:
$scriptBlock = {
Set-Location 'C:\some\folder'
& ping.exe localhost
}

Executing batch file in the remote machines using powershell as a background job

All I am trying to do is to execute a batch file in remote machines as a job.I have batch file located in all machines inside C:\Users\temp folder.Here is my code
$batFile = "test.bat"
foreach($m in $machine)
{
Invoke-Command -ComputerName $m -ScriptBlock{param($batFile) & cmd.exe /c "C:\Users\temp\$batFile"} -Authentication negotiate -Credential $cred -ArgumentList $batFile -AsJob
}
But I keep getting
The expression after '&' in a pipeline element produced an object that was not valid. It must result in a command name, a script
block, or a CommandInfo object
I tried using $using:batFile inside ScriptBlock as well with no success. Can anyone suggest me what I might be doing wrong? I am using powershell version 4.
do a trace on that,
Invoke-Command -ComputerName $m -ScriptBlock{param($batFile) Trace-Command NativeCommandParameterBinder -Expression { & cmd.exe /c "C:\Users\temp\$batFile"}} -Authentication negotiate -Credential $cred -ArgumentList $batFile -AsJob
and Try using Invoke-Expression as a workaround instead of &
invoke-Expression "cmd.exe /c 'C:\Users\temp\$batFile'"
Regards,
Kvprasoon

Process list of commands on remote machine with Invoke-Command

I'm trying to write a powershell script that will take a list of commands and then run them on a remote machine, I have the following code:
foreach($command in $commands)
{
Invoke-Command -computer "BNEBAK" -scriptblock{"$command"}
}
Which does not throw any error but also does not actually run the command (e.g stop-service servicename). $commands is read in from a text file passed as an argument when the script is called, I know the rest of this script works because I have been using it to do local commands with Invoke-Expression for some time.
Any help would be fantastic.
The correct code would be
$commands = #(get-content com.txt)
for($command in $commands) {
$scriptblock = $ExecutionContext.InvokeCommand.NewScriptBlock($command)
Invoke-Command -computer $computer -scriptblock $scriptblock
}