The Packager and Command line Arguments
- Details
- Written by David Corrales
- Last Updated: 19 April 2016
- Created: 09 February 2010
- Hits: 16229
Also see Revisiting The Packager and Command Line Arguments.
Per forum request, this article provides examples of how to access the packager's command line arguments as well as provide some useful functions to parse the contents. These examples apply to PowerShell Studio's Packager and as well as PrimalScript's packager.
The package's script host provides a convenient string variable named $CommandLine. This variable contains the complete argument string that is passed to the package. To illustrate how the $CommandLine variable is used, a script package named "mypackage.exe" will be executed with the following arguments:
mypackage.exe –Parameter1 Value1 –Parameter2 Value2
The resulting string value of $CommandLine is as follows:
$CommandLine: "–Parameter1" "Value1" "–Parameter2" "Value2"
As you can see all the parameter / values are in a single line and each surrounded by quotes.
Accessing the Argument Parameters
The simplest example of command line argument use is when a parameter is passed and there is no associated value. In order to determine if the argument is present, a simple search of the string will suffice.
For example:
mypackage.exe /? /a<
In this example we only care that "/?" is present; therefore, we only need to search the $CommandLine string for "/?" parameter.
$CommandLine: "/?" "/a" if($CommandLine.Contains("""/?""")) { Write-Host "Found Parameter" }
In other instances a value pair may be needed. The first example above illustrates the value pair.
mypackage.exe –Parameter1 Value1 –Parameter2 Value2
In this case, the information will need to be parsed from the command line string which requires a more complex approach then a simple search. To help facilitate this, a function called Parse-Commandline was created which will parse the $CommandLine string values from the quotes and place them into a StringCollection.
function Parse-Commandline { Param([string]$CommandLine) $Arguments = New-Object System.Collections.Specialized.StringCollection #Find First Quote $index = $CommandLine.IndexOf('"') while ( $index -ne -1) { #Continue as along as we find a quote #Find Closing Quote $closeIndex = $CommandLine.IndexOf('"',$index + 1) if($closeIndex -eq -1) { break #Can't find a match } $value = $CommandLine.Substring($index + 1,$closeIndex – ($index + 1)) [void]$Arguments.Add($value) $index = $closeIndex #Find First Quote $index = $CommandLine.IndexOf('"',$index + 1) } return $Arguments }
Using the following command line will yield these results:
$CommandLine: "–Parameter1" "Value1" "–Parameter2" "Value2"
Results:
$Parameter[0] = –Parameter $Parameter[1] = Value1 $Parameter[2] = –Parameter2 $Parameter[3] = Value2
The parameters can be compared by simply checking each element of the collection. It can be taken even further by creating a function called Convert-ArgumentsToDictionary which will convert the value pairs into a Dictionary (Hashtable). Convert-ArgumentsToDictionary takes two parameters: The first is the parsed StringCollection and the second is a character that denotes a parameter. In the argument string above, the '-' character denotes a parameter.
function Convert-ArgumentsToDictionary { Param([System.Collections.Specialized.StringCollection] $Params, [char] $ParamIndicator) $Dictionary = New-Object System.Collections.Specialized.StringDictionary for($index = 0; $index -lt $Params.Count; $index++) { [string]$param = $Params[$index] #Clear the values $key = "" $value = "" if($param.StartsWith($ParamIndicator)) { #Remove the indicator $key = $param.Remove(0,1) if($index + 1 -lt $Params.Count) { #Check if the next Argument is a parameter [string]$param = $Params[$index + 1] if($param.StartsWith($ParamIndicator) -ne $true ) { #If it isn't a parameter then set it as the value $value = $param $index++ } } $Dictionary[$key] = $value }#else skip } return $Dictionary }
Once the parsed arguments are converted to a Dictionary, simply check for the parameter name and it will return the value.
$value = $Dictionary["Parameter"] if($value –eq $null){ Write-Host "Parameter = {0}" – f $value }
The following script utilizes the functions described above:
#Verify that the $CommandLine variable exists if($CommandLine -ne $null -and $CommandLine -ne "") { $Arguments = Parse-Commandline $CommandLine #Convert the Arguments. Use – as the Argument Indicator $Dictionary= Convert-ArgumentsToHashtable $Arguments '-' #Output the original command line string "Command Line: {0}`r`n" -f $CommandLine | Write-Output #Output the Dictionary in a formatted table $Dictionary | Format-Table @{label="Key";Expression={$_.Key}},@{label="Value";Expression={$_.Value}} | Out-String | Write-Output } else { #Not running in a packager or no command line arguments passed Write-Output "There are no command line arguments to parse." }
The script verifies the $CommandLine variable is not null because it only exists in the package's Script Host. Then the function are used to parse the $CommandLine variable and convert it to a Dictionary. Once the Dictionary is generated, the contents are formatted and displayed.
The results are as follows:
***Run Powershell*** Command Line: "-Parameter1" "Value1" "-Parameter2" "Value2"
Key Value -- -- Parameter2 Value2 Parameter1 Value1 ***Exiting Powershell***
You should now have a better understanding on how to use command line arguments with your packaged scripts. Feel free to use and customize these functions to make accessing the command line arguments quick and easy.
For licensed customers, use the forum associated with your product in our Product Support Forums for Registered Customers.
For users of trial versions, please post in our Former and Future Customers - Questions forum.