# Script for user creation on Exchange Server 2007 Power Shell # Modeled after http://gsexdev.blogspot.com/2006/12/quick-create-mailbox-powershell-form.html [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") # Make commands fail hard, so the traps work $ErrorActionPreference = "stop" # Constants $company = "Corp" $upnDomain = "corp.ch" $mailDomain = "corp.ch" $addn = "dc=myadc,dc=local" $adroot = "LDAP://ou=ADUsers,"+$addn $jobList = @( "Allocator", "Deallocator" ) $admin = (get-item env:username).Value # Base Paths $pathBase="\\fileserver\" $pathUsr="\\fileserver\users$\" $pathPro="\\fileserver\profile$\" $pathRed="\\fileserver\redir$\" $logfile = "\\fileserver\all$\IT\Scripts\AD\AD-New.log" # Logging function log { param([string]$msg) $date = get-date -format "yyyy.MM.dd HH:mm:ss" $msg = $date.ToString()+": [STATUS] "+$msg write-output $msg | out-file -filepath $logfile -append write-host $msg } function err { param([string]$msg) $date = get-date -format "yyyy.MM.dd HH:mm:ss" $msg = $date.ToString()+": [ERROR] "+$msg write-output $msg | out-file -filepath $logfile -append write-host $msg } # Error Handling # Make commands fail hard, so the traps work $ErrorActionPreference = "stop" trap [Exception] # Error handler { err("Global: " + ($_.Exception.GetType().FullName) + ": " + ($_.Exception.Message)) #err($_.InvocationInfo.PositionMessage) break } # Methods function createUser { trap [Exception] # Error handler { err("createUser: " + ($_.Exception.GetType().FullName) + ": " + ($_.Exception.Message)) #err($_.InvocationInfo.PositionMessage) continue } $upn = $upnNameTextBox.text $alias = $aliasTextBox.text $mailDB = $mailBoxHashTable[$mailStoreDrop.SelectedItem.ToString()] $ou = $ouHashTable[$ouNameDrop.SelectedItem.ToString()] $department = $ou.nn if (($ou.ds -ne $null) -and ($ou.ds -ne "")) { $department = $ou.ds } log("("+$admin+") Creating User "+$upn+" in "+$ou.cn) if ($validUntilCheckBox.Checked) { $validUntil = $validUntilDatePicker.Value.AddDays(1) } else { # This probably only works in our own timezone # and maybe only during winter time. $validUntil = [DateTime]::FromFiletimeUTC(36000000000) } # Create a Secure Password String $securePasswordString = new-object System.Security.SecureString foreach($char in $pwPassWordTextBox1.Text.ToCharArray()) { $securePasswordString.AppendChar($char) } $result = new-mailbox -UserPrincipalName $upn -alias $alias -database $mailDB ` -Name $displayNameTextBox.text -OrganizationalUnit $ou.cn ` -FirstName $firstNameTextBox.text -LastName $lastNameTextBox.text -DisplayName $displayNameTextBox.text ` -password $securePasswordString -resetPasswordOnNextLogon $true if ($result -ne $null) { #$mb = get-mailbox -identity $upn #$mb.EmailAddresses += $alias + "@" + $mailDomain #$mb | set-mailbox log("Mailbox Created Successfully") # Data $desc = $jobDescDrop.Text $phone = $phoneTextBox.Text $webpage = $webpageTextBox.Text # General Stuff (alternative: use set-user, for some of those) $user = get-user -identity $upn $aduser = [ADSI]("LDAP://"+$user.DistinguishedName) if ($desc -ne "") { $aduser.description = $jobDescDrop.Text } if ($phone -ne "") { $aduser.telephonenumber = $phone } if ($webpage -ne "") { $aduser.wwwhomepage = $webpage } $aduser.company = $company $aduser.department = $department # FS $aduser.profilePath = $pathPro + $alias + "\%osversion%" $aduser.homeDrive = "P:" $aduser.homeDirectory = $pathBase + $alias + "$" # Commit Settings $aduser.SetInfo() # Hard to change Expiration Date is set directly #$aduser.psbase.InvokeGet("AccountExpirationDate") $aduser.psbase.InvokeSet("AccountExpirationDate", $validUntil) $aduser.psbase.CommitChanges() log("AD User configured") createFolders($alias) } else { log("Error Creating Mailbox") } } function createFolders { param([string]$alias) trap [Exception] # Error handler { err("createFolders: " + ($_.Exception.GetType().FullName) + ": " + ($_.Exception.Message)) #err($_.InvocationInfo.PositionMessage) continue } # Create Usr/Pro/Red createFolder ($pathUsr+$alias) $alias createFolder ($pathPro+$alias) $alias createFolder ($pathRed+$alias) $alias # Important subfolders and files createFolder ($pathUsr+$alias+"\Windows") } function createFolder { param([string]$path, [string]$user) # Create Folder log("Create Folder " + $path) new-item -type directory $path if ($user) { log("Grant FullControl on " + $path + " to " + $user) # Set ACL (makes problems with seSecurityPrivilege requirement error # $rule = new-object System.Security.AccessControl.FileSystemAccessRule (($user+"@"+$upnDomain),"FullControl ","Allow") # $acl = get-acl $path # $acl.AddAccessRule($rule) # set-acl $path $acl $rightstring = $user+"@"+$upnDomain+":f" cacls $path /e /g $rightstring } } # String replacements/cleaning $stringReplacementMap = @{ "ä" = @("a","e") "ö" = @("o","e") "ü" = @("u","e") "é" = "e" "è" = "e" "à" = "a" "ç" = "c" "ß" = "ss" " " = "" } filter cleanChar { $r = $stringReplacementMap["$_"] if ($r) {return $r} elseif ($_ -ge "a" -and $_ -le "z") {return $_} elseif ($_ -ge "A" -and $_ -le "Z") {return $_} else {write-host "Filtered character " $_} } # Changes the dependent names based on first name and last name function updateUID { $shortname = "" $lastNameTextBox.Text.ToLower().ToCharArray() | cleanChar $lnArray = @($lastNameTextBox.Text.ToLower().ToCharArray() | cleanChar) $fnArray = @($firstNameTextBox.Text.ToLower().ToCharArray() | cleanChar) $shortname = $lnArray[0]+$lnArray[1]+$fnArray[0] $offset = 10 $res = get-user -resultsize 1 -erroraction SilentlyContinue ([string]"" + $shortname + $offset) while ($res -ne $null) { $offset += 1 $res = get-user -resultsize 1 -erroraction SilentlyContinue ([string]"" + $shortname + $offset) } $shortname += $offset $aliasTextBox.Text = $shortname $upnNameTextBox.Text = [string]"" + $shortname +"@"+ $upnDomain $displayNameTextBox.Text = $lastNameTextBox.Text + ", " + $firstNameTextBox.Text $fnFiltered = arrayToString($fnArray) $lnFiltered = arrayToString($lnArray) $mailTextBox.Text = ($fnFiltered + "." + $lnFiltered + "@" + $mailDomain) } # A probably very inefficient array to string converter function arrayToString { param($ar) $st = "" foreach ($c in $ar) { $st += $c } return $st } # Refreshes the mail store dropdown function refreshMailStore { $mailStoreDrop.Items.Clear() $mailBoxHashTable.Clear() get-mailboxdatabase -Server $serverNameDrop.SelectedItem.ToString() | ForEach-Object ` { $null = $mailStoreDrop.Items.Add($_.Name) $mailBoxHashTable.add($_.Name,$_.ServerName + "\" + $_.StorageGroup.Name + "\" + $_.Name) } # Select a random mail-store if ($mailStoreDrop.Items.Count -gt 1) { $rand = new-object system.random $mailStoreDrop.SelectedIndex = $rand.next(1,$mailStoreDrop.Items.Count-1) # from 1 to count-1 (not inclusive) } } # Verify Password (check if both passwords are the same) function verifyPassword { $pw1 = $pwPassWordTextBox1.Text $pw2 = $pwPassWordTextBox2.Text if ($pw1 -eq $pw2 -and $pw1 -ne "" -and $pw1.length -ge 6) { $crButton.Enabled = $true $pwPassWordTextBox1.BackColor = [System.Drawing.Color]::White $pwPassWordTextBox2.BackColor = [System.Drawing.Color]::White } else { $crButton.Enabled = $false $pwPassWordTextBox1.BackColor = [System.Drawing.Color]::Red $pwPassWordTextBox2.BackColor = [System.Drawing.Color]::Red } } $ouHashTable = @{ } $mailBoxHashTable = @{ } ############################################################################### # User Interface ############################################################################### $posXControl = 100 $posXLable = 10 $posY = 0 $lineHeight = 30 $controlWidth = 300 $controlHeight = 20 $form = new-object System.Windows.Forms.form $form.Text = "Exchange 2007 User Create Form" $form.size = new-object System.Drawing.Size(440,550) $form.AutoSize = $true $form.AutoSizeMode = "GrowOnly" ### FirstName $posY += $lineHeight # Add FirstName Box $firstNameTextBox = new-object System.Windows.Forms.TextBox $firstNameTextBox.Location = new-object System.Drawing.Size($posXControl,$posY) $firstNameTextBox.size = new-object System.Drawing.Size($controlWidth,$controlHeight) $firstNameTextBox.add_TextChanged({updateUID}) $form.Controls.Add($firstNameTextBox) # Add FirstName Lable $firstNameLableBox = new-object System.Windows.Forms.Label $firstNameLableBox.Location = new-object System.Drawing.Size($posXLable,$posY) $firstNameLableBox.size = new-object System.Drawing.Size(60,20) $firstNameLableBox.Text = "First Name" $form.Controls.Add($firstNameLableBox) ### LastName $posY += $lineHeight # Add LastName Box $lastNameTextBox = new-object System.Windows.Forms.TextBox $lastNameTextBox.Location = new-object System.Drawing.Size($posXControl,$posY) $lastNameTextBox.size = new-object System.Drawing.Size($controlWidth,$controlHeight) $lastNameTextBox.add_TextChanged({updateUID}) $form.Controls.Add($lastNameTextBox) # Add LastName Lable $lastNameLableBox = new-object System.Windows.Forms.Label $lastNameLableBox.Location = new-object System.Drawing.Size($posXLable,$posY) $lastNameLableBox.size = new-object System.Drawing.Size(60,20) $lastNameLableBox.Text = "Last Name" $form.Controls.Add($lastNameLableBox) ### E-Mail $posY += $lineHeight # Add LastName Box $mailTextBox = new-object System.Windows.Forms.TextBox $mailTextBox.Location = new-object System.Drawing.Size($posXControl,$posY) $mailTextBox.size = new-object System.Drawing.Size($controlWidth,$controlHeight) $form.Controls.Add($mailTextBox) # Add LastName Lable $mailLableBox = new-object System.Windows.Forms.Label $mailLableBox.Location = new-object System.Drawing.Size($posXLable,$posY) $mailLableBox.size = new-object System.Drawing.Size(60,20) $mailLableBox.Text = "E-Mail" $form.Controls.Add($mailLableBox) ### Alias $posY += $lineHeight # Add Alias Box $aliasTextBox = new-object System.Windows.Forms.TextBox $aliasTextBox.Location = new-object System.Drawing.Size($posXControl,$posY) $aliasTextBox.size = new-object System.Drawing.Size($controlWidth,$controlHeight) $aliasTextBox.ReadOnly = $true $form.Controls.Add($aliasTextBox) # Add Alias Lable $aliasLableBox = new-object System.Windows.Forms.Label $aliasLableBox.Location = new-object System.Drawing.Size($posXLable,$posY) $aliasLableBox.size = new-object System.Drawing.Size(100,20) $aliasLableBox.Text = "Alias" $form.Controls.Add($aliasLableBox) ### Username $posY += $lineHeight # Add UserName Box $upnNameTextBox = new-object System.Windows.Forms.TextBox $upnNameTextBox.Location = new-object System.Drawing.Size($posXControl,$posY) $upnNameTextBox.size = new-object System.Drawing.Size($controlWidth,$controlHeight) $upnNameTextBox.ReadOnly = $true $form.Controls.Add($upnNameTextBox) # Add Username Lable $upnNameLableBox = new-object System.Windows.Forms.Label $upnNameLableBox.Location = new-object System.Drawing.Size($posXLable,$posY) $upnNameLableBox.size = new-object System.Drawing.Size(100,20) $upnNameLableBox.Text = "Username UPN" $form.Controls.Add($upnNameLableBox) ### Display Name $posY += $lineHeight # Add DisplayName Box $displayNameTextBox = new-object System.Windows.Forms.TextBox $displayNameTextBox.Location = new-object System.Drawing.Size($posXControl,$posY) $displayNameTextBox.size = new-object System.Drawing.Size($controlWidth,$controlHeight) $displayNameTextBox.ReadOnly = $true $form.Controls.Add($displayNameTextBox) # Add DisplayName Lable $displayNameLableBox = new-object System.Windows.Forms.Label $displayNameLableBox.Location = new-object System.Drawing.Size($posXLable,$posY) $displayNameLableBox.size = new-object System.Drawing.Size(100,20) $displayNameLableBox.Text = "Display Name" $form.Controls.Add($displayNameLableBox) ### Job Description $posY += $lineHeight # Add JobDesc Box $jobDescDrop = new-object System.Windows.Forms.ComboBox $jobDescDrop.Location = new-object System.Drawing.Size($posXControl,$posY) $jobDescDrop.size = new-object System.Drawing.Size($controlWidth,$controlHeight) $jobDescDrop.DropDownStyle = "DropDown" $jobList | foreach {$null = $jobDescDrop.Items.Add($_)} $form.Controls.Add($jobDescDrop) # Add JobDesc Lable $jobDescLableBox = new-object System.Windows.Forms.Label $jobDescLableBox.Location = new-object System.Drawing.Size($posXLable,$posY) $jobDescLableBox.size = new-object System.Drawing.Size(100,20) $jobDescLableBox.Text = "Job Description" $form.Controls.Add($jobDescLableBox) ### Phone $posY += $lineHeight # Add JobDesc Box $phoneTextBox = new-object System.Windows.Forms.TextBox $phoneTextBox.Location = new-object System.Drawing.Size($posXControl,$posY) $phoneTextBox.size = new-object System.Drawing.Size($controlWidth,$controlHeight) $form.Controls.Add($phoneTextBox) # Add JobDesc Lable $phoneLableBox = new-object System.Windows.Forms.Label $phoneLableBox.Location = new-object System.Drawing.Size($posXLable,$posY) $phoneLableBox.size = new-object System.Drawing.Size(100,20) $phoneLableBox.Text = "Phone" $form.Controls.Add($phoneLableBox) ### Web Page $posY += $lineHeight # Add JobDesc Box $webpageTextBox = new-object System.Windows.Forms.TextBox $webpageTextBox.Location = new-object System.Drawing.Size($posXControl,$posY) $webpageTextBox.size = new-object System.Drawing.Size($controlWidth,$controlHeight) $form.Controls.Add($webpageTextBox) # Add JobDesc Lable $webpageLableBox = new-object System.Windows.Forms.Label $webpageLableBox.Location = new-object System.Drawing.Size($posXLable,$posY) $webpageLableBox.size = new-object System.Drawing.Size(100,20) $webpageLableBox.Text = "Web Page" $form.Controls.Add($webpageLableBox) ### Valid Until $posY += $lineHeight # No Expiration Checkbox $validUntilCheckBox = new-object System.Windows.Forms.CheckBox $validUntilCheckBox.Location = new-object System.Drawing.Size($posXControl,$posY) $validUntilCheckBox.size = new-object System.Drawing.Size($controlHeight,$controlHeight) $validUntilCheckBox.Checked = $false $validUntilCheckBox.add_CheckStateChanged({$validUntilDatePicker.Enabled = $validUntilCheckBox.Checked}) $form.Controls.Add($validUntilCheckBox) # Add Valid Until $validUntilDatePicker = new-object System.Windows.Forms.DateTimePicker $validUntilDatePicker.Location = new-object System.Drawing.Size(($posXControl+30),$posY) $validUntilDatePicker.size = new-object System.Drawing.Size(($controlWidth-30),$controlHeight) $validUntilDatePicker.enabled = $false $form.Controls.Add($validUntilDatePicker) # Add Valid Lable $validUntilLableBox = new-object System.Windows.Forms.Label $validUntilLableBox.Location = new-object System.Drawing.Size($posXLable,$posY) $validUntilLableBox.size = new-object System.Drawing.Size(100,20) $validUntilLableBox.Text = "Valid Until" $form.Controls.Add($validUntilLableBox) ### Active Directory Organisation Unit $posY += $lineHeight # Add OU Drop Down $ouNameDrop = new-object System.Windows.Forms.ComboBox $ouNameDrop.Location = new-object System.Drawing.Size($posXControl,$posY) $ouNameDrop.Size = new-object System.Drawing.Size($controlWidth,30) $ouNameDrop.DropDownStyle = "DropDownList" # Find all suitable OUs $searcher = new-object System.DirectoryServices.DirectorySearcher $searcher.Filter = '(objectClass=organizationalUnit)' $searcher.SearchRoot = [ADSI]$adroot $searcher.SearchScope = "Subtree" $null = $searcher.PropertiesToLoad.Add("canonicalName") $null = $searcher.PropertiesToLoad.Add("distinguishedName") $null = $searcher.PropertiesToLoad.Add("Name") $null = $searcher.PropertiesToLoad.Add("Description") $searcher1 = $searcher.FindAll() # Extract the results from the search results object into a (sortable) list $ouList = @() # empty list foreach ($ou in $searcher1) { $ht = @{} $ht.dn = [string]$ou.Properties.distinguishedname $ht.cn = [string]$ou.Properties.canonicalname $ht.nn = [string]$ou.Properties.name $ht.ds = [string]$ou.Properties.description $ouList += $ht } $ouList = $ouList | sort-object @{expression={$_.cn}} foreach ($ou in $ouList) { $o = [ADSI]("LDAP://"+$ou.dn) $cn = $ou.cn $i = $cn.indexof("/") $s = $cn.substring($i,$cn.length-$i) $ouHashTable.Add($s,$ou) $null = $ouNameDrop.Items.Add($s) } $ouList = $null $ouNameDrop.SelectedIndex = 0 $form.Controls.Add($ouNameDrop) # Add OU DropLable $ouNameLableBox = new-object System.Windows.Forms.Label $ouNameLableBox.Location = new-object System.Drawing.Size($posXLable,$posY) $ouNameLableBox.size = new-object System.Drawing.Size(100,20) $ouNameLableBox.Text = "OU Name" $form.Controls.Add($ouNameLableBox) ### Mail Server $posY += $lineHeight # Add Server Drop Down $serverNameDrop = new-object System.Windows.Forms.ComboBox $serverNameDrop.Location = new-object System.Drawing.Size($posXControl,$posY) $serverNameDrop.Size = new-object System.Drawing.Size($controlWidth,$lineHeight) $serverNameDrop.DropDownStyle = "DropDownList" get-mailboxserver | ForEach-Object{$null = $serverNameDrop.Items.Add($_.Name)} if ($serverNameDrop.Items.Count -gt 0) {$serverNameDrop.SelectedIndex = 0} $serverNameDrop.Add_SelectedIndexChanged({refreshMailStore}) $form.Controls.Add($serverNameDrop) # Add Server DropLable $serverNameLableBox = new-object System.Windows.Forms.Label $serverNameLableBox.Location = new-object System.Drawing.Size($posXLable,$posY) $serverNameLableBox.size = new-object System.Drawing.Size(100,20) $serverNameLableBox.Text = "ServerName" $form.Controls.Add($serverNameLableBox) ### Mailbox-Store $posY += $lineHeight # Add MailStore Drop Down $mailStoreDrop = new-object System.Windows.Forms.ComboBox $mailStoreDrop.Location = new-object System.Drawing.Size($posXControl,$posY) $mailStoreDrop.Size = new-object System.Drawing.Size($controlWidth,$lineHeight) $mailStoreDrop.DropDownStyle = "DropDownList" $form.Controls.Add($mailStoreDrop) # Add MailStore DropLable $msMailStoreLableBox = new-object System.Windows.Forms.Label $msMailStoreLableBox.Location = new-object System.Drawing.Size($posXLable,$posY) $msMailStoreLableBox.size = new-object System.Drawing.Size(100,20) $msMailStoreLableBox.Text = "Mail-Store" $form.Controls.Add($msMailStoreLableBox) ### Password 1 $posY += $lineHeight # Add Password Box $pwPassWordTextBox1 = new-object System.Windows.Forms.TextBox $pwPassWordTextBox1.Location = new-object System.Drawing.Size($posXControl,$posY) $pwPassWordTextBox1.size = new-object System.Drawing.Size($controlWidth,$controlHeight) $pwPassWordTextBox1.UseSystemPasswordChar = $true $pwPassWordTextBox1.add_TextChanged({verifyPassword}) $form.Controls.Add($pwPassWordTextBox1) # Add Password Lable $pwPassWordLableBox = new-object System.Windows.Forms.Label $pwPassWordLableBox.Location = new-object System.Drawing.Size($posXLable,$posY) $pwPassWordLableBox.size = new-object System.Drawing.Size(60,20) $pwPassWordLableBox.Text = "Password" $form.Controls.Add($pwPassWordLableBox) ### Password 2 $posY += $lineHeight # Add Password Box $pwPassWordTextBox2 = new-object System.Windows.Forms.TextBox $pwPassWordTextBox2.Location = new-object System.Drawing.Size($posXControl,$posY) $pwPassWordTextBox2.size = new-object System.Drawing.Size($controlWidth,$controlHeight) $pwPassWordTextBox2.UseSystemPasswordChar = $true $pwPassWordTextBox2.add_TextChanged({verifyPassword}) $form.Controls.Add($pwPassWordTextBox2) # Add Password Lable $pwPassWordLableBox = new-object System.Windows.Forms.Label $pwPassWordLableBox.Location = new-object System.Drawing.Size($posXLable,$posY) $pwPassWordLableBox.size = new-object System.Drawing.Size(60,20) $pwPassWordLableBox.Text = "Verification" $form.Controls.Add($pwPassWordLableBox) # Add Buttons $posY += $lineHeight # Add Create Button $crButton = new-object System.Windows.Forms.Button $crButton.Location = new-object System.Drawing.Size(300,$posY) $crButton.Size = new-object System.Drawing.Size(100,23) $crButton.Text = "Create Account" $crButton.Add_Click({createUser}) $form.Controls.Add($crButton) $form.AcceptButton = $crButton # Add Cancel Button $ccButton = new-object System.Windows.Forms.Button $ccButton.Location = new-object System.Drawing.Size($posXLable,$posY) $ccButton.Size = new-object System.Drawing.Size(100,23) $ccButton.Text = "Exit" $ccButton.Add_Click({$form.Close()}) $form.Controls.Add($ccButton) refreshMailStore verifyPassword $form.topmost = $true $form.Add_Shown({$form.Activate()}) $form.ShowDialog()