Staff Off-Boarding with Office 365

office-365

Over time in any environment the day will come around when the inevitable happens and staff leave. This happens due to lots of different reasons but there is often a question as to what to do with user accounts when this happens. This is particularly true in smaller companies with no set process for IT departments off-boarding staff.

In my own environment, I decided to set up a standard script which would work with Active Directory and Office 365 to achieve the following;

  1. Connects to your local DC for active directory functions and Office 365 for mailbox functions
  2. Disable the employee’s user account (verifies the user details before proceeding)
  3. Stamp details on the disabled user account with the IT person who disabled the account for audit purposes
  4. Move the disabled user account to a separate OU
  5. Disable all forms of remote mail access (OWA, ActiveSync, POP, etc)
  6. Set an Out of Office stating that the employee has left the company
  7. Place the mailbox into Legal hold for data retention purposes
  8. Hides the account from the GAL
  9. Emails the former employee’s manager advising that the account has been disabled

The user account is then maintained for a period of 30 days before being deleted and thus returning any assigned Office 365 licenses to the pool etc.

This might help to give you some ideas about setting up your own scripting process for dealing with this issue.

Script Download Link – https://gallery.technet.microsoft.com/scriptcenter/Staff-Off-Boarding-Script-430bdd0a


<#
.NOTES
===========================================================================
Created with: SAPIEN Technologies, Inc., PowerShell Studio 2016 v5.2.128
Created on: 04/11/2016 21:00
Created by: Maurice Daly
Filename: DisableUserOffice365.ps1
===========================================================================
.DESCRIPTION
This script provides a standard off-boarding method for staff leaving
the company.

The script does the following;
1. Disables the specified user account
2. Updates the user description with the user who disabled the account
and the time/date when the account was disabled
3. Moves the account to the disabled user account OU (needs to exist)
4. Sets an out of office reply stating that the employee has left the company
5. Disables activesync, pop3, imap etc
6. Places mail account into legal hold for 7 years (requires Office 365 E3)
7. Hides the mail account from the GAL
8. Emails the former employee's manager advising that the account has been disabled

Version 1.0
Initial release

Use : This script is provided as it and I accept no responsibility for
any issues arising from its use.

Twitter : @modaly_it
Blog : https://modalyitblog.wordpress.com/
#>

Write-Host " **************** PLEASE ENTER ACTIVE DIRECTORY ADMIN CREDENTIALS **************** "
$Credential = Get-Credential -Credential "$env:USERDOMAIN\$env:USERNAME"
$DC = $env:LOGONSERVER.Substring(2)

#Initiate Remote PS Session to local DC
$ADPowerShell = New-PSSession -ComputerName $DC -Authentication Negotiate -Credential $Credential

# Import-Module ActiveDirectory
write-host "Importing Active Directory PowerShell Commandlets"
Invoke-Command -Session $ADPowerShell -scriptblock { import-module ActiveDirectory }
Import-PSSession -Session $ADPowerShell -Module ActiveDirectory -AllowClobber -ErrorAction Stop

# Retrieve AD Details
$ADDetails = Get-ADDomain
$Domain = $ADDetails.DNSRoot
Clear-Host

write-host "Importing Office 365 PowerShell Commandlets"
Write-Host -ForegroundColor White -BackgroundColor DarkBlue " **************** PLEASE ENTER OFFICE 365 ADMIN CREDENTIALS **************** "
$Office365Credential = Get-Credential
$Office365PowerShell = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $Office365Credential -Authentication Basic -AllowRedirection
Import-PSSession $Office365PowerShell
Clear-Host

write-host " **************** Disable Active Directory User Account & Enable Out Of Office **************** "
write-host " "

# Get Variables
$DisabledDate = Get-Date
$LeaveDate = Get-Date -Format "dddd dd MMMM yyyy"
$DisabledBy = Get-ADUser "$env:username" -properties Mail
$DisabledByEmail = $DisabledBy.Mail

