Running PowerShell Scripts From TestComplete

Applies to TestComplete 14.92, last modified on September 16, 2021
Information in this topic applies to desktop applications only.

PowerShell is a command-line shell and a scripting language for Windows that lets you automate many tasks on the local and remote computers. PowerShell is based on .NET Framework and can use .NET assemblies, classes, and methods.

PowerShell is included in Windows starting with Windows 7.

There are several ways to run PowerShell scripts from TestComplete tests, depending on whether you want to get the script result.

Run PowerShell Script Without Getting the Result

The easiest way to run PowerShell scripts from TestComplete tests is to use the PowerShell command-line executable, PowerShell.exe. To run PowerShell code without getting its result, you can use a script like this:

JavaScript

getActiveXObject("WScript.Shell").Run("powershell -file C:\\MyScript.ps1");

// Run one command.
getActiveXObject("WScript.Shell").Run("powershell -command echo Test");

JScript

Sys.OleObject("WScript.Shell").Run("powershell -file C:\\MyScript.ps1");

// Run one command.
Sys.OleObject("WScript.Shell").Run("powershell -command echo Test");

Python

# Run a script
Sys.OleObject["WScript.Shell"].Run("powershell -file C:\\MyScript.ps1"); 

# Run one command
Sys.OleObject["WScript.Shell"].Run("powershell -command echo Test");

VBScript

' Run a script
Call Sys.OleObject("WScript.Shell").Run("powershell -file C:\MyScript.ps1")

' Run one command
Call Sys.OleObject("WScript.Shell").Run("powershell -command echo Test")

DelphiScript

// Run a script
Sys.OleObject('WScript.Shell').Run('powershell -file C:\MyScript.ps1');

// Run one command
Sys.OleObject('WScript.Shell').Run('powershell -command echo Test');

C++Script, C#Script

// Run a script
Sys["OleObject"]("WScript.Shell")["Run"]("powershell -file C:\\MyScript.ps1");

// Run one command
Sys["OleObject"]("WScript.Shell")["Run"]("powershell -command echo Test");

TestComplete also allows to use a WshShell object instead of the Sys.OleObject(WScript.Shell), like in following examples:

JavaScript, JScript

// Run a script
WshShell.Run("powershell -file C:\\MyScript.ps1")

// Run one command
WshShell.Run("powershell -command echo Test")

Python

# Run a script
WshShell.Run("powershell -file C:\MyScript.ps1")

# Run one command
WshShell.Run("powershell -command echo Test")

VBScript

' Run a script
Call WshShell.Run("powershell -file C:\MyScript.ps1")

' Run one command
Call WshShell.Run("powershell -command echo Test")

DelphiScript

// Run a script
WshShell.Run('powershell -file C:\MyScript.ps1');

// Run one command
WshShell.Run('powershell -command echo Test');

C++Script, C#Script

// Run a script
WshShell["Run"]("powershell -file C:\\MyScript.ps1");

// Run one command
WshShell["Run"]("powershell -command echo Test");

Note: To learn more about WshShell object, see its description.

For more information on PowerShell command-line arguments, see:

PowerShell.exe Command-Line Help

Run PowerShell Script and Get the Result as Text

Command-line applications, including PowerShell.exe, write results to the so-called standard output of the console. To run a PowerShell script and read its output as text, you need to:

  1. Run PowerShell via the command line by using the Exec method of the WScript.Shell scripting object.

  2. Read the StdOut property of the resulting Exec object.

The example below runs PowerShell’s Get-Process command to get a list of running processes and then outputs the results to the test log line by line.

JavaScript

function GetProcesses()
{
  var oShell = getActiveXObject("WScript.Shell"); // Or oShell = WshShell
  var oExec = oShell.Exec("powershell -command Get-Process");
  oExec.StdIn.Close(); // Close standard input before reading output

  // Get PowerShell output
  var strOutput = oExec.StdOut.ReadAll();
  // Trim leading and trailing empty lines
  strOutput = aqString.Trim(strOutput, aqString.stAll);

  // Post PowerShell output to the test log line by line
  aqString.ListSeparator = "\r\n";
  for (var i = 0; i < aqString.GetListLength(strOutput); i++)
  {
    Log.Message(aqString.GetListItem(strOutput, i));
  }
}

JScript

