How to execute PowerShell script (ps1 file) from C# code

Tarun Kumar Chatterjee
.Net – Technology Specialist
Published On :   31 May 2016
Visit Count
Today :  23    Total :   6722

There are two way-out I found out to call the ps1 file from C#:

1. Created a batch file which will have the code to execute the ps1 file & the batch file will be executed by C# code

Batch files Code:

@echo offPowershell.exe -executionpolicy remotesigned -File  <ps1 file path>

C# code to execute the batch file:

 System.Security.SecureString pass = new System.Security.SecureString();
             string strPass = Admin Password";
             foreach (char c in strPass)
 System.Diagnostics.Process.Start(@"Batch File Path","Admin User ID", pass,"Domain Name");

2. Created RunSpace & Pipeline to execute the ps1 file directly from C# code

 private Collection<PSObject> RunPsScript(string psScriptPath)
             string psScript = string.Empty;
             if (File.Exists(psScriptPath))
                 psScript = File.ReadAllText(psScriptPath);
                 throw new FileNotFoundException("Wrong path for the script file");
             RunspaceConfiguration config = RunspaceConfiguration.Create();
             PSSnapInException psEx;
             //add Microsoft SharePoint PowerShell SnapIn
             PSSnapInInfo pssnap = config.AddPSSnapIn("Microsoft.SharePoint.PowerShell", out  psEx);
             //create powershell runspace
             Runspace cmdlet = RunspaceFactory.CreateRunspace(config);
             RunspaceInvoke scriptInvoker = new RunspaceInvoke(cmdlet);
             // set powershell execution policy to unrestricted
             scriptInvoker.Invoke("Set-ExecutionPolicy Unrestricted");
             // create a pipeline and load it with command object
             Pipeline pipeline = cmdlet.CreatePipeline();
                 // Using Get-SPFarm powershell command 
                 // this will format the output
                 Collection<PSObject> output = pipeline.Invoke();
                 // process each object in the output and append to stringbuilder  
                 StringBuilder results = new StringBuilder();
                 foreach (PSObject obj in output)
                 return output;
             catch(Exception ex)
                 return null;

Here is my ps1 file code to delete the list items:

 if ((Get-PSSnapin -Name "Microsoft.SharePoint.PowerShell" ) -eq $null) {
     Add-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue  
 $rootWeb= Get-Spweb <"Site URL">   
 $listToProcess = $rootWeb.GetList("List URL") 
 $NumberOfItemsToDeleteInBatch = 1000
 if($listToProcess -ne $null)
     $numberOfItemsToRetrieve = $NumberOfItemsToDeleteInBatch;
     $camlQueryString = "<Where><Neq><FieldRef Name='ID'/><Value Type='Counter'>-1</Value></Neq></Where>"
     $viewFields="<FieldRef Name='ID' />"
     $camlQuery = New-Object -TypeName "Microsoft.SharePoint.SPQuery" -ArgumentList @($listToProcess.DefaultView);
     $itemCount = 0;
     $listId = $listToProcess.ID;
     [System.Text.StringBuilder]$batchXml = New-Object "System.Text.StringBuilder";
     $batchXml.Append("<?xml version=`"1.0`" encoding=`"UTF-8`"?><Batch>");
     $command = [System.String]::Format( "<Method><SetList>{0}</SetList><SetVar Name=`"ID`">{1}</SetVar><SetVar Name=`"Cmd`">Delete</SetVar></Method>", $listId, "{0}" );
     $listItems = $listToProcess.GetItems($camlQuery)
     $camlQuery.ListItemCollectionPosition = $listItems.ListItemCollectionPosition
     foreach ($item in $listItems)
         if($item -ne $null)
             $batchXml.Append([System.String]::Format($command, $item.ID.ToString())) | Out-Null;$itemCount++;
     $rootWeb.ProcessBatchData($batchXml.ToString())   | Out-Null;
     #Write-Host "Item deleted successfully" + $itemCount;
 while ($query.ListItemCollectionPosition -ne $null)
     #Write-Host "Cannot find list: " $listToProcess;
 Stop-SPAssignment -Global -AssignmentCollection $assignmentCollection;
  #Write-Host "Finished";

One issue I found at the time of executing ps1 file script from C# & pipeline.invoke() was throwing error "Cannot invoke this function because the current host does not implement it." But it was deleted the list item successfully.

To resolve the issue I had to comment out Write-Host from ps1 script & execute the C# code, that’s it.

Let’s add one item in the list


As a result of executing the RunPsScript or the code written to execute batch file, the item will be deleted from the list


Happy Coding

Tarun Kumar Chatterjee