Create exchange mailbox in c# - 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);

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?

Using PowerShell to Read Office 365 Group Members in C#

I'm attempting to connect to an Office 365 Group and list the membership of the Group using Powershell through a C# Project.
From this article, I've determined the command I need to use is
Get-UnifiedGroupLinks –Identity groupalias –LinkType Members
Here is my current code:
string connectionUri = "https://outlook.office365.com/powershell-liveid/";
SecureString secpassword = new SecureString();
foreach (char c in Password)
{
secpassword.AppendChar(c);
}
PSCredential credential = new PSCredential(UserName, secpassword);
Runspace runspace = RunspaceFactory.CreateRunspace();
PSObject SessionHolder = null;
using (PowerShell powershell = PowerShell.Create())
{
PSCommand command = new PSCommand();
command.AddCommand("New-PSSession");
command.AddParameter("ConfigurationName", "Microsoft.Exchange");
command.AddParameter("ConnectionUri", new Uri(connectionUri));
command.AddParameter("Credential", credential);
command.AddParameter("Authentication", "Basic");
powershell.Commands = command;
runspace.Open();
powershell.Runspace = runspace;
Collection<System.Management.Automation.PSObject> result = powershell.Invoke();
if (powershell.Streams.Error.Count > 0 || result.Count != 1)
{
throw new Exception("Fail to establish the connection");
}
else
SessionHolder = result[0];
}
using (PowerShell powershell = PowerShell.Create())
{
PSCommand command = new PSCommand();
// –Identity groupalias –LinkType Members
command = new PSCommand();
command.AddCommand("Invoke-Command");
command.AddParameter("ScriptBlock", System.Management.Automation.ScriptBlock.Create("Get-UnifiedGroupLinks"));
command.AddParameter("Session", SessionHolder);
command.AddParameter("Identity", groupAddress);
command.AddParameter("LinkType", "Members");
powershell.Commands = command;
powershell.Runspace = runspace;
Collection<PSObject> PSOutput = powershell.Invoke();
// loop through each output object item
foreach (PSObject outputItem in PSOutput)
{
}
}
Variables used above, declaration not shown: "UserName", "Password", "groupAddress"
I am able to make a connection to the service, but when I try to get the group members I get the error "A parameter cannot be found that matches parameter name 'Identity'"
I'm not sure how to proceed in troubleshooting my code. I've tried the Group email, Group Alias, and Group Display Name in the Identity parameter. Perhaps I have something else wrong?
I'm using the following Libraries in Visual Studio 2017 on a Windows 10 machine:
using System.Management.Automation;
using System.Management.Automation.Runspaces;
Usually I get that error when I'm passing the variable with some extra characters. Check how the variable is being passed, if its just "email" or if it contains other info like #{"email"}. Very common in Powershell.
Hope that sheds some light. Because the command is very simple:
Get-UnifiedGroupLinks -Identity [name] -LinkType members
I found a bit of code that makes things work... It slows it down, so I'm not sure if there is a better way, but here is my updated code:
string connectionUri = "https://outlook.office365.com/powershell-liveid/";
SecureString secpassword = new SecureString();
foreach (char c in Password)
{
secpassword.AppendChar(c);
}
PSCredential credential = new PSCredential(UserName, secpassword);
Runspace runspace = RunspaceFactory.CreateRunspace();
PSObject SessionHolder = null;
using (PowerShell powershell = PowerShell.Create())
{
string connectionUri = "https://outlook.office365.com/powershell-liveid/";
SecureString secpassword = new SecureString();
foreach (char c in Password)
{
secpassword.AppendChar(c);
}
PSCredential credential = new PSCredential(UserName, secpassword);
PSCommand command = new PSCommand();
command.AddCommand("New-PSSession");
command.AddParameter("ConfigurationName", "Microsoft.Exchange");
command.AddParameter("ConnectionUri", new Uri(connectionUri));
command.AddParameter("Credential", credential);
command.AddParameter("Authentication", "Basic");
powershell.Commands = command;
runspace.Open();
powershell.Runspace = runspace;
Collection<System.Management.Automation.PSObject> result = powershell.Invoke();
if (powershell.Streams.Error.Count > 0 || result.Count != 1)
throw new Exception("Fail to establish the connection");
else
SessionHolder = result[0];
PSCommand ImportSession = new PSCommand();
ImportSession.AddCommand("Import-PSSession");
ImportSession.AddParameter("Session", SessionHolder);
powershell.Commands = ImportSession;
powershell.Invoke();
PSCommand GrabGroup = new PSCommand();
GrabGroup.AddCommand("Get-UnifiedGroupLinks");
GrabGroup.AddParameter("Identity", GroupAddress);
GrabGroup.AddParameter("LinkType", "Members");
powershell.Commands = GrabGroup;
Collection<PSObject> PSOutput_GroupMembers = powershell.Invoke();
foreach (PSObject outputItem in PSOutput_GroupMembers)
{
//Process Members
}
}
The key seems to be that I need to Import the session before I can begin using it.

