Saturday, March 15, 2008

Exchange 2007 Mail enable User Powershell Quick Form

A couple of weeks okay I had to mail enable (as opposed to create mailboxes) for a bunch of Active Directory accounts in a variety of OU’s in Active Directory. With previous versions of Exchange being able to do this directly from ADUC made this task relative easy and depending on the number of accounts you had to do probably not something that was worth writing a script for. With the loss of this functionality out of ADUC you have to use either a wizard in the Exchange Management Console or do it directly from Powershell. I’m not a fan of the EMC wizards they are there to do a job which they do adequately but are just too time consuming to use for repetitive tasks that aren’t worth writing a larger script to do. So I decided to port the form I had for doing quick mailbox creates to do quick mail enabled's. I wouldn’t say the result was brilliant but in the end once I had the form up I could bang though the accounts I wanted to mail enable resonably quickly (what helped is the external mail address I wanted to mail enable the user for was already in the mail attribute) vs going through the wizard for each user and clicking, cut and paste etc .

The script is similar to a lot of the others I’ve posted before it uses a .net winform to present a user interface to the users. Once you select an OU it runs the Get-User cmdlet to filter and retrieve only the users from that OU selected that aren’t currently mail-enabled or have a mailbox associated with it. This populates the UserName Drop down box. Once a user is selected from the dropdown the other textboxes are populated in the form from the information in the User account (retrieved using the Get-User cmdlet). This then builds a Enable-MailUser cmd line if you edit any of the information in the text boxes that affects the cmdline that will run which you click the mail enable button the cmd is updated as you type. This is achived by hooking into the TextChange event of each of the texboxes. Maybe the form isn’t that impressive but this function is pretty funky and worth giving a check out if you want to build your own little GUI's for your helpdesk users to use (you know all those people who’s eyes glaze over when you try to explain what powershell is).

Because this script requires the Exchange Management Shell Cmdlet's it needs to run from the Exchange Management Shell. If you download the script file from this site you need to right click the file and select unblock from the properties menu to allow the script to be executed.

I’ve put a download copy of this script here the script itself look like.

· Warning this script may cause Global Warming if keep buying incandescent light globes.

