powershell script loop that runs two python files - powershell

I would like to use powershell script in windows 10 that calls a python file, waits for completion, then calls another, waits for completion and loops this forever.
I know how to run one in a loop but know nothing of powershell scripts.
I am however fimaliar with Dos batch files and loops.
something like this:
while ($true)
{
start-Process -wait .\python1.py
start-Process -wait .\python2.py
}
This command does what I want with one file from powershell prompt
while ($true) {start-Process -wait .\python1.py}

while ($true) { start-Process -wait .\python1.py ; start-Process -wait .\python2.py }
Thanks Bill!

Related

Powershell Start-Process - notify when finished

So I am running a script to download from web and install a binary. I do that in a separate command prompt. When its done, prompt is closed. How can I know when that happened?
Example (from Windows 10) - powershell Start-Process cmd "/C tasklist"
Can I assign it to a variable and listen to some fallback function call, etc.? Like this pseudo code:
$process = powershell Start-Process cmd "/C tasklist"
while (!$process.done) {
// do stuff
}
p.s. I am very new to PowerShell. So sorry if that doesnt make sence
You could use WaitForExit()
$process = Start-Process cmd "/C tasklist" -PassThru
$process.WaitForExit()
Since you are using PowerShell, you can use background jobs for scenario:
$job = Start-Job -ScriptBlock {cmd.exe /c tasklist}
while ($job.State -eq 'Running') {
# do other stuff while waiting for job to complete
}
# To get the job results
Receive-Job $job
Based on your comments, adding -Wait makes Start-Process a synchronous command. At that point, you don't need Start-Process. You may as well just execute cmd.exe /c tasklist.

How to continue powershell script after child generated powershell scripts have finished?

I'm currently struggling with an issue and would appreciated any help or input.
I have a powershell script that, during it's execution, spawns other powershell scripts that run various commands. All of these generated powershell scripts exit automatically after their commands have been executed.
What I'm trying to do is that after all of these spawned powershell instances exited, run another command within the initial powershell script. Basically wait for all generated powershell instances to exit and then run a command.
Any ideas on how to implement that?
Thanks
Edit: The code that spawns the powershell scripts looks like this:
foreach ($var in $filters){
start-process powershell.exe -Verb Runas -argument "-nologo -noprofile -command .\$var"}
You can use Wait-Process. Use the -PassThru switch to return the started processes. This should work:
$processes = foreach ($var in $filters) {
Start-Process powershell.exe -PassThru -Verb RunAs -Arg "-nologo -noprofile -command .\$var"
}
# wait for processes to finish
$processes | Wait-Process
# now, run your other commands
# ...
You could also use background jobs like this (using the $PWD automatic variable):
# run all scripts as background jobs
$jobs = foreach ($var in $filters) {
Start-Job -FilePath "$PWD\$var"
}
# wait for all jobs to finish
$jobs | Wait-Job
# now, run your other commands
# ...
or in a one-liner:
$filters | foreach { Start-Job -FilePath "$PWD\$_" } | Wait-Job
You can try this using powershell jobs as #jeorenmostert said
$j=$filters|%{
start-job -filepath "$($_)"
}
$j|wait-job
here first iterate over the $filters using % alias of ForEach
then start each job ($_) is the pipeline variable
get them inside $j variable
pipe $j jobs to wait-job to wait until the jobs has finished (you can pipe receive-job too to get passthru like results)

Invoke-Expression to Launch .ps1 scripts

I am trying to make a service that scans a folder. When it detects certain files it renames them and then creates variables for the rest of the script. This all works fine, but I am trying to find a way to run this script so that the subsequent windows that it launches are minimized. I've tried the below, but the 2 scripts still launch a window each that flashes on the screen.
I have tried converting the file into an EXE and a service but then it refuses to work. Hoping for a quick one-liner if anyone can help?
Set-Location -Path C:\scripts\ICVT
while ($true) {
invoke-expression 'cmd /c start powershell -WindowStyle Minimized -Command {.\file_checker.ps1}';
Start-Sleep 5
invoke-expression 'cmd /c start powershell -WindowStyle Minimized -Command {.\kill_checker.ps1}';
Start-Sleep 5
}
Sounds like you need to use Start-Job to run the script in the background. Simply replace the Invoke-Expression with Start-Job:
Set-Location -Path C:\scripts\ICVT
while ($true) {
Start-Job -FilePath '.\file_checker.ps1}';
Start-Sleep 5
Start-Job -FilePath '.\kill_checker.ps1}';
Start-Sleep 5
}
It will also accept script blocks as well. See about_jobs for more information on running and managing background jobs.

Calling another executable and capturing output

Using a PowerShell script I'm trying to execute SqlPackage.exe to update a database. The problem is that it spawns a new CMD window and I can't capture the output effectively.
Here is my script:
&$SqlPackage "/Action:Script", "/SourceFile:$($Environment.PackageFile)", "/Profile:$($Environment.PublishProfile)", "/OutputPath:$($Environment.ScriptFile)";
where SqlPackage = "SQLPackage\SqlPackage.exe";.
Strangely when I execute the script on a Windows 2008 R2 web server the output is inline with the PowerShell output, which is ideally what I want. On my Windows 7 machine it spawns a new CMD window.
How can I route the output to the PowerShell window all the time, or at least pipe to another file?
Edit
Full solution with waiting for process to finish:
$p = Start-Process $SqlPackage -ArgumentList #("/Action:Script", "/SourceFile:$($Environment.PackageFile)", "/Profile:$($Environment.PublishProfile)", "/OutputPath:$($Environment.ScriptFile)") -NoNewWindow -Wait -Passthru
$p.WaitForExit()
You should be able to get the result you are looking for if you use Start-Process with the -NoNewWindow parameter:
Start-Process $SqlPackage -ArgumentList #("/Action:Script", "/SourceFile:$($Environment.PackageFile)", "/Profile:$($Environment.PublishProfile)", "/OutputPath:$($Environment.ScriptFile)") -NoNewWindow
If you need to direct the output to a file you can also use the -RedirectStandardOutput / -RedirectStandardError parameters of Start-Process

PowerShell - Start-Process and Cmdline Switches

I can run this fine:
$msbuild = "C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe"
start-process $msbuild -wait
But when I run this code (below) I get an error:
$msbuild = "C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe /v:q /nologo"
start-process $msbuild -wait
Is there a way I can pass parameters to MSBuild using start-process? I'm open to not using start-process, the only reason I used it was I needed to have the "command" as a variable.
When I have
C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe /v:q /nologo
on a line by itself, how does that get handled in Powershell?
Should I be using some kind of eval() kind of function instead?
you are going to want to separate your arguments into separate parameter
$msbuild = "C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe"
$arguments = "/v:q /nologo"
start-process $msbuild $arguments
Using explicit parameters, it would be:
$msbuild = 'C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe'
start-Process -FilePath $msbuild -ArgumentList '/v:q','/nologo'
EDIT: quotes.
Warning
If you run PowerShell from a cmd.exe window created by Powershell, the 2nd instance no longer waits for jobs to complete.
cmd> PowerShell
PS> Start-Process cmd.exe -Wait
Now from the new cmd window, run PowerShell again and within it start a 2nd cmd window:
cmd2> PowerShell
PS> Start-Process cmd.exe -Wait
PS>
The 2nd instance of PowerShell no longer honors the -Wait request and ALL background process/jobs return 'Completed' status even thou they are still running !
I discovered this when my C# Explorer program is used to open a cmd.exe window and PS is run from that window, it also ignores the -Wait request.
It appears that any PowerShell which is a 'win32 job' of cmd.exe fails to honor the wait request.
I ran into this with PowerShell version 3.0 on windows 7/x64
I've found using cmd works well as an alternative, especially when you need to pipe the output from the called application (espeically when it doesn't have built in logging, unlike msbuild)
cmd /C "$msbuild $args" >> $outputfile
Unless the OP is using PowerShell Community Extensions which does provide a Start-Process cmdlet along with a bunch of others. If this the case then Glennular's solution works a treat since it matches the positional parameters of pscx\start-process : -path (position 1) -arguments (positon 2).