Using PowerShell to Bulk Create Exchange users with unique passwords

by Nicolas Blank on 20 September 2011 · 7 comments

in Exchange,PowerShell

There’s a number of articles which detail how to create an Exchange user from a CSV file using Exchange Management Shell, however most of them harvest a password at runtime by prompting the user to type in credentials. The password is then set for all users. However, what if your users all need to have different passwords assigned to them?

Great question, and I’m glad you asked.

When creating a mailbox using the new-mailbox CMDlet, you are required to specify the password as a secure string, what I’m doing in the script below, is reading the csv file, iterating through it and converting the $_.password field into a secure string. That secure string is then passed over into the new-mailboxname CMDlet, quite simple actually.

Note that in Exchange 2010 we do not need to specify a mailbox server, only the mailbox database hosting the mailbox.

The CSV file format can be whatever you like, however for the sake of the script below at minimum needs to be “Alias,Firstname, Lastname,Name,UPN,OUpath,Database,password”

image

This allows you to create users, in different OU’s with specified passwords using nothing more than Exchange Management Shell.

 

Copy and paste the text below, and use as required.

 

#csv format needs to be as follows:
#Alias,Firstname, Lastname,Name,UPN,OUpath,Database,password

#change the name and path of the csv file as required.
$users = Import-CSV C:\scripts\users.csv
$users| foreach

{

$Password = convertto-securestring $_.password -asplaintext -force

new-mailbox -name $_.name -alias $_.alias -FirstName $_.Firstname -LastName $_.Lastname -userPrincipalName  $_.UPN -database $_.Database -OrganizationalUnit $_.OUpath -Password $Password –ResetPasswordOnNextLogon:$true

}

Share this post:
  • Twitter
  • muti
  • laaik.it
  • Facebook
  • Posterous
  • del.icio.us
  • Digg
  • Live
  • LinkedIn
  • Slashdot
  • StumbleUpon
  • Suggest to Techmeme via Twitter
  • Fark
  • email

{ 6 comments }

Chris Mangiapane September 22, 2011 at 7:20 pm

Hi Nicolas

I am writing a C# application, and creating Exchange 2010 mailboxes. I am trying to submit ‘New-Mailbox’ script text, but I am unable to set the password to a SecuredString. I have tried a couple different ways to set the password correctly, but each time the mailbox is not created. Below is a sample of the C# code. Can you please advise how to set the -Password in C# manged code?

string script = String.Format(“New-Mailbox -UserPrincipalName {0} -SamAccountName {1} -Name {2} “, emailAddress, samAccountName, accountName);
script += String.Format(“-Password (ConvertTo-SecureString {0} -AsPlainText -Force) -OrganizationalUnit {1} -FirstName {2} “, password, organizationUnit, firstName);
script += String.Format(“-LastName {0} -DisplayName {1} -Database MigrationProject -ResetPasswordOnNextLogon $false”, lastName, displayName);
Collection results = null;
using (Runspace runspace = RunspaceFactory.CreateRunspace(GetExchangeConnectionInfo()))
{
runspace.Open();
using (PowerShell powershell = PowerShell.Create())
{
//powershell.AddCommand(String.Format(“$securedpassword = ConvertTo-SecureString \”{0}\” -AsPlainText -Force “, password));
powershell.AddScript(script);
powershell.Runspace = runspace;
try
{
results = powershell.Invoke();

Nicolas Blank September 22, 2011 at 7:24 pm

Hi Chris
You’re executing PowerShell inside managed code, so you have an option of creating the secure string in C#.
Can you post the exact error you’re having?

Chris Mangiapane September 22, 2011 at 8:00 pm

Sure, but these results aren’t too helpful:

1) Yields No error on powershell.Invoke()

New-Mailbox -UserPrincipalName DemoAgent007@interorealestate-beta.com -SamAccountName newDemoAgent007 -Name DemoAgent007 -Password (ConvertTo-SecureString test11!! -AsPlainText -Force) -OrganizationalUnit interorealestate-beta -FirstName Really Cool Monty -LastName DemoAgent007 -DisplayName Really Cool Monty DemoAgent007 -Database MigrationProject -ResetPasswordOnNextLogon $false

2) System.Management.Automation.RemoteException: The term ‘$securedpassword = ConvertTo-SecureString “test11!!” -AsPlainText -Force ‘ 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.

New-Mailbox -UserPrincipalName DemoAgent007@interorealestate-beta.com -SamAccountName newDemoAgent007 -Name DemoAgent007 -Password $securedpassword -OrganizationalUnit interorealestate-beta -FirstName Really Cool Monty -LastName DemoAgent007 -DisplayName Really Cool Monty DemoAgent007 -Database MigrationProject -ResetPasswordOnNextLogon $false

3) Yields No error on powershell.Invoke(), but obviously is problematic.
New-Mailbox -UserPrincipalName DemoAgent007@interorealestate-beta.com -SamAccountName newDemoAgent007 -Name DemoAgent007 -Password System.Security.SecureString -OrganizationalUnit interorealestate-beta -FirstName Really Cool Monty -LastName DemoAgent007 -DisplayName Really Cool Monty DemoAgent007 -Database MigrationProject -ResetPasswordOnNextLogon $false

