0

I'm starting a process with PsExec in the script and I want the results to appear on the screen.

The command runs without problem. There is no error message And no result message either.

How can I start the process in the same window. The -NoNewWindow argument just hides the newly opened window. It doesn't print the result to Powershell.

$PSExec = "C:\Windows\System32\PsExec.exe"
$hostname = Read-Host -Prompt 'Hostname or IP Adress'
$command1 = 'cmd /c "net stop issuser"'
$command2 = 'cmd /c "net start issuser"'

Start-Process -Wait -Filepath "$PSExec" -ArgumentList "\\$hostname $command1" -NoNewWindow
Start-Process -Wait -Filepath "$PSExec" -ArgumentList "\\$hostname $command2" -NoNewWindow

Thanks.

virtue
  • 13
  • 4

3 Answers3

1

getting somthing back: add the parameter -passthru to start-process.

But I think why do you use psexec and net start/stop - welcome to powershell:

$hosts = @("hostA","hostB")
$code = {
    try {
        $null = Stop-Service -Name issuer -ErrorAction:stop
        $stopOperation='success'
    }
    Catch {
        $stopOperation='failed'
        $stopException=$_
    }
    try {
        $startOperation = start-service -Name issuer -ErrorAction:stop
        $startOperation='success'
    }
    Catch {
        $startOperation='failed'
        $startException=$_        
    }
    $attrsht = @{
        Name=Issuer 
        stopOperation=$stopOperation
        stopOperationExecption=$stopException
        startOperation=$startOperation
        startOperationException=$startException
    }
    return New-Object -typename psobject -Property $attrsht
 
}
$result = invoke-command -computername $hosts -ScriptBlock $code

ok that makes much sense, but it is what it is ;-) alternatively:

Invoke-CimMethod -Query "select name from win32_service where name = 'issuer'" -MethodName startservice -ComputerName $host

Invoke-CimMethod -Query "select name from win32_service where name = 'issuer'" -MethodName stopservice -ComputerName $host

Hehe, sorry the cim cmdlets are also using WinRm behind the scenes. Back to the old/outdated wmi:

(Get-WmiObject -Query "select name from win32_service where name = 'issuer'" -ComputerName $host).startservice()

(Get-WmiObject -Query "select name from win32_service where name = 'issuer'" -ComputerName $host).stopservice()
Toni
  • 1,738
  • 1
  • 3
  • 11
  • Unfortunately Powershell PSSession is closed due to company policies. So i have to use psexec. :) – virtue Sep 04 '22 at 12:48
  • Here is the error: WinRM cannot complete the operation. Verify that the specified computer name is valid, that the computer is accessible over the network, and that a firewall exception for the WinRM service is enabled and allows access from this computer. By default, the WinRM firewall exception for public profiles limits acc ess to remote computers within the same local subnet. – virtue Sep 04 '22 at 13:10
  • 2
    What good does this "company policy" as you actual might enable `winrm` remotely with `psexec`? See: [how winrm can be enabled using psexec from powershell](https://stackoverflow.com/a/43203048/1701026) – iRon Sep 04 '22 at 14:12
1

Note:

  • You stated that use of psexec is a must in your case - see the next section, which applies to calling any external console application from PowerShell.

  • In cases where PowerShell remoting is available or can be set up, you could use Invoke-Command, which, like psexec, relays the output from remotely executed commands:

    # Add -ErrorAction Stop to abort the script if stderr output is received.
    # To act on process exit codes, examine $LASTEXITCODE in the script block.
    Invoke-Command -ComputerName $hostname { net stop issuser; net start issuser }
    
    • More simply, you can use PowerShell's Restart-Service cmdlet:

      Invoke-Command -ComputerName $hostname { Restart-Service issuser}
      

In order to invoke console applications synchronously in the current window, with their stdout and stderr streams connected to PowerShell's, invoke them directly - do not use Start-Process:

  • Start-Process cannot directly return a command's output (you can only redirect to files, with -RedirectStandardOutput and -RedirectStandardError).
  • See this answer for more information about direct invocation vs. Start-Process.

Therefore:

# Directly executes psexec and outputs its results (stdout and stderr).
# Note: 
#   -replace '"', '\"' is unfortunately needed up to a least PowerShell 7.2.x
& $PSExec \\$hostname ($command1 -replace '"', '\"')
& $PSExec \\$hostname ($command2 -replace '"', '\"')

Note: You could combine the net stop and net start commands into a single cmd /c invocation and therefore a single psexec call.

Note:

  • Since your executable path is specified as a variable, you must use &, the call operator for invocation; the same would apply if the path were quoted - see this answer for more information.

  • Unfortunately, -replace '"', '\"', which escapes embedded " characters as \", is necessary up to at least PowerShell 7.2.x, due to a long-standing bug - see this answer. (Note that your particular commands don't strictly need embedded " characters.)

mklement0
  • 382,024
  • 64
  • 607
  • 775
0

Why don't you use PowerShell Remoting instead of PSExec for this? That way your command would be something like this

Invoke-Command -ComputerName $hostname -ScriptBlock { Stop-Service iisuser -PassThru }
Invoke-Command -ComputerName $hostname -ScriptBlock { Start-Service iisuser -PassThru }

Of course you have to have enabled PowerShell remoting for that, but capturing output will be much easier from remote machines to your machine.

If you really want to use PSExec, you should use Invoke-Expression instead of Start-Process.

For example, starting remote notepad process:

Invoke-Expression -Command 'psexec -i \\server01 notepad'

Your command would be something like this then

Invoke-Expression -Command "psexec \\$hostname $command1"

This will open a new window and stop the service, but after is finishes it will close the window. If you want to capture the output you need to redirect that to a text file you could do something like this

Invoke-Expression -Command "psexec \\$hostname $command2" 2> C:\Scripts\output2.txt
MarcoJ
  • 41
  • 5