27-12-20 04:35 AM
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
There are the output parameters
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-------------------------------------------------------------------
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
------------------------------
03-05-21 07:51 AM
03-05-21 07:59 AM
09-09-21 01:25 PM
Hi Stefan!
Thanks and appreciate your thuoghts, effort and sharing it here. I used your VBO as base and modified to our need. basically what we did is getting the PowerShell modules/ functions installed in the VDI/ mahines. Wrote a C# code that calls/ invokes the Powershell scripts/ function/ modules. It is working perfectly fine when w run in debugging mode (From Process studio). If we try to run the function or process in Control room, I am getting the following error though it works when called in debug mode and in Powershell application. The error is as follows.
ERROR: System Exception : Error occurred while executing Powershell script. Please find the details below.
An error occured while executing code
Exception Details :The term 'userlist' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
This function basically gets the list of users from a DL and saves in CSV format in the location passed in the paramters. We pass the parameter as below.
csvfile=C:\Temp\ADD_Users\Input_File_Add_Users\Input_File_Add_Users_20210909.csv,Name=Previous,csvariable=DL_Name,LogLocation=C:\Temp\ADD_Users
This how it looks in Log from the automation run from control room.
Any help would be greatly appreciated. Thanks!
28-01-22 05:04 PM
29-01-22 09:48 AM
"Param([String]$var1, [String]$var2);Import-Excel $var1 | Export-Csv $var2;"
Parameters:"var1 = ""D:\RCS_BluePrism\RQA Alerts\Input\Archive\PsTesting.xlsx"", var2 = ""D:\RCS_BluePrism\RQA Alerts\Input\Archive\PsTesting.csv"""
09-02-22 09:56 PM
10-02-22 07:27 AM
//-Begin----------------------------------------------------------------
void AddText(FileStream fstream, string value) {
fstream.Seek(fstream.Length, SeekOrigin.Begin);
byte[] info = new UTF8Encoding(true).GetBytes(value);
fstream.Write(info, 0, info.Length);
//fstream.Flush();
};
string[] columnNames = Collection.Columns.Cast<DataColumn>().Select(column => column.ColumnName).ToArray();
using (FileStream fs = File.Create(FileName)) {
AddText(fs, string.Join(Delimiter, columnNames) + Environment.NewLine);
foreach (DataRow row in Collection.Rows) {
string[] fields = row.ItemArray.Select(field => field.ToString()).ToArray();
AddText(fs, string.Join(Delimiter, fields) + Environment.NewLine);
}
}
//-End------------------------------------------------------------------
10-02-22 02:13 PM
10-02-22 04:32 PM
10-02-22 05:12 PM