Why we need to change our current user creation scripts to powershell scripts in Exchange 2007
In Exchange Server 2003 we have a background service named Recipient Update Service (RUS) which update all users to have necessary exchange attributes; for example e-mail address. In Exchange Server 2007 we don't have a service for doing same updates for newly created objects. As a replacement to this functionality in Exchange Server 2007 (E2K7) we have a new component that behaves like a provider rather than a service, maybe we can call this "Recipient Update Provider" . As you understand it's actually working as a provider not a daemon, process or service. If we need to create an object with exchange attributes, we will need to call this "update provider" help.
By default E2K7 GUI interface (Exchange Management Console --- EMC) and (Exchange Management Shell --- EMS) powershell commands has ( such as New-mailbox) this integration. So when you use GUI or powershell command to create a sample user, this both of methods calls to provider in the background to fill Exchange related attributes to objects.
Actually in E2K7 RUS API working as follows;
1- Admin user attempt to create/update user object mailbox via EMS or EMC operation, it calls RUS API
2- RUS API requests all policies from memory
3- DC' s returns address policy and adress lists to RUS API
4- RUS API returns list of attributes to the EMS or EMC
5- EMS or EMC requests required attribute list to RUS API and RUS API returns back to the EMC or EMS
6- EMC or EMS creates or updates object with required attributes in Active Directory (AD)
Whole of the above steps runs on mailbox server under the System Attendant process control.
I've try to write a sample script for user creation process and I've used New-Mailbox powershell command in this script. I hope this script helps for your business.
Actually following sample script doesn't have any risk for your system but please modify following script according your needs and don't run on your production environment before testing it in your test environment !!!
Note: You can copy following lines to a simple text file via notepad and run from powershell console.
Additional information regarding powershell;
https://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx
https://blogs.msdn.com/powershell/
-kekici-
# **************************************************************************
# This is a sample script for creating new server and mail enable process
#
# Author: Kutbettin Ekici
# **************************************************************************
# **************************************************************************
# This is first function which we have to use for new user data collection
function dataenter
{
Write-Host " "
Write-Host "New user (Required) information ... " -ForeGroundColor DarkGreen
Write-Host " "
# Required basic information for a sample user will collect by that way...
$FirstName = Read-Host "First Name"
$LastName = Read-Host "Last Name"
# Password need to collect as a secure string
$passWord = Read-Host "Password" -AsSecureString
# Global variable declaration in a function like that...
# By default variable scoping was local...
$global:Name = Read-Host "Logon name (it needs a unique value)"
$global:Displayname = $FirstName + " " + $LastName
$HomeMDB = Read-Host "Database path (HomeMDB) [For example; servername\StorageGroupName\DatabaseName] "
$alias = Read-Host "Alias name (it needs a unique value)"
$domain = Read-Host "What is the domain name for new user [For example; contoso.local] "
$UPN = $Name+"@"+$domain
Write-Host " "
Write-Host "Optional information for user... " -ForeGroundColor DarkGreen
Write-Host " "
# Optional data for new user
$OU = Read-Host "Organizational Unit location for new user [For example; /Contoso/Bim/Users/ ]"
if ($OU -eq "")
{
# Following line is not necessary but addressing static path will be fine…
$OU = $domain + "/" + "USERS"
}
# normally variable scope in a function by default is local, we can set it global with the following sample line...
# set-variable OU value -scope global
$SendSize = Read-Host "Mail send limit [For example; 1230KB, 2MB ]"
if ($SendSize -eq "")
{
$SendSize = "0KB"
}
$ReceiveSize = Read-Host "Mail receive limit [For example; 10000KB, 2MB ]"
if ($ReceiveSize -eq "")
{
$ReceiveSize = "0KB"
}
$global:Description = Read-Host "User Description [For example; Customer Account Manager]"
$global:title = Read-Host "Title : [For example; Account Manager]"
# Calling createUserMBX function
createUserMBX
}
function createUserMBX
{
Write-Host " "
Write-Host " User Information will be… : " -ForeGroundColor DarkGreen
Write-Host "Name : " $DisplayName -ForeGround Blue
Write-Host "Alias : " $Alias -ForeGround Blue
Write-Host "OU : " $OU -ForeGround Blue
Write-Host "UPN : " $UPN -ForeGround Blue
Write-Host "Logon Name : " $Name -ForeGround Blue
Write-Host "DB address : "$HomeMDB -ForeGround Blue
Write-Host "Send Limit : " $SendSize -ForeGround Blue
Write-Host "Receive Limit : " $ReceiveSize -ForeGround Blue
Write-Host " "
# ************************************************************************
$SecondQuestion = Read-Host "Do you want to create this user with the above information ? Yes (Y) / No: (N)"
if ($SecondQuestion -eq 'Y' )
{
# exception handling lines....
trap {
Write-Host " An error occured, please check the following detailed information and take an action for resolution. " -ForeGroundColor RED -BackGroundColor WHITE
Write-Host " "
break
}
# we are creating user by calling RUS API with the “new-mailbox” command...
New-Mailbox -Name $Name -Alias $Alias -OrganizationalUnit $OU -UserPrincipalName $UPN -SamAccountName $Name -FirstName $FirstName -LastName $LastName -Database $HomeMDB -ResetPasswordOnNextLogon $false -Password $passWord;
if (($SendSize -eq '0KB') -and ($ReceiveSize -eq '0KB'))
{
}
else
{
if ($SendSize -ne '0KB')
{
Set-Mailbox -identity $Alias -MaxSendSize $SendSize
}
if ($ReceiveSize -ne '0KB')
{
Set-Mailbox -identity $Alias -MaxReceiveSize $ReceiveSize
}
}
# This is a sample line for additional settings
# OWA enabled by default With the following line we can disable OWA for new users
# Set-CASMailbox -identity $Alias -OWAEnabled $false
#We are calling new user Ldap path for optional data entry
}
else
{
Write-Host " An error occurred in user creation phase...! " -ForeGround Blue
break
}
}
# **************************************************************************
function get-dn ($Name)
{
Write-Host " "
write-host "Searching" $DisplayName "named new user in the active directory..."
Write-Host " "
trap {
Write-Host " Problems occurred related AD connection or user creation. " -ForeGroundColor RED -BackGroundColor WHITE
Write-Host " Please check error message and take correct action. " -ForeGroundColor RED -BackGroundColor WHITE
Write-Host " "
break
}
# We are starting a powershell ADSI session...
$root = [ADSI]
# By using .NET directory service we are describe a searcher object for ADSI interface
$searcher = new-object DirectoryServices.DirectorySearcher($root)
#Setting up a name filter for user class
$searcher.filter = "(&(objectClass=user)(name= $Name))"
#Listing all possible results... (It's a unique value...)
$user = $searcher.findall()
if ($user.count -gt 1)
{
$count = 0
foreach($i in $user)
{
write-host $count ": " $i.path
$count = $count + 1
}
$selection = Read-Host "Please select item: "
# returning Ldap path back to the requested function...
return $user[$selection].path
}
else
{
return $user[0].path
}
}
function lastUserSetup
{
$global:LDAPpath = get-dn $Name
# another variable scope declaration way is: set-variable var -scope global
trap {
Write-Host " Probably script didn't complete update user: $DisplayName for it's additional attributes. " -ForeGroundColor RED -BackGroundColor WHITE
Write-Host " Please check the error message and take required action. " -ForeGroundColor RED -BackGroundColor WHITE
Write-Host " "
break
}
$NewUser = New-Object System.DirectoryServices.DirectoryEntry $LDAPpath
if ($Displayname -ne "")
{$NewUser.Put('displayName',$DisplayName)}
if ($Description -ne "")
{$NewUser.Put('description',$Description)}
if ($title -ne "")
{$NewUser.Put('title',$title)}
if (($Displayname -eq "") -and ($Description -eq "") -and ($title -eq ""))
{
Write-Host "There isn't any update ..."
}
else
{
Write-Host " "
#We are writing all attributes with the following line
$NewUser.SetInfo()}
Write-Host "Update operation completed successfully."
Write-Host " "
}
function results
{
$NewUser = New-Object System.DirectoryServices.DirectoryEntry $LDAPpath | Select-Object *
Write-Host "************************************************************************** " -ForeGroundColor DarkGREEN
Write-Host "********* User created or updated with the following information ********* " -ForeGroundColor DarkGREEN
Write-Host "E-mail Address : "
Write-Host $newUser.mail -ForeGroundColor DarkGreen
Write-Host " "
Write-Host "Server Path : "
write-host $newUser.msExchHomeServerName -ForeGroundColor DarkGreen
Write-Host " "
Write-Host "Database Path : "
write-host $newUser.homeMDB -ForeGroundColor DarkGreen
Write-Host " "
Write-Host "Display Name : "
write-Host $newUser.DisplayName -ForeGroundColor DarkGreen
Write-Host " "
Write-Host "Logon Name : "
write-host $newUser.sAMAccountName -ForeGroundColor DarkGreen
Write-Host " "
Write-Host "Title : "
Write-Host $newUser.title -ForeGroundColor DarkGreen
Write-Host " "
Write-Host "Description : "
write-host $newUser.description -ForeGroundColor DarkGreen
Write-Host " "
Write-Host " ************************************************************************** " -ForeGroundColor DarkGREEN
}
# This is the start point of powershell script
# Just giving a sample for Read-Host and if statement....
$FirstQuestion = Read-Host " What do you need ? For a new user plase press:Y / For updating a user please press: U "
# if statement sample...
if ($FirstQuestion -eq 'Y' )
{
# We are calling dataenter function by the following line
dataenter
lastUserSetup
results
break
}
else
{
Write-Host " Update function is not implemented yet. " -ForeGroundColor GREEN
break
}