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)
{
pass.AppendChar(c);
}
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);
else
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);
cmdlet.Open();
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();
try
{
// Using Get-SPFarm powershell command
pipeline.Commands.AddScript(psScript);
pipeline.Commands.AddScript("Out-String");
// this will format the output
Collection<PSObject> output = pipeline.Invoke();
pipeline.Stop();
cmdlet.Close();
// process each object in the output and append to stringbuilder
StringBuilder results = new StringBuilder();
foreach (PSObject obj in output)
{
results.AppendLine(obj.ToString());
}
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);
$camlQuery.Query=$camlQueryString;
$camlQuery.ViewFields=$viewFields;
$camlQuery.ViewFieldsOnly=$true
$camlQuery.RowLimit=$numberOfItemsToRetrieve;
do
{
$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++;
}
}
$batchXml.Append("</Batch>");
$itemCount;
$rootWeb.ProcessBatchData($batchXml.ToString()) | Out-Null;
#Write-Host "Item deleted successfully" + $itemCount;
}
while ($query.ListItemCollectionPosition -ne $null)
$rootWeb.Dispose();
}
else
{
#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
Leave a comment