cancel
Showing results for 
Search instead for 
Did you mean: 

VBO to Invoke PowerShell Files

StefanSchnell1
Level 7

Hello Community,

these days I tried to build my first own VBO. I thought a Code Stage that executes a PowerShell script might be a good example. So I developed a small routine that reads and executes a PowerShell script. It also offers the possibility to pass parameters to the script. Here the code:

//-Begin----------------------------------------------------------------

//-Initialization of output variables-----------------------------------
ErrorMessage = "";
Result = "";

//-Check if file exists-------------------------------------------------
if(!File.Exists(PowerShellFileName)) {
  ErrorMessage = "File not found";
  return;
}

//-Read the content of the file and check-------------------------------
string PSCode = File.ReadAllText(PowerShellFileName);
if(System.String.IsNullOrEmpty(PSCode)) {
  ErrorMessage = "Code missed";
  return;
}

//-Checking the Separator-----------------------------------------------
if(System.String.IsNullOrEmpty(Separator)) {
  Separator = ",";
}

//-Read parameters and add it to a list---------------------------------
object[] Params = null;
if(!System.String.IsNullOrEmpty(Parameters)) {
  string[] partsParam = Parameters.Split(new char[] {Separator[0]});
  Params = new List<string>(partsParam).ToArray();
}

//-Open the runspace----------------------------------------------------
Runspace runspace;

try {

  runspace = RunspaceFactory.CreateRunspace();
  if(STA == true) {
    runspace.ApartmentState = System.Threading.ApartmentState.STA;
  } else {
    runspace.ApartmentState = System.Threading.ApartmentState.MTA;
  }
  runspace.ThreadOptions = PSThreadOptions.ReuseThread;
  runspace.Open();

} catch(System.Exception ex) {
  ErrorMessage = ex.Message;
  return;
}

//-Create PowerShell----------------------------------------------------
System.Management.Automation.PowerShell PS;

try {

  PS = System.Management.Automation.PowerShell.Create();
  PS.Runspace = runspace;
  PS.AddScript(PSCode);

} catch(System.Exception ex) {
  runspace.Close();
  ErrorMessage = ex.Message;
  return;
}

//-Add parameters to PowerShell-----------------------------------------
if(Params != null) {
  foreach(string PSParam in Params) {
    string[] partsPSParam = PSParam.Split('=');
    PS.AddParameter(partsPSParam[0].Trim(), partsPSParam[1].Trim());
  }
}

//-Invoke PowerShell----------------------------------------------------
try {

  Collection<PSObject> Ret = PS.Invoke();
  runspace.Close();

  //-Set Result---------------------------------------------------------
  StringBuilder stringBuilder = new StringBuilder();
  foreach(PSObject oPS in Ret) {
    stringBuilder.AppendLine(oPS.ToString());
  }
  Result = stringBuilder.ToString();

} catch(System.Exception ex) {
  runspace.Close();
  ErrorMessage = ex.Message;
  return;
}

//-End------------------------------------------------------------------

There are the input parameters

  • PowerShellFileName = Path and name of the PowerShell script which should be executed.
  • Parameters = Parameters of the PowerShell script, if available.
  • Separator = The separator between the parameters, default is a comma.
  • STA = Single-Threaded Apartment if true, Multi Threaded Apartment if false, default is true.

There are the output parameters

  • Result = Output of the PowerShell script.
  • ErrorMessage = In case of error an explanatory text.

12672.png

To test it I use this PowerShell script example, with a few parameters and an output:

#-Begin-----------------------------------------------------------------

Param (
  [String]$var1,
  [String]$var2,
  [String]$desc,
  [Int]$i
)

$varHost = Get-Host;

$Ret = $Null;
For($j = 1; $j -le $i; $j++) {
  $Ret += "PowerShell greets " + $j + "`r`n";
}
$Ret += "Hello World via " + $var1 + " version " + $var2 + " from ";
$Ret += $varHost.Name + " " + $varHost.Version + "`r`n";
$Ret += $desc;
$Ret | Out-String;

#-End-------------------------------------------------------------------

12673.png

It works as expected. As far as I can see, this should make it easier to integrate PowerShell into Blue Prism processes. Since the basis is available with Windows, this approach should be executable without additional installations. In some cases, such integration can be very profitable, for example if consolidated scripts already exist and can be further used.

Best regards
Stefan



------------------------------
Stefan Schnell
Senior Systems Engineer at BWI GmbH
------------------------------

38 REPLIES 38

ritansh.jatwani
Level 9

Great  @StefanSchnell1 for making a useful utility.



------------------------------
Ritansh Jatwani
Consultant
EY
Gurgaon
------------------------------

StefanSchnell1
Level 7
Hello Community,
I have modified the code of the VBO a little bit to make it possible to store the PowerShell code inside the object. Now it is possible to select whether the PowerShell code should be loaded from an external file or if the code is passed.
Best regards
Stefan

//-Begin----------------------------------------------------------------

//-Initialization of output variables-----------------------------------
ErrorMessage = "";
Result = "";
string PSCode = "";

if(System.String.IsNullOrEmpty(PowerShellFileName)) {
  PSCode = PowerShellCode;
} else {
  //-Check if file exists-----------------------------------------------
  if(!File.Exists(PowerShellFileName)) {
    ErrorMessage = "File not found";
    return;
  }
  //-Read the content of the file---------------------------------------
  PSCode = File.ReadAllText(PowerShellFileName);
}

//-Check if code is available-------------------------------------------
if(System.String.IsNullOrEmpty(PSCode)) {
  ErrorMessage = "Code missed";
  return;
}

//-Checking the Separator-----------------------------------------------
if(System.String.IsNullOrEmpty(Separator)) {
  Separator = ",";
}

//-Read parameters and add it to a list---------------------------------
object[] Params = null;
if(!System.String.IsNullOrEmpty(Parameters)) {
  string[] partsParam = Parameters.Split(new char[] {Separator[0]});
  Params = new List<string>(partsParam).ToArray();
}

//-Open the runspace----------------------------------------------------
Runspace runspace;

try {

  runspace = RunspaceFactory.CreateRunspace();
  if(STA == true) {
    runspace.ApartmentState = System.Threading.ApartmentState.STA;
  } else {
    runspace.ApartmentState = System.Threading.ApartmentState.MTA;
  }
  runspace.ThreadOptions = PSThreadOptions.ReuseThread;
  runspace.Open();

} catch(System.Exception ex) {
  ErrorMessage = ex.Message;
  return;
}

//-Create PowerShell----------------------------------------------------
System.Management.Automation.PowerShell PS;

try {

  PS = System.Management.Automation.PowerShell.Create();
  PS.Runspace = runspace;
  PS.AddScript(PSCode);

} catch(System.Exception ex) {
  runspace.Close();
  ErrorMessage = ex.Message;
  return;
}

//-Add parameters to PowerShell-----------------------------------------
if(Params != null) {
  foreach(string PSParam in Params) {
    string[] partsPSParam = PSParam.Split('=');
    PS.AddParameter(partsPSParam[0].Trim(), partsPSParam[1].Trim());
  }
}

//-Invoke PowerShell----------------------------------------------------
try {

  Collection<PSObject> Ret = PS.Invoke();
  runspace.Close();

  //-Set Result---------------------------------------------------------
  StringBuilder stringBuilder = new StringBuilder();
  foreach(PSObject oPS in Ret) {
    stringBuilder.AppendLine(oPS.ToString());
  }
  Result = stringBuilder.ToString();

} catch(System.Exception ex) {
  runspace.Close();
  ErrorMessage = ex.Message;
  return;
}

//-End------------------------------------------------------------------
​

12426.png


------------------------------
Stefan Schnell
Senior Systems Engineer at BWI GmbH
------------------------------

Hey Stefan, really good job on this.

This allows for a lot of possibilities, triggering schedules on other resources is what I´m most excited for.



------------------------------
Atli Harðarson
------------------------------

Hello Atli,

thank you very much.

Best regards
Stefan

------------------------------
Stefan Schnell
Senior Systems Engineer at BWI GmbH
------------------------------

Hello Community,
here a slightly extended version.
Best regards
Stefan

------------------------------
Stefan Schnell
Senior Systems Engineer at BWI GmbH
------------------------------

Hi Stefan,
Have you considered submitting this as an asset on the Blue Prism Digital Exchange?
You can do this by going to the DX (https://digitalexchange.blueprism.com/) and clicking My Account -> Submit Asset.
#DigitalExchange

------------------------------
Patrick Aucoin
Senior Product Consultant
Blue Prism
------------------------------

@PatrickAucoin

Hello Patrick,
thanks for your reply.
No, I haven't even thought of that yet, but it is my pleasure to do that. Thank you very much for your hint.
Best regards
Stefan



------------------------------
Stefan Schnell
Senior Systems Engineer at BWI GmbH
------------------------------

Hi Stefan

Thanks for your fantastic job on this. I really appreciate it. ​



------------------------------
Pia van Acker
Digitaliseringskonsulent
Gladsaxe Commune
Europe/Copenhagen
------------------------------

Hello Pia,

thank you very much.

Best regards
Stefan

------------------------------
Stefan Schnell
Senior Systems Engineer at BWI GmbH
------------------------------