Using the PowerShell Definition Type
The Microsoft Windows PowerShell is a shell meant for interactive use that can also be used for non-interactive scripts. It comes as standard with Microsoft Server 2008 and later.
note
You must assign at least one process server to run PowerShell processes in order to use the definition type.
The PowerShell is very strong in interacting with .Net objects, as it can pass objects between different 'cmdlets' instead of strings, as in most shells.
32/64-bit
By default, the 32-bit versions of the interpreters are used on Windows platforms, this can be changed using the following:
JCS_INTERPRETER_PS1
- parameter used to override default, can be set toC:/Windows/Sysnative/WindowsPowershell/v1.0/powershell.exe
for 64-bit; default when non-existent or empty and process server parameterLocalInterpreter_PS1
not set:C:/Windows/System32/WindowsPowershell/v1.0/powershell.exe
InterpreterWhitelist_PS1
- process server parameter that takes a regex expression matching all interpreters you want supported. Use*
. to allow any orC:/Windows/.*/powershell.exe
to allow anypowershell.exe
in a subfolder ofC:/Windows
. You can also explicitly set two separated by a comma without space (regex syntax):C:/Windows/Sysnative/WindowsPowershell/v1.0/powershell.exe,C:/Windows/System32/WindowsPowershell/v1.0/powershell.exe
LocalInterpreter_PS1
- process server parameter used to set default to 64-bit, can be set toC:/Windows/Sysnative/WindowsPowershell/v1.0/powershell.exe
for 64-bit; affects all processes for the process server that do not haveJCS_INTERPRETER_PS1
set, default or when not set:C:/Windows/System32/WindowsPowershell/v1.0/powershell.exe
- LocalInterpreterBits - Set this key to
64
and all Windows platform agents will use 64-Bit interpreters.
note
Remember that on 64-bit Windows platforms the System32
directory contains 64-bit binaries and SYSWOW64
is the directory containing 32-bit binaries.
note
In Windows 64-bit, you have to explicitly call the 32-bit binaries to access C:\\Windows\\Sysnative
; the path does not exist for 64-bit applications.
Execution Policy
The default execution policy of the PowerShell is Restricted, which does not allow the execution of scripts. As of v9.0.2 Redwood Server calls the powershell scripting engine in a mode that enables scripting for that session only, making it no longer necessary to set the execution policy beforehand.
Background and Foreground Processes
By default, commands are executed in the background; you will not see any dialog in the server. If you want to display a process on-screen, you use the {session}
or {console}
keywords in the Run As User field followed by the credential or username and password.
{session}
- RDP, Windows Terminal Server, or console session{console}
- Console session, only; console sessions are displayed on the physical monitor screen attached to the server.
note
The specified user must be logged in to a console session (for {console}
) or any type of the supported sessions (for {session}
) or the process will reach status Error.
note
Sessions are always for a user account; it is not possible to run session/console Processes under NT Authority\LocalSystem
.
Examples
Specifying a Run As User field with {session}
and virtual user
{session}{virtual}:ops
Specifying a Run As User field with {console}
and credential
{console}example@example.corp
Variables and Parameters
- Parameters to the process definition are manipulated in the PS1 source simply as if they are variables, using the standard $VARIABLE syntax. You can also use
get-variable -name <name> -scope global
. - The PowerShell language has knowledge of data-types. The String and Number data-types are supported. DateTimeZone parameters are stored in DateTime variables. This means that you cannot transfer the time zone of a parameter to a PowerShell variable; it will be converted to the corresponding date-time in the local time zone of the Microsoft Windows system. Out parameters are converted to UTC (GMT).
- Out parameters are supported by setting the parameter using the
$VARIABLE = VALUE
syntax or theSet-Variable
,New-Variable
cmdlets. - Array parameters are now supported in PowerShell, limited to unique elements, only.
Error Handling
If your script code exits with an error this is correctly reflected in the server, and output parameters are set as far as they were already set. Do note that the PS1 process modifies ErrorActionPreference
, its default value in Redwood Server is "Stop". If you want your script to continue on error set it to "Continue" (default in PowerShell) in the beginning of your script:
$ErrorActionPreference = "Continue"
Apartment Models
Microsoft Windows has a concept of an "Apartment model". This is a remnant of (very) old Windows versions where it was usual that COM and OLE objects were not multi-threaded, and would not be usable from a multi-threaded application. To get around this Microsoft developed a set of shims that allow multi-threaded applications such as PowerShell to funnel all access to COM and OLE objects through a single thread. This is called the Single Thread Apartment model. Depending on which commandlets and COM/OLE objects you call you may need to have the PowerShell started either in Single Thread Apartment (STA) or Multi Thread Apartment (MTA) model.
Redwood Server starts the PowerShell in its default mode. For v1 and v2 of PowerShell this is MTA. For v3 it is STA. Note that Windows PowerShell ISE is always started in STA mode.
If you want to use an explicit model, specify the LocalInterpreter_PS1 process server parameter and set it to
powershell -sta
or
powershell -mta
Examples
Parameters
The following shows how to pass numeric (N1), string (S1) and date (D1) parameters to and from PS1 scripts:
$N1=$N1 + $N1
# Concatenate string
$S1="$S1 $S1"
[datetime]$DTEMP="2023/10/02 23:59:59Z"
echo "You said $D1, I prefer $DTEMP"
$D1=$DTEMP
Error Out
The following example shows you how to return a non-zero exit code resulting in the process going into Error:
$N=1
echo "Exiting with value $N."
if ($N -gt 0)
{
[Environment]::Exit($N);
}
echo "Not reached"
Rename Files
The following example shows how to rename all the files in a directory:
ls | foreach {ren $_.fullname $_.name.replace("BI1", "BI2")}
Display Bittiness
if ([System.IntPtr]::Size -eq 4) { "32-bit" } else { "64-bit" }
Arrays
The following example shows how to use arrays in PowerShell; the process definition has two Out parameters, myArray and myArrayLength, the first will be filled with values as specified in the source, the second will contain the number of elements in the array. Note that numbers are formatted according to your locale; with a German locale, for example, the array will be displayed as 10,Hello,3,54321,World
, note the decimal mark is a,
in German locales. In this example, the myArrayLength
parameter is correctly filled with 4
.
$myArray = @(10,"Hello",3.54321,"World")
foreach ($i in $myArray) {
write-host $myArray[$i]
}
Populating an array parameter (Out, or In/Out parameter) from Powershell; notice the comma to indicate to append to existing array.
$MyOutArray = $MyOutArray
$myArray = @(10,"Hello",3.54321,"World")
foreach ($i in $myArray) {
$MyOutArray = $MyOutArray + ,$myArray[$i]
}
Taking a Screenshot of an Application
The following example requires a Run As User field prefix of {session}
followed by a user/credential. A session must be open on the target host (where the platform agent runs) for that user.
$app = Start-Process notepad -ArgumentList /redwood/Books.rtx -passthru
#Sleep some to ensure notepad has time to open
start-sleep -m 500
jtool screenshot -p $app.Id
$app.CloseMainWindow()
$app.Close()