# Prompt for AD Username
$Employee = Read-Host "Employee Username"
$EmployeeDetails = Get-ADUser $Employee -properties *
If ($EmployeeDetails.Manager -ne $null)
{
$Manager = Get-ADUser $EmployeeDetails.Manager -Properties Mail
}

Clear-Host

# Prompt for confirmation
write-host " ******************************** CONFIRM USER DISABLE REQUEST ******************************** "
write-host " "
write-host -ForegroundColor Yellow "Please review the Employee details below to ensure you are disabling the correct user account."
$EmployeeDetails | fl Name, Title, Company, @{ Expression = { $_.mail }; Label = "Email Address" }, @{Expression = { $_.Created }; Label = "Employment Started"}

$choice = " "
while ($choice -notmatch "[y|n]")
{
$choice = read-host "Do you want to continue? (Y/N)"
}

# Actions
if ($choice -eq "y")
{
Clear-Host
write-host " ******************************** DISABLING USER ACCOUNT ******************************** "
write-host " "
write-host "Step1. Modifying user description for audit purposes" -ForegroundColor Yellow
Set-ADUser $Employee -Description "Disabled by $($DisabledBy.name) on $DisabledDate"
write-host "Step2. Disabling $Employee Active Directory Account." -ForegroundColor Yellow
Disable-ADAccount $Employee
write-host "Step3. Moving $Employee to the Disabled User Accounts OU." -ForegroundColor Yellow
write-host " "
Move-ADObject -Identity $EmployeeDetails.DistinguishedName -targetpath "OU=Disabled User Accounts,DC=YOURDOMAIN,DC=SUFFIX"
write-host "Waiting 5 seconds for AD & Exchange OU update to complete"
sleep -Seconds 5
write-host " "
write-host "Refreshing Employee Details for Exchange Modification."
write-host " "
Get-ADUser $Employee -Properties Description | Format-List Name, Enabled, Description
write-host "Step 4. Setting Exchange Out Of Office Auto-Responder." -ForegroundColor Yellow
Set-MailboxAutoReplyConfiguration -Identity $EmployeeDetails.Mail -AutoReplyState enabled -ExternalAudience all -InternalMessage "Please note that I no longer work for $($EmployeeDetails.company) as of $LeaveDate." -ExternalMessage "Please note that I no longer work for $($EmployeeDetails.company) as of $LeaveDate. Direct all correspondence to info@yourdomain.suffix."
Write-Host "Step 5. Disabling POP,IMAP, OWA and ActiveSync access for $User" -ForegroundColor Yellow
Set-CasMailbox -Identity $EmployeeDetails.mail -OWAEnabled $false -POPEnabled $false -ImapEnabled $false -ActiveSyncEnabled $false
Write-Host "Step 6. Placing mailbox $($EmployeeDetails.name) into Ligitgation hold for 7 years" -ForegroundColor Yellow
Set-Mailbox -Identity $EmployeeDetails.mail -LitigationHoldEnabled $true -LitigationHoldDuration 2555
Write-Host "Step 7. Hiding $($EmployeeDetails.name) from Global Address lists" -ForegroundColor Yellow
Set-ADUser -identity $Employee -add @{ msExchHideFromAddressLists = "True" }
Set-ADUser -instance $EmployeeDetails -whatif
If ($Manager.Mail -like "*@*")
{
Write-Host "Step 8. Sending Confirmation E-mail To Employee's Manager." -ForegroundColor Yellow
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient("youroffice365mailserveraddress")
$msg.From = "Support@yourdomain.suffix"
$msg.To.Add("$($Manager.Mail)")
$msg.subject = "IT Notification - Employee Leaver Confirmation"
$msg.body = "This email is confirm that $($EmployeeDetails.Name)'s account has been disabled. An out of office notification advising that $($EmployeeDetails.Name) has left the company has also been set. Note that the account will be deleted after 30 days."
$smtp.Send($msg)
}
}else{
write-host " "
write-host "Employee disable request cancelled" -ForegroundColor Yellow
}

 

Powershell – Check Client Machine Uptime