4) And again, no error, but no mailbox created
New-Mailbox -UserPrincipalName DemoAgent007@interorealestate-beta.com -SamAccountName newDemoAgent007 -Name DemoAgent007 -Password test11!! -OrganizationalUnit interorealestate-beta -FirstName Really Cool Monty -LastName DemoAgent007 -DisplayName Really Cool Monty DemoAgent007 -Database MigrationProject -ResetPasswordOnNextLogon $false

I think this must be related to using a PSSession???

Hannes de Jager September 23, 2011 at 5:35 am

I do the following which works:

string s = string.Format(“$p = ConvertTo-SecureString -String \”{0}\” -asplaintext -force”, Password);
String cmd = string.Format(“{0}; New-Mailbox -Name ‘{1}’ -Alias ‘{2}’ -UserPrincipalName ‘{3}’ -SamAccountName ‘{4}’ -ResetPasswordOnNextLogon $false -Password $p”,
s, Name, Alias, UserPrincipalName, SamAccountName);

if (!FirstName.IsNullOrEmpty())
cmd += string.Format(” -FirstName ‘{0}’”, FirstName);
if (!LastName.IsNullOrEmpty())
cmd += string.Format(” -LastName ‘{0}’”, LastName);
if (!Initials.IsNullOrEmpty())
cmd += string.Format(” -Initials ‘{0}’”, Initials);

String result = cmd.EmsExec();

Where cmd.EmsExec() an extention method and the equivalent of adding the script to the already initialized runspace and executing it..

This is how I initialize my powershell (Exchange Management shell session) session:

public sealed override void InitSession()
{
PSSnapInException ex;
Logger.Debug(“Adding powershell snap-in”);
powershell.Runspace.RunspaceConfiguration.AddPSSnapIn(“Microsoft.Exchange.Management.PowerShell.E2010″, out ex);
if (ex != null)
throw ex;
Logger.Debug(“Executing environment script”);
powershell.AddScript(“. $env:ExchangeInstallPath\\bin\\RemoteExchange.ps1″);
Logger.Debug(“Connecting to the exchange server”);
powershell.AddScript(“Connect-ExchangeServer -auto”);
var results = powershell.Invoke();
/* if (powershell.Streams.Error.Count > 0)
throw powershell.Streams.Error[0].Exception; */
// FIXME: We get alot of “Cannot invoke this function because the current host does not implement it.” errors when the above is enabled.
powershell.Streams.ClearStreams();
powershell.Commands.Clear();
}

Find the missing code or the full listing here:

http://pastebin.com/GRHpF12X

Hannes de Jager September 23, 2011 at 5:39 am

Rather use this link than the one above (which will expire in one day)

http://pastebin.com/66psx0qi

admin September 23, 2011 at 6:59 am

Hannes, thats Great Stuff, well done, and thanks for answering Chris. Chris please post back and let us know if this worked for you or not?

Comments on this entry are closed.

{ 1 trackback }

Previous post:

Next post: