I came up with the below script to help with creating and migration users as a batch from On-prem Exchange to Office 365.
#####################
#
# Powershell Script
#
# Author - KumoInsight
# Email - kumoinsight@kumoinsight.co.uk
# Date - 09/09/2019
# Description - Office 365 Migration Script
#
# Version History
# 0.1 - 09/09/2019 Initial Version
#
#####################
#
# Requirements:
# - Will need to run as Admin and have Execution Policy set to Unrestricted.
#
#####################
#
# Legal Disclaimer:
# This script is written by Patrick Carder is not supported under any support program or service.
# All scripts are provided AS IS without warranty of any kind.
# The author further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose.
# The entire risk arising out of the use or performance of the sample scripts and documentation remains with you.
# In no event shall its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if the author has been advised of the possibility of such damages.
#
#####################
# --- Starting Message --- #
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host "* Preparing PowerShell environment"
Write-Host "* You'll shortly be prompted to enter your Office 365 email address and password"
Write-Host "* The required PowerShell cmdlets will then be loaded"
Write-Host "* The screen will then clear and you'll be at the main menu."
Start-Sleep -s 5
# --- Check if MSOnline is installed, if not it will install it --- #
Write-Host "Checking if MSOnline is installed"
if (Get-Module -ListAvailable -Name MSOnline) {
Write-Host "MSOnline Module exists"
}
else {
Write-Host "Module does not exist, installing MSOnline Module"
Install-Module -Name MSOnline -ErrorAction SilentlyContinue -Force -Confirm:$false
Write-Host "Installation Complete"
}
# --- Connect to O365 and Exchange Online PowerShell --- #
Write-Host 'Connecting to O365 and Exchange Online PowerShell'
Import-Module MSOnline
$LiveCred = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $LiveCred -Authentication Basic -AllowRedirection
Import-PSSession $Session
Connect-MsolService –Credential $LiveCred
Write-Host "You've connected to O365 and Exchange Online PowerShell"
# --- Launch Menu --- #
function Show-Menu
{
param (
[string]$Title = 'Office 365 Tasks'
)
cls
Write-Host "**********************************************************"
Write-Host "******************** $Title ********************"
write-Host "**********************************************************"
Write-Host ""
Write-Host "1: Declare/Change Migration Batch Name"
Write-Host "2: Create Migration Batch"
Write-Host "3: Start Migration Batch"
Write-Host "4: Check Migration Batch Status"
Write-Host "5: Complete Migration Batch (Only if all users have sucessfully Synced)"
Write-Host "6: Complete Synced Users from a Incomplete Migration Batch"
Write-Host "7: License Batch Users"
Write-Host "8: Check if all users in a Batch are licensed"
Write-Host "9: List Existing Migration Batches"
Write-Host "10: Generate CSV Template"
Write-Host ""
Write-Host "Q: Press 'Q' to quit."
Write-Host ""
}
# --- Office 365 License SKUs --- #
$MCOMEETADV = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*MCOMEETADV'}
$AAD_BASIC = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*AAD_BASIC'}
$AAD_PREMIUM = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*AAD_PREMIUM'}
$AAD_PREMIUM_P2 = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*AAD_PREMIUM_P2'}
$RIGHTSMANAGEMENT = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*RIGHTSMANAGEMENT'}
$DYN365_ENTERPRISE_PLAN1 = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*DYN365_ENTERPRISE_PLAN1'}
$DYN365_ENTERPRISE_CUSTOMER_SERVICE = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*DYN365_ENTERPRISE_CUSTOMER_SERVICE'}
$DYN365_FINANCIALS_BUSINESS_SKU = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*DYN365_FINANCIALS_BUSINESS_SKU'}
$DYN365_ENTERPRISE_SALES_CUSTOMERSERVICE = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*DYN365_ENTERPRISE_SALES_CUSTOMERSERVICE'}
$DYN365_ENTERPRISE_SALES = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*DYN365_ENTERPRISE_SALES'}
$DYN365_ENTERPRISE_TEAM_MEMBERS = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*DYN365_ENTERPRISE_TEAM_MEMBERS'}
$Dynamics_365_for_Operations = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*Dynamics_365_for_Operations'}
$EMS = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*EMS'}
$EMSPREMIUM = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*EMSPREMIUM'}
$EXCHANGESTANDARD = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*EXCHANGESTANDARD'}
$EXCHANGEENTERPRISE = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*EXCHANGEENTERPRISE'}
$EXCHANGEARCHIVE_ADDON = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*EXCHANGEARCHIVE_ADDON'}
$EXCHANGEARCHIVE = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*EXCHANGEARCHIVE'}
$EXCHANGEESSENTIALS = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*EXCHANGEESSENTIALS'}
$EXCHANGE_S_ESSENTIALS = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*EXCHANGE_S_ESSENTIALS'}
$EXCHANGEDESKLESS = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*EXCHANGEDESKLESS'}
$EXCHANGETELCO = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*EXCHANGETELCO'}
$INTUNE_A = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*INTUNE_A'}
$SPB = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*SPB'}
$SPE_E3 = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*SPE_E3'}
$SPE_E3_USGOV_DOD = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*SPE_E3_USGOV_DOD'}
$SPE_E3_USGOV_GCCHIGH = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*SPE_E3_USGOV_GCCHIGH'}
$SPE_E5 = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*SPE_E5'}
$CRMSTANDARD = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*CRMSTANDARD'}
$CRMPLAN2 = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*CRMPLAN2'}
$INTUNE_A = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*INTUNE_A'}
$IT_ACADEMY_AD = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*IT_ACADEMY_AD'}
$O365_BUSINESS = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*O365_BUSINESS'}
$SMB_BUSINESS = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*SMB_BUSINESS'}
$O365_BUSINESS_ESSENTIALS = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*O365_BUSINESS_ESSENTIALS'}
$SMB_BUSINESS_ESSENTIALS = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*SMB_BUSINESS_ESSENTIALS'}
$O365_BUSINESS_PREMIUM = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*O365_BUSINESS_PREMIUM'}
$SMB_BUSINESS_PREMIUM = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*SMB_BUSINESS_PREMIUM'}
$ENTERPRISEPACK_USGOV_DOD = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*ENTERPRISEPACK_USGOV_DOD'}
$ENTERPRISEPACK_USGOV_GCCHIGH = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*ENTERPRISEPACK_USGOV_GCCHIGH'}
$STANDARDPACK = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*STANDARDPACK'}
$STANDARDWOFFPACK = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*STANDARDWOFFPACK'}
$ENTERPRISEPACK = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*ENTERPRISEPACK'}
$DEVELOPERPACK = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*DEVELOPERPACK'}
$ENTERPRISEWITHSCAL = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*ENTERPRISEWITHSCAL'}
$ENTERPRISEPREMIUM = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*ENTERPRISEPREMIUM'}
$ENTERPRISEPREMIUM_NOPSTNCONF = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*ENTERPRISEPREMIUM_NOPSTNCONF'}
$DESKLESSPACK = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*DESKLESSPACK'}
$MIDSIZEPACK = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*MIDSIZEPACK'}
$OFFICESUBSCRIPTION = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*OFFICESUBSCRIPTION'}
$LITEPACK = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*LITEPACK'}
$LITEPACK_P2 = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*LITEPACK_P2'}
$WACONEDRIVESTANDARD = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*WACONEDRIVESTANDARD'}
$WACONEDRIVEENTERPRISE = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*WACONEDRIVEENTERPRISE'}
$POWER_BI_ADDON = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*POWER_BI_ADDON'}
$POWER_BI_PRO = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*POWER_BI_PRO'}
$PROJECTCLIENT = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*PROJECTCLIENT'}
$PROJECTESSENTIALS = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*PROJECTESSENTIALS'}
$PROJECTPREMIUM = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*PROJECTPREMIUM'}
$PROJECTONLINE_PLAN_1 = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*PROJECTONLINE_PLAN_1'}
$PROJECTPROFESSIONAL = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*PROJECTPROFESSIONAL'}
$PROJECTONLINE_PLAN_2 = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*PROJECTONLINE_PLAN_2'}
$SHAREPOINTSTANDARD = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*SHAREPOINTSTANDARD'}
$SHAREPOINTENTERPRISE = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*SHAREPOINTENTERPRISE'}
$MCOEV = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*MCOEV'}
$MCOIMP = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*MCOIMP'}
$MCOSTANDARD = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*MCOSTANDARD'}
$MCOMEETADV = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*MCOMEETADV'}
$MCOPSTN2 = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*MCOPSTN2'}
$MCOPSTN1 = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*MCOPSTN1'}
$MCOPSTN5 = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*MCOPSTN5'}
$VISIOONLINE_PLAN1 = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*VISIOONLINE_PLAN1'}
$VISIOCLIENT = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*VISIOCLIENT'}
$WIN10_PRO_ENT_SUB = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*WIN10_PRO_ENT_SUB'}
# --- Old Office 365 Enterprise E3 | ENTERPRISEPACK --- #
$E3License = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*ENTERPRISEPACK'}
$EOLP2License = Get-MsolAccountSku | where {$_.AccountSkuId -Like '*ENTERPRISEPACK'}
# --- Various Functions Called by Option Functions --- #
function Pause { $null = Read-Host 'Press Enter to return to the Main Menu...' }
function ContinuePrompt {$input = read-host "Do you want to continue? (Yes or No)"
switch ($input) `
{'yes' {Write-Host "Script will continue"}
'no' {write-host 'You Selected no, the Script will now exit'}
default {write-host 'You may only answer yes or no, please try again.'
Get-SomeInput}
}
}
function OpenFile {Add-Type -AssemblyName System.Windows.Forms
$fd = New-Object system.windows.forms.openfiledialog
$fd.InitialDirectory = '%'
$fd.filter = "CSV (*.csv)| *.csv"
$fd.MultiSelect = $false
$fd.showdialog()
$Global:path = $fd.filename}
Function Get-Folder($initialDirectory) {
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")|Out-Null
$foldername = New-Object System.Windows.Forms.FolderBrowserDialog
$foldername.Description = "Select a folder"
$foldername.rootfolder = "MyComputer"
if($foldername.ShowDialog() -eq "OK")
{
$folder += $foldername.SelectedPath
}
return $folder
}
# --- Option 1: Declare/Change Migration Batch Name --- #
Function Option1 { cls
Write-Host "**********************************************************"
Write-Host "************************ Option 1 ************************"
write-Host "**********************************************************"
Write-Host ""
$Global:BatchName = Read-Host -Prompt 'Enter the Migration Batch Name'
Write-Host ""
Write-Host "The Migration Batch Name is now set to" $BatchName
Write-Host ""
}
# --- End of Option 1 --- #
# --- Option 2: Create Migration Batch --- #
Function Option2 {cls
Write-Host "**********************************************************"
Write-Host "************************ Option 2 ************************"
write-Host "**********************************************************"
Write-Host ""
$NotificationEmail = Read-Host -Prompt 'Enter the email address to recieve notification updates'
Write-Host "Importing Batch User CSV"
OpenFile
$BatchUsers = import-csv $Path
Start-Sleep -s 3
Write-Host ""
Write-Host "Analysing Batch Users"
Start-Sleep -s 5
$MigrationBatchUsers = $BatchUsers | Select EmailAddress
Write-Host ""
Write-Host "Creating Migration Batch"
$MigrationEndpoint = Get-MigrationEndpoint -Identity "Hybrid Migration Endpoint - EWS (Default Web Site)"
New-MigrationBatch -Name $BatchName -SourceEndpoint $MigrationEndpoint.Identity -CSVData ([System.IO.File]::ReadAllBytes("$Path")) -BadItemLimit 10 -NotificationEmails $NotificationEmail
}
# --- End of Option 2 --- #
# --- Option 3: Start Migration Batch --- #
Function Option3 {cls
Write-Host "**********************************************************"
Write-Host "************************ Option 3 ************************"
write-Host "**********************************************************"
Write-Host ""
Write-Host "Starting Migration Batch"
Start-MigrationBatch -Identity $BatchName
Write-Host ""
Write-Host "Migration Batch Started"
Write-Host ""
}
# --- End of Option 3 --- #
# --- Option 4: Check Migration Batch Status --- #
Function Option4 {cls
Write-Host "**********************************************************"
Write-Host "************************ Option 4 ************************"
write-Host "**********************************************************"
Write-Host ""
Write-Host "Generating the Status of the following Migration Batch:" $BatchName
Write-Host ""
Get-MigrationUser -BatchId $BatchName | Get-MigrationUserStatistics
Write-Host ""
}
# --- End of Option 4 --- #
# --- Option 5: Complete Migration Batch (Only if all users have sucessfully Synced) --- #
Function Option5 {cls
Write-Host "**********************************************************"
Write-Host "************************ Option 5 ************************"
write-Host "**********************************************************"
Write-Host ""
Write-Host "Completing the following Migration Batch:" $BatchName
Write-Host ""
Complete-MigrationBatch -Identity $BatchName
Write-Host ""
}
# --- End of Option 5 --- #
# --- Option 6: Complete Synced Users from a Incomplete Migration Batch --- #
Function Option6 {cls
Write-Host "**********************************************************"
Write-Host "************************ Option 6 ************************"
write-Host "**********************************************************"
Write-Host ""
Write-Host "Setting the users within" $BatchName "to complete the migration"
Write-Host ""
$SyncedUsers = Get-MigrationUser -BatchId $BatchName | where Status -Match "Synced"
#$SyncedUsers
ForEach ($SyncedUser in $SyncedUsers) {Get-MoveRequest -Identity $SyncedUser.Identity | Set-MoveRequest -CompleteAfter (Get-Date) ; Resume-MoveRequest -Identity $SyncedUser.Identity ; Write-Host "$SyncedUser.Identity is now set to complete migration" }
Write-Host ""
}
# --- End of Option 6 --- #
# --- Option 7: License Batch Users --- #
Function Option7 {cls
Write-Host "**********************************************************"
Write-Host "************************ Option 7 ************************"
write-Host "**********************************************************"
Write-Host ""
Write-Host "Importing Batch User CSV"
OpenFile
$BatchUsers = import-csv $Path
Start-Sleep -s 3
Write-Host ""
Write-Host "Assigning O365 Licenses to the list of users"
Write-Host ""
ForEach ($member in $BatchUsers) {$license = $member.License ; Set-MsolUser -UserPrincipalName $member.EmailAddress -UsageLocation GB ; Set-MsolUserLicense -UserPrincipalName $member.EmailAddress -AddLicenses $(Get-Variable "$license" -ValueOnly).AccountSkuID ; Write-Host $member.EmailAddress "has been assigned a" $License "license"}
Write-Host ""
Write-Host "All Licenses Applied"
Write-Host ""
}
# --- End of Option 7 --- #
# --- Option 8: Check if all users in a Batch are licensed --- #
Function Option8 {cls
Write-Host "**********************************************************"
Write-Host "************************ Option 8 ************************"
write-Host "**********************************************************"
Write-Host ""
Write-Host "Generating list of users in Batch:"$BatchName
Write-Host ""
$BatchUsers = Get-MigrationUser -BatchId $BatchName | Get-MigrationUserStatistics
Write-Host ""
Write-Host "Checking if the list of users are licensed"
Write-Host ""
Write-Host "Checking" $BatchName "to see if they are licensed"
Write-Host ""
ForEach ($member in $BatchUsers) {$userlicense = Get-MsolUser -UserPrincipalName $member.Identity | Select Licenses; $license = $UserLicense | ft -hidetableheaders | out-string ; $Regex = [Regex]::new("(?<=:)(.*)(?=})") ; $Match = $Regex.Match($License) ; IF($Match.Value -eq "" ) {Write-Host $member.Identity "is not licensed"} else {Write-Host $member.Identity "is licensed with" $Match.Value } }
Write-Host ""
}
# --- End of Option 8 --- #
# --- Option 9: List Existing Migration Batches --- #
Function Option9 {cls
Write-Host "**********************************************************"
Write-Host "************************ Option 9 ************************"
write-Host "**********************************************************"
Write-Host ""
Write-Host "Generating list of Migration Batches"
Write-Host ""
Get-MigrationBatch | FT
Write-Host ""
}
# --- End of Option 9 --- #
# --- Option 10: Generate CSV Template --- #
Function Option10 {cls
Write-Host "**********************************************************"
Write-Host "************************ Option 10 ************************"
write-Host "**********************************************************"
Write-Host ""
Write-Host "Choose File Export Location"
$Folder = Get-Folder
Write-Host ""
$report = @()
$header = New-Object PSObject
$header | Add-Member Noteproperty "EmailAddress" ""
$header | Add-Member Noteproperty "License" ""
$report += $header
$report | Export-CSV "$folder\BatchCSVTemplate.csv" -NoTypeInformation
Write-Host "File Exported to $folder\BatchCSVTemplate.csv"
Write-Host ""
}
# --- End of Option 10 --- #
do
{
Show-Menu
$input = Read-Host "Please make a valid selection or enter Q to quit"
Write-Host ""
$Choice = $input
switch ($input)
{
'1' {Option1
Pause}
'2' {Option2
Pause}
'3' {Option3
Pause}
'4' {Option4
Pause}
'5' {Option5
Pause}
'6' {Option6
Pause}
'7' {Option7
Pause}
'8' {Option8
Pause}
'9' {Option9
Pause}
'10' {Option10
Pause}
'q' {return
Remove-PSSession $Session}
}
}
until ($input -eq 'q')
0 Comments