117

I can not get a powershell script to execute a bat file directly. For example, this works on the command line:

.\\my-app\my-fle.bat

When I add this command to a script, it outputs:

The term '.\\my-app\my-file.bat' is not recognized as the 
name of a cmdlet, function, script file, or operable program. 
Check the spelling of the name, or if a path was included, 
verify that the path is correct and try again.

I also tried the following, with the same result:

& .\\my-app\my-fle.bat
& ".\\my-app\my-fle.bat"
\my-app\my-fle.bat
& \my-app\my-fle.bat
& "\my-app\my-fle.bat"

Note: It must return the lastexitcode as I need to verify success of batch.

2
  • 1
    Two backslashes indicate a server share. Commented Feb 21, 2020 at 15:57
  • What did you mean by safest? Commented Jun 4, 2021 at 17:58

8 Answers 8

143
cmd.exe /c '\my-app\my-file.bat'

If the batch file needs a couple of parameters:

cmd.exe /c """\my-app\my-file.bat"" prm1 prm2"
Sign up to request clarification or add additional context in comments.

3 Comments

How do I add an argument to the bat file here? Specifically if the argument is a variable? I tried this[Start-Process "cmd.exe" "/B /C test.bat $inputFilePath"], but it says: "A positional parameter cannot be found that accepts argument 'test.bat'."
@Horizon - Specify each of your arguments in an array of strings with the -ArgumentList parameter: Start-Process -FilePath "cmd.exe" -ArgumentList @("/B", "/C", "test.bat", "$inputFilePath"); It's important to note that the value of $inputFilePath is interpreted like it would be directly in DOS. E.g. a value of "a\b c\d e\f.txt" would cause test.bat to see %1="a\b", %2="c\d", and %3="e\f.txt"
Oh. Forgot: Technically, the .bat and all of its arguments are considered a single argument to cmd.exe, so if you have spaces in the path to "test.bat" it gets more complicated. To be safe, surround your entire DOS command in double-quotes and DOS-escape the quotes you actually wanted to use before you found out you had to do this extra step. E.g. Start-Process -FilePath "cmd.exe" -ArgumentList @("/B", "/C", "`"", "^`"test.bat^`"", "^`"$inputFilePath^`"", "`"");
55

To run the .bat, and have access to the last exit code, run it as:

 & .\my-app\my-fle.bat

3 Comments

That only works when my-app is in the relative path or I use the drive letter. I was trying to avoid tying to the script to specific drive.
@Casey I guess I misunderstood. So my-app is a folder at the root of whatever drive you're working with? If so, & \my-app\my-file.bat works for me. How are you calling the .ps1 script?
What's wrong with just invoking it directly? On Windows 10 using PowerShell 7.2.6, invoking e.g. mvn clean build from inside a .ps1 script seems to work just fine. In this case mvn is the mvn.cmd script on the path.
31

Try this, your dot source was a little off. Edit, adding lastexitcode bits for OP.

$A = Start-Process -FilePath .\my-app\my-fle.bat -Wait -passthru;$a.ExitCode

add -WindowStyle Hidden for invisible batch.

2 Comments

That worked. Will this also return the exit status in LastExitCode?
to access $lastexitcode from start-process, you'll need to assisn the command to a variable and use the passthru switch, then read exitcode from variable.
19

You can simply do:

Start-Process -FilePath "C:\PathToBatFile\FileToExecute.bat" -ArgumentList $argstr -Wait -NoNewWindow

Here,

ArgumentList - to pass parameters or parameter values if needed by bat file

Wait - waits for the process(bat) to complete

NoNewWindow - starts the new process in the current console window.

1 Comment

For -ArgumentList see docs
3

Assuming my-app is a subdirectory under the current directory. The $LASTEXITCODE should be there from the last command:

.\my-app\my-fle.bat

If it was from a fileshare:

\\server\my-file.bat

Comments

3

What about invoke-item script.bat.

1 Comment

What about it, indeed?
0

@Rynant 's solution worked for me. I had a couple of additional requirements though:

  1. Don't PAUSE if encountered in bat file
  2. Optionally, append bat file output to log file

Here's what I got working (finally):

[PS script code]

& runner.bat bat_to_run.bat logfile.txt

[runner.bat]

@echo OFF

REM This script can be executed from within a powershell script so that the bat file
REM passed as %1 will not cause execution to halt if PAUSE is encountered.
REM If {logfile} is included, bat file output will be appended to logfile.
REM
REM Usage:
REM runner.bat [path of bat script to execute] {logfile}

if not [%2] == [] GOTO APPEND_OUTPUT
@echo | call %1
GOTO EXIT

:APPEND_OUTPUT
@echo | call %1  1> %2 2>&1

:EXIT

Comments

0

Even using win_shell ansible module this can be achieved:

- name: Install the WebApp Service
  win_shell: 'Service_Install.bat'
  args:
    executable: cmd
    chdir: 'D:\MyWebApp\Services'
  register: result

Here D:\MyWebApp\Services is the location where your .bat file is available.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.