• Create new user mailbox in Exchange 2010 using Powershell

    Posted on August 14, 2013 by in C#, Dotnet

    It is a time-saver to automate creation of mailboxes and active directory accounts for new or existing employees. It is really disappointing that we have to use powershell commands to create mailboxes in exchange. I was really hoping that Microsoft should have exposed this through exchange web services.

    Prerequisites:

    In order to execute or invoke powershell commands, we need to download Windows Management Framework. You can download it from following link.
    http://www.microsoft.com/en-us/download/details.aspx?id=34595

    Assembly References:
    Since we are using system automation API, we need to add reference to System.Management.Automation.dll. (path on my windows 7 laptop: C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll)

    Source Code:
    I have created a new class SMAHelper.cs and a static method CreateADAccountAndMailBox which takes some basic input to create the account in active directory and enable mailbox for the same.

    public static void CreateADAccountAndMailBox(string firstname, string lastname, string userActiveDirectoryAccount, string password)

    Next, I have created some local variables to store the login name and password I would use to connect to Exchange 2010 RPS URI (Remote PowerShell Uniform Resource Identifier).

    // Prepare the credentials that will be used when connecting to the server                         
    string loginName = @"{domainname\loginname}";
    string loginPassword = "{password}";
                
    //The Exchange 2010 RPS is available on each server which has the Client //Access (CAS) role of Exchange 2010 installed. Leveraging remote PowerShell //it allows you to send commands to Exchange 2010 without the need for the //Exchange Management tools
    string exchangePowershellRPSURI = "http://{exchangeservername}/PowerShell";
    
    SecureString ssLoginPassword = new SecureString();
    foreach (char x in loginPassword)
      ssLoginPassword.AppendChar(x);
    
    //create security credentials required to make the connection
    PSCredential credentials = new PSCredential(loginName, ssLoginPassword);
    

    We need to give appropriate permissions to the login we use. It could be done in couple of ways.

      1. User should belong to the “Recipient Management” RoleGoup by going to “Exchange Management Console > Microsoft Exchange > Microsoft Exchange On-Premises > Toolbox > Role Based Access Control (RBAC) User Editor”.
      2. User should have Remote PowerShell rights. You could give those rights by running following powershell command.

    Set-User {loginname} -RemotePowerShellEnabled:$true

    Once we have the RPS URI & credentials, we can create the WMI connection.

    //Provides the connection information that is needed to connect to a remote runspace
    WSManConnectionInfo connInfo = new WSManConnectionInfo(new Uri(exchangePowershellRPSURI), "http://schemas.microsoft.com/powershell/Microsoft.Exchange", credentials);
                connInfo.AuthenticationMechanism = AuthenticationMechanism.Basic;
    

    Next we need to create a runspace where we could run powershell commands.

    // Create the runspace where the command will be executed            
    Runspace runspace = RunspaceFactory.CreateRunspace(connInfo);
    

    Now we create and populate the actual powershell command. Then we add the command to the pipeline and then invoke it.

    // create the PowerShell command      
    //New-Mailbox cmdlet is used to create new account in AD and enable mailbox for the same
    Command command = new Command("New-Mailbox");
    command.Parameters.Add("Name", firstname + " " + lastname);
    command.Parameters.Add("Alias", userActiveDirectoryAccount);
    command.Parameters.Add("UserPrincipalName", userActiveDirectoryAccount + "@" + fullDomainName);
    command.Parameters.Add("SamAccountName", userActiveDirectoryAccount);
    command.Parameters.Add("FirstName", firstname);
    command.Parameters.Add("LastName", lastname);
    command.Parameters.Add("Password", userAccountPassword);
    command.Parameters.Add("ResetPasswordOnNextLogon", false);
    command.Parameters.Add("Database", "{databasename}");
    
    // Add the command to the runspace's pipeline            
    runspace.Open();
    
    //Represents the base functionality of a pipeline that can be used to invoke commands
    Pipeline pipeline = runspace.CreatePipeline();
    pipeline.Commands.Add(command);
    
    // Execute the command            
    //PSObject object is the basis for access to all objects from the scripting language and provides an abstraction for the cmdlet develope
    Collection<PSObject> results = pipeline.Invoke();
    

    SMAHelper.cs

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Security;
    using System.Management.Automation;
    using System.Management.Automation.Runspaces;
    
    namespace ExchangeDemo
    {
    public class SMAHelper2
        {
            public static void CreateADAccountAndMailBox(string firstname, string lastname,
                                                      string userActiveDirectoryAccount, string password)
            {
                // Prepare the credentials that will be used when connecting to the server                         
                string loginName = @"{domainname\loginname}"; // replace with actual login name
                string loginPassword = "{password}"; //replace it with password for the login
    
                //The Exchange 2010 RPS is available on each server which has the Client Access (CAS) 
                //role of Exchange 2010 installed. Leveraging remote PowerShell it allows you to send commands to Exchange 2010 
                //without the need for the Exchange Management tools
                string exchangePowershellRPSURI = "http://{exchangeservername}/PowerShell";
    
                SecureString ssLoginPassword = new SecureString();
                foreach (char x in loginPassword)
                    ssLoginPassword.AppendChar(x);
    
                //create security credentials required to make the connection
                PSCredential credentials = new PSCredential(loginName, ssLoginPassword);
    
                //Provides the connection information that is needed to connect to a remote runspace
                // Prepare the connection            
                WSManConnectionInfo connInfo = new WSManConnectionInfo(new Uri(exchangePowershellRPSURI), "http://schemas.microsoft.com/powershell/Microsoft.Exchange", credentials);
                connInfo.AuthenticationMechanism = AuthenticationMechanism.Basic;
    
                // Create the runspace where the command will be executed            
                Runspace runspace = RunspaceFactory.CreateRunspace(connInfo);
    
                SecureString userAccountPassword = new SecureString();
                foreach (char c in password)
                    userAccountPassword.AppendChar(c);
    
                // create the PowerShell command      
                //New-Mailbox cmdlet is used to create new account in AD and enable mailbox for the same
                Command command = new Command("New-Mailbox");
                command.Parameters.Add("Name", firstname + " " + lastname);
                command.Parameters.Add("Alias", userActiveDirectoryAccount);
                string fullDomainName = "{domainname}.com"; //actual domain name such as microsoft.com
                command.Parameters.Add("UserPrincipalName", userActiveDirectoryAccount + "@" + fullDomainName);
                command.Parameters.Add("SamAccountName", userActiveDirectoryAccount);
                command.Parameters.Add("FirstName", firstname);
                command.Parameters.Add("LastName", lastname);
                command.Parameters.Add("Password", userAccountPassword);
                command.Parameters.Add("ResetPasswordOnNextLogon", false);
                command.Parameters.Add("Database", "{exchangedatabasename}"); //replace with exchange database
    
                // Add the command to the runspace's pipeline            
                runspace.Open();
    
                //Represents the base functionality of a pipeline that can be used to invoke commands
                Pipeline pipeline = runspace.CreatePipeline();
                pipeline.Commands.Add(command);
    
                // Execute the command            
                //PSObject object is the basis for access to all objects from the scripting language 
                //and provides an abstraction for the cmdlet develope
                Collection<PSObject> results = pipeline.Invoke();
                runspace.Dispose();
    
                if (results.Count > 0)
                    Console.WriteLine("{0} AD account created and email account enabled", results[0].ToString());
                else
                    Console.WriteLine("Failed to create Active directory account");
            }
        }
    }

    Program.cs:
    Created a simple console application to test this method.

    class Program
        {
            static void Main(string[] args)
            {
                SMAHelper.CreateADAccountAndMailBox("Test17", "Test17", "Test17.Test17", "ACor2013");
            }
        }
    

    Client Configuration:
    We have to do some little configuration changes on the client machine where we run this application. Failure to do so will result in exceptions at runtime.WinRM configuration on the client has to be modified to

    1. Allow unencrypted traffic
    2. Trust the remote machine

    Step 1: Launch “Local Group Policy user interface”  by typing gpedit.msc  in the run promput.

    Step 2: Navigate to “Local Computer Policy > Computer Configuration > Administrative Templates > Windows Components > Windows Remote Management (WinRM) > WinRM Client”.

    Step 3: Enable “Allow unencrypted traffic”
    Create new user mailbox in Exchange 2010 using Powershell 1

    Step 4: Enable “Trust the remote machine”.

    Create new user mailbox in Exchange 2010 using Powershell 3

    Failure do these configurations will result in one of below exceptions

    "Connecting to remote server failed with the following error message: The WinRM client cannot process the request. Unencrypted traffic is currently disabled in the client configuration. Change the client configuration and try the request again. For more information, see the about_Remote_Troubleshooting Help topic."
    (or)
    Connecting to remote server failed with the following error message : The WinRM client cannot process the request. If the authentication scheme is different from Kerberos, or if the client computer is not joined to a domain, then HTTPS transport must be used or the destination machine must be added to the TrustedHosts configuration setting. Use winrm.cmd to configure TrustedHosts. Note that computers in the TrustedHosts list might not be authenticated. You can get more information about that by running the following command: winrm help config. For more information, see the about_Remote_Troubleshooting Help topic.
    
    Be Sociable, Share!

    Written by

    Software architect with over 10 years of proven experience in designing & developing n-tier and web based software applications, for Finance, Telecommunication, Manufacturing, Internet and other Commercial industries. He believes that success depends on one's ability to integrate multiple technologies to solve a simple as well as complicated problem.

    View all articles by

    Email : [email protected]

    Leave a Reply