I have a function that is able to send email by sending it through PowerShell.
Using the System.Management.Automation reference I am able to use the PowerShell class that allows me to add PowerShell script that will send the email.
If I were to type it directly into the PowerShell window it would look like this:
$password = ConvertTo-SecureString 'PASSWORD' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('sender#email.com', $password)
Send-MailMessage -From 'sender#email.com' -To 'receiver#email.com' -Subject 'Heres the Email Subject' -Body 'This is what I want to say' -SmtpServer 'smtp.office365.com' -Port '587' -UseSsl -Credential $Cred –DeliveryNotificationOption OnSuccess
It is able to send an email but I how would I check if an email wasn't sent?
The function is below.
private void SendEmail()
{
string from = "sender#email.com";
string to = "receiver#email.com";
string subject = "Heres the Email Subject";
string body = "This is what I want to say";
string server = "smtp.office365.com";
string port = "587";
//Password goes here
string password = "PASSWORD";
string pw = "ConvertTo-SecureString '" + password + "' -AsPlainText -Force";
string cred = "New-Object System.Management.Automation.PSCredential('" + from + "', $password)";
string send = "Send-MailMessage -From '" + from + "' -To '" + to + "' -Subject '" + subject + "' -Body '" + body + "' -SmtpServer '" + server + "' -Port '" + port + "' -UseSsl -Credential $Cred -DeliveryNotificationOption OnSuccess";
string psScript = "$password = " + pw + System.Environment.NewLine +
"$Cred = " + cred + System.Environment.NewLine +
send;
using (PowerShell ps = PowerShell.Create())
{
ps.AddScript(psScript);
// invoke execution on the pipeline (collecting output)
Collection<PSObject> PSOutput = ps.Invoke();
// loop through each output object item
foreach (PSObject outputItem in PSOutput)
{
// if null object was dumped to the pipeline during the script then a null
// object may be present here. check for null to prevent potential NRE.
if (outputItem != null)
{
//TODO: do something with the output item
Console.WriteLine(outputItem.BaseObject.GetType().FullName);
Console.WriteLine(outputItem.BaseObject.ToString() + "\n");
}
}
}
}
I found a way to check for errors using ps.HadErrors
using (PowerShell ps = PowerShell.Create())
{
//Add the powershell script to the pipeline
ps.AddScript(psScript);
// invoke execution on the pipeline (collecting output)
Collection<PSObject> PSOutput = ps.Invoke();
//check for any errors
if (ps.HadErrors)
{
foreach (var errorRecord in ps.Streams.Error)
{
Console.WriteLine(errorRecord);
}
}
}
Related
I have the following script to schedule an event on an O365 calendar.
The goal is to run this script from an Asp.net C# page.
If I run it in WindowPowershell ISE, it works perfectly.
The problem is when I run it from the page.
It returns me the following error: "The term 'Connect-MgGraph' 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."
C# CODE
public static string SetEvent(string Subject, string Date, string StartHour, string EndHour, string Location, string[] Attendees, string Body)
{
string result = "";
try
{
//Subject
string strSubject = Subject;
//Param StartDateHour && EndDateHour
DateTime datDate = Convert.ToDateTime(Date);
string strStartDateHour = datDate.Year.ToString() + "-" + datDate.Month.ToString() + "-" + datDate.Day.ToString() + "T" + StartHour;
string strEndDateHour = datDate.Year.ToString() + "-" + datDate.Month.ToString() + "-" + datDate.Day.ToString() + "T" + EndHour;
// Location
string strLocation = Location;
// Attendees
string strAttendees = "#(";
foreach (string item in Attendees)
{
strAttendees += "#{EmailAddress = #{" +
"Address = ' + item.ToString() + ' " +
"} " +
"Type = 'Required'" +
"}";
}
strAttendees += ")";
// Body
string strBody = Body;
//Secrets!
string strAppID = HIDDEN;
string strTenantID = HIDDEN;
string strClientSecret = HIDDEN;
// create Powershell runspace
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
RunspaceInvoke runSpaceInvoker = new RunspaceInvoke(runspace);
string scriptfile = HttpContext.Current.Server.MapPath(#"~/PowerShell/scripts/Calendar/SetEvent.ps1");
// create a pipeline and feed it the script text
Pipeline pipeline = runspace.CreatePipeline();
Command myCommand = new Command(scriptfile);
CommandParameter SubjectParam = new CommandParameter("subject", strSubject);
myCommand.Parameters.Add(SubjectParam);
CommandParameter StartDateHourParam = new CommandParameter("startdatehour", strStartDateHour);
myCommand.Parameters.Add(StartDateHourParam);
CommandParameter EndDateHourParam = new CommandParameter("enddatehour", strEndDateHour);
myCommand.Parameters.Add(EndDateHourParam);
CommandParameter LocationParam = new CommandParameter("location", strLocation);
myCommand.Parameters.Add(LocationParam);
CommandParameter AttendeesParam = new CommandParameter("attendees", strAttendees);
myCommand.Parameters.Add(AttendeesParam);
CommandParameter BodyParam = new CommandParameter("body", strBody);
myCommand.Parameters.Add(BodyParam);
CommandParameter AppIDParam = new CommandParameter("appid", strAppID);
myCommand.Parameters.Add(AppIDParam);
CommandParameter TenantIDParam = new CommandParameter("tenantid", strTenantID);
myCommand.Parameters.Add(TenantIDParam);
CommandParameter ClientSecretParam = new CommandParameter("clientsecret", strClientSecret);
myCommand.Parameters.Add(ClientSecretParam);
pipeline.Commands.Add(myCommand);
pipeline.Invoke();
runspace.Close();
}
catch (Exception ex)
{
result = ex.Message;
}
return result;
}
POWERSHELL CODE
[string]$subject,
[string]$startdatehour,
[string]$enddatehour,
[string]$location,
[string]$attendees,
[string]$appid,
[string]$tenantid,
[string]$clientsecret
)
Import-Module MSAL.PS
Import-Module Microsoft.Graph.Calendar
#Generate Access Token to use in the connection string to MSGraph
$AppId = $appid
$TenantId = $tenantid
$ClientSecret = $clientsecret
$MsalToken = Get-MsalToken -TenantId $TenantId -ClientId $AppId -ClientSecret ($ClientSecret | ConvertTo-SecureString -AsPlainText -Force)
#Connect to Graph using access token
Connect-MgGraph -AccessToken $MsalToken.AccessToken -Scopes "User.Read.All","Calendars.ReadWrite"
$params = #{
Subject = $subject
Start = #{
DateTime = $startdatehour
TimeZone = "GMT Standard Time"
}
End = #{
DateTime = $enddatehora
TimeZone = "GMT Standard Time"
}
Location = #{
DisplayName = $location
LocationType = "Default"
}
IsOnlineMeeting = $true
OnlineMeetingProvider = "teamsForBusiness"
Attendees = $attendees
}
# Create event
New-MgUserEvent -UserId "a#a.net" -BodyParameter $params´´´
I've tried to run the a piece of code in a Console Application - C# (.NET Framework 4.5 project) and it works. But when I tried to migrate it to ASP.NET Core 2.0, the code would return an error(as shown below).
using System.Management.Automation.Runspaces;
public void Powershell()
{
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript("Import-Module AzureAD -Force;");
pipeline.Commands.AddScript("$password = ConvertTo-SecureString " + "\"Accenture01\"" + " -AsPlainText -Force");
pipeline.Commands.AddScript("$Cred = New-Object System.Management.Automation.PSCredential (" + "\"TestID01#eso.dev.accenture.com\"" + ", $password)");
pipeline.Commands.AddScript("Connect-AzureAD -Credential $Cred");
pipeline.Commands.AddScript("Get-AzureADApplication -Filter " + "\"DisplayName eq " + "\'TestApp\'" + "\"");
var result = pipeline.Invoke();
}
The error is
"'System.PlatformNotSupportedException: 'ReflectionOnly loading is
not supported on this platform.'"
Any ideas on this?
Use Powershell.Create() instead of Pipeline, Invoke the Import-Module before you continue, use Add-Command instead of AddScript
Try this: (after opening the runspace, e.g runspace.Open();)
using (var powershell = PowerShell.Create())
{
powershell.Runspace = runspace;
powershell.Commands.AddCommand("Import-Module").AddArgument("AzureAD");
powershell.Invoke();
powershell.Commands.Clear();
powershell.AddScript("$password = ConvertTo-SecureString " + "\"Accenture01\"" + " -AsPlainText -Force");
powershell.AddScript("$Cred = New-Object System.Management.Automation.PSCredential (" + "\"TestID01#eso.dev.accenture.com\"" + ", $password)");
powershell.AddScript("Connect-AzureAD -Credential $Cred");
powershell.AddScript("Get-AzureADApplication -Filter " + "\"DisplayName eq " + "\'TestApp\'" + "\"");
powershell.Invoke();
var results = powershell.Invoke();
}
So basically im running a script to receive the IP adress of computer, date and time an account is locked out at work and to do this im making a small gui so all the network technicians can use it, my code Currently goes
private void btnSearch_Click(object sender, EventArgs e)
{
var username = textBox1.Text;
using (var powerShellInstance = PowerShell.Create())
{
try
{
powerShellInstance.AddScript(
"Get-WinEvent -ComputerName COMPUTERNAMEHERE -FilterHashtable #{logname=LOGNAMEHERE;id=IDHERE;data=" +
username + "} |" +
"Select-Object -Property timecreated, " +
"#{label='computername';expression={$_.properties[6].value.Split(':')[3]}} " +
"Get-WinEvent -ComputerName COMPUTERNAMEHERE -FilterHashtable #{logname=LOGNAMEHERE;id=IDHERE;data=" +
username + "} | " +
"Select-Object -Property timecreated, " +
"#{label='computername';expression={$_.properties[6].value.Split(':')[3]}} " +
"Get-WinEvent -ComputerName COMPUTERNAMEHERE -FilterHashtable #{logname=LOGNAMEHERE;id=IDHERE;data=" +
username + "} | " +
"Select-Object -Property timecreated, " +
"#{label='computername';expression={$_.properties[6].value.Split(':')[3]}} ");
// invoke execution on the pipeline (collecting output)
Collection<PSObject> PSOutput = powerShellInstance.Invoke();
// loop through each output object item
foreach (PSObject outputItem in PSOutput)
{
// if null object was dumped to the pipeline during the script then a null
// object may be present here. check for null to prevent potential NRE.
if (outputItem != null)
{
listView1.Items.Add(OUTPUTHERE);
}
}
}
catch
{
listView1.Items.Add("Failed");
}
}
but it currently crashes on the part of code where i invoke it, I've never worked on power shell before so any help would be appreciated and im really sorry if this is a stupid question xD
I'm trying to start Zookeeper and Solr remotely via PowerShell scriptblock.
Then I see that the process is created in the remote machine (by checking the port 2181 of Zookeeper). And on the script completion it is being terminated.
How do I keep this alive even after the completion?
This code below stops the remote process on script completion. The script.ps1 does a lot of things that includes starting Zookeeper and Solr asJob.
int iRemotePort = 5985;
string strShellURI = #"http://schemas.microsoft.com/powershell/Microsoft.PowerShell";
string strAppName = #"/wsman";
WSManConnectionInfo ci = new WSManConnectionInfo(
false,
machineName,
iRemotePort,
strAppName,
strShellURI,
new PSCredential(userName, secure));
Runspace runspace = RunspaceFactory.CreateRunspace(ci);
runspace.Open();
using (PowerShell ps = PowerShell.Create())
{
session.Log(#"c:\temp\script.ps1 -serverID " + counter + " -copySolrConfig $" + status + " -currentHost \"" + machineName + "\" -IP_PORT_List \"" + String.Join(", ", machineWithPort) + "\"");
ps.Runspace = runspace;
ps.AddScript(#"c:\temp\script.ps1 -serverID " + counter + " -copySolrConfig $" + status + " -currentHost \"" + machineName + "\" -IP_PORT_List \"" + String.Join(", ", machineWithPort) + "\"");
var results = ps.Invoke();
foreach (var result in results)
{
session.Log(result.ToString());
}
}
runspace.Close();
So after a long try I came to a conclusion, Using power-shell script alive is not a appropriate way to keep zookeeper and solr running effectively. So moved it as a windows service and installed it on the remote machine via WiX.
Trying to run sudo command with user who has all the priviledges, but something is wrong in my code .
I am trying to remove a file present on the remote server via C# code. It says : The name 'pass' does not exist in the current context.:
My Code :
SshExec sshExec = new SshExec("sj1slm612", "karansha");
sshExec.Password = "pass";
sshExec.Connect();
//Removing config files from sj1slm612 server
string remove_config_file_express = "echo " + "'" + pass + "'" + "| sudo -S -u wtsnqa rm " + "/apps/instances/express_13000/configuration/standalone-full.xml";
string output_express = sshExec.RunCommand(remove_config_file_express);
Console.WriteLine("All config files removed");
Console.ReadLine();
the compiler is indeed correct. you reference a variable called pass which you probably meant to be the string "pass"
string remove_config_file_express = "echo " + "'" + pass + "'" + "| sudo -S -u wtsnqa rm " + "/apps/instances/express_13000/configuration/standalone-full.xml";
Use tamir Library next code.
public static bool BorrarArchivo(string rutaRemota)
{
try
{
SshExec comando = new SshExec(Servidor, Usuario);
comando.Password = Password;
comando.Connect();
string paso = comando.RunCommand("rm " + rutaRemota);
comando.Close();
return true;
}
catch (Exception ex)
{
mErrorSFTP = ex.Message;
return false;
}
}