Calling powershell script and capturing output into ASP via C# - c#

I am calling a PowerShell script from c# within an ASP page. The script executes just fine but the output (write-host) of my PowerShell does not get captured. I would like to be able to capture any output back into the ASP page.
The following is is my current code.
protected void ExecuteInputClick(object sender, EventArgs e)
{
Result.Text = string.Empty;
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
string scriptfile = "C:\\PRJ_Templates\\CreateProject.ps1";
Command myCommand = new Command(scriptfile);
CommandParameter DestDirParam = new CommandParameter("DestinationDirectory", DropDownList1.SelectedValue);
CommandParameter ProjNamParam = new CommandParameter("ProjectName", Input.Text);
myCommand.Parameters.Add(DestDirParam);
myCommand.Parameters.Add(ProjNamParam);
pipeline.Commands.Add(myCommand);
try
{
System.Collections.ObjectModel.Collection<PSObject> results = pipeline.Invoke();
runspace.Close();
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject obj in results)
{
stringBuilder.AppendLine(obj.ToString());
}
Result.Text = Server.HtmlEncode(stringBuilder.ToString());
}
catch (ActionPreferenceStopException Error) { Result.Text = Error.Message; }
catch (RuntimeException Error) { Result.Text = Error.Message; }
}
Any thought why the write-host is not getting put into Results?

Related

Capture the console logs of powershell script using c#

