Creating Exchange 2010 Mailboxes in C#
Wow, it’s been a while! I had full intentions of creating regular posts but that kind of slipped away. So I’ll make this one fairly short and just highlight the basics of creating an Exchange 2010 mailbox via remote code. Nothing fancy, but I will highlight one gotcha that I encountered when updating our user creation code after we migrated from Exchange 2003. Keep in mind that Exchange 2010 is built on Powershell and as such, all of connections and manipulation must be done through it.
First, we want to add our usings…
using System.Management.Automation; using System.Management.Automation.Remoting; using System.Management.Automation.Runspaces;
Next, we’re going to create the PSCredential, the WSManConnectionInfo, and the Runspace. We’ll then create a powershell command, invoke the powershell with the command and cross our fingers. 😀
PSCredential newCred = (PSCredential)null; WSManConnectionInfo connectionInfo = new WSManConnectionInfo(new Uri("http://exchangeserver01.my.domain/powershell?serializationLevel=Full"), "http://schemas.microsoft.com/powershell/Microsoft.Exchange", newCred); connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Kerberos; Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo); PowerShell powershell = PowerShell.Create(); PSCommand command = new PSCommand(); command.AddCommand("Enable-Mailbox"); command.AddParameter("Identity", user.Guid.ToString()); command.AddParameter("Alias", user.UserName); command.AddParameter("DomainController", ConnectingServer); powershell.Commands = command; try { runspace.Open(); powershell.Runspace = runspace; Collectionresults = powershell.Invoke(); } catch (Exception ex) { string er = ex.InnerException.ToString(); } finally { runspace.Dispose(); runspace = null; powershell.Dispose(); powershell = null; }
Now, a couple of things to note…
1) My gotcha…You don’t find a lot of information about creating a PSCredential using the credentials of the currently logged in user. Even the MSDN documentation only shows one constructor where you pass in a username and password. After searching around, some trial and error, I finally found this post detailing creating the PSCredential using Windows Authentication with no username or password supplied. Supplying credentials isn’t a problem, but as we log the account creations, and we didn’t have this issue when creating boxes in 2003, I wanted as seamless transition as possible. So this code just replaced the old code and my other Admins had no idea anything was different.
2) Accounts for my users need to be created at one of many different sites, and many times it’s not a site I’m currently at. So, the account is created on the ‘local to them’ server so they can immediately login and not need to wait for replication. Because of this, Exchange needs to know what server holds the account. If you don’t need this functionality, you can remove the DomainController command parameter above.
3) It is important to properly dispose of the runspace and powershell objects. Make sure this is done.
Hi, may you perhaps know, how to code this in VB 2008? I only can do VB and need windows authentication, but do not know how to achieve this.
——————-
PSCredential newCred = (PSCredential)null;
WSManConnectionInfo connectionInfo = new WSManConnectionInfo(new Uri(“http://exchangeserver01.my.domain/powershell?serializationLevel=Full”),
“http://schemas.microsoft.com/powershell/Microsoft.Exchange”, newCred);
Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo);
connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Kerberos;
————-
Thank you
Hi Klaus. This reply is a little late but this code should at least be close.
Dim newCred As PSCredential = DirectCast(Nothing, PSCredential)
Dim connectionInfo As New WSManConnectionInfo(New Uri(“http://exchangeserver01.my.domain/powershell?serializationLevel=Full”), “http://schemas.microsoft.com/powershell/Microsoft.Exchange”, newCred)
Dim runspace As Runspace = RunspaceFactory.CreateRunspace(connectionInfo)
connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Kerberos
Dim powershell As PowerShell = PowerShell.Create()
I found the above code very useful. Thanks!
The only part I found suspect was that you are setting your auth mechanism to Kerberos after you use the connectionInfo to create the runspace. I believe you are still connecting with Basic auth in the example above.
Jeremy, great catch! I’ll update the code and thanks for the feedback.
Does something else need to be done if the only exchange server access is with SSL or is the only was to create the account without using SSL? I am getting a few SSL errors in the event viewer when I use our server, which contains “https” instead of “http”
Mike…we force all connections to SSL on the Exchange server and this code hasn’t thrown any errors for us. Have you tried it without the ‘s’? That being said, one of the constructors for WSManConnctionInfo allows you to specify the use of SSL.
WSManConnectionInfo connectionInfo = new WSManConnectionInfo(true, “Exchange.FQDN”, 443, “/Powershell”, “http://schemas.microsoft.com/powershell/Microsoft.Exchange”, newCred);
I have not tested this but it matches according to the documentation here.
http://bit.ly/Ya8ZvZ
thanks a lot for this code snipped. saved my day!
No problem. Hope to get back to updating the site again soon.
Thank you for this code !
I made it in vb.net:
Sub runremotenew(ByVal username As String, ByVal emailadres As String)
Dim newCred As PSCredential = DirectCast(Nothing, PSCredential)
Dim connectionInfo As New WSManConnectionInfo(New Uri(“http://” & My.Settings.ExchangeServer & “/powershell?serializationLevel=Full”), “http://schemas.microsoft.com/powershell/Microsoft.Exchange”, newCred)
Dim runspace As Runspace = RunspaceFactory.CreateRunspace(connectionInfo)
connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Kerberos
Dim powershell As PowerShell = powershell.Create()
Dim command As New PSCommand()
‘Email adres without @
command.AddCommand(“Enable-Mailbox”)
command.AddParameter(“Identity”, My.Settings.WindowsDomainname & “\” & username)
command.AddParameter(“Alias”, emailadres)
command.AddParameter(“DomainController”, My.Settings.DomainControllerFQDN)
powershell.Commands = command
Try
runspace.Open()
powershell.Runspace = runspace
Dim psresult As New System.Collections.ObjectModel.Collection(Of PSObject)
psresult = powershell.Invoke()
For Each i In psresult
Powershelloutput = vbNewLine & i.ToString
Next i
Catch ex As Exception
Powershelloutput = ex.Message
Finally
runspace.Dispose()
runspace = Nothing
powershell.Dispose()
powershell = Nothing
End Try
End Sub
Thanks for the code Marc!