How to handle command-line arguments in PowerShell
command-line-arguments, powershell
Solution
You are reinventing the wheel. Normal PowerShell scripts have parameters starting with `-`, like `script.ps1 -server http://devserver`
Then you handle them in a `param` section (note that this must begin at the first non-commented line in your script).
You can also assign default values to your params, read them from console if not available or stop script execution:
param (
[string]$server = "http://defaultserver",
[Parameter(Mandatory=$true)][string]$username,
[string]$password = $( Read-Host "Input password, please" )
)
Inside the script you can simply
write-output $server
since all parameters become variables available in script scope.
In this example, the `$server` gets a default value if the script is called without it, script stops if you omit the `-username` parameter and asks for terminal input if `-password` is omitted.
Update: You might also want to pass a "flag" (a boolean true/false parameter) to a PowerShell script. For instance, your script may accept a "force" where the script runs in a more careful mode when force is not used.
The keyword for that is `[switch]` parameter type:
param (
[string]$server = "http://defaultserver",
[string]$password = $( Read-Host "Input password, please" ),
[switch]$force = $false
)
Inside the script then you would work with it like this:
if ($force) {
//deletes a file or does something "bad"
}
Now, when calling the script you'd set the switch/flag parameter like this:
.\yourscript.ps1 -server "http://otherserver" -force
If you explicitly want to state that the flag is not set, there is a special syntax for that
.\yourscript.ps1 -server "http://otherserver" -force:$false
Links to relevant Microsoft documentation (for PowerShell 5.0; tho versions 3.0 and 4.0 are also available at the links):
- about_Scripts
- about_Functions
- about_Functions_Advanced_Parameters
Problem
What is the "best" way to handle command-line arguments? It seems like there are several answers on what the "best" way is and as a result I am stuck on how to handle something as simple as: ``` script.ps1 /n name /d domain ``` AND ``` script.ps1 /d domain /n name. ``` Is there a plugin that can handle this better? I know I am reinventing the wheel here. Obviously what I have already isn't pretty and surely isn't the "best", but it works.. and it is UGLY. ``` for ( $i = 0; $i -lt $args.count; $i++ ) { if ($args[ $i ] -eq "/n"){ $strName=$args[ $i+1 ]} if ($args[ $i ] -eq "-n"){ $strName=$args[ $i+1 ]} if ($args[ $i ] -eq "/d"){ $strDomain=$args[ $i+1 ]} if ($args[ $i ] -eq "-d"){ $strDomain=$args[ $i+1 ]} } Write-Host $strName Write-Host $strDomain ```
Related problems
- Powershell non-positional, optional params
- PowerShell 2.0 and "The term 'Param' is not recognized as the name of a cmdlet, function, script file, or operable program"
- How to check if a PowerShell optional argument was set by caller
- How can I pass an argument to a PowerShell script?
- Import-PSSession fails in script, works in shell