function GetProcesses()
{
  var oShell = Sys.OleObject("WScript.Shell"); // Or oShell = WshShell
  var oExec = oShell.Exec("powershell -command Get-Process");
  oExec.StdIn.Close(); // Close standard input before reading output

  // Get PowerShell output
  var strOutput = oExec.StdOut.ReadAll();
  // Trim leading and trailing empty lines
  strOutput = aqString.Trim(strOutput, aqString.stAll);

  // Post PowerShell output to the test log line by line
  aqString.ListSeparator = "\r\n";
  for (var i = 0; i < aqString.GetListLength(strOutput); i++)
  {
    Log.Message(aqString.GetListItem(strOutput, i));
  }
}

Python

def Test():
  oShell = Sys.OleObject["WScript.Shell"] # or oShell = WshShell
  oExec = oShell.Exec("powershell -command Get-Process")
  oExec.StdIn.Close() # Close standard input before reading output

  # Get PowerShell output
  strOutput = oExec.StdOut.ReadAll();
  # Trim leading and trailing empty lines
  strOutput = aqString.Trim(strOutput, aqString.stAll);

  # Post PowerShell output to the test log line by line
  aqString.ListSeparator = "\r\n";
  for i in range(0, aqString.GetListLength(strOutput)):
    Log.Message(aqString.GetListItem(strOutput, i))

VBScript

Sub GetProcesses
  Dim oShell, oExec, strOutput, i

  Set oShell = Sys.OleObject("WScript.Shell") ' or oShell = WshShell
  Set oExec = oShell.Exec("powershell -command Get-Process")
  oExec.StdIn.Close ' Close standard input before reading output

  ' Get PowerShell output
  strOutput = oExec.StdOut.ReadAll
  ' Trim leading and trailing empty lines
  strOutput = aqString.Trim(strOutput, aqString.stAll)

  ' Post PowerShell output to the test log line by line
  aqString.ListSeparator = vbCrLf
  For i = 0 To aqString.GetListLength(strOutput) - 1
    Call Log.Message(aqString.GetListItem(strOutput, i))
  Next
End Sub

DelphiScript

procedure GetProcesses;
var oShell, oExec, strOutput, i;
begin 
  oShell := Sys.OleObject('WScript.Shell'); // or oShell := WshShell
  oExec := oShell.Exec('powershell -command Get-Process');
  oExec.StdIn.Close; // Close standard input before reading output

  // Get PowerShell output
  strOutput := oExec.StdOut.ReadAll;
  // Trim leading and trailing empty lines
  strOutput := aqString.Trim(strOutput, aqString.stAll);

  // Post PowerShell output to the test log line by line
  aqString.ListSeparator := #13#10;
  for i := 0 to aqString.GetListLength(strOutput)-1 do
  begin
    Log.Message(aqString.GetListItem(strOutput, i));
  end;
end;

C++Script, C#Script

function GetProcesses()
{
  var oShell = Sys["OleObject"]("WScript.Shell"); // or oShell = WshShell
  var oExec = oShell["Exec"]("powershell -command Get-Process");
  oExec["StdIn"]["Close"](); // Close standard input before reading output

  // Get PowerShell output
  var strOutput = oExec["StdOut"]["ReadAll"]();
  // Trim leading and trailing empty lines
  strOutput = aqString["Trim"](strOutput, aqString["stAll"]);

  // Post PowerShell output to the test log line by line
  aqString["ListSeparator"] = "\r\n";
  for (var i = 0; i < aqString["GetListLength"](strOutput); i++)
  {
    Log["Message"](aqString["GetListItem"](strOutput, i));
  }
}

Run PowerShell Script and Get the Result as an Object

You can also get PowerShell results as .NET objects rather than text. This way you can process PowerShell results by reading object properties instead of parsing text.

To use this approach, you need to add the System.Management.Automation assembly to your project’s CLR Bridge options:

  • Select Tools | Current Project Properties from the TestComplete main menu.

  • Select the CLR Bridge category.

  • Click Browse GAC, select the check box next to the System.Management.Automation assembly and click OK.

Now you can use PowerShell’s .NET class, System.Management.Automation.PowerShell, to work with PowerShell from TestComplete. For more information on this class and its members, see:

PowerShell Members

Start by creating a PowerShell object:

JavaScript, JScript

var PowerShell = dotNET.System_Management_Automation.PowerShell.Create();

Python

PowerShell = dotNET.System_Management_Automation.PowerShell.Create()