I am trying to execute powershell script and capture the formatted output from powershell into C# console window but always return null.
C# Code:
public List<SplunkEvent> events { get; set; } = new List<SplunkEvent>();
public void InvokeCrawl()
{
try
{
List<UrlTracker> urls = new List<UrlTracker>();
urls.Add(new UrlTracker() { AirId = "4812", SiteId = "6976843556", Url = "https://test.com/homepage", RequestorEnterpriseId = "asif.iqbal.khan" });
RunScript("4812", "asif", "iqbal", "pinku", "", urls);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void RunScript(string airID, string requestorEnterpriseId, string areaLeadEnterpriseId, string mDEnterpriseId, string serviceLeadEnterpriseId, List<UrlTracker> urls)
{
string _path = AppDomain.CurrentDomain.BaseDirectory + "Script\\Test.ps1";
System.IO.StreamReader sr = new System.IO.StreamReader(_path);
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
Command myCommand = new Command(_path);
CommandParameter _airId = new CommandParameter("AirId", airID);
myCommand.Parameters.Add(_airId);
CommandParameter _url = new CommandParameter("SiteUrl", urls[0].Url);
myCommand.Parameters.Add(_url);
pipeline.Commands.Add(myCommand);
//pipeline.Commands.AddScript(sr.ReadToEnd());
pipeline.Commands.Add("Out-String");
var results = pipeline.Invoke();
runspace.Close();
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject obj in results)
{
stringBuilder.AppendLine(obj.ToString());
}
Console.WriteLine(stringBuilder.ToString());
}
Test.ps1 Code:
Output from C#:
Executing the script directly inside windows powershell i could see the result getting printed.
In your Powershell script, use Write-Output instead of Write-Host
You can also remove this line from the C# code.
pipeline.Commands.Add("Out-String");
More info on the difference between the two here: PowerShell difference between Write-Host and Write-Output?

Exception Handling in C# for handling errors in the powershell script

I am trying to call a power shell script file from C# which automates some task.
I want to efficiently handle exception that may occur while the power shell script executes and capture it in c# code.
Below is the sample code I am currently using, but am not sure if it is correct.
Any suggestions on what needs to be changed.
I also tried pipeline.Error.Count but the value returned is 0 even if exception has occurred.
string cmdArg = "mypowerscript.ps1";
Runspace runspace = null;
Pipeline pipeline = null;
try
{
runspace = RunspaceFactory.CreateRunspace();
pipeline = runspace.CreatePipeline();
runspace.ApartmentState = System.Threading.ApartmentState.STA;
runspace.ThreadOptions = PSThreadOptions.UseCurrentThread;
runspace.Open();
pipeline.Commands.AddScript(cmdArg, true);
pipeline.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
Collection<PSObject> results = null;
results = pipeline.Invoke();
if (results.Count == 0)
MessageBox.Show(" Failed",MessageBoxButtons.OK, MessageBoxIcon.Error);
else
MessageBox.Show("Successful",MessageBoxButtons.OK, MessageBoxIcon.Information);
foreach (PSObject obj in results)
{
// Consume the results
Debug.WriteLine(obj);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
Cursor.Current = Cursors.Default;
MessageBox.Show("Failed", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
if (runspace != null)
runspace.Close();

Create exchange mailbox in c#

I want to create Mailbox in exchange server 2013 using c# .
I tried lots of codes but each one gets an error that there is no obvious solution to solve it.
my code is
public static Boolean CreateUser(string FirstName, string LastName, string Alias,string PassWord, string DomainName, string OrganizationalUnit)
{
string Name = FirstName + " " + LastName;
string PrincipalName = FirstName + "." + LastName + "#" + DomainName;
Boolean success = false;
string consolePath = #"C:\Program Files\Microsoft\Exchange Server\V15\bin\exshell.psc1";
PSConsoleLoadException pSConsoleLoadException = null;
RunspaceConfiguration rsConfig = RunspaceConfiguration.Create(consolePath, out pSConsoleLoadException);
SecureString spassword = new SecureString();
spassword.Clear();
foreach (char c in PassWord)
{
spassword.AppendChar(c);
}
PSSnapInException snapInException = null;
Runspace myRunSpace = RunspaceFactory.CreateRunspace(rsConfig);
myRunSpace.Open();
Pipeline pipeLine = myRunSpace.CreatePipeline();
Command myCommand = new Command("New-MailBox");
myCommand.Parameters.Add("Name", Name);
myCommand.Parameters.Add("Alias", Alias);
myCommand.Parameters.Add("UserPrincipalName", PrincipalName);
myCommand.Parameters.Add("Confirm", true);
myCommand.Parameters.Add("SamAccountName", Alias);
myCommand.Parameters.Add("FirstName", FirstName);
myCommand.Parameters.Add("LastName", LastName);
myCommand.Parameters.Add("Password", spassword);
myCommand.Parameters.Add("ResetPasswordOnNextLogon", false);
myCommand.Parameters.Add("OrganizationalUnit", OrganizationalUnit);
pipeLine.Commands.Add(myCommand);
pipeLine.Invoke(); // got an error here
myRunSpace.Dispose();
}
and call it :
Boolean Success = CreateUser("firstname", "lastName", "aliasName", "AAaa12345", "mydomain.com", "mydomain.com/Users");
which I get this error :
Additional information: The term 'New-MailBox' 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.
and another code that I test is:
string userName = "administrator";
string password = "mypass";
System.Security.SecureString securePassword = new System.Security.SecureString();
foreach (char c in password)
{
securePassword.AppendChar(c);
}
PSCredential credential = new PSCredential(userName, securePassword);
WSManConnectionInfo connectionInfo = new WSManConnectionInfo(new Uri("https://{my server IP}/POWERSHELL/Microsoft.Exchange"),
"http://schemas.microsoft.com/powershell/Microsoft.Exchange",
credential);
connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Basic;
connectionInfo.SkipCACheck = true;
connectionInfo.SkipCNCheck = true;
connectionInfo.MaximumConnectionRedirectionCount = 2;
using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
{
runspace.Open();
using (PowerShell powershell = PowerShell.Create())
{
powershell.Runspace = runspace;
//Create the command and add a parameter
powershell.AddCommand("Get-Mailbox");
powershell.AddParameter("RecipientTypeDetails", "UserMailbox");
//Invoke the command and store the results in a PSObject collection
Collection<PSObject> results = powershell.Invoke();
//Iterate through the results and write the DisplayName and PrimarySMTP
//address for each mailbox
foreach (PSObject result in results)
{
Console.WriteLine(
string.Format("Name: { 0}, PrimarySmtpAddress: { 1}",
result.Properties["DisplayName"].Value.ToString(),
result.Properties["PrimarySmtpAddress"].Value.ToString()
));
}
}
}
and I get this error
Additional information: Connecting to remote server {Server IP Address} failed with the following error message : [ClientAccessServer=WIN-FRP2TC5SKRG,BackEndServer=,RequestId=460bc5fe-f809-4454-8472-ada97eacb9fb,TimeStamp=4/6/2016 6:23:28 AM] Access is denied. For more information, see the about_Remote_Troubleshooting Help topic.
I think I gave every permission which is needed to my administrator user and firewall is off but it doesn't work yet.
Any help or hint !!
thanks
Try this:
//Secure String
string pwd = "Password";
char[] cpwd = pwd.ToCharArray();
SecureString ss = new SecureString();
foreach (char c in cpwd)
ss.AppendChar(c);
//URI
Uri connectTo = new Uri("http://exchserver.domain.local/PowerShell");
string schemaURI = "http://schemas.microsoft.com/powershell/Microsoft.Exchange";
//PS Credentials
PSCredential credential = new PSCredential("Domain\\administrator", ss);
WSManConnectionInfo connectionInfo = new WSManConnectionInfo(connectTo, schemaURI, credential);
connectionInfo.MaximumConnectionRedirectionCount = 5;
connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Kerberos;
Runspace remoteRunspace = RunspaceFactory.CreateRunspace(connectionInfo);
remoteRunspace.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = remoteRunspace;
ps.Commands.AddCommand("Get-Mailbox");
ps.Commands.AddParameter("Identity","user#domain.local");
foreach (PSObject result in ps.Invoke())
{
Console.WriteLine("{0,-25}{1}", result.Members["DisplayName"].Value,
result.Members["PrimarySMTPAddress"].Value);
}
I unchecked "prefer 32-bit" and changed platform target to x64, the problem was solved.
with the following code :
public class ExchangeShellExecuter
{
public Collection<PSObject> ExecuteCommand(Command command)
{
RunspaceConfiguration runspaceConf = RunspaceConfiguration.Create();
PSSnapInException PSException = null;
PSSnapInInfo info = runspaceConf.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", out PSException);
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConf);
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.Add(command);
Collection<PSObject> result = pipeline.Invoke();
return result ;
}
}
public class ExchangeShellCommand
{
public Command NewMailBox(string userLogonName,string firstName,string lastName,string password
,string displayName,string organizationUnit = "mydomain.com/Users",
string database = "Mailbox Database 1338667540", bool resetPasswordOnNextLogon = false)
{
try
{
SecureString securePwd = ExchangeShellHelper.StringToSecureString(password);
Command command = new Command("New-Mailbox");
var name = firstName + " " + lastName;
command.Parameters.Add("FirstName", firstName);
command.Parameters.Add("LastName", lastName);
command.Parameters.Add("Name", name);
command.Parameters.Add("Alias", userLogonName);
command.Parameters.Add("database", database);
command.Parameters.Add("Password", securePwd);
command.Parameters.Add("DisplayName", displayName);
command.Parameters.Add("UserPrincipalName", userLogonName+ "#mydomain.com");
command.Parameters.Add("OrganizationalUnit", organizationUnit);
//command.Parameters.Add("ResetPasswordOnNextLogon", resetPasswordOnNextLogon);
return command;
}
catch (Exception)
{
throw;
}
}
public Command AddEmail(string email, string newEmail)
{
try
{
Command command = new Command("Set-mailbox");
command.Parameters.Add("Identity", email);
command.Parameters.Add("EmailAddresses", newEmail);
command.Parameters.Add("EmailAddressPolicyEnabled", false);
return command;
}
catch (Exception)
{
throw;
}
//
}
public Command SetDefaultEmail(string userEmail, string emailToSetAsDefault)
{
try
{
Command command = new Command("Set-mailbox");
command.Parameters.Add("Identity", userEmail);
command.Parameters.Add("PrimarySmtpAddress", emailToSetAsDefault);
return command;
}
catch (Exception)
{
throw;
}
//PrimarySmtpAddress
}
}
and run with :
var addEmailCommand = new ExchangeShellCommand().AddEmail("unos4#mydomain.com","unos.bm65#yahoo.com");
var res2 = new ExchangeShellExecuter().ExecuteCommand(addEmailCommand);
var emailDefaultCommand = new ExchangeShellCommand().AddSetDefaultEmail("unos4#mydomain.com", "unos.bm65#yahoo.com");
var res3 = new ExchangeShellExecuter().ExecuteCommand(emailDefaultCommand);

Unable to do waitforexit while invoking EXE

I am running EXE using below code. EXE opens up properly and runs properly. I am facing two issues.
is there anything similar to Process.WaitforExit() while invoking PowerShell.Invoke.Once user completes operations on EXE and closes the same,then the remaining execution should continue.
The output of EXE is coming as System.Management.ManagementBaseObject. It should contain the executable result.
If I run the EXE using Process.Start, I can achieve both the above results. The output also coming up properly. Please help on this.
using (Runspace runSpace = RunspaceFactory.CreateRunspace())
{
string remoteScriptPath="e:\shared\test.ex";
string parameterString="p1";
runSpace.Open();
using (Pipeline pipeline = runSpace.CreatePipeline())
{
RunspaceInvoke invoke = new RunspaceInvoke();
PowerShell ps = PowerShell.Create();
ps.Runspace = runSpace;
ps.AddCommand("invoke-wmimethod");
ps.AddParameter("class", "Win32_Process");
ps.AddParameter("name", "Create");
if (string.IsNullOrEmpty(parameterString))
{
ps.AddParameter("argumentlist", remoteScriptPath);
}
else
{
ps.AddParameter("argumentlist", remoteScriptPath + " " + parameterString);
}
Collection<PSObject> psOutput = ps.Invoke();
if (ps.Streams.Error.Count == 0)
{
string result="";
foreach (PSObject psObject in psOutput)
{
if (psObject != null)
{
result += psObject.BaseObject.ToString();
result += Environment.NewLine;
}
}
return result;
}

C# Remote Powershell SharePoint 2010

I'm trying to run powershell commands on a remote sharepoint server from a c# console app. This is the code I have so far. It runs without errors but does nothing. What am I doing wrong?
Thanks
server name, username password, and url were taken out
public static string RunScript()
{
Runspace remoteRunspace = null;
openRunspace("http://server/wsman",
"http://schemas.microsoft.com/powershell/Microsoft.PowerShell",
#"domain\user",
"password",
ref remoteRunspace);
try
{
StringBuilder stringBuilder = new StringBuilder();
using (PowerShell powershell = PowerShell.Create())
{
powershell.Runspace = remoteRunspace;
powershell.AddScript("Add-PsSnapin Microsoft.SharePoint.PowerShell");
powershell.AddScript("enable-SPFeature -identity \"2dfc204b-e9da-4c6c-8b4f-c2f7c593ad4e\" -url sharepointsite -Confirm:$False");
powershell.Invoke();
Collection<PSObject> results = powershell.Invoke();
remoteRunspace.Close();
foreach (PSObject obj in results)
{
stringBuilder.AppendLine(obj.ToString());
}
}
return stringBuilder.ToString();
}
catch (Exception e)
{
return "";
}
}
public static void openRunspace(string uri, string schema, string username, string livePass, ref Runspace remoteRunspace)
{
System.Security.SecureString password = new System.Security.SecureString();
foreach (char c in livePass.ToCharArray())
{
password.AppendChar(c);
}
PSCredential psc = new PSCredential(username, password);
WSManConnectionInfo rri = new WSManConnectionInfo(new Uri(uri), schema, psc);
rri.AuthenticationMechanism = AuthenticationMechanism.Kerberos;
rri.ProxyAuthentication = AuthenticationMechanism.Negotiate;
remoteRunspace = RunspaceFactory.CreateRunspace(rri);
remoteRunspace.Open();
}
You can try to check if you have access to the SharePoint databases, to add snap-in correctly you need ShellAccess permission on Configuration database as I remember and farm admin rights. Possibly your script can't add snap-in, so cant do anything with SharePoint object model.

Categories

Resources