Want to check the last time all of your client machines booted in a particular OU?. Well here is a nice little two liner to do so.

$SearchBase = Get-ADComputer -SearchBase "OU=OUTARGET,DC=YOURDOMAIN,DC=YOURDOMAIN" -Filter * | ForEach-Object (Write-Output {$_.name})
Get-CimInstance -ComputerName $SearchBase -ClassName win32_operatingsystem -ErrorAction SilentlyContinue | select pscomputername, lastbootuptime, Description | Sort-Object -Property lastbootuptime -Descending | Out-GridView

Azure AD SSO in a non-ADFS environment – Windows 10

In a world without ADFS.. Single Sign On is possible..

Having made the migration from onsite Exchange and SharePoint to Office 365 in early 2015 one of the key issues that users had was the lack of single sign on facilities to applications based in the cloud. You might ask why didn’t you use ADFS for your implementation, well I like many SME systems admins had made a conscious decision to run with DirSync as this lowered the overall foot print of our hybrid set up, I also liked the idea that even in the event of a complete loss of internal resources the Office 365 cloud would still allow employees to authenticate.

In my case the decision was concreted only after speaking with Microsoft Office 365 speakers and product development engineers, as their view was unless you have a specific reason for using ADFS then the DirSync product road map with the migration to Azure AD Connect would be more than sufficient for my needs. I convinced my manager and the migration went ahead..

So to fast forward to today and with the improvements in the ability to sync details to and from Azure Active Directory without an ADFS environment I am going to run through one of the newer authentication features of Windows 10, this being Azure AD SSO on domain joined devices.

Single Sign On without ADFS.. What Is This Black Magic???

The ability to open cloud based resources which integrate with Azure Active Directory without having to sign on again has been the domain of ADFS up until this point. With the latest release of Azure AD Connect and Windows 10 1511 on-wards however we can now achieve a similar experience.

The system works by issuing authentication tokens when registering the physical device of the user. Further in depth technical info is available on TechNet – https://blogs.technet.microsoft.com/enterprisemobility/2016/02/17/azure-ad-domain-join-windows-10/

So How Do I Implement It?

The implementation process is very straight forward;

  1. Enable users to join devices to Azure AD

    Log onto the Azure Admin Portal, open your tenant and click on the Configure tab. Scroll down to the Devices section and apply either a selected or all device configuration depending on your security requirements. Example screenshots below;

  2. Download and install the latest version of Azure AD Connect from https://www.microsoft.com/en-us/download/details.aspx?id=47594.azureaddownloadNote if you are still using DirSync or Azure AD Sync, you should migrate to Azure AD Connect before the 13th of April 2017 as support will be deprecated at that point. The upgrade process from these old legacy tools is very straight forward during the setup wizard.
  3. Ensure your Windows 10 clients are compatible

    Windows 10 build 1511 (November 2015) onwards support Azure AD SSO device join via group poilcy. If you are running the RTM build 10240, you will need to upgrade first.To check this either open a command prompt and read the Windows version on the second line or open PowerShell and type;

    (Get-WmiObject win32_operatingsystem).version

    checkwindowsversion

    For those of you using SCCM, I suggest you create a collection based on the version of Windows 10 for management purposes. The following query will add clients running build 1607 to your collection;

    select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_OPERATING_SYSTEM on SMS_G_System_OPERATING_SYSTEM.ResourceID = SMS_R_System.ResourceId where SMS_G_System_OPERATING_SYSTEM.BuildNumber = “14393”


  4. Update Your Central Store – Group Policy Administrative Templates In order to enable this feature you will need to ensure that your group policy administrative templates are up to date. The latest Windows 10 templates can be downloaded from the following link – https://www.microsoft.com/en-us/download/details.aspx?id=53430azureadtemplates
  5. Enable Device Sync – Azure AD Connect

    Now we have to enable device synchronization with Azure AD. There are two ways to achieve this, you can either run the Azure AD Connect wizard or edit the connectors yourself. In the below example I am going to go with the later;

    • On your Azure AD Connect server, open the Synchronization Service Managersyncscreen1Right-click on the Connectors button and right click on the Active Directory Domain Services and to to Properties
    • Configure Directory Partitions Click on Configure Directory Partitions and then click on the Containers button.syncscreen2
      When prompted enter an account with sufficient rights to Active Directory.
    • Select Computer OU to Sync Browse through your Active Directory and select the OU’s which contain computer accounts you wish to synchronize to Azure AD for the purpose of using Azure SSO.

      syncscreen3

    • Force Full Synchronization

      Right click on your Active Directory Domain Services connector and click on Run.

      syncscreen4

      On this screen click on the Full Import button. Once this job has completed do the same for the Windows Azure Active Directory connector.

  6. Configure GPO Settings

    Open Group Policy Management Editor and either create a new GPO or modify an existing one which applies settings to computers within the OU’s you have set to sync.

    Open the Computer Settings\Policies\Administrative Templates\Windows Components\Device Registration folderClick on the Register Domain Joined Computers As Devices setting and click Enable.

    GPODeviceReg.jpg

  7. Have Patience…There will obviously be delay between devices refreshing their GPO policies, Azure AD Sync times and devices registering.
  8. Verifying Device Sync Status

    Download the Microsoft Azure Active Directory Module for Windows PowerShell from the following link : https://azure.microsoft.com/en-us/documentation/articles/powershell-install-configure/Open a Azure AD Module PS window and connect to your Azure tenant environment by typing;

    Connect-MsolService
    


    azurepsconnect

    Once connected type the following to display a full list of registered devices and their current state;

    Get-MsolDevice -All | FT DisplayName, DeviceOS*, DeviceTrust*
    


    adpslist

    You can also run the following PS command to get a count of machines registered and compare this to your SCCM collection;

    (Get-MsolDevice -All).Count
    