VBScript

Set PowerShell = dotNET.System_Management_Automation.PowerShell.Create

DelphiScript

PowerShell := dotNET.System_Management_Automation.PowerShell.Create;

C++Script, C#Script

var PowerShell = dotNET["System_Management_Automation"]["PowerShell"]["Create"]();

Then, use the AddScript method to specify PowerShell commands or scripts to run. You can specify a single command, a pipeline with several commands or a path to a PowerShell script file.

JavaScript, JScript

// Add one command
PowerShell.AddScript("Get-Process");

// Add a pipeline with several commands
PowerShell.AddScript("Get-Process iexplore | Stop-Process");

// Add a script file
PowerShell.AddScript("C:\\Tests\\Script.ps1");

Python

# Add one command
PowerShell.AddScript("Get-Process")

# Add a pipeline with several commands
PowerShell.AddScript("Get-Process iexplore | Stop-Process")

# Add a script file
PowerShell.AddScript("C:\\Tests\\Script.ps1")

VBScript

' Add one command
Call PowerShell.AddScript("Get-Process")

' Add a pipeline with several commands
Call PowerShell.AddScript("Get-Process iexplore | Stop-Process")

' Add a script file
Call PowerShell.AddScript("C:\Tests\Script.ps1")

DelphiScript

// Add one command
PowerShell.AddScript('Get-Process');

// Add a pipeline with several commands
PowerShell.AddScript('Get-Process iexplore | Stop-Process');

// Add a script file
PowerShell.AddScript('C:\Tests\Script.ps1');

C++Script, C#Script

// Add one command
PowerShell["AddScript"]("Get-Process");

// Add a pipeline with several commands
PowerShell["AddScript"]("Get-Process iexplore | Stop-Process");

// Add a script file
PowerShell["AddScript"]("C:\\Tests\\Script.ps1");

To run the specified PowerShell script and get the results, use the Invoke method:

JavaScript, JScript

var results = PowerShell.Invoke();

Python

results = PowerShell.Invoke();

VBScript

Set results = PowerShell.Invoke

DelphiScript

results := PowerShell.Invoke;

C++Script, C#Script

var results = PowerShell["Invoke"]();

The Invoke method returns a collection of PSObject objects that are wrappers for the actual returned .NET objects. To get a real .NET object from a PSObject, use the ImmediateBaseObject property.

The following example gets the last 10 errors and warnings from the Windows event log and posts them to the test log.

JavaScript, JScript

function GetEventLog()
{
  var PowerShell, colEvents, oEvent, i;

  PowerShell = dotNET.System_Management_Automation.PowerShell.Create();

  PowerShell.AddScript('get-eventlog system -entrytype ("Error", "Warning") -newest 10');
  colEvents = PowerShell.Invoke();

  for (i = 0; i < colEvents.Count; i++)
  {
     oEvent = colEvents.Item(i).ImmediateBaseObject;

     Log.AppendFolder("Source: " + oEvent.Source);
     Log.Message("Type: " + oEvent.EntryType);
     Log.Message("Time: " + aqConvert.VarToStr(oEvent.TimeGenerated));
     Log.Message("Index: " + aqConvert.VarToStr(oEvent.Index));
     Log.Message("InstanceID: " + aqConvert.VarToStr(oEvent.InstanceID));
     Log.Message("MachineName: " + oEvent.MachineName);
     Log.Message("Message: (See Details)", oEvent.Message);
     Log.Message("UserName: " + oEvent.UserName);
     Log.Message("EventID: " + aqConvert.VarToStr(oEvent.EventID));
     Log.PopLogFolder();
  }
}

Python

def GetEventLog():
  PowerShell = dotNET.System_Management_Automation.PowerShell.Create()

  PowerShell.AddScript('get-eventlog system -entrytype ("Error", "Warning") -newest 10')
  colEvents = PowerShell.Invoke()

  for i in range (0, colEvents.Count):
     oEvent = colEvents.Item[i].ImmediateBaseObject

     Log.AppendFolder("Source: " + aqConvert.VarToStr(oEvent.Source))
     Log.Message("Type: " + aqConvert.VarToStr(oEvent.EntryType))
     Log.Message("Time: " + aqConvert.VarToStr(oEvent.TimeGenerated))
     Log.Message("Index: " + aqConvert.VarToStr(oEvent.Index))
     Log.Message("InstanceID: " + aqConvert.VarToStr(oEvent.InstanceID))
     Log.Message("MachineName: " + aqConvert.VarToStr(oEvent.MachineName))
     Log.Message("Message: (See Details)", aqConvert.VarToStr(oEvent.Message))
     Log.Message("UserName: " + aqConvert.VarToStr(oEvent.UserName))
     Log.Message("EventID: " + aqConvert.VarToStr(oEvent.EventID))
     Log.PopLogFolder()

