For years, I have used the
cmd/DOS/Windows
shell and passed command-line arguments to batch files. For example, I have a file,
zuzu.bat
and in it, I access
%1
,
%2
, etc. Now, I want to do the same when I call a
PowerShell
script
when I am in a Cmd.exe shell
. I have a script,
xuxu.ps1
(and I've added PS1 to my PATHEXT variable and associated PS1 files with PowerShell). But no matter what I do, I seem unable to get anything from the
$args
variable. It always has length 0.
If I am in a
PowerShell
shell, instead of
cmd.exe
, it works (of course). But I'm not yet comfortable enough to live in the PowerShell environment full time. I don't want to type
powershell.exe -command xuxu.ps1 p1 p2 p3 p4
. I want to type
xuxu p1 p2 p3 p4
.
Is this possible, and if so, how?
The sample I cannot get to work is trivial, foo.ps1:
Write-Host "Num Args:" $args.Length;
foreach ($arg in $args) {
Write-Host "Arg: $arg";
The results are always like this:
C:\temp> foo
Num Args: 0
C:\temp> foo a b c d
Num Args: 0
c:\temp>
-File
Runs the specified script in the local scope ("dot-sourced"), so that the functions and variables that the script creates are available in the current session. Enter the script file path and any parameters. File must be the last parameter in the command, because all characters typed after the File parameter name are interpreted as the script file path followed by the script parameters.
powershell.exe -File "C:\myfile.ps1" arg1 arg2 arg3
means run the file myfile.ps1 and arg1 arg2 & arg3 are the parameters for the PowerShell script.
–
OK, so first this is breaking a basic security feature in PowerShell. With that understanding, here is how you can do it:
Open an Windows Explorer window
Menu Tools -> Folder Options -> tab File Types
Find the PS1 file type and click the advanced button
Click the New button
For Action put: Open
For the Application put: "C:\WINNT\system32\WindowsPowerShell\v1.0\powershell.exe" "-file" "%1" %*
You may want to put a -NoProfile
argument in there too depending on what your profile does.
–
–
–
–
After digging through the PowerShell documentation, I discovered some useful information about this issue. You can't use the $args
if you used the param(...)
at the beginning of your file; instead you will need to use $PSBoundParameters
. I copy/pasted your code into a PowerShell script, and it worked as you'd expect in PowerShell version 2 (I am not sure what version you were on when you ran into this issue).
If you are using $PSBoundParameters
(and this ONLY works if you are using param(...)
at the beginning of your script), then it is not an array, it is a hash table, so you will need to reference it using the key / value pair.
param($p1, $p2, $p3, $p4)
$Script:args=""
write-host "Num Args: " $PSBoundParameters.Keys.Count
foreach ($key in $PSBoundParameters.keys) {
$Script:args+= "`$$key=" + $PSBoundParameters["$key"] + " "
write-host $Script:args
And when called with...
PS> ./foo.ps1 a b c d
The result is...
Num Args: 4
$p1=a $p2=b $p3=c $p4=d
–
–
–
–
–
If you then placed this file under a folder in your PATH
, you could call PowerShell scripts like this:
ps foo 1 2 3
Quoting can get a little messy, though:
ps write-host """hello from cmd!""" -foregroundcolor green
You may not get "xuxu p1 p2 p3 p4" as it seems. But when you are in PowerShell and you set
PS > set-executionpolicy Unrestricted -scope currentuser
You can run those scripts like this:
./xuxu p1 p2 p3 p4
.\xuxu p1 p2 p3 p4
./xuxu.ps1 p1 p2 p3 p4
I hope that makes you a bit more comfortable with PowerShell.
if you want to invoke ps1 scripts from cmd and pass arguments without invoking the script like
powershell.exe script.ps1 -c test
script -c test ( wont work )
you can do the following
setx PATHEXT "%PATHEXT%;.PS1" /m
assoc .ps1=Microsoft.PowerShellScript.1
ftype Microsoft.PowerShellScript.1=powershell.exe "%1" %*
This is assuming powershell.exe is in your path
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/ftype
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
site design / logo © 2019 Stack Exchange Inc; user contributions licensed under cc by-sa 4.0
with attribution required.
rev 2019.9.23.34994