Its Done..

Once your devices are successfully registered, your users should be automatically signed into their Azure AD cloud services. Now you have another little win for making their lives that bit easier without going to the extent of implementing a full ADFS environment.
Update – 29/9/2016

With the latest 16.0.7341.2035 build of Office 2016, SSO is now fully functional when opening Outlook. The below screen is now presented to the user rather than the usual Add Account wizard which prompts you for your password at the end. Now all the user has to do is click Connect and the settings download & sign in happens in the background in the initial launch;

outlook

 

 

Automating Management of Local Administrator Passwords – Microsoft LAPS

Managing Local Administrator Passwords

So you have a complex password policy on your domain, ensuring that users change their password every 60-90 days, passwords are complex, their passwords can’t be re-used and your users are not local admins but one thing poses a security risk, the local administrator password.

The chances are you have deployed your standard Windows image using a password specified within the image/MDT or SCCM task sequence and in some cases you do not have the IT resources to ensure that this password is changed on a regular basis and even if you are, are you ensuring that the passwords are being documented and stored securely?.

Security Risk – Local Administrator Rights

If you do not have a well maintained local administrator password strategy it opens your network up to security vulnerabilities including elevation of privilege. It isn’t going to go down well when your standard local workstation admin password is shared and users add themselves to the local admin group, potentially in a worst case scenario adding malware, key loggers etc.

The Answer – Microsoft Local Administrator Password Solution (LAPS)

Microsoft LAPS is a free tool released back on May 1st 2015 and allows you to automate the process of updating local administrator passwords on your workstations and servers across your Active Directory domain/forest. LAPS uses a local agent in conjunction with GPO deployed settings to update the local administrator password at set intervals, based on complexity settings that you specify and most importantly it automatically stores backups of this info within Active Directory.

Deploying Microsoft LAPS