VBScript

Sub GetEventLog
  Dim PowerShell, colEvents, oEvent, i

  Set PowerShell = dotNET.System_Management_Automation.PowerShell.Create

  Call powerShell.AddScript("get-eventlog system -entrytype (""Error"", ""Warning"") -newest 10")
  Set colEvents = powerShell.Invoke

  For i = 0 To colEvents.Count -1
    Set oEvent = colEvents.Item(i).ImmediateBaseObject

    Call Log.AppendFolder("Source: " & oEvent.Source)
    Call Log.Message("Type: " & oEvent.EntryType)
    Call Log.Message("Time: " & aqConvert.VarToStr(oEvent.TimeGenerated))
    Call Log.Message("Index: " & aqConvert.VarToStr(oEvent.Index))
    Call Log.Message("InstanceID: " & aqConvert.VarToStr(oEvent.InstanceID))
    Call Log.Message("MachineName: " & oEvent.MachineName)
    Call Log.Message("Message: (See Details)", oEvent.Message)
    Call Log.Message("UserName: " & aqConvert.VarToStr(oEvent.UserName))
    Call Log.Message("EventID: " & aqConvert.VarToStr(oEvent.EventID))
    Call Log.PopLogFolder
  Next
End Sub

DelphiScript

procedure GetEventLog;
var PowerShell, colEvents, oEvent, i;
begin
  PowerShell := dotNET.System_Management_Automation.PowerShell.Create();

  PowerShell.AddScript('get-eventlog system -entrytype ("Error", "Warning") -newest 10');
  colEvents := PowerShell.Invoke;

  for i := 0 to colEvents.Count - 1 do
  begin
    oEvent := colEvents.Item(i).ImmediateBaseObject;

    Log.AppendFolder('Source: ' + oEvent.Source);
    Log.Message('Type: ' + oEvent.EntryType);
    Log.Message('Time: ' + aqConvert.VarToStr(oEvent.TimeGenerated));
    Log.Message('Index: ' + aqConvert.VarToStr(oEvent.Index));
    Log.Message('InstanceID: ' + aqConvert.VarToStr(oEvent.InstanceID));
    Log.Message('MachineName: ' + oEvent.MachineName);
    Log.Message('Message: (See Details)', oEvent.Message);
    Log.Message('UserName: ' + oEvent.UserName);
    Log.Message('EventID: ' + aqConvert.VarToStr(oEvent.EventID));
    Log.PopLogFolder;
  end;
end;

C++Script, C#Script

function GetEventLog()
{
  var PowerShell, colEvents, oEvent, i;

  PowerShell = dotNET["System_Management_Automation"]["PowerShell"]["Create"]();

  PowerShell["AddScript"]('get-eventlog system -entrytype ("Error", "Warning") -newest 10');
  colEvents = PowerShell["Invoke"]();

  for (i = 0; i < colEvents["Count"]; i++)
  {
     oEvent = colEvents["Item"](i)["ImmediateBaseObject"];

     Log.AppendFolder("Source: " + oEvent["Source"]);
     Log["Message"]("Type: " + oEvent["EntryType"]);
     Log["Message"]("Time: " + aqConvert["VarToStr"](oEvent["TimeGenerated"]));
     Log["Message"]("Index: " + aqConvert["VarToStr"](oEvent["Index"]));
     Log["Message"]("InstanceID: " + aqConvert["VarToStr"](oEvent["InstanceID"]));
     Log["Message"]("MachineName: " + oEvent["MachineName"]);
     Log["Message"]("Message: (See Details)", oEvent["Message"]);
     Log["Message"]("UserName: " + oEvent["UserName"]);
     Log["Message"]("EventID: " + aqConvert["VarToStr"](oEvent["EventID"]));
     Log["PopLogFolder"]();
  }
}

See Also

Using External Functions
Calling Functions From .NET Assemblies

Highlight search results