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.
CodePudding user response:
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()
CodePudding user response:
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
CodePudding user response:
Note:
You stated that use of
psexec
is a must in your case - see the next section.In cases where PowerShell remoting is available or can be set up, you could use
Invoke-Command
, which, likepsexec
, 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 }
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.)