First of all you will need to download the installer from the following URL – https://www.microsoft.com/en-us/download/details.aspx?id=46899. In the below section we will run through the entire installation and configuration process;

  1. Management Server Installation

    A single installer is used for both the server and client installs, the only real difference being that the management tools need to be installed on the management server. Run the LAPS.x86 or LAPS.x64 installer as per your system architecture, then run through the following;

    1. Launch the installer

      install6

    2. At the custom setup screen select the management tools and select run from my computer and then click Next

      install4

    3. Click on the Finish button to finalise the install

      install1

  2. Active Direct Schema Modification

    In order for computers to write back their local administrator passwords and expiry date/time, a schema update is required. The update adds the following two values:

    ms-Mcs-AdmPwd – Stores the password in clear text
    ms-Mcs-AdmPwdExpirationTime – Stores the time to reset the password

    To add these values, launch a PowerShell session on your management server and perform the following actions;

    • Type – Import-Module AdmPwd.PS to import the required LAPS module

      psscreen1

    • Type – Update-AdmPwdADSchema

      psscreen2

      Note: If you have an RODC installed in the environment and you need to replicate the value of the attribute ms-Mcs-AdmPwd to the RODC, you will need to change the 10th bit of the searchFlags attribute value for ms-Mcs-AdmPwd schema objet to 0 (substract 512 from the current value of the searchFlags attribute). For more information on Adding Attributes to or Removing attributes from the RODC Filtered Attribute Set, please refer to http://technet.microsoft.com/en-us/library/cc754794(v=WS.10).aspx.


  3. Active Directory Rights


    Computer Rights

    In order for computer accounts to write values to the ms-Mcs-AdmPwdExpirationTime and ms-Mcs-AdmPwd attributes in Active Directory, the following PowerShell command needs to be run (note if closed the previous PowerShell window you will need to run Import-Module AdmPwd.ps again)

    Set-AdmPwdComputerSelfPermission -OrgUnit <name of the OU to delegate permissions>
    


    User Rights
    By default members of the Domain Admins group will have rights to view the local administrator passwords stored in Active Directory, however what happens if you want your desktop support team to view them?. To facilitate this you will need to delegate rights.

    To do so use the following PS command:

    Set-AdmPwdReadPasswordPermission -OrgUnit <name of the OU to delegate permissions> -AllowedPrincipals <users or groups>
    

    Going another step further you can also delegate rights to allow groups or individuals to force a password change. To do so use the following PS command:

    Set-AdmPwdResetPasswordPermission -OrgUnit <name of the OU to delegate permissions> -AllowedPrincipals <users or groups>
    


  4. Group Policy Configuration

    First of all you will need to copy the LAPS ADMX and ADML files to your central store. The two files are located in the %WINDIR%\PolicyDefinitions folder on the management server.

    Now follow the below;

    1. Open Group Policy Manager and either create or modify a GPO that you wish to apply the LAPS settings.

    2. Expand Computer Configuration\Policies\Administrative Templates\LAPS

    gposettings1

    3. Configure your Password Settings, Name of the Local Admin Account and Enable Password Management, as per the below examples:

     

  5. Deploying the LAPS client
    Deploying the client is a simple process. Using the same MSI installation files you can deploy the client to your x86 and x64 clients via GPO, SCCM or other third party application deployment systems. Simply use the /quiet switch for client deployments.
  6. Check its working..Active Directory Users & Computers

    Opening the Active Directory Users & Computers console and viewing the Attribute Editor of a machine located within the OU that you earlier deployed your LAPS enabled GPO to, should result in values being available as per the below screenshot;

    aducscreen

    LAPS Admin GUI

    On the management server that earlier installed LAPS on, you will have the LAPS GUI. This will allow you to both look up details from computers but also set a new expiration date for the existing local admin password;

    lapsadmin

For more info on LAPS, visit Microsoft TechNet – https://technet.microsoft.com/en-us/mt227395.aspx

Office 365 Online Archive Error – Failed to enable the new cloud archive

A couple of days ago I came across a strange issue whilst updating our archive directory contact details. A couple of our user updates did not reflect in the global address book in our Office 365 hybrid environment. I logged onto our domain controller and the details where correct, so I then logged into Azure Active Directory (as we are using Direction Sync) and found that the details pulled back from Azure were also correct, so what was the issue?.

