User Rating: 0 / 5

Star InactiveStar InactiveStar InactiveStar InactiveStar Inactive
 

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.

If you have questions about our products, please post in our support forum.
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 Trial Software Questions forum.
Copyright © 2017 SAPIEN Technologies, Inc.