I need to call .bat file from Powershell script - powershell

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: --%.

Related

How do I execute a script from Windows Powershell?

I created a small aws.bat script and then in PowerShell I navigated to the script directory.
But when I type aws then I get an error message and it does not execute the script. Is there a special thing I should be doing?
Here's what I have tried:
PS C:\G> .\aws.bat
C:\G>$BucketName = "ab-user"
'$BucketName' is not recognized as an internal or external command,
operable program or batch file.
The very first and every othre command has a similar message.
You can't just enter the name on its own, with or without file extension, you first have to tell powershell what to do with it.
You can call it as follows:
& .\aws.bat
If you need the LastExitCode returned in powershell to check if the bat file worked (0 usually means it worked, anything else usually means it didn't), use Start-Process as follows:
$batch = Start-Process -FilePath .\aws.bat -Wait -passthru;$batch.ExitCode
And if you want the batch file to be hidden when it is run by powershell do this:
$batch = Start-Process -FilePath .\aws.bat -Wait -passthru -WindowStyle Hidden;$batch.ExitCode

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).

PowerShell and executable

Every time I run an application (.exe) in PowerShell, instead of executing it as it does with scripts, the program gets run in Command Prompt.
Invoke-Item MyProgram.exe
I thought PowerShell was supposed to replace the Command Prompt but instead PowerShell opens Command Prompt which then runs the program. Is there some way I can get PowerShell to completely replace the Command Prompt?
I thought PowerShell was supposed to replace the Command Prompt
It is, so why don't you just do MyProgram.exe
Your question is pretty vague, and in short, it will depend on the program because Invoke-Item uses the Windows default file association stuff by default.
I'm betting that using & MyProgram.exe instead of Invoke-Item MyProgram.exe will work though.
Did you try Start-Process Program.exe -NoNewWindow
I got the answer from another question:
Start-Process .\MyProgram.exe -NoNewWindow -Wait

Set up PowerShell Script for Automatic Execution

I have a few lines of PowerShell code that I would like to use as an automated script. The way I would like it to be able to work is to be able to call it using one of the following options:
One command line that opens PowerShell, executes script and closes PowerShell (this would be used for a global build-routine)
A file that I can double-click to run the above (I would use this method when manually testing components of my build process)
I have been going through PowerShell documentation online, and although I can find lots of scripts, I have been unable to find instructions on how to do what I need. Thanks for the help.
From http://blogs.msdn.com/b/jaybaz_ms/archive/2007/04/26/powershell-polyglot.aspx
If you're willing to sully your beautiful PowerShell script with a little CMD, you can use a PowerShell-CMD polyglot trick. Save your PowerShell script as a .CMD file, and put this line at the top:
#PowerShell -ExecutionPolicy Bypass -Command Invoke-Expression $('$args=#(^&{$args} %*);'+[String]::Join(';',(Get-Content '%~f0') -notmatch '^^#PowerShell.*EOF$')) & goto :EOF
If you need to support quoted arguments, there's a longer version, which also allows comments. (note the unusual CMD commenting trick of double #).
##:: This prolog allows a PowerShell script to be embedded in a .CMD file.
##:: Any non-PowerShell content must be preceeded by "##"
##setlocal
##set POWERSHELL_BAT_ARGS=%*
##if defined POWERSHELL_BAT_ARGS set POWERSHELL_BAT_ARGS=%POWERSHELL_BAT_ARGS:"=\"%
##PowerShell -ExecutionPolicy Bypass -Command Invoke-Expression $('$args=#(^&{$args} %POWERSHELL_BAT_ARGS%);'+[String]::Join(';',$((Get-Content '%~f0') -notmatch '^^##'))) & goto :EOF
Save your script as a .ps1 file and launch it using powershell.exe, like this:
powershell.exe .\foo.ps1
Make sure you specify the full path to the script, and make sure you have set your execution policy level to at least "RemoteSigned" so that unsigned local scripts can be run.
Run Script Automatically From Another Script (e.g. Batch File)
As Matt Hamilton suggested, simply create your PowerShell .ps1 script and call it using:
PowerShell C:\Path\To\YourPowerShellScript.ps1
or if your batch file's working directory is the same directory that the PowerShell script is in, you can use a relative path:
PowerShell .\YourPowerShellScript.ps1
And before this will work you will need to set the PC's Execution Policy, which I show how to do down below.
Run Script Manually Method 1
You can see my blog post for more information, but essentially create your PowerShell .ps1 script file to do what you want, and then create a .cmd batch file in the same directory and use the following for the file's contents:
#ECHO OFF
SET ThisScriptsDirectory=%~dp0
SET PowerShellScriptPath=%ThisScriptsDirectory%MyPowerShellScript.ps1
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '%PowerShellScriptPath%'"
Replacing MyPowerShellScript.ps1 on the 3rd line with the file name of your PowerShell script.
This will allow you to simply double click the batch file to run your PowerShell script, and will avoid you having to change your PowerShell Execution Policy.
My blog post also shows how to run the PowerShell script as an admin if that is something you need to do.
Run Script Manually Method 2
Alternatively, if you don't want to create a batch file for each of your PowerShell scripts, you can change the default PowerShell script behavior from Edit to Run, allowing you to double-click your .ps1 files to run them.
There is an additional registry setting that you will want to modify so that you can run scripts whose file path contains spaces. I show how to do both of these things on this blog post.
With this method however, you will first need to set your execution policy to allow scripts to be ran. You only need to do this once per PC and it can be done by running this line in a PowerShell command prompt.
Start-Process PowerShell -ArgumentList 'Set-ExecutionPolicy RemoteSigned -Force' -Verb RunAs
Set-ExecutionPolicy RemoteSigned -Force is the command that actually changes the execution policy; this sets it to RemoteSigned, so you can change that to something else if you need. Also, this line will automatically run PowerShell as an admin for you, which is required in order to change the execution policy.
Source for Matt's answer.
I can get it to run by double-clicking a file by creating a batch file with the following in it:
C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe LocationOfPS1File
you can use this command :
powershell.exe -argument c:\scriptPath\Script.ps1