When I opened the user properties in the Office 365 console I received the following error message:

“Exchange: Failed to enable the new cloud archive xxxxxxxx-xxxx-xxxxx-xxxx-xxxxxxxx of mailbox xxxxxxxx-xxxx-xxxxx-xxxx-xxxxxxxx because a different archive xxxxxxxx-xxxx-xxxxx-xxxx-xxxxxxxx exists. To enable the new archive, first disable the archive on-premises. After the next Dirsync sync cycle, enable the archive on-premises again.
Exchange: An unknown error has occurred. Refer to correlation ID: c0e37858-6d41-423a-b0bd-7d9bec686457″
So the issue was obviously related to a mailbox move that took place whereby the offline archive link was broken. So I used the Azure Active Directory PS (download from https://azure.microsoft.com/en-us/documentation/articles/powershell-install-configure/) and connected again to my Azure environment to check the health properties of my users.
To do this run the following PS commands
Connect-MSOLService
Get-MSOLUser | Sort-Object DisplayName | ft DisplayName, ValidationStatus
This will return the full list of Office 365 enabled user accounts and their status. Narrowing this down with the following command will display a list of users with validation errors;
Get-MSOLUser | Where-Object {$_.ValidationStatus -eq "Error"} | Sort-Object DisplayName | ft DisplayName, ValidationStatus
Once you have the list of users with errors it is time to get their online archive information to compare against the details from Exchange. First lets retrieve the Archive GUID by running the following script in an Office365 PowerShell environment;
Get-Mailbox "user identity with error status" | ft Name, ArchiveGuid
Now switching over to our Exchange PS console I ran the following script to check what archive details matched;
Get-RemoteMailbox -Identity "user identity with error status" | fl DisplayName, ArchiveGuid
Comparing the two ArchiveGuid values presented the cause of the issue. During a routine mailbox move the ArchiveGuid value had not been updated to the current version.
I resolved this by running the following process;
1. Update the remote mailbox properties with the ArchiveGuid value obtained from Azure AD;
– Set-RemoteMailbox -Identity  “user identity with error status” –ArchiveGuid “Guid value from Azure AD”
2. Run a full directory sync in DirSync
3. Run Start-OnlineCoexistenceSync PS command:
On your DirSync server –
PS:\Import-Module DirSync
PS:\Start-OnlineCoexistenceSync
Now wait a few minutes, go back into your Office 365 portal and the issue should be resolved 🙂

PowerShell – Create new AD user account, Exchange mailbox and add to Lync Pool

The below script presents a simple means of setting up a user in Active Directory, Exchange and Lync in one go.


###############################################################################
#                                                                             #
# ****************** CREATED BY MAURICE DALY ON 18/12/2013 ****************** #
#                                                                             #
# Create user account, exchange mailbox and lync account                      #
#                                                                             #
# Version 1.0                                                                 #
#                                                                             #
# ****************** UPDATED BY MAURICE DALY ON 09/01/2014 ****************** #
#                                                                             #
# Version 2.0 - All modules are imported automatically with detection for     #
#               Active Directory, Exchange & Lync environments. Notification  #
#               feature also added for predetermined admin mail account       #
#               Added OU location menu.                                       #
#                                                                             #
# THIS SCRIPT IS USED AT YOUR OWN RISK. I ACCEPT NO RESPONSIBILITY FOR ANY    #
# ISSUES ARRISING FROM IT                                                     #
#                                                                             #
###############################################################################


cls

Write-Host "**************** PLEASE ENTER YOUR SECURITY DETAILS ****************"
$Credential = Get-Credential -Credential "$env:USERDOMAIN\$env:USERNAME"
$DC = $env:LOGONSERVER.Substring(2)

#Initiate Remote PS Session to local DC
$ADPowerShell = New-PSSession -ComputerName $DC -Authentication Negotiate -Credential $Credential

# Import-Module ActiveDirectory
Invoke-Command -Session $ADPowerShell -scriptblock {import-module ActiveDirectory}
Import-PSSession -Session $ADPowerShell -Module ActiveDirectory -AllowClobber -ErrorAction Stop

# Retrieve AD Details
$ADDetails = Get-ADDomain
$Domain = $ADDetails.DNSRoot
$ExchangeServer = Get-ADObject -Filter "(ServicePrincipalNAme -like 'IMAP*')" -SearchBase (Get-ADDomain).DistinguishedName.tostring()  -Properties ServiceDNSName, ServiceClassName | where name -NotLike *SDK* | ForEach-Object {Write-Output $($_.Name + "." + $Domain)} | Get-Random

cls
Write-Host "********************* NEW USER CREATION SCRIPT *****************"
Write-Host ""
Write-Host "Please enter the following required details:"
$FirstName = read-host "Firstname"
$FirstName = $FirstName.substring(0,1).toupper()+$FirstName.substring(1).tolower()   
$Surname = read-host "Surname"
$Surname = $Surname.substring(0,1).toupper()+$Surname.substring(1).tolower()  
$FirstInitial = $FirstName.Substring(0,1)

# Select Office Location
$OUChoice = ""
 while ($OUChoice -notmatch "[1|2|3|4|5]"){
     Write-Host ""
     Write-Host "[1] Office 1" 
     Write-Host "[2] Office 2"
     Write-Host "[3] Office 3"
     Write-Host "[4] Office 4"
     Write-Host "[5] Office 5"
     Write-Host ""
     $OUChoice = read-host "Please select the office location for $FirstName $Surname"
     }

if ($OUChoice -eq "1"){$ADPath = "OU=Office1,DC=YOUR,DC=DOMAIN"}
if ($OUChoice -eq "2"){$ADPath = "OU=Office2,DC=YOUR,DC=DOMAIN"}
if ($OUChoice -eq "3"){$ADPath = "OU=Office3,DC=YOUR,DC=DOMAIN"}
if ($OUChoice -eq "4"){$ADPath = "OU=Office4,DC=YOUR,DC=DOMAIN"}
if ($OUChoice -eq "5"){$ADPath = "OU=Office5,DC=YOUR,DC=DOMAIN"}


# Detect if username already exists and create AD account
Write-Host -ForegroundColor Green "Creating new active directory user accounnt for $Firstname $Surname"
$ADAccountName = ($Surname + $FirstInitial)
$UserCheck = Get-ADUser -LDAPFilter "(sAMAccountName=$ADAccountName)"
If (($UserCheck) -eq $null)
 {
    write-host -ForegroundColor Green "Active Directory user account created"
    New-ADUser -DisplayName:($FirstName + " " + $Surname) -GivenName:$FirstName -Name:($FirstName + " " + $Surname) -Path:$ADPath -SamAccountName:$ADAccountName -Server:$DC -Surname:$Surname -Type:"user" -UserPrincipalName:($ADAccountName + "@" + $Domain) -Description:($Surname + $FirstInitial) -AccountPassword:(ConvertTo-SecureString "Secret123!" -AsPlainText -Force) -Enabled:$true
    Set-ADAccountControl -AccountNotDelegated:$false -AllowReversiblePasswordEncryption:$false -CannotChangePassword:$false -DoesNotRequirePreAuth:$false -Identity:$ADAccountName -PasswordNeverExpires:$false -Server:$DC -UseDESKeyOnly:$false
 }
 Else
 {
    $ADAccountName = Read-Host "The automatically generated username for $FirstName $Surname alreay exists. Please enter an alternative username" 
    New-ADUser -DisplayName:($FirstName + " " + $Surname) -GivenName:$FirstName -Name:($FirstName + " " + $Surname) -Path:$ADPath -SamAccountName:$ADAccountName -Server:$DC -Surname:$Surname -Type:"user" -UserPrincipalName:($ADAccountName + "@" + $Domain) -Description:$ADAccountName -AccountPassword:(ConvertTo-SecureString "Secret123!" -AsPlainText -Force) -Enabled:$true
    Set-ADAccountControl -AccountNotDelegated:$false -AllowReversiblePasswordEncryption:$false -CannotChangePassword:$false -DoesNotRequirePreAuth:$false -Identity:$ADAccountName -PasswordNeverExpires:$false -Server:$DC -UseDESKeyOnly:$false
 }


# Require password change on log on
Set-ADUser -ChangePasswordAtLogon:$true -Identity:$ADAccountName -Server:$DC -SmartcardLogonRequired:$false

# Exchange Mailbox creation
Write-Host -ForegroundColor Green "Creating new Microsoft Exchange mailbox for $Firstname $Surname"
$ExchangePowerShell = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://$ExchangeServer/Powershell
Import-PSSession $ExchangePowerShell -AllowClobber | Out-Null

If ($FirstInitial -ge "A") { $MailboxStore = "Mailboxes A-C" }
If ($FirstInitial -ge "D") { $MailboxStore = "Mailboxes D-J" }
If ($FirstInitial -ge "K") { $MailboxStore = "Mailboxes K-M" }
If ($FirstInitial -ge "N") { $MailboxStore = "Mailboxes N-R" }
If ($FirstInitial -ge "S") { $MailboxStore = "Mailboxes S-Z" }

Enable-Mailbox -Identity $ADAccountName -Alias $ADAccountName -Database $MailboxStore -RetentionPolicy 'YOUR Retention Policy' | Out-Null

Write-Host -ForegroundColor Green Yellow "Waiting 10 seconds for Exchange details to apply to Active Directory"
sleep -Seconds 10

# Lync Registrar
$LyncServer = Get-ADObject -Filter "(ServicePrincipalNAme -like 'SIP*')" -SearchBase (Get-ADDomain).DistinguishedName.tostring()  -Properties ServiceDNSName, ServiceClassName | ForEach-Object {Write-Output $($_.Name + "." + $Domain)}
$LyncRegistrarPool = $LyncServer

# Lync Module Import
$LyncPowerShell = New-PSSession -ConnectionUri https://$LyncServer/OCSPowerShell -Credential $Credential
Import-PSSession $LyncPowerShell -AllowClobber | Out-Null

# Lync Add User
Write-Host -ForegroundColor Green "Creating new Lync account for $Firstname $Surname"
Enable-CsUser -Identity $ADAccountName -RegistrarPool $LyncRegistrarPool -SipAddressType EmailAddress

# Notification variables
$ExchangeSMTP = "YOUR EXCHANGE SMTP SERVER"
$CreatedBy = Get-ADUser "$env:username" -properties Mail

# Notify Admin

$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($ExchangeSMTP)
$msg.From = "$($CreatedBy.Mail)"
$msg.To.Add("Administrator@your.domain")
$msg.subject = "New User Account Created"
$msg.body = "$($CreatedBy.Name) has created a new user account for $FirstName $Surname." 
$msg.priority = [System.Net.Mail.MailPriority]::Low
$smtp.Send($msg)

Write-Host -ForegroundColor Green "Waiting 10 seconds for Lync details to apply"
sleep -Seconds 10

# Confirm User Account Creation
cls
Write-Host -ForegroundColor Green "********************* NEW USER CREATION COMPLETE *****************"
Write-Host ""
Write-Host -ForegroundColor Green "Displaying Active Directory Account Details"
Get-ADUser $ADAccountName

Write-Host -ForegroundColor Green "Displaying Microsoft Exchange Account Details"
Get-Mailbox -Identity $ADAccountName | ft DisplayName, PrimarySMTPAddress, Database, RetentionPolicy

Write-Host -ForegroundColor Green "Displaying Microsoft Lync Account Details"
Get-CsUser -Identity $ADAccountName | ft FirstName, LastName, WindowsEmailAddress, AudioVideoDisabled

# Remove Remote PowerShell Sessions
Remove-PSSession $LyncPowerShell
Remove-PSSession $ExchangePowerShell
Remove-PSSession $ADPowerShell

sleep -Seconds 10