[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")

Function Enableuser{
$result = Enable-MailUser -Identity $emIdentityTextBox.Text -Alias $AliasNameText.Text -ExternalEmailAddress ("SMTP:" + $exExternalMail.Text)
if ($result -ne $null){write-host "User Mail enabled"}
else{write-host "Error Mail enabling user check command Line for Details"}
$unUserNameDropBox.Items.Clear()
get-user -sortby "LastName" -OrganizationalUnit $OUhash1[$ouOuNameDrop.SelectedItem.ToString()] where { $_.RecipientType -eq "User" } foreach-object{
# $uname = $_.LastName + " " + $_.FirstName
$uname = $_.DisplayName
$unUserNameDropBox.Items.Add($uname)}
}


$OUhash1 = @{ }
$MBhash1 = @{ }

$form = new-object System.Windows.Forms.form
$form.Text = "Exchange 2007 Quick User Mail User Form"
$form.size = new-object System.Drawing.Size(600,400)

# Add OU DropLable
$ouOuNamelableBox = new-object System.Windows.Forms.Label
$ouOuNamelableBox.Location = new-object System.Drawing.Size(10,10)
$ouOuNamelableBox.size = new-object System.Drawing.Size(70,20)
$ouOuNamelableBox.Text = "OU Name"
$form.Controls.Add($ouOuNamelableBox)

# Add OU Drop Down
$ouOuNameDrop = new-object System.Windows.Forms.ComboBox
$ouOuNameDrop.Location = new-object System.Drawing.Size(100,10)
$ouOuNameDrop.Size = new-object System.Drawing.Size(230,30)
$ouOuNameDrop.Items.Add("/Users")
$OUhash1.Add("/Users","Users")
$root = [ADSI]''
$searcher = new-object System.DirectoryServices.DirectorySearcher($root)
$searcher.Filter = '(objectClass=organizationalUnit)'
$searcher.PropertiesToLoad.Add("canonicalName")
$searcher.PropertiesToLoad.Add("Name")
$searcher1 = $searcher.FindAll()
foreach ($person in $searcher1){
[string]$ent = $person.Properties.canonicalname
$OUhash1.Add($ent.substring($ent.indexof("/"),$ent.length-$ent.indexof("/")),$ent)
$ouOuNameDrop.Items.Add($ent.substring($ent.indexof("/"),$ent.length-$ent.indexof("/")))
}
$ouOuNameDrop.Add_SelectedValueChanged({
$unUserNameDropBox.Items.Clear()
get-user -sortby "LastName" -OrganizationalUnit $OUhash1[$ouOuNameDrop.SelectedItem.ToString()] where { $_.RecipientType -eq "User" } foreach-object{
$uname = $_.DisplayName
$unUserNameDropBox.Items.Add($uname)
}
})

$form.Controls.Add($ouOuNameDrop)


# Add UserName Box
$unUserNameDropBox = new-object System.Windows.Forms.ComboBox
$unUserNameDropBox.Location = new-object System.Drawing.Size(100,40)
$unUserNameDropBox.size = new-object System.Drawing.Size(330,20)
$unUserNameDropBox.Add_SelectedValueChanged({
$user = get-user $unUserNameDropBox.SelectedItem.ToString()
$emIdentityTextBox.text = $user.Identity
$unFirstNameTextBox.text = $User.FirstName
$lnLastNameTextBox.text = $user.LastName
$dsDisplayNameTextBox.text = $user.DisplayName
$AliasNameText.text = $user.SamAccountName
$exExternalMail.text = $user.WindowsEmailAddress
$pscmd = "Enable-MailUser -Identity '" + $user.Identity + "' -Alias '" + $user.SamAccountName + "' -ExternalEmailAddress 'SMTP:" + $user.WindowsEmailAddress + "'"
$msCmd.text = $pscmd
})
$form.Controls.Add($unUserNameDropBox)


# Add Username Lable
$unUserNamelableBox = new-object System.Windows.Forms.Label
$unUserNamelableBox.Location = new-object System.Drawing.Size(10,40)
$unUserNamelableBox.size = new-object System.Drawing.Size(100,20)
$unUserNamelableBox.Text = "Username UPN"
$form.Controls.Add($unUserNamelableBox)

# Add Identity Box
$emIdentityTextBox = new-object System.Windows.Forms.TextBox
$emIdentityTextBox.Location = new-object System.Drawing.Size(100,65)
$emIdentityTextBox.size = new-object System.Drawing.Size(330,20)
$emIdentityTextBox.Add_TextChanged({
$pscmd = "Enable-MailUser -Identity '" + $emIdentityTextBox.Text + "' -Alias '" + $AliasNameText.Text + "' -ExternalEmailAddress 'SMTP:" + $exExternalMail.Text + "'"
$msCmd.text = $pscmd
})
$form.Controls.Add($emIdentityTextBox)

# Add Identity Lable
$emIdentitylableBox = new-object System.Windows.Forms.Label
$emIdentitylableBox.Location = new-object System.Drawing.Size(10,65)
$emIdentitylableBox.size = new-object System.Drawing.Size(100,20)
$emIdentitylableBox.Text = "Identity"
$form.Controls.Add($emIdentitylableBox)

# Add FirstName Box
$unFirstNameTextBox = new-object System.Windows.Forms.TextBox
$unFirstNameTextBox.Location = new-object System.Drawing.Size(100,90)
$unFirstNameTextBox.size = new-object System.Drawing.Size(130,20)
$form.Controls.Add($unFirstNameTextBox)

# Add FirstName Lable
$unFirstNamelableBox = new-object System.Windows.Forms.Label
$unFirstNamelableBox.Location = new-object System.Drawing.Size(10,90)
$unFirstNamelableBox.size = new-object System.Drawing.Size(60,20)
$unFirstNamelableBox.Text = "First Name"
$form.Controls.Add($unFirstNamelableBox)

# Add LastName Box
$lnLastNameTextBox = new-object System.Windows.Forms.TextBox
$lnLastNameTextBox.Location = new-object System.Drawing.Size(100,120)
$lnLastNameTextBox.size = new-object System.Drawing.Size(130,20)
$form.Controls.Add($lnLastNameTextBox)

# Add LastName Lable
$lnLastNamelableBox = new-object System.Windows.Forms.Label
$lnLastNamelableBox.Location = new-object System.Drawing.Size(10,120)
$lnLastNamelableBox.size = new-object System.Drawing.Size(60,20)
$lnLastNamelableBox.Text = "Last Name"
$form.Controls.Add($lnLastNamelableBox)

# Add DisplayName Box
$dsDisplayNameTextBox = new-object System.Windows.Forms.TextBox
$dsDisplayNameTextBox.Location = new-object System.Drawing.Size(100,150)
$dsDisplayNameTextBox.size = new-object System.Drawing.Size(130,20)
$form.Controls.Add($dsDisplayNameTextBox)

# Add DisplayName Lable
$dsDisplayNamelableBox = new-object System.Windows.Forms.Label
$dsDisplayNamelableBox.Location = new-object System.Drawing.Size(10,150)
$dsDisplayNamelableBox.size = new-object System.Drawing.Size(100,20)
$dsDisplayNamelableBox.Text = "Display Name"
$form.Controls.Add($dsDisplayNamelableBox)

# Add Alias Text
$AliasNameText = new-object System.Windows.Forms.TextBox
$AliasNameText.Location = new-object System.Drawing.Size(100,180)
$AliasNameText.Size = new-object System.Drawing.Size(230,30)
$AliasNameText.Add_TextChanged({
$pscmd = "Enable-MailUser -Identity '" + $emIdentityTextBox.Text + "' -Alias '" + $AliasNameText.Text + "' -ExternalEmailAddress 'SMTP:" + $exExternalMail.Text + "'"
$msCmd.text = $pscmd
})
$form.Controls.Add($AliasNameText)

# Add Alias TextBox Lable
$AliasNameTextlableBox = new-object System.Windows.Forms.Label
$AliasNameTextlableBox.Location = new-object System.Drawing.Size(10,180)
$AliasNameTextlableBox.size = new-object System.Drawing.Size(100,20)
$AliasNameTextlableBox.Text = "Alias"
$form.Controls.Add($AliasNameTextlableBox)

# Add External Email Address
$exExternalMail = new-object System.Windows.Forms.TextBox
$exExternalMail.Location = new-object System.Drawing.Size(100,210)
$exExternalMail.Size = new-object System.Drawing.Size(300,30)
$exExternalMail.Add_TextChanged({
$pscmd = "Enable-MailUser -Identity '" + $emIdentityTextBox.Text + "' -Alias '" + $AliasNameText.Text + "' -ExternalEmailAddress 'SMTP:" + $exExternalMail.Text + "'"
$msCmd.text = $pscmd
})
$form.Controls.Add($exExternalMail)

# Add External DropLable
$exExternalMaillableBox = new-object System.Windows.Forms.Label
$exExternalMaillableBox.Location = new-object System.Drawing.Size(10,210)
$exExternalMaillableBox.size = new-object System.Drawing.Size(100,20)
$exExternalMaillableBox.Text = "External Email"
$form.Controls.Add($exExternalMaillableBox)

# Add cmdbox
$msCmd = new-object System.Windows.Forms.RichTextBox
$msCmd.Location = new-object System.Drawing.Size(100,240)
$msCmd.Size = new-object System.Drawing.Size(400,75)
$msCmd.readonly = $true
$form.Controls.Add($msCmd)

# Add CMd DropLable
$msCmdlableBox = new-object System.Windows.Forms.Label
$msCmdlableBox.Location = new-object System.Drawing.Size(10,240)
$msCmdlableBox.size = new-object System.Drawing.Size(100,20)
$msCmdlableBox.Text = "PowerShell CMD"
$form.Controls.Add($msCmdlableBox)

# Add Mail Enabled Button

$crButton = new-object System.Windows.Forms.Button
$crButton.Location = new-object System.Drawing.Size(110,330)
$crButton.Size = new-object System.Drawing.Size(100,23)
$crButton.Text = "Enabled User"$crButton.Add_Click({Enableuser})$form.Controls.Add($crButton)

$form.topmost = $true
$form.Add_Shown({$form.Activate()})
$form.ShowDialog()

19 comments:

Chad said...

I, Looove.. that's L.O.V.E your little GUI PS scripts.

This helps me out so much as a MACS ECS Admin, I had a question for you, do you create your forms in VB or someother tool? or use vb and grab the location and size data?

OR do you just have "mad skillz" and can draw it all in your mind?

-Chad Ringstrom, MS: v-chring

Glen said...

I usually use Visual Studio to work out properties and components i want to add. But usually i just use Trial and Error to work out where things should go in regards to size and location. Its a little time consuming to do it this way but pretty most everything i write (script wise) i use Notepad. But you could do the same thing with Visual Studio ect but it wouldn't be a script at the end of the day. Considering the .net framework is going to be on most everything i'm not sure it really matters.

Cheers
Glen

Chad said...

Glen, I need some help modifying your script, I need to add a "-domaincontroller" variable, I'm not sure what the PS command would be to list/propigate a list of available domain controllers associated with that mail server to chose from.

Oh and to help me create the forms I found "admin script editor" I'll use the trial untill I gut the GUI commands memorised.

I know to create another hash array, but If you could also tell me what to tell the script to look for to add the server to the list would be appreciated.

I'm new at this and I havent gotten my Powershell books from amazon yet.

One last thing, is it also possible for it to create a list of active sync profiles to choose from?

-Thanks!

Glen said...

Hi Chad,

You can get a list of all the DC in a domain using something like

$context = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext(”Domain”,[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name)
$dclist = [System.DirectoryServices.ActiveDirectory.DomainController]::findall($context)
$dclist | %{
$_.name
}

To add a value to a hash table you just need to use the add method eg

$hash.add(Key,Value)

You probably don't need to use a Hashtable because just can just add a list of the FQDN's directly unless you just want to make it look pretty.

You can get the activeSync policies using the Get-ActiveSyncMailboxPolicy

If you still can't get it to work let me know and I'll knock up a version that includes those. Books are good but getting your hands dirty and writing as many scripts as you can is a much better way to learn IMO.

Cheers
Glen

Chad said...

Hey thank you so much for the tips and code, I have figured out the DC's.. now I'm working on the ActiveSync Stuff..

This is what I have so far with no luck..

# Add Active Sync Box Lable
$syncBox = new-object System.Windows.Forms.Label
$syncbox.Location = new-object System.Drawing.Size(10,400)
$syncbox.size = new-object System.Drawing.Size(80,20)
$syncbox.Text = "ActiveSyncPol"
$form.Controls.Add($syncBox)

# Add sync Box
$actsyncBox = new-object System.Windows.Forms.ComboBox
$actsyncBox.Location = new-object System.Drawing.Size(100,400)
$actsyncBox.size = new-object System.Drawing.Size(330,20)
$actsyncBox.Add_SelectedValueChanged({
$actsyncBox.Items.Clear()

Get-ActiveSyncMailboxPolicy | foreach-object{
$test = $_.Name
$actsyncBox.Items.Add($test)
}

})
$form.Controls.Add($actsyncbox)



I thought I understood the concept..
when I do Get-ActiveSyncMailboxPolicy | FL name

I Get:

Name : default
Name : strict

do I need to hash something? or change the syntax of my array? or do I just grab everything and remove the char's "Name :"

-Thanks!

Glen said...

Hi Chad,

Remove the line

$actsyncBox.Items.Clear()

Your actually clearing the drop downbox everytime it changes which means it will never be populated for you to see. When i used this in the script i was actually clearing a value for another box that would populated in response to what was selected in this dropdown you don't need to do this

Also you might want to add

$test = $_.Name.ToString()

To make sure your getting the string value and not just the property object.

Cheers
Glen

Anonymous said...

Love your scripts. Thank you much.

You can mailenable an account through ADUC if you install Exchange 2000/2003 System Manager.

Scott

Glen said...

You should not do this on Exchange 2007 it will not work because Exchange doesn't includes the RUS anymore always,always use the Exchange Management Shell

Anonymous said...

"always,always use the Exchange Management Shell"

You are correct for Exchange 2007 "only' installations...addresses will not be fully provisioned.

But for anyone in interop mode this is just fine, and supported by Microsoft.

Scott

JWP said...

Hi,
great script!

Did anyone modified this script for mass "mail enable user", for instance in a OU basis?

I used to do this in VBS (LDAP manipulation), but it seems to me that this is the most correct way of doing it.

Regards,
Jhonny

psilverio said...

Great scripts!!!

I was wondering instead of Enable-Mailuser if I could use Enable-mailbox? I also added the drop downs for server and database from another of your great scripts but I get errors.

Thanks

Glen said...

see http://gsexdev.blogspot.com/2006/12/quick-create-mailbox-powershell-form.html

Cheers
Glen

Pérsio Hartmann said...

Dude, this form is awesome.
Perfect.

Gongrats,
Pérsio

Anonymous said...

The form worked great but after I refreshed Exchange Management Console, the only user showing up is the Administrator which has been available since I installed Exchange.

Anonymous said...

Glen,

All my accounts show up now so disregard my previous message.

How could this be modified to import security and distribution groups from active directory?

Anonymous said...

Great script..

what it lacks is a button to clear all form controlss (clear previously entered user information)

how would that be achieved?

Glen said...

You need to set the Text property of each control to "" or null

Cheers
Glen

Glen said...

You need to use something like

[Reflection.Assembly]::LoadFile("c:\EWSOofUtil.dll")
$oofutil = new-object EWSOofUtil.OofUtil
$oofutil.setoof("user@domain.com","Scheduled”, [datetime]::Now.Date.ToUniversalTime(),[datetime]::Now.Date.AddDays(7).ToUniversalTime(),"userName","password","domain","https://servername/EWS/Exchange.asmx"

where

[datetime]::Now.Date.ToUniversalTime(),[datetime]::Now.Date.AddDays(7).ToUniversalTime(),

Is the start and enddate of the OOF period. You can also use EWS MAnaged API to do this now.

Cheers
Glen

Américo said...

Hi Glen!

Just found your blog and liked it instantly! Thanks for sharing...

I tried your Mail Enable Script, but I get an error and, as I am a newbie to PS, would like your help:

"The term 'Get-User' 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 in
cluded, verify that the path is correct and try again.
At C:\Documents and Settings\Administrator.SCOSTA\Desktop\qmuserv2.ps1:49 char:
10
+ Get-User <<<< -sortby "LastName" -OrganizationalUnit $OUhash1[$ouOuName
Drop.SelectedItem.ToString()] | where { $_.RecipientType -eq "User" } | foreach
-object{
+ CategoryInfo : ObjectNotFound: (Get-User:String) [], CommandNot
FoundException
+ FullyQualifiedErrorId : CommandNotFoundException"

Thank you very much.

Américo Nascimento

PS. Hope you get a good job soon!