Call .bat file from powershell script synchronously - powershell

I need to call a .bat file from a powershell script synchronously.
I am currently working on a utiity where I need to call a .bat file to generate data in an excel sheet , use powershell script to extract parts of that data and then call .bat file again to processs the extracted data however when the script runs, complete powershell script is executed first and calls to .bat files are made later.
Code snippet:
echo "Hello world"
Start-Process C:/dataloader/bin/process.bat -ArgumentList $tempLibraryPath ExtractTest
Echo "Foobar"
expected output:
Hello world
call process.bat
Foobar
Actual output
Hello World
Foobar
Call process.bat

You need to tell PowerShell to wait for the process to finish:
Start-Process C:/dataloader/bin/process.bat -ArgumentList $tempLibraryPath ExtractTest -Wait

Related

Powershell Redirecting standard output to file from git-bash.exe

Ive got a very basic powershell script which uses Start-Process to start another .sh script, this is working and the scripts do execute but what I need is to be able to capture the output of the called script.
Content of the scripts is below:
main.ps1
Start-Process 'C:\Program Files\Git\git-bash.exe' -ArgumentList '-- C:\test\sub.sh' -Wait -RedirectStandardOutput output.txt
sub.sh
#!/bin/bash
echo "Hello World"
The sub.sh launches and prints out Hello World in its own console, but I really need the output to either go to the calling powershell scripts console window, or to a file. The file I specify in the -RedirectStandardOutput parameter is created, but is empty.
How can I get the sh script to print to standard out to the calling script?
Thank you
git-bash is in a different world than powershell so you can not directly redirect output or use -RedirectStandardOutput.
As you supposed, you can use an temporary file but the trick is to use internal bash operand ">" to redirect output to the file from bash process :
#!/bin/bash
echo "Hello from bash World" > /c/test/tempFile.txt
Then call it from powershell, you might hide the window also :
Start-Process 'C:\Program Files\Git\git-bash.exe' -ArgumentList C:\test\sub.sh -Wait -WindowStyle Hidden
$s = Get-Content c:\test\tempFile.txt
Write-Host "s=$s"
Remove-Item c:\test\tempFile.txt
Note : You have to specifilly fully qualified path.
Another option might be using Windows 10 own bash interpreter : https://stackoverflow.com/a/44359679/11867971
As written in sub.sh, the program to execute sh files is /bin/bash, not git-bash.exe.
$output = & 'C:\Program Files\Git\usr\bin\bash.exe' C:\test\sub.sh
$output
Hello World

How to call batch from powershell so I can see realtime output in powershell console

I need to call batch from powershell with specific working directory. I don't want new console to be opened, but I would like to see the output of the batch as a part of the output from powershell script.
I could forward the standard output to file and then write it by Write-Host, but the batch takes time and I would like to see the output in realtime as it is processing.
I tried Process-Start, but I don't know how to redirect standard output of batch to standard output of powershell.
You can add 'cmd /c ' to your ps script, and to change directories, you can use #jisaak suggestion, so:
$wd = Get-Location;
Set-Location "batch file directory";
cmd /c "Your batch";
Set-Location $wd;
That will open a new cmd in the current console and all the output will be directed to it(when the batch will reach EOF the cmd terminates).

I need to call .bat file from Powershell script

We are migrating perl script to powershell script.
In Perl the code is as shown below
$rc='D:\\EmailConnector\\run.bat> $EmailConnector_log;';
I tried as shown below but not working
StartProcess "cmd.exe" "/c D:\EmailConnector\run.bat> $EmailConnector_log"
When I tried as shown below the .bat script ran, but I want to update the log file. Could you help me on this.
StartProcess run.bat -workingdirectory "D:\EmailConnector"
The .bat file consist of jar file for email functionality. But we want to get log in log file.
Use the call operator (&), like this:
& 'D:\EmailConnector\run.bat' > $EmailConnector_log
The return value of the batch script is automatically put into the variable $LastExitCode.
Is that what you mean?
Start-Process "cmd" -ArgumentList '/c','D:\EmailConnector\run.bat' -WorkingDirectory "D:\EmailConnector"
or this one if you need another argument for logfile
Start-Process "cmd" -ArgumentList '/c','D:\EmailConnector\run.bat','EmailConnector_log' -WorkingDirectory "D:\EmailConnector"
Or, since there are no spaces in the path, you can just execute the batch file directly from PowerShell:
D:\EmailConnector\run.bat > $EmailConnector_log
This is one of the advantages of PowerShell being both a "shell" and a "scripting language". Execution of batch, cmd, vbs, exe files is straightforward - usually. Parameter passing can be an issue but these days that is easily solved with the stop parsing operator: --%.

Launching additional Powershell instance with commands from a text file

I'm writing a Powershell script that takes in a text file as a parameter. The text file looks similar to this:
echo "1"
echo "2"
echo "3"
What I would want is for each line to be executed in a new Powershell instance. So in the example above, 3 additional instances would be created and each of the 3 would execute one line from the text file. I'm able to launch instances, but I cannot get the instances to treat the lines in the file as commands.
$textFile=$args[0] #File with Powershell commands
foreach($cmdd in get-content $textFile){
cmd /c start powershell -NoExit -command {param($cmdd) iex $cmdd} -ArgumentList $cmdd
}
Running this code opens the instances, prints a lot of information, and then immediately closes. It closes so quickly that I cannot see what the info is. However, since the text file is only composed of printing the numbers 1, 2, and 3, I don't think that it's working correctly. Is there also a way to keep the windows from closing after execution?
If you're launching additional instances of PowerShell from PowerShell, you won't need to call cmd. Try using Start-Process:
$textFile=$args[0] #File with Powershell commands
foreach($cmdd in get-content $textFile){
Start-Process -FilePath powershell -ArgumentList "-NoExit -Command $cmdd"
}
This will leave newly created instances open as you have asked.
Switch from CMD /C to CMD /K to leave the command session open after the command finishes.

How to get Powershell result from inner start-processs

I have a ps script like:
Start-Process powershell -Verb runAs -ArgumentList "Get-WebApplication"
Because Get-WebApplication needs admin right, so I use "-verb runAs".
My question is: now the result only shows in the new powershell windows. How can I make my main powershell get/display the result?
You have two choices that I see:
Run your script as administrator and just run Get-WebApplication directly.
Capture the output from the powershell process you're starting with Start-process and then do whatever you want with the output in your script. To capture the output you can either redirect the output to a file and then read the file in your script, or you can use .NET [diagnostics.process]::start to redirect stdout and directly read the output stream in your script (no file is created).