Powershell remote commandlet from c# for cim-session

using (PowerShell pInst=PowerShell.Create()) // implements Idisposable
{
string username = Console.ReadLine();
System.Security.SecureString pwd = getPassword();
PSCredential credential = new PSCredential(username, pwd);
pInst.Runspace.SessionStateProxy.SetVariable("cred", credential);
//pInst.AddScript("$cred;");
//pInst.AddScript("$session= New-CimSession -ComputerName anksahawin8a $cred");
//pInst.AddScript("$session;");
//pInst.AddScript("param($param1) $d = get-date;"+"$d; $s; $param1; get-service");
//.AddParameter("param1","Ankit");
//pInst.Invoke(); // Synchronous Invocation
pInst.AddScript("$session= New-CimSession -ComputerName anksahawin8a -Credential $cred;");
//psOutput = pInst.Invoke();
pInst.AddScript("$session;");
Collection<PSObject> psOutput = pInst.Invoke();
//psOutput = pInst.Invoke();
if(pInst.Streams.Error.Count>0) // Errors
{
}
foreach(PSObject pso in psOutput)
{
Console.WriteLine(pso);
if (pso != null)
{
//String result=pso.Members["Value"].Value.ToString();
Console.WriteLine(pso.BaseObject.GetType().FullName);
Console.WriteLine(pso.BaseObject.ToString() + "\n");
}
}
Console.WriteLine("Hello");
}
This code is not working. Whereas
pInst.AddScript("$session= New-CimSession");
for local computer works...

Using C# To Return Data From PowerShell

I am trying to return a PrimarySMTPAddress to a variable, in Powershell the code I run is this:
Get-Mailbox -identity UserName | select PrimarySMTPAddress
And it returns the correct value, I want to get this in my C# Code, I have done the following:
string getPrimarySMTP = "Get-Mailbox -identity " + username + "| select PrimarySMTPAddress";
var runSpace = RunspaceFactory.CreateRunspace(Utility.CreateConnectionInfo());
runSpace.Open();
var pipeline = runSpace.CreatePipeline();
pipeline.Commands.AddScript(getPrimarySMTP);
var primarySmtp = pipeline.Invoke();
runSpace.Dispose();
I would Expect this to return the same data, but it doesn't. I just get an exception:
The term 'select' 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.
Is this the way to return values from a powershell command?
For what version of Exchange ? for 2010 up you need to use Remote Powershell see https://msdn.microsoft.com/en-us/library/office/ff326159%28v=exchg.150%29.aspx . (even in 2007 your code would work because you haven't loaded the snapin).
Cheers
Glen
You may need to add an additional space character before the pipe. It' being concatenated to the username, with the resulting string becoming ... -identity UserName| select ..."
Here's the corrected statement:
string getPrimarySMTP = "Get-Mailbox -identity " + username + " | select PrimarySMTPAddress";
Thanks for asking this question, it helped me to lead to the answer I needed. My code resulted in the following using RemoteRunspace to an Exchange 2013 environment:
try
{
var target = new Uri(Uri);
SecureString PSPassword = new SecureString();
foreach (char c in ConfigurationManager.AppSettings["Password"])
{
PSPassword.AppendChar(c);
}
//var cred = (PSCredential)null;
PSCredential cred = new PSCredential(ConfigurationManager.AppSettings["Username"], PSPassword);
WSManConnectionInfo connectionInfo = new WSManConnectionInfo(target, shell, cred);
connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Default;
connectionInfo.OperationTimeout = 1 * 60 * 1000; // 4 minutes.
connectionInfo.OpenTimeout = 1 * 30 * 1000; // 1 minute.
using (Runspace remoteRunspace = RunspaceFactory.CreateRunspace(connectionInfo))
{
remoteRunspace.Open();
using (PowerShell powershell = PowerShell.Create())
{
powershell.Runspace = remoteRunspace;
powershell.AddScript(PSSnapin);
powershell.Invoke();
powershell.Streams.ClearStreams();
powershell.Commands.Clear();
Pipeline pipeline = remoteRunspace.CreatePipeline();
Command getMailBox = new Command("Get-Mailbox");
getMailBox.Parameters.Add("Identity", Username);
Command cmd = new Command("Select-Object");
string[] Parameter = new string[] { "PrimarySMTPAddress" };
cmd.Parameters.Add("Property", Parameter);
pipeline.Commands.Add(getMailBox);
pipeline.Commands.Add(cmd);
Collection<PSObject> results = pipeline.Invoke();
primarySMTPAddress = results[0].ToString();
primarySMTPAddress = primarySMTPAddress.ToUpper().Replace("#{PRIMARYSMTPADDRESS=", "");
primarySMTPAddress = primarySMTPAddress.ToUpper().Replace("}", "");
}
remoteRunspace.Close();
}
return primarySMTPAddress;
}
catch
{
return "Error";
}
Hope this helps anyone in future.

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