eryksun's comments on the question are all worth heeding.
This section of the answer provides a generic answer to the generic question in the question's title. See the next section for considerations specific to the OP's scenario.
Generally speaking, there are only a few things to watch out for when invoking a batch file from PowerShell:
Always include the specific filename extension (.bat
or .cmd
) in the filename, e.g., script_name.bat
- This ensures that no other forms of the same command (named
script_name
, in the example) with higher precedence are accidentally executed, which could be:
- In case of a command name without a path component:
- An alias, function, cmdlet, or an external executable / PowerShell script (
*.ps1
) that happens to be located in a directory listed earlier in the $env:PATH
(%PATH%
) variable; if multiple executables by the same name are in the same (earliest) directory, the next point applies too.
- In case of a command name with a path component:
- A PowerShell script (
*.ps1
) or executable with the same filename root whose extension comes before .bat
or .cmd
in the %PATHEXT%
environment variable.
If the batch file is located in the current directory, you must prefix its filename with ./
By design, as a security measure, PowerShell - unlike cmd.exe
- does NOT invoke executables located in the current directory by filename only, so invoking script_name.bat
to invoke a batch file of that name in the current directory does not work.[1]
Instead, you must use a path to target such an executable so as to explicitly signal the intent to execute something located in the current directory, and the simplest approach is to use prefix ./
(.\
, if running on Windows only); e.g., ./script_name.bat
.
When passing parameters to the batch file:
- Either: be aware of PowerShell's parsing rules, which are applied before the arguments are passed to the batch file - see this answer of mine.
- Or: use
--%
(the PSv3+ stop-parsing symbol) to pass the remaining arguments as if they'd been passed from a batch file (no interpretation by PowerShell other than expansion of %<var>%
-style environment-variable references).
[1] eryksun points out that on Vista+ you can make cmd
behave like PowerShell by defining environment variable NoDefaultCurrentDirectoryInExePath
(its specific value doesn't matter).
While ill-advised, you can still force both environments to always find executables in the current directory by explicitly adding .
to the %PATH%
/ $env:PATH
variable; if you prepend .
, you get the default cmd
behavior.
As for your specific scenario:
After installing the Windows Creator's update, where PowerShell becomes the new default Windows shell via Explorer's menu options
This applies to the following scenarios:
Pressing Win-X (system-wide keyboard shortcut) now offers PowerShell rather than cmd in the shortcut menu that pops up.
Using File Explore's File
menu now shows Open Windows PowerShell
in place of Open command prompt
(cmd
).
However, nothing has changed with respect to how batch files are invoked when they are opened / double-clicked from File Explorer: The subkeys of HKEY_CLASSES_ROOT\batchfile
and HKEY_CLASSES_ROOT\cmdfile
in the registry still define the shell\open
verb as "%1" %*
, which should invoke a batch file implicitly with cmd /c
, as before.
However, per your comments, your batch file is never run directly from File Explorer, because it require parameter values, and it is invoked in two fundamental ways:
Explicitly via a cmd
console, after entering cmd
in the Run
dialog that is presented after pressing Win-R (system-wide keyboard shortcut).
- In this case, everything should work as before: you're invoking your batch file from
cmd
.
Explicitly via PowerShell, using File Explorer's File
menu.
Per your comments, the PowerShell console may either be opened:
- directly in the directory in which the target batch file resides.
- in an ancestral directory, such as the root of a thumb drive on which the batch file resides.
In both cases, PowerShell's potential interpretation of arguments does come into play.
Additionally, in the 2nd case (ancestral directory), the invocation will only work the same if the batch file either does not depend on the current directory or explicitly sets the current directory (such as setting it to its own location with cd /d "%~dp0"
).