Powershell Wait-Process - powershell

I have used Wait-Process in the past and it works fine. This time I am trying to close down visual studio gracefully (allow time to save any unsaved files) and once that is completed for notepad to open.
(Get-Process devenv).CloseMainWindow() | Wait-Process | notepad
Unfortunately while Visual Studio does close gracefully, notepad pops up simultaneously with the save files dialog. Why in this instance does Wait-Process not work as per norm. There is a powershell error accompanied which I cannot understand at the moment.
Wait-Process : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input. At line:1 char:54 (Get-Process devenv).CloseMainWindow() | Wait-Process <<<<
However I have done many DoSomethingA | WaitProcess | DoSomethingB commands which work. I can't figure out the different scenario here.

Try like this:
Get-Process devenv | % {$_.CloseMainWindow()}; wait-process devenv -ea silentlycontinue ; notepad

CloseMainWindow returns a Boolean value which is piped to Wait-Process, but Wait-Process expects a process object and not a Boolean value. Give this a try
Get-Process devenv | ForEach-Object {
$null=$_.CloseMainWindow()
Wait-Process -Id $_.id
notepad
}

Related

Multiple commands in powershell [duplicate]

I have a PowerShell 1.0 script to just open a bunch of applications. The first is a virtual machine and the others are development applications. I want the virtual machine to finish booting before the rest of the applications are opened.
In bash I could just say "cmd1 && cmd2"
This is what I've got...
C:\Applications\VirtualBox\vboxmanage startvm superdooper
&"C:\Applications\NetBeans 6.5\bin\netbeans.exe"
Normally, for internal commands PowerShell does wait before starting the next command. One exception to this rule is external Windows subsystem based EXE. The first trick is to pipeline to Out-Null like so:
Notepad.exe | Out-Null
PowerShell will wait until the Notepad.exe process has been exited before continuing. That is nifty but kind of subtle to pick up from reading the code. You can also use Start-Process with the -Wait parameter:
Start-Process <path to exe> -NoNewWindow -Wait
If you are using the PowerShell Community Extensions version it is:
$proc = Start-Process <path to exe> -NoNewWindow -PassThru
$proc.WaitForExit()
Another option in PowerShell 2.0 is to use a background job:
$job = Start-Job { invoke command here }
Wait-Job $job
Receive-Job $job
Besides using Start-Process -Wait, piping the output of an executable will make Powershell wait. Depending on the need, I will typically pipe to Out-Null, Out-Default, Out-String or Out-String -Stream. Here is a long list of some other output options.
# Saving output as a string to a variable.
$output = ping.exe example.com | Out-String
# Filtering the output.
ping stackoverflow.com | where { $_ -match '^reply' }
# Using Start-Process affords the most control.
Start-Process -Wait SomeExecutable.com
I do miss the CMD/Bash style operators that you referenced (&, &&, ||). It
seems we have to be more verbose with Powershell.
Just use "Wait-process" :
"notepad","calc","wmplayer" | ForEach-Object {Start-Process $_} | Wait-Process ;dir
job is done
If you use Start-Process <path to exe> -NoNewWindow -Wait
You can also use the -PassThru option to echo output.
Some programs can't process output stream very well, using pipe to Out-Null may not block it.
And Start-Process needs the -ArgumentList switch to pass arguments, not so convenient.
There is also another approach.
$exitCode = [Diagnostics.Process]::Start(<process>,<arguments>).WaitForExit(<timeout>)
Including the option -NoNewWindow gives me an error: Start-Process : This command cannot be executed due to the error: Access is denied.
The only way I could get it to work was to call:
Start-Process <path to exe> -Wait
The question was asked long ago, but since answers here are kind of references, I may mention an up to date usage. With the current implementation of PowerShell (it's 7.2 LTS as of writing) you can use && as you would do in Bash.
Conditionally execute the right-hand side pipeline based on the success of the left-hand side pipeline.
# If Get-Process successfully finds a process called notepad,
# Stop-Process -Name notepad is called
Get-Process notepad && Stop-Process -Name notepad
Further info on documentation
Taking it further you could even parse on the fly
e.g.
& "my.exe" | %{
if ($_ -match 'OK')
{ Write-Host $_ -f Green }
else if ($_ -match 'FAIL|ERROR')
{ Write-Host $_ -f Red }
else
{ Write-Host $_ }
}
Building upon #Justin & #Nathan Hartley 's answers:
& "my.exe" | Out-Null #go nowhere
& "my.exe" | Out-Default # go to default destination (e.g. console)
& "my.exe" | Out-String # return a string
the piping will return it in real-time
& "my.exe" | %{
if ($_ -match 'OK')
{ Write-Host $_ -f Green }
else if ($_ -match 'FAIL|ERROR')
{ Write-Host $_ -f Red }
else
{ Write-Host $_ }
}
Note: If the executed program returns anything other than a 0 exitcode, the piping will not work. You can force it to pipe with redirection operators such as 2>&1
& "my.exe" 2>&1 | Out-String
sources:
https://stackoverflow.com/a/7272390/254276
https://social.technet.microsoft.com/forums/windowsserver/en-US/b6691fba-0e92-4e9d-aec2-47f3d5a17419/start-process-and-redirect-output-to-powershell-window
There's always cmd.
cmd /c start /wait notepad
Or
notepad | out-host

Wait for file to finish writing before performing next script [duplicate]

I have a PowerShell 1.0 script to just open a bunch of applications. The first is a virtual machine and the others are development applications. I want the virtual machine to finish booting before the rest of the applications are opened.
In bash I could just say "cmd1 && cmd2"
This is what I've got...
C:\Applications\VirtualBox\vboxmanage startvm superdooper
&"C:\Applications\NetBeans 6.5\bin\netbeans.exe"
Normally, for internal commands PowerShell does wait before starting the next command. One exception to this rule is external Windows subsystem based EXE. The first trick is to pipeline to Out-Null like so:
Notepad.exe | Out-Null
PowerShell will wait until the Notepad.exe process has been exited before continuing. That is nifty but kind of subtle to pick up from reading the code. You can also use Start-Process with the -Wait parameter:
Start-Process <path to exe> -NoNewWindow -Wait
If you are using the PowerShell Community Extensions version it is:
$proc = Start-Process <path to exe> -NoNewWindow -PassThru
$proc.WaitForExit()
Another option in PowerShell 2.0 is to use a background job:
$job = Start-Job { invoke command here }
Wait-Job $job
Receive-Job $job
Besides using Start-Process -Wait, piping the output of an executable will make Powershell wait. Depending on the need, I will typically pipe to Out-Null, Out-Default, Out-String or Out-String -Stream. Here is a long list of some other output options.
# Saving output as a string to a variable.
$output = ping.exe example.com | Out-String
# Filtering the output.
ping stackoverflow.com | where { $_ -match '^reply' }
# Using Start-Process affords the most control.
Start-Process -Wait SomeExecutable.com
I do miss the CMD/Bash style operators that you referenced (&, &&, ||). It
seems we have to be more verbose with Powershell.
Just use "Wait-process" :
"notepad","calc","wmplayer" | ForEach-Object {Start-Process $_} | Wait-Process ;dir
job is done
If you use Start-Process <path to exe> -NoNewWindow -Wait
You can also use the -PassThru option to echo output.
Some programs can't process output stream very well, using pipe to Out-Null may not block it.
And Start-Process needs the -ArgumentList switch to pass arguments, not so convenient.
There is also another approach.
$exitCode = [Diagnostics.Process]::Start(<process>,<arguments>).WaitForExit(<timeout>)
Including the option -NoNewWindow gives me an error: Start-Process : This command cannot be executed due to the error: Access is denied.
The only way I could get it to work was to call:
Start-Process <path to exe> -Wait
The question was asked long ago, but since answers here are kind of references, I may mention an up to date usage. With the current implementation of PowerShell (it's 7.2 LTS as of writing) you can use && as you would do in Bash.
Conditionally execute the right-hand side pipeline based on the success of the left-hand side pipeline.
# If Get-Process successfully finds a process called notepad,
# Stop-Process -Name notepad is called
Get-Process notepad && Stop-Process -Name notepad
Further info on documentation
Taking it further you could even parse on the fly
e.g.
& "my.exe" | %{
if ($_ -match 'OK')
{ Write-Host $_ -f Green }
else if ($_ -match 'FAIL|ERROR')
{ Write-Host $_ -f Red }
else
{ Write-Host $_ }
}
Building upon #Justin & #Nathan Hartley 's answers:
& "my.exe" | Out-Null #go nowhere
& "my.exe" | Out-Default # go to default destination (e.g. console)
& "my.exe" | Out-String # return a string
the piping will return it in real-time
& "my.exe" | %{
if ($_ -match 'OK')
{ Write-Host $_ -f Green }
else if ($_ -match 'FAIL|ERROR')
{ Write-Host $_ -f Red }
else
{ Write-Host $_ }
}
Note: If the executed program returns anything other than a 0 exitcode, the piping will not work. You can force it to pipe with redirection operators such as 2>&1
& "my.exe" 2>&1 | Out-String
sources:
https://stackoverflow.com/a/7272390/254276
https://social.technet.microsoft.com/forums/windowsserver/en-US/b6691fba-0e92-4e9d-aec2-47f3d5a17419/start-process-and-redirect-output-to-powershell-window
There's always cmd.
cmd /c start /wait notepad
Or
notepad | out-host

Use Get-Process incorrectly piped to Stop-Process

I am trying to stop multiple chrome instances in one row through powershell but get a strange behaviour :
Get-Process -Name chrome | stop-process $_
Returns an error:
Cannot link paramter Id because it is null.
But I have 8 processes running, and I can issue a stop-process on the first one.
So I do not understand what's going on. (Windows 7)
Any ideas ?
Just pipe Get-Process cmdlet it to the Stop-Process and omit the $_:
Get-Process -Name chrome | stop-process

Wait for an Active Directory query to finish before executing next line

Trying to work out how I can make the below code:
Wait for line 1 to complete before continuing.
Wait for line 4 to complete before running line 5
.
$invokevar = Get-ADComputer -Filter * -SearchBase $searchbase | select -Expand dnshostname
New-Variable -name "invoke$dom" -value $invokevar -Force
$fullvar = Get-Variable -Name "invoke$dom" -ValueOnly
$results = Invoke-Command -ComputerName $fullvar -ScriptBlock $sbmain
$badhosts = Compare-Object $($invokevar | Sort-Object) $($results | select -expand pscomputername | Sort-Object) | select -expand InputObject
Having a mental block, any help would be appreciated.
In powershell, the script executes line by line
Unless or until the execution of line 1 finishes, the script wont go for line 2.
So ideally you shouldn't be worrying about the problem stated above.
For internal commands PowerShell does wait before starting the next command. One exception to this rule is external Windows subsystem based EXE applications, you can apply out-null
PowerShell will wait until the exe process has been exited before continuing.
You can also use Start-Process with the -Wait parameter:
Start-Process <path to exe> -NoNewWindow -Wait
If you are using the PowerShell Community Extensions version it is:
$proc = Start-Process <path to exe> -NoWindow
$proc.WaitForExit()
Another option in PowerShell 2.0 is to use a background job:
$job = Start-Job { invoke command here }
Wait-Job $job
Receive-Job $job
In your case it will wait for the execution to get completed. Else you can check the status using a do-While loop and keep on adding a start-sleep of 1 sec
Hope this approach helps you.
Those answers are wrong. Get-ADUser absolutely may return data in the middle of the script down the line..
Some get-aduser command
echo "some string"
I have seen output line 2 first and then the results from line 1.
The only way around this is to assign a variable to the query and process the variable.
$string = get-aduser....
process $string
echo "some string"
This will process in order 1,2,3 without failure.

How to tell PowerShell to wait for each command to end before starting the next?

I have a PowerShell 1.0 script to just open a bunch of applications. The first is a virtual machine and the others are development applications. I want the virtual machine to finish booting before the rest of the applications are opened.
In bash I could just say "cmd1 && cmd2"
This is what I've got...
C:\Applications\VirtualBox\vboxmanage startvm superdooper
&"C:\Applications\NetBeans 6.5\bin\netbeans.exe"
Normally, for internal commands PowerShell does wait before starting the next command. One exception to this rule is external Windows subsystem based EXE. The first trick is to pipeline to Out-Null like so:
Notepad.exe | Out-Null
PowerShell will wait until the Notepad.exe process has been exited before continuing. That is nifty but kind of subtle to pick up from reading the code. You can also use Start-Process with the -Wait parameter:
Start-Process <path to exe> -NoNewWindow -Wait
If you are using the PowerShell Community Extensions version it is:
$proc = Start-Process <path to exe> -NoNewWindow -PassThru
$proc.WaitForExit()
Another option in PowerShell 2.0 is to use a background job:
$job = Start-Job { invoke command here }
Wait-Job $job
Receive-Job $job
Besides using Start-Process -Wait, piping the output of an executable will make Powershell wait. Depending on the need, I will typically pipe to Out-Null, Out-Default, Out-String or Out-String -Stream. Here is a long list of some other output options.
# Saving output as a string to a variable.
$output = ping.exe example.com | Out-String
# Filtering the output.
ping stackoverflow.com | where { $_ -match '^reply' }
# Using Start-Process affords the most control.
Start-Process -Wait SomeExecutable.com
I do miss the CMD/Bash style operators that you referenced (&, &&, ||). It
seems we have to be more verbose with Powershell.
Just use "Wait-process" :
"notepad","calc","wmplayer" | ForEach-Object {Start-Process $_} | Wait-Process ;dir
job is done
If you use Start-Process <path to exe> -NoNewWindow -Wait
You can also use the -PassThru option to echo output.
Some programs can't process output stream very well, using pipe to Out-Null may not block it.
And Start-Process needs the -ArgumentList switch to pass arguments, not so convenient.
There is also another approach.
$exitCode = [Diagnostics.Process]::Start(<process>,<arguments>).WaitForExit(<timeout>)
Including the option -NoNewWindow gives me an error: Start-Process : This command cannot be executed due to the error: Access is denied.
The only way I could get it to work was to call:
Start-Process <path to exe> -Wait
The question was asked long ago, but since answers here are kind of references, I may mention an up to date usage. With the current implementation of PowerShell (it's 7.2 LTS as of writing) you can use && as you would do in Bash.
Conditionally execute the right-hand side pipeline based on the success of the left-hand side pipeline.
# If Get-Process successfully finds a process called notepad,
# Stop-Process -Name notepad is called
Get-Process notepad && Stop-Process -Name notepad
Further info on documentation
Taking it further you could even parse on the fly
e.g.
& "my.exe" | %{
if ($_ -match 'OK')
{ Write-Host $_ -f Green }
else if ($_ -match 'FAIL|ERROR')
{ Write-Host $_ -f Red }
else
{ Write-Host $_ }
}
Building upon #Justin & #Nathan Hartley 's answers:
& "my.exe" | Out-Null #go nowhere
& "my.exe" | Out-Default # go to default destination (e.g. console)
& "my.exe" | Out-String # return a string
the piping will return it in real-time
& "my.exe" | %{
if ($_ -match 'OK')
{ Write-Host $_ -f Green }
else if ($_ -match 'FAIL|ERROR')
{ Write-Host $_ -f Red }
else
{ Write-Host $_ }
}
Note: If the executed program returns anything other than a 0 exitcode, the piping will not work. You can force it to pipe with redirection operators such as 2>&1
& "my.exe" 2>&1 | Out-String
sources:
https://stackoverflow.com/a/7272390/254276
https://social.technet.microsoft.com/forums/windowsserver/en-US/b6691fba-0e92-4e9d-aec2-47f3d5a17419/start-process-and-redirect-output-to-powershell-window
There's always cmd.
cmd /c start /wait notepad
Or
notepad | out-host