Advertisement
contr0l

Create mailbox in 365 from user in AD

Sep 24th, 2018
228
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <# Script to enable a new remote mailbox
  2. An AD user object that has been synchronized to O365 needs to already be created
  3. So the user must already be created in AD and synced to 365 before we can run this script to create the mailbox and assign license.
  4.  
  5. Update 12/11/2017
  6. - Removed hard set server names, added logic to dynamically find Exchange on-premises PowerShell endpoint
  7. - Removed option to assign licenses other than E3
  8. - Added logic to accomodate UPN's other than @quantaservices.com
  9. - Cleaned up recipient validation logic and added check for UPN to email address collision
  10. - Added logic to dynamically create RemoteRoutingAddress
  11. Update 2/4/201
  12. - Added a check for mail enabled user
  13. Updated 10/7/2014
  14. - Fixed requireS statement in script
  15. - Added CleanExit function
  16. Updated 9/22/2014
  17. - Fixed error trap on Set-MSOLUser and Set-MsolUserLicenses cmdlets
  18. Updated 8/6/2014
  19. - Fixed error trap on Enable-RemoteMailbox cmdlet
  20. Updated 7/7/2014
  21.  - Do not assign license to Room or Equipment mailboxes
  22. Updated 7/1/2014
  23.  - Changed check for proxyAddresses to only look for SMTP:, fixing an issue when user was enabled for Lync before creating a mailbox.
  24. Updated 4/22/2014
  25.  - Changed check of proxyAddresses to existence only
  26.  - Added checks for attributes: mDBUseDefaults,msExchHomeServerName,msExchUMDtmfMap,msExchUserAccountControl
  27.  - Replaced Pause command with ReadKey function
  28.  - Commented out initial Company field warning
  29.  - Added CredDelete method to ADVAPI32
  30.  - Added check for class to ADVAPI32get-adus
  31. Updated 3/19/2014
  32.  - Added URL to country code list
  33. Updated 3/6/2014
  34.  - Slightly modified how licenses are displayed
  35. Updated 3/3/2014
  36.  - License assignment choice by user (from Microsoft Office 365 Plan E4 or Exchange Online Plan 1)
  37.  - Added check for Company attribute
  38.  - Pulls country code from C user attribute
  39.  - Added Pause if run from ConsoleHost
  40. Updated 1/1/2014
  41.  - Digitally signed
  42.  - Logs into Exchange on prem and Office 365 using same credentials pulled from Credential Manager
  43.  
  44. Created 10/2013
  45.  
  46. ToDo:
  47.  - Check that user has rights to assign license in 365 before creating mailbox
  48.  -
  49. #>
  50.  
  51. #requires -version 3
  52. #requires -module ActiveDirectory
  53.  
  54. param()
  55.  
  56. Import-Module ActiveDirectory -ErrorAction Stop
  57. Import-Module MSOnline -ErrorAction Stop
  58.  
  59. $script:session = $null
  60. $script:userLogonName = $null
  61. $script:countryCode = $null
  62. $script:adminCreds = $null
  63.  
  64. # Prompt for exit, if run from windowed PowerShell
  65. function CleanExit() {
  66.     If ($Host.Name -eq "ConsoleHost") { Write-Host "Press any key to continue..."; $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | Out-Null }
  67.     Exit
  68. }
  69.  
  70. # The following credential manager stuff was taken from the MS script O365-Fed-MetaData-Update-Task-Installation used on the ADFS servers
  71. function GetCredentialsFromCredentialManager() {
  72.     Write-Host "Retrieving admin credentials from credential manager" -ForegroundColor Green
  73.  
  74.     $sig = @"
  75. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  76. public struct NativeCredential
  77. {
  78.    public UInt32 Flags;
  79.    public CRED_TYPE Type;
  80.    public IntPtr TargetName;
  81.    public IntPtr Comment;
  82.    public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
  83.    public UInt32 CredentialBlobSize;
  84.    public IntPtr CredentialBlob;
  85.    public UInt32 Persist;
  86.    public UInt32 AttributeCount;
  87.    public IntPtr Attributes;
  88.    public IntPtr TargetAlias;
  89.    public IntPtr UserName;
  90.    internal static NativeCredential GetNativeCredential(Credential cred)
  91.    {
  92.        NativeCredential ncred = new NativeCredential();
  93.        ncred.AttributeCount = 0;
  94.        ncred.Attributes = IntPtr.Zero;
  95.        ncred.Comment = IntPtr.Zero;
  96.        ncred.TargetAlias = IntPtr.Zero;
  97.        ncred.Type = CRED_TYPE.GENERIC;
  98.        ncred.Persist = (UInt32)1;
  99.        ncred.CredentialBlobSize = (UInt32)cred.CredentialBlobSize;
  100.        ncred.TargetName = Marshal.StringToCoTaskMemUni(cred.TargetName);
  101.        ncred.CredentialBlob = Marshal.StringToCoTaskMemUni(cred.CredentialBlob);
  102.        ncred.UserName = Marshal.StringToCoTaskMemUni(System.Environment.UserName);
  103.        return ncred;
  104.    }
  105. }
  106. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  107. public struct Credential
  108. {
  109.    public UInt32 Flags;
  110.    public CRED_TYPE Type;
  111.    public string TargetName;
  112.    public string Comment;
  113.    public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
  114.    public UInt32 CredentialBlobSize;
  115.    public string CredentialBlob;
  116.    public UInt32 Persist;
  117.    public UInt32 AttributeCount;
  118.    public IntPtr Attributes;
  119.    public string TargetAlias;
  120.    public string UserName;
  121. }
  122. public enum CRED_TYPE : uint
  123.    {
  124.        GENERIC = 1,
  125.        DOMAIN_PASSWORD = 2,
  126.        DOMAIN_CERTIFICATE = 3,
  127.        DOMAIN_VISIBLE_PASSWORD = 4,
  128.        GENERIC_CERTIFICATE = 5,
  129.        DOMAIN_EXTENDED = 6,
  130.        MAXIMUM = 7,      // Maximum supported cred type
  131.        MAXIMUM_EX = (MAXIMUM + 1000),  // Allow new applications to run on old OSes
  132.    }
  133. public class CriticalCredentialHandle : Microsoft.Win32.SafeHandles.CriticalHandleZeroOrMinusOneIsInvalid
  134. {
  135.    public CriticalCredentialHandle(IntPtr preexistingHandle)
  136.    {
  137.        SetHandle(preexistingHandle);
  138.    }
  139.    public Credential GetCredential()
  140.    {
  141.        if (!IsInvalid)
  142.        {
  143.            NativeCredential ncred = (NativeCredential)Marshal.PtrToStructure(handle,
  144.                  typeof(NativeCredential));
  145.            Credential cred = new Credential();
  146.            cred.CredentialBlobSize = ncred.CredentialBlobSize;
  147.            cred.CredentialBlob = Marshal.PtrToStringUni(ncred.CredentialBlob,
  148.                  (int)ncred.CredentialBlobSize / 2);
  149.            cred.UserName = Marshal.PtrToStringUni(ncred.UserName);
  150.            cred.TargetName = Marshal.PtrToStringUni(ncred.TargetName`);
  151.            cred.TargetAlias = Marshal.PtrToStringUni(ncred.TargetAlias);
  152.            cred.Type = ncred.Type;
  153.            cred.Flags = ncred.Flags;
  154.            cred.Persist = ncred.Persist;
  155.            return cred;
  156.        }
  157.        else
  158.        {
  159.            throw new InvalidOperationException("Invalid CriticalHandle!");
  160.        }
  161.    }
  162.    override protected bool ReleaseHandle()
  163.    {
  164.        if (!IsInvalid)
  165.        {
  166.            CredFree(handle);
  167.            SetHandleAsInvalid();
  168.            return true;
  169.        }
  170.        return false;
  171.    }
  172. }
  173. [DllImport("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
  174. public static extern bool CredRead(string target, CRED_TYPE type, int reservedFlag, out IntPtr CredentialPtr);
  175. [DllImport("Advapi32.dll", EntryPoint = "CredFree", SetLastError = true)]
  176. public static extern bool CredFree([In] IntPtr cred);
  177. [DllImport("Advapi32.dll", SetLastError=true, EntryPoint="CredWriteW", CharSet=CharSet.Unicode)]
  178. public static extern bool CredWrite([In] ref Credential userCredential, [In] UInt32 flags);
  179. [DllImport("Advapi32.dll", EntryPoint = "CredDelete", CharSet = CharSet.Unicode, SetLastError = true)]
  180. public static extern bool CredDelete(string target, CRED_TYPE type, int reservedFlag);
  181. "@
  182.     If (-not ([System.Management.Automation.PSTypeName]'ADVAPI32.Util').Type) {
  183.         Add-Type -MemberDefinition $sig -Namespace "ADVAPI32" -Name 'Util'
  184.     }
  185.     $readtargetName = "Microsoft-Office365-NewMailboxCred"
  186.     $nCredPtr= New-Object IntPtr
  187.     $success = [ADVAPI32.Util]::CredRead($readtargetName,1,0,[ref] $nCredPtr)
  188.  
  189.     if($success){
  190.         $critCred = New-Object ADVAPI32.Util+CriticalCredentialHandle $nCredPtr
  191.         $readCred = $critCred.GetCredential()
  192.         $UserName = $readCred.UserName
  193.         $Password = $readCred.CredentialBlob
  194.         $Password = ConvertTo-SecureString -String $Password -AsPlainText -Force
  195.         $script:adminCreds = New-Object Management.Automation.PSCredential $UserName, $Password
  196.         Write-Host "`n`tSuccessfully retrieved credentials from credential manager" -ForegroundColor Yellow
  197.     } else {
  198.         Write-Host "`n`tCredentials not found" -ForegroundColor Red
  199.     }
  200. }
  201.  
  202. # The following credential manager stuff was taken from the O365-Fed-MetaData-Update-Task-Installation used on the ADFS servers
  203. function SaveCredentialsInCredentialManager() {
  204.     $saveCred = New-Object ADVAPI32.Util+Credential
  205.     $saveCred.flags = 0
  206.     $saveCred.type = 1
  207.  
  208.     #Get MSOL creds
  209.     While (!$UserName) { $UserName = (Read-Host "`n Admin username (user`@domain)").ToUpper(); }
  210.  
  211.     #Set the name of the CredMan credentials
  212.     $saveCred.targetName = "Microsoft-Office365-NewMailboxCred"
  213.     $saveCred.userName = $UserName
  214.     $saveCred.attributeCount = 0
  215.     $saveCred.persist = 2
  216.     While (!$Password) { $Password = Read-Host -assecurestring "`n Admin password"; }
  217.     $objCreds = New-Object Management.Automation.PSCredential $UserName, $Password
  218.     $Password = $objCreds.GetNetworkCredential().Password
  219.  
  220.     #Validating MSOL creds
  221.     Write-Host "Validating credentials with O365..." -ForegroundColor Green
  222.     Connect-MsolService -Credential $objCreds
  223.  
  224.     if ($?) {
  225.         Write-Host "`n`tSuccess" -ForegroundColor Green
  226.     } else {
  227.         Write-Host "`n`tFailed credential validation. Exiting...`n" -ForegroundColor Red
  228.         CleanExit
  229.     }
  230.  
  231.     $saveCred.credentialBlobSize = [System.Text.Encoding]::Unicode.GetBytes($Password).length
  232.     $saveCred.credentialBlob = $Password
  233.  
  234.     #Store the MSOL creds in CredMan
  235.     $CredWrite = [ADVAPI32.Util]::CredWrite([ref]$saveCred,0)
  236.     If ($CredWrite)
  237.     {
  238.         Write-Host "`n`tAdded credentials to the local Credential Manager" -ForegroundColor Green
  239.     }
  240.     Else
  241.     {
  242.         Write-Host "`n`tFailed adding credentials to the local Credential Manager. Exiting...`n" -ForegroundColor Red
  243.         CleanExit
  244.     }
  245. }
  246.  
  247. # Create a tenant PSSession.
  248. function CreateTenantSession() {
  249.     #Find Exchange 2013 Client Access Servers
  250.     [array]$arrServers = Get-ADObject -LDAPFilter "(&(objectCategory=msexchExchangeServer)(msExchCurrentServerRoles:1.2.840.113556.1.4.803:=16385))" -SearchBase ([ADSI]"LDAP://RootDSE").configurationNamingContext.ToString() | foreach {
  251.         $domainName = $_.DistinguishedName -split "," -match "^DC=" -replace "^DC=" -join "."
  252.         "$($_.Name).$domainName".ToUpper()
  253.     }
  254.    
  255.     # connect to exchange online tenant
  256.     # we must skip the certificate check because we are connecting to a specifc server, not the friendly webmail dns name
  257.     $psOptions = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck -OpenTimeout 2000
  258.     while ($script:session -eq $null -and $arrServers.Count -gt 0) {
  259.         $objServer, $arrServers = $arrServers | sort {Get-Random}
  260.         Write-Host "`r`nAttempting to connect to $objServer..." -NoNewline
  261.         try {
  262.             $script:session = New-PSSession -SessionOption $psOptions -ConfigurationName Microsoft.Exchange -ConnectionUri http://$objServer/Powershell -Credential $script:adminCreds -ErrorAction Stop
  263.             Write-Host "success`r`n"
  264.         }
  265.         catch {
  266.             Write-Host "unsuccessful`r`n"
  267.             if ($_.Exception -match 'bad password') {
  268.                 Write-Host "Input credentials are incorrect"`r`n -ForegroundColor Red
  269.                 CleanExit
  270.             }
  271.         }
  272.     }
  273.    
  274.     if ($script:session -eq $null)
  275.     {
  276.         Write-Host "Could not establish connection to Exchange"`r`n -ForegroundColor Red
  277.         CleanExit
  278.     }
  279.     else
  280.     {
  281.         $params = @{
  282.                     "Session" = $script:session
  283.                     "AllowClobber" = $true
  284.                     "DisableNameChecking" = $true
  285.                     "CommandName" = "Enable-RemoteMailbox","Get-Recipient"#,"Get-Mailbox","Get-RemoteMailbox","Update-AddressList","Update-GlobalAddressList"
  286.                   }
  287.         if ( -not (&"Import-PSSession" @params))
  288.         {
  289.             Write-Host "Exchange session cannot be imported to current PowerShell window."`r`n -ForegroundColor Red
  290.             Remove-PSSession $script:session
  291.             CleanExit;                
  292.         }
  293.     }
  294. }
  295.  
  296. function DisconnectTenantSession($errorMsg) {
  297.     if($errorMsg) {
  298.         Write-Host $errorMsg`r`n -ForegroundColor Red -BackgroundColor Black
  299.     }
  300.  
  301.     if($script:session) {
  302.         Write-Host "Disconnecting from Exchange..."`r`n
  303.         Remove-PSSession $script:session
  304.     }
  305. }
  306.  
  307. function CreateMailbox() {
  308.     if($script:userLogonName) {
  309.         # Check that the user object exists
  310.         try {
  311.             $ADUser = Get-ADUser $script:userLogonName -Properties msExchRecipientDisplayType,proxyaddresses,c,company,mDBUseDefaults,msExchHomeServerName,msExchUMDtmfMap,msExchUserAccountControl,ObjectGUID -ErrorAction SilentlyContinue
  312.         } catch {
  313.             DisconnectTenantSession("User does not exist in AD.")
  314.             CleanExit
  315.         }
  316.  
  317.         # Use country from AD user object, if it exists
  318.         $script:countryCode = $ADUser.c
  319.         If (-not $script:countryCode) {
  320.             Write-Host "`r`nVisit http://www.dovestones.com/country-codes-used-active-directory/ for a list of valid country codes." -ForegroundColor Yellow
  321.             $script:countryCode = Read-Host " New user country code (press <Enter> for US)"
  322.             if ([string]::IsNullOrEmpty($script:countryCode)) {
  323.                 $script:countryCode = "US"
  324.                 Write-Host "`r`nUsing default country code of US" -ForegroundColor Yellow
  325.             }
  326.         }
  327.         Else { Write-Host "`n`tSuccessfully retrieved countryCode from AD: $script:countryCode`r`n" -ForegroundColor Yellow; }
  328.  
  329.         # Get list of valid UPN suffixes
  330.         $UpnSuffixes = Get-ADForest | select -ExpandProperty UPNSuffixes | sort
  331.         $strUpnSuffixes = $UpnSuffixes -join "){1}$|^.+(@"
  332.         # Check that the UPN is valid
  333.         $isValidUPN = $ADUser.UserPrincipalName -match "^.+(@$strUpnSuffixes){1}$"
  334.         if(-not($isValidUPN)) {
  335.             $localPrefix = $ADUser.UserPrincipalName -replace "@.*$"
  336.             DisconnectTenantSession("`r`nError: username is currently setup as $($ADUser.UserPrincipalName).`r`n")
  337.             Write-Host "`n`tTo correct this, please follow the instructions below.`r`n" -ForegroundColor Yellow
  338.             Write-Host "`n`tUsername must be in the following format: $($localPrefix)@<domain name>, where <domain name> matches one of the following:`r`n`t`t$($UpnSuffixes -join "`r`n`t`t")`r`n`tIn the ADUC Account tab, change the user logon suffix to a valid domain name from the drop down next to the User Logon Name." -ForegroundColor Green
  339.             CleanExit
  340.         }
  341.  
  342.         # Check that the Company field exists
  343.         $isValidCompany = ![string]::IsNullOrEmpty($ADUser.Company)
  344.         if(-not $isValidCompany) {
  345.             DisconnectTenantSession("`r`nError: username $($ADUser.UserPrincipalName) does not have the Company attribute set.`r`n")
  346.             Write-Host "`n`tTo correct this, please follow the instructions below.`r`n" -ForegroundColor Yellow
  347.             Write-Host "`n`tIn the ADUC Organization tab, enter the company name in the Company field." -ForegroundColor Green
  348.             CleanExit
  349.         }
  350.        
  351.         # Check that the user has been created in O365 (i.e. Dirsync has run once)
  352.         Connect-MsolService -Credential $script:adminCreds -ErrorAction Stop
  353.         $msolUser = Get-MsolUser -UserPrincipalName $ADUser.UserPrincipalName -ErrorAction SilentlyContinue
  354.         if(-not($msolUser)) {
  355.             DisconnectTenantSession("`r`nUser not found in Office 365.")
  356.             Write-Host "`n`tSynchronization runs every 30 minutes." -ForegroundColor Yellow
  357.             Write-Host "`n`tIf you still receive this message after 45 minutes, please contact QCO IT - Messaging (QCOIT-Messaging@QuantaServices.com).`r`n" -ForegroundColor Yellow
  358.             CleanExit
  359.         }
  360.  
  361.         # Connect to Exchange
  362.         CreateTenantSession
  363.        
  364.         #Check for conflicting recipients
  365.         $conflictingRecipient = Get-Recipient -Filter "(EmailAddresses -eq '$($ADUser.UserPrincipalName)') -and (Guid -ne '$($ADUser.ObjectGuid)')"
  366.         if (-not($conflictingRecipient -eq $null)) {
  367.             $strMailboxLocation = `
  368.                 if ($conflictingRecipient.Count -gt 1) {
  369.                     "Multiple recipients"
  370.                 }
  371.                 elseif ($conflictingRecipient.RecipientTypeDetails -match "^Remote") {
  372.                     "Office 365 recipient"
  373.                 }
  374.                 else {
  375.                     "Quanta hosted recipient"
  376.                 }
  377.             DisconnectTenantSession("$strMailboxLocation already exists with this email address: $($ADUser.UserPrincipalName). Please verify the logon name.`r`n")
  378.             CleanExit            
  379.         }
  380.        
  381.         # Check that the mDBUseDefaults attribute isn't set
  382.         # This is an indication that the account was copied from AD and retains some Exchange related properties that cause the Enable-RemoteMailbox command to fail
  383.         if([string]::IsNullOrEmpty($ADUser.mDBUseDefaults) -eq $false) {
  384.             DisconnectTenantSession("`r`nError: username $($ADUser.UserPrincipalName) has the 'mDBUseDefaults' attribute set.`r`n")
  385.             Write-Host "`n`tTo correct this, please follow the instructions below.`r`n" -ForegroundColor Yellow
  386.             Write-Host "`n`tIn the ADUC Attribute Editor tab, remove the 'mDBUseDefaults' attribute value." -ForegroundColor Green
  387.             CleanExit
  388.         }
  389.  
  390.         # Check that the msExchHomeServerName attribute isn't set
  391.         # This is an indication that the account was copied from AD and retains some Exchange related properties that cause the Enable-RemoteMailbox command to fail
  392.         if($ADUser.msExchHomeServerName -ne $null -and $ADUser.msExchHomeServerName -ne "") {
  393.             DisconnectTenantSession("`r`nError: username $($ADUser.UserPrincipalName) has the 'msExchHomeServerName' attribute set.`r`n")
  394.             Write-Host "`n`tTo correct this, please follow the instructions below.`r`n" -ForegroundColor Yellow
  395.             Write-Host "`n`tIn the ADUC Attribute Editor tab, remove the 'msExchHomeServerName' attribute value." -ForegroundColor Green
  396.             CleanExit
  397.         }
  398.  
  399.         # Only run these checks if NOT a mail enabled user
  400.         If ($ADUser.msExchRecipientDisplayType -ne 6) {
  401.             # Check that the msExchUMDtmfMap attribute isn't set
  402.             # This is an indication that the account was copied from AD and retains some Exchange related properties that cause the Enable-RemoteMailbox command to fail
  403.             if([string]::IsNullOrEmpty($ADUser.msExchUMDtmfMap) -eq $false) {
  404.                 DisconnectTenantSession("`r`nError: username $($ADUser.UserPrincipalName) has the 'msExchUMDtmfMap' attribute set.`r`n")
  405.                 Write-Host "`n`tTo correct this, please follow the instructions below.`r`n" -ForegroundColor Yellow
  406.                 Write-Host "`n`tIn the ADUC Attribute Editor tab, remove the 'msExchUMDtmfMap' attribute value." -ForegroundColor Green
  407.                 CleanExit
  408.             }
  409.  
  410.             # Check that the msExchUserAccountControl attribute isn't set
  411.             # This is an indication that the account was copied from AD and retains some Exchange related properties that cause the Enable-RemoteMailbox command to fail
  412.             if([string]::IsNullOrEmpty($ADUser.msExchUserAccountControl) -eq $false) {
  413.                 DisconnectTenantSession("`r`nError: username $($ADUser.UserPrincipalName) has the 'msExchUserAccountControl' attribute set.`r`n")
  414.                 Write-Host "`n`tTo correct this, please follow the instructions below.`r`n" -ForegroundColor Yellow
  415.                 Write-Host "`n`tIn the ADUC Attribute Editor tab, remove the 'msExchUserAccountControl' attribute value." -ForegroundColor Green
  416.                 CleanExit
  417.             }
  418.  
  419.             # Check that the proxyAddresses attribute isn't set
  420.             # This is an indication that the account was copied from AD and retains some Exchange related properties that cause the Enable-RemoteMailbox command to fail
  421.             if($ADUser.proxyAddresses -match "^smtp:") {
  422.                 DisconnectTenantSession("`r`nError: username $($ADUser.UserPrincipalName) has proxy addresses.`r`n")
  423.                 Write-Host "`n`tTo correct this, please follow the instructions below.`r`n" -ForegroundColor Yellow
  424.                 Write-Host "`n`tIn the ADUC Attribute Editor tab, remove the 'proxyAddresses' attribute value(s)." -ForegroundColor Green
  425.                 CleanExit
  426.             }
  427.         }
  428.  
  429.         # Create the remote mailbox
  430.         Write-Host "Enabling remote mailbox..." -ForegroundColor Green
  431.         try {
  432.             Write-Host "Choose which type of mailbox to create:"
  433.             Write-Host "    1   - User Mailbox (or, just press <Enter>)"
  434.             Write-Host "    2   - Room Mailbox"
  435.             Write-Host "    3   - Equipment Mailbox"
  436.             Write-Host "    4   - Shared Mailbox"
  437.             Write-Host "    5   - Service Account Mailbox"
  438.             $mailboxType = Read-Host "Selection"
  439.             if ([string]::IsNullOrEmpty($mailboxType)) {
  440.                 $mailboxType = 1
  441.                 Write-Host "`n`tUsing default mailbox type of 'User Mailbox'"
  442.             }
  443.             # Find unique remote routing address
  444.             $EmailAddressPrefix = $ADUser.UserPrincipalName -split "@" | select -First 1
  445.             $RemoteRoutingAddress = "$EmailAddressPrefix@quantaservices.mail.onmicrosoft.com"
  446.             $AddressInUse = Get-Recipient $RemoteRoutingAddress -ErrorAction SilentlyContinue
  447.             while (($AddressInUse -ne $null) -and ($AddressInUse.Guid -ne $ADUser.ObjectGuid)) {
  448.                 $RemoteRoutingAddress = `
  449.                     if ($EmailAddressPrefix -match "(?<EndingNumber>\d+)$") {
  450.                         $IncreaseDigit = ([int]$Matches['EndingNumber']) + 1
  451.                         $EmailAddressPrefix = $EmailAddressPrefix -replace "$($Matches['EndingNumber'])$",$IncreaseDigit
  452.                         "$EmailAddressPrefix@quantaservices.mail.onmicrosoft.com"
  453.                     } else {
  454.                         "$EmailAddressPrefix`1@quantaservices.mail.onmicrosoft.com"
  455.                     }
  456.                 $AddressInUse = Get-Recipient $RemoteRoutingAddress -ErrorAction SilentlyContinue
  457.             }
  458.             # Create hashtable to hold parameters passed to Enable-RemoteMailbox cmdlet
  459.             $hashEnableRemoteMailboxParams = @{
  460.                 Identity = $ADUser.ObjectGuid.ToString();
  461.                 RemoteRoutingAddress = $RemoteRoutingAddress;
  462.                 ErrorAction = "Stop";
  463.             }
  464.             $EOP2Only = $false
  465.             switch ($mailboxType) {
  466.                 1 { #User mailbox
  467.                     break
  468.                 }
  469.                 2 { #Room mailbox
  470.                     $hashEnableRemoteMailboxParams["Room"] = $true
  471.                     $EOP2Only = $true
  472.                     break
  473.                 }
  474.                 3 { #Equipment mailbox
  475.                     $hashEnableRemoteMailboxParams["Equipment"] = $true
  476.                     $EOP2Only = $true
  477.                     break
  478.                 }
  479.                 4 { #Shared mailbox
  480.                     $EOP2Only = $true
  481.                     Write-Host "To complete the setup of the Shared Mailbox, please refer to the `“How to setup a Shared Mailbox`” process document." -ForegroundColor Yellow -BackgroundColor Black
  482.                     break
  483.                 }
  484.                 5 { #Service account mailbox
  485.                     $EOP2Only = $true
  486.                     break
  487.                 }
  488.                 default { #Unknown
  489.                     DisconnectTenantSession("Invalid selection")
  490.                     CleanExit
  491.                 }
  492.             }
  493.             Enable-RemoteMailbox @hashEnableRemoteMailboxParams | Out-Null
  494.         } catch {
  495.             DisconnectTenantSession("Error enabling remote mailbox")
  496.             CleanExit
  497.         }
  498.  
  499.         # Assign the license to the user
  500.         Write-Host "Licensing user..." -ForegroundColor Green
  501.         try {
  502.             # region prep for license assignment
  503.             if ($msolUser.UsageLocation -ne $script:countryCode) {
  504.                 Write-Host "`n`tSetting user location to $script:countryCode" -ForegroundColor Yellow
  505.                 Set-MSOLUser -UserPrincipalName $msolUser.UserPrincipalName -UsageLocation $script:countryCode -ErrorAction Stop
  506.             }
  507.             # assign licenses
  508.             $LicenseAccountSku =`
  509.                 if ($EOP2Only) {
  510.                     # Assign EOP2 only
  511.                     "quantaservices:EXCHANGEENTERPRISE"
  512.                 } else {
  513.                     # Assign full E3
  514.                     "quantaservices:ENTERPRISEPACK"
  515.                 }
  516.             [bool]$LicenseNeeded = -not ($msolUser.Licenses.AccountSkuId -contains $LicenseAccountSku)
  517.             if ($LicenseNeeded) {
  518.                 Write-Host "`n`tAssigning license" -ForegroundColor Yellow
  519.                 Set-MsolUserLicense -UserPrincipalName $msolUser.UserPrincipalName -AddLicenses $LicenseAccountSku -ErrorAction Stop
  520.             } else {
  521.                 Write-Host "`n`tUser already has license assigned" -ForegroundColor Yellow
  522.             }
  523.         } catch {
  524.             DisconnectTenantSession("Error assigning license")
  525.         }
  526.  
  527.         # Disconnect from Exchange
  528.         DisconnectTenantSession
  529.     } else {
  530.         Write-Host "Invalid input" -ForegroundColor Red -BackgroundColor Black
  531.     }
  532. }
  533.  
  534. Write-Host `r`n
  535. Write-Host "This script will create a new Office 365 mailbox for an existing AD user." -ForegroundColor Green
  536. Write-Host "The mailbox should be created within 2 hours of successfully running this script.`r`n" -ForegroundColor Green
  537. #Write-Host "The 'Company' field of the user account must have a value!`r`n" -ForegroundColor Yellow
  538.  
  539. # Retrieve the credentials
  540. GetCredentialsFromCredentialManager
  541.  
  542. if(-not($script:adminCreds)) {
  543.     SaveCredentialsInCredentialManager
  544.    
  545.     GetCredentialsFromCredentialManager
  546.     if(-not($script:adminCreds)) {
  547.         DisconnectTenantSession("There was an issue retrieving your credentials from the connection manager.")
  548.         CleanExit
  549.     }
  550. }
  551.  
  552. $script:userLogonName = Read-Host "`n`n New user logon name (pre-Windows 2000)"
  553.  
  554. CreateMailbox
  555. CleanExit
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement