HOW TO: Call .PS1 script from Managed code using Remote Powershell(Exchange 2010)
As promised below is the code to call a .PS1 script and pass parameters to it. Most of the code is very similar to my previous post that showed how to call Exchange & PowerShell cmdlet.
using System;
using System.Collections.Generic;
using System.Text;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Management.Automation.Remoting;
using System.Collections.ObjectModel;
using System.Security;
namespace CallingScriptPS
{
class Program
{
static void Main(string[] args)
{
string password = "Password";
string userName = "Domain\\Administrator";
System.Uri uri = new Uri("https://CAS-SERVER/powershell?serializationLevel=Full");
System.Security.SecureString securePassword = String2SecureString(password);
System.Management.Automation.PSCredential creds = new System.Management.Automation.PSCredential(userName, securePassword);
Runspace runspace = System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace();
PowerShell powershell = PowerShell.Create();
PSCommand command = new PSCommand();
command.AddCommand("New-PSSession");
command.AddParameter("ConfigurationName", "Microsoft.Exchange");
command.AddParameter("ConnectionUri", uri);
command.AddParameter("Credential", creds);
command.AddParameter("Authentication", "Default");
PSSessionOption sessionOption = new PSSessionOption();
sessionOption.SkipCACheck = true;
sessionOption.SkipCNCheck = true;
sessionOption.SkipRevocationCheck = true;
command.AddParameter("SessionOption", sessionOption);
powershell.Commands = command;
try
{
// open the remote runspace
runspace.Open();
// associate the runspace with powershell
powershell.Runspace = runspace;
// invoke the powershell to obtain the results
Collection<PSSession> result = powershell.Invoke<PSSession>();
foreach (ErrorRecord current in powershell.Streams.Error)
{
Console.WriteLine("Exception: " + current.Exception.ToString());
Console.WriteLine("Inner Exception: " + current.Exception.InnerException);
}
if (result.Count != 1)
throw new Exception("Unexpected number of Remote Runspace connections returned.");
// Set the runspace as a local variable on the runspace
powershell = PowerShell.Create();
command = new PSCommand();
command.AddCommand("Set-Variable");
command.AddParameter("Name", "ra");
command.AddParameter("Value", result[0]);
powershell.Commands = command;
powershell.Runspace = runspace;
powershell.Invoke();
// First import the cmdlets in the current runspace (using Import-PSSession)
powershell = PowerShell.Create();
command = new PSCommand();
command.AddScript("Import-PSSession -Session $ra");
powershell.Commands = command;
powershell.Runspace = runspace;
powershell.Invoke();
// Now run get-ExchangeServer
System.Collections.ObjectModel.Collection<PSObject> results = new System.Collections.ObjectModel.Collection<PSObject>();
powershell = PowerShell.Create();
powershell.Runspace = runspace;
//Change the Path to the Script to suit your needs
System.IO.StreamReader sr = new System.IO.StreamReader("..\\..\\Script.ps1");
powershell.AddScript(sr.ReadToEnd());
powershell.Runspace.SessionStateProxy.SetVariable("proc", "C*");
powershell.Runspace.SessionStateProxy.SetVariable("mbx", "*MBX");
results = powershell.Invoke();
if (powershell.Streams.Error.Count > 1)
{
foreach (ErrorRecord er in powershell.Streams.Error)
Console.WriteLine(er.ErrorDetails);
}
else
{
foreach (PSObject ps in results)
{
Console.WriteLine(ps.Properties["Name"].Value.ToString());
}
}
}
finally
{
// dispose the runspace and enable garbage collection
runspace.Dispose();
runspace = null;
// Finally dispose the powershell and set all variables to null to free
// up any resources.
powershell.Dispose();
powershell = null;
}
}
private static SecureString String2SecureString(string password)
{
SecureString remotePassword = new SecureString();
for (int i = 0; i < password.Length; i++)
remotePassword.AppendChar(password[i]);
return remotePassword;
}
}
}
Below is what the Script.PS1 looks like:
get-process |where {$_.Name -like $proc}
get-exchangeserver | Where {$_.Name -like $mbx}
The two parameters that we pass in are called “proc” & “mbx”.
Note:This code will not work if we do not call the New-PSSession & the Import-PSSession cmdlet’s for reasons explained in my previous post .
Enjoy!