1. Parameters in Powershell scripts

    Article: AN0002411Updated: 01.05.2020

    In this article we will show how to pass parameters into Powershell scripts emphasizing the differences between a common execution of Powershell script from the command line and execution by Piklo program. We will provide here rules described in the documentation of the program Piklo.

    First we will show an example of a Powershell script.

    Executing Powershell script from the command line

    In our first example we are going to create a file by means of Powershell script, that we will call e.g. _Test_param.ps1. We can see that the script is taking over two arguments, with which it should be executed, in the first couple of lines of code which define variables. Another variable is compounding the resulting value from the first two variables and the last two are defined as constants: text and encoding.

    # --- Variables
    [string]$Root = $args[0]
    [string]$OutputName = $args[1]
    [string]$OutputFile = "$($Root)\$($OutputName)"
    [string]$FileContent = "Text to be included in the file"
    [string]$Encoding = "UTF8"
    # #########################################################################################################
    # ---------------------------------------------------------------------------------------------------------
    $FileContent | Out-File -filepath $OutPutFile -Encoding $Encoding -append -ErrorAction SilentlyContinue
    exit

    If we put our file _Test_param.ps1 containing our script into the folder C:\PS\, we will execute it from the command line e.g. like this:

    "C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe" "-File" "C:\PS\_Test_param1.ps1" "C:\PS" "OutputName.txt"

    The script will perform one thing: it will create a text file containing text "Text to be included in the file" in the folder according to the first parameter ("C:\PS") and name according to the second parameter ("OutputName.txt").

    Note: In some cases above stated command may not work - it depends on operating system and patches. In such a case try one of below examples.

    In command line CMD:

    "powershell.exe" "-File" "C:\PS\_Test_param1.ps1" "C:\PS" "OutputName.txt"

    In Powershell console:

    & "powershell.exe" "-File" "C:\PS\_Test_param1.ps1" "C:\PS" "OutputName.txt"

    or

    "powershell.exe" "-File" "C:\PS\_Test_param1.ps1" "C:\PS" "OutputName.txt"

    or

    C:\...\powershell.exe "-File" "C:\PS\_Test_param1.ps1" "C:\PS" "OutputName.txt"

     

    Handling error states

    We should handle error states in the script. These are situations when parameters are not passed to the script or they are erroneous (e.g. the defined folder cannot be accessed or it does not exist). Therefore, two new conditions were added to the script (highlighted in bold and blue) which in case, that less than two arguments will be provided or that the folder path is not accessible, will raise an error message into the command line console and terminate the script.

    # --- Variables
    [string]$Root = $args[0]
    [string]$OutputName = $args[1]
    [string]$OutputFile = "$($Root)\$($OutputName)"
    [string]$FileContent = "Text to be included in the file"
    [string]$Encoding = "UTF8"
    # #########################################################################################################
    # ---------------------------------------------------------------------------------------------------------
    IF ( $args.Count -lt 2 ) {
    "Error: Parameters were not provided!" | Write-Host -ForegroundColor Red
    exit
    }

    IF ( ! (Test-Path $Root) ) {
    "Error: Path '$($Root)' does not exist!" | Write-Host -ForegroundColor Red
    exit
    }


    $FileContent | Out-File -filepath $OutPutFile -Encoding $Encoding -append -ErrorAction SilentlyContinue

    exit

    We  can execute the script in the same way like in the previous example. In case of not all the parameters are passed or the folder path is not accessible, respective error messages are returned.

    Executing the script from ObjectGears

    We will show now what are the differences when the script is executed from ObjectGears.

    We are starting the process e.g. from a job step, workflow activity or another activity executed by winservice. In case of executing e.g. from the button or class rule, when the given script would be executed by web server, the request would be recycled by MS IIS.

    We shall notice following points in the below example:

    1. We are not defining the executed script with a full file name including the path but only with the name (without suffix). The file is searched in the subfolder Scripts of the folder defined in the element PikloDir (see web.config and winservice.config).
    2. The folder for the output file has doubled backslashes (control character in JavaScript).
    3. The output file is in the folder which is accessible to the winservice account. Folder C:\PS from the previous example will probably not be accessible by this account.
    4. Outcome of the Piklo program call will be stored in a variable which we will write into the log. It will help us resolving possible errors.

    var a = OG.Process.RunPiklo('_Test_param1','-type C C:\\OG_intance1\\Piklo OutputName.txt');
    OG.Log.Write(a);

    The main change compared to the previous examples of executing Powershell files from the command line is in processing the parameters, with which the script _Test_param1 is executed. We are defining type of the execution -type C and then two parameters separated by a space in the above example. Everything is passed in a single text string. Parameters C:\\OG_intance1\\Piklo and OutputFileName.txt will not be available in the script under $args[0] and $args[1], but under variables $ScriptPar1 and $ScriptPar2. Therefore, the script has to be modified:

    # --- Variables
    [string]$Root = $args[0]
    [string]$OutputName = $args[1]
    [string]$OutputFile = "$($Root)\$($OutputName)"
    [string]$FileContent = "Text to be included in the file"
    [string]$Encoding = "UTF8"
    # #########################################################################################################
    # ---------------------------------------------------------------------------------------------------------
    IF ( $args.Count -lt 2 ) {
    #"Error: Parameters were not provided!" | Write-Host -ForegroundColor Red
    $Root = $ScriptPar1
    $OutputName = $ScriptPar2
    $OutputFile = "$($Root)\$($OutputName)"

    }

    IF ( ! (Test-Path $Root) ) {
    #"Error: Path '$($Root)' does not exist!" | Write-Host -ForegroundColor Red
    exit
    }


    $FileContent | Out-File -filepath $OutPutFile -Encoding $Encoding -append -ErrorAction SilentlyContinue

    exit

    Please notice that the variables  $ScriptPar1 and $ScriptPar2 are not defined in the script and despite that we are assigning their value into the variables $Root and $OutputFileName. This is given by the fact that ObjectGears does not execute the script like in the previous example but inserts first into the script parameters with values with which the function is called. Therefore, in case that $args do not contain any values, we do not terminate the script but we assign values $ScriptPar1, $ScriptPar2 etc.

    You can imagine that the above script has at the time of its execution at its beginning (before the block # --- Variables) this:

    [string]$ScriptPar1 = "C:\OG_intance1\Piklo"
    [string]$ScriptPar2 = "OutputFileName.txt"

    We have commented out in the script commands for messages to the command line console because this context is not available when executing by winservice (highlighted in red).

    Parameters from configuration files

    Sometimes it is suitable to pass the parameters by means of configuration files. It is useful e.g. in the case when there is a lot of parameters or when they are shared by many scripts. Within a script itself you can read such custom files. Program Piklo is providing you on top two levels of configuration files that you can use and variables from which you will have available in the script in the same way as parameters $ScriptPar1, $ScriptPar2 ...

    File with parameters common for all the scripts

    The first file is og_configuration.ps1. It is located in the folder of the Piklo program (element PikloDir in web.config and winservice.config). It is useful to define global parameters, which we are going to use in all the scripts, in this folder. A good example is adress of the web service of the ObjectGears instance or default encoding for all the output files.

    [string]$Webservice = "http://yourweb/OGService.asmx"
    [string]$Encoding = "UTF8"

    Web service can be used to read the data by the script from ObjectGears on the fly. E.g. if you want to restart servers belonging to a certain group, you can get their list from the ObjectGears configuration database. If you migrate ObjectGears instance to a new server, the new webservice address can then be updated in a single place and all the scripts will immediately work with this address.

    Files with parameters specific for a particular script

    Furthermore, you have for each script executed by Piklo a configuration file available (in our case it would be called _Test_param.config), in which you will state parameters specific for the given script and you can corrigate the value from the global file mentioned above. E.g.

    [string]$CsvDelimiter = ";"
    [string]$Encoding = "ASCII"

    Let`s assume that we have filled the configuration files according to above examples and we are executing above stated script by means of this command:

    var a = OG.Process.RunPiklo('_Test_param1','-type C C:\\OG_intance1\\Piklo OutputName.txt');
    OG.Log.Write(a);

    The following resulting script will be executed (changes indicated in bold and blue). Notice the triplicate assignment of the value into the variable $Encoding that appears gradually. The first one comes from the common file og_configuration.ps1, second one from the configuration file _Test_param.config and the third one occurs directly in the script _Test_param.ps1 itself. The third assignment will be actually used. It means that when there are parameters (variables) of the same name the parameter from the configuration file for the given script is prioritized over the parameter from the common configuration file and variable defined directly in the script is preferred over parameters from the configuration files.

    [string]$Webservice = "http://youreb/OGService.asmx"
    [string]$Encoding = "UTF8"
    [string]$ScriptPar1 = "C:\OG_intance1\Piklo"
    [string]$ScriptPar2 = "OutputFileName.txt"
    [string]$CsvDelimiter = ";"
    [string]$Encoding = "ASCII"

    # --- Variables
    [string]$Root = $args[0]
    [string]$OutputName = $args[1]
    [string]$OutputFile = "$($Root)\$($OutputName)"
    [string]$FileContent = "Text to be included in the file"
    [string]$Encoding = "UTF8"
    # #########################################################################################################
    # ---------------------------------------------------------------------------------------------------------
    IF ( $args.Count -lt 2 ) {
    #"Error: Parameters were not provided!" | Write-Host -ForegroundColor Red
    $Root = $ScriptPar1
    $OutputName = $ScriptPar2
    $OutputFile = "$($Root)\$($OutputName)"
    }

    IF ( ! (Test-Path $Root) ) {
    #"Error: Path '$($Root)' does not exist!" | Write-Host -ForegroundColor Red
    exit
    }

    $FileContent | Out-File -filepath $OutPutFile -Encoding $Encoding -append -ErrorAction SilentlyContinue

    exit

    You should reach an agreement on parameters in the common configuration file within your organization.

    Bear in mind that each script can be executed with various parameters by means of selecting the configuration file when executing the script (see parameter -config). In such a case parameters from this file are added instead of parameters from the file _Test_param.ps1.

×