Moonshot365.psm1

function Connect-Office365
{
#Description: Connect to Office 365 PowerShell services. Alt: CO365
<#
.NOTES
===========================================================================
Created on: 2/4/2019 10:42 PM
Created by: Bradley Wyatt
E-Mail: Brad@TheLazyAdministrator.com
GitHub: https://github.com/bwya77
Website: https://www.thelazyadministrator.com
Organization: Porcaro Stolarek Mete Partners; The Lazy Administrator
Filename: Connect-Office365.ps1
Version: 1.0.4
Contributors: /u/Sheppard_Ra
Changelog:
1.0.4
- Host title will add a service or services you are connected to. If unable to connect it will not display connection status until connection is valid
===========================================================================
.SYNOPSIS
Connect to Office 365 Services
.DESCRIPTION
 
.PARAMETER MFA
Description: Specifies MFA requirement to sign into Office 365 services. If set to $True it will use the Office 365 ExoPSSession Module to sign into Exchange & Compliance Center using MFA. Other modules support MFA without needing another external module
.PARAMETER Exchange
Description: Connect to Exchange Online
.PARAMETER SkypeForBusiness
Description: Connect to Skype for Business
.PARAMETER SharePoint
Description: Connect to SharePoint Online
.PARAMETER SecurityandCompliance
Description: Connect to Security and Compliance Center
.PARAMETER AzureAD
Description: Connect to Azure AD V2
.PARAMETER MSOnline
Type: Switch
Description: Connect to Azure AD V1
.PARAMETER Teams
Type: Switch
Description: Connect to Teams
.EXAMPLE
Description: Connect to SharePoint Online
C:\PS> Connect-Office365 -SharePoint
.EXAMPLE
Description: Connect to Exchange Online and Azure AD V1 (MSOnline)
C:\PS> Connect-Office365 -Service Exchange, MSOnline
.EXAMPLE
Description: Connect to Exchange Online and Azure AD V2 using Multi-Factor Authentication
C:\PS> Connect-Office365 -Service Exchange, MSOnline -MFA
.EXAMPLE
Description: Connect to Teams and Skype for Business
C:\PS> Connect-Office365 -Service Teams, SkypeForBusiness
.EXAMPLE
Description: Connect to SharePoint Online
C:\PS> Connect-Office365 -Service SharePoint -SharePointOrganizationName bwya77 -MFA
.LINK
 
#>

[OutputType()]
[CmdletBinding(DefaultParameterSetName)]
$ServicesIndex = ""
$MFAcheck = ""
Write-Host ""
Write-Host "==============================================" -ForegroundColor Yellow
Write-Host "Services to Connect To:" -ForegroundColor Yellow
Write-Host "1. AzureAD" -ForegroundColor Yellow
Write-Host "2. Exchange Online" -ForegroundColor Yellow
Write-Host "3. MSOnline (AzureAD v2)" -ForegroundColor Yellow
Write-Host "4. Teams" -ForegroundColor Yellow
Write-Host "5. SkypeForBusiness" -ForegroundColor Yellow
Write-Host "6. SharePoint" -ForegroundColor Yellow
Write-Host "7. Security and Compliance - Requires MFA" -ForegroundColor Yellow
Write-Host "==============================================" -ForegroundColor Yellow
Write-Host ""
Write-Host ""
Write-Host "Which services do you want to connect to? Type the numbers, separated by a comma." -ForegroundColor Yellow
$ServicesIndex = Read-Host "Services"
Write-Host ""
Write-Host "Connect via MFA?" -ForegroundColor Yellow
$MFAcheck = Read-Host "Yes or No"
Start-Sleep -seconds 1

$ServicesString = ""
$ConnectCall = "Connect-Office365 -Service "

if($ServicesIndex -like "*1*"){
$ServicesString = -join ($ServicesString,"AzureAD,")
}
if($ServicesIndex -like "*2*"){
$ServicesString = -join ($ServicesString,"ExchangeOnline,")
}
if($ServicesIndex -like "*3*"){
$ServicesString = -join ($ServicesString,"MSOnline,")
}
if($ServicesIndex -like "*4*"){
$ServicesString = -join ($ServicesString,"Teams,")
}
if($ServicesIndex -like "*5*"){
$ServicesString = -join ($ServicesString,"SkypeForBusiness,")
}
if($ServicesIndex -like "*7*"){
$ServicesString = -join ($ServicesString,"SecurityandCompliance,")
}
if($ServicesIndex -like "*6*"){
Write-Host ""
Write-Host "SharePoint:" -ForegroundColor Yellow
$SharePointOrganizationName = Read-Host "What is your tenant name? (<tenant name>.onmicrosoft.com)"
$ServicesString = -join ($ServicesString,"SharePoint,")
}
$ServicesString = $ServicesString.trimend(",")
$ServicesString = $ServicesString.trimstart(",")
$ServicesString = $ServicesString.trimstart(" ")
$ConnectCall = -join ($ConnectCall,$ServicesString)
$MFA = ""
if($MFAcheck -like "*yes*"){
$MFA = $True
}else{
$MFA = $False}
Start-Sleep -seconds 1
Write-Host ""
Write-Host ""
Write-Host "Calling connection script..." -ForegroundColor Yellow
Write-Host ""
Write-Host ""
Start-Sleep -seconds 1

$Service = $ServicesString -split(',')
$getModuleSplat = @{
ListAvailable = $True
Verbose          = $False
}
If ($MFA -ne $True)
{
Write-Host "Gathering PSCredentials object for non MFA sign on"
$Credential = Get-Credential -Message "Please enter your Office 365 credentials"
}
ForEach ($Item in $Service)
{
Write-Host "Attempting connection to $Item"
Switch ($Item)
{
AzureAD {
If ($null -eq (Get-Module @getModuleSplat -Name "AzureAD"))
{
Write-Error "SkypeOnlineConnector Module is not present!"
continue
}
Else
{
If ($MFA -eq $True)
{
$Connect = Connect-AzureAD
$Connect
If ($Connect -ne $Null)
{
If (($host.ui.RawUI.WindowTitle) -notlike "*Connected To:*")
{
$host.ui.RawUI.WindowTitle += " - Connected To: AzureAD"
}
Else
{
$host.ui.RawUI.WindowTitle += " - AzureAD"
}
}
}
Else
{
$Connect = Connect-AzureAD -Credential $Credential
$Connect
If ($Connect -ne $Null)
{
If (($host.ui.RawUI.WindowTitle) -notlike "*Connected To:*")
{
$host.ui.RawUI.WindowTitle += " - Connected To: AzureAD"
}
Else
{
$host.ui.RawUI.WindowTitle += " - AzureAD"
}
}
}
}
continue
}
ExchangeOnline {
If ($MFA -eq $True)
{
$getChildItemSplat = @{
Path = "$Env:LOCALAPPDATA\Apps\2.0\*\CreateExoPSSession.ps1"
Recurse = $true
ErrorAction = 'SilentlyContinue'
Verbose = $false
}
$MFAExchangeModule = ((Get-ChildItem @getChildItemSplat | Select-Object -ExpandProperty Target -First 1).Replace("CreateExoPSSession.ps1", ""))
If ($null -eq $MFAExchangeModule)
{
Write-Error "The Exchange Online MFA Module was not found!
https://docs.microsoft.com/en-us/powershell/exchange/exchange-online/connect-to-exchange-online-powershell/mfa-connect-to-exchange-online-powershell?view=exchange-ps"

continue
}
Else
{
Write-Host "Importing Exchange MFA Module"
Import-Module -Name "$MFAExchangeModule\CreateExoPSSession.ps1" -Global
Write-Host "Connecting to Exchange Online"
$null = Connect-EXOPSSession -ConnectionUri "https://ps.outlook.com/powershell/" | Out-Null
$global:exchangeOnlineSession = (Get-PSSession | Where-Object { ($_.ConfigurationName -eq 'Microsoft.Exchange') -and ($_.State -eq 'Opened') })[0]
Import-Module -AsCustomObject (Import-PSSession $exchangeOnlineSession -AllowClobber) -Global

If ($Null -ne (Get-PSSession | Where-Object { $_.ConfigurationName -like "*Exchange*" }))
{
If (($host.ui.RawUI.WindowTitle) -notlike "*Connected To:*")
{
$host.ui.RawUI.WindowTitle += " - Connected To: Exchange"
}
Else
{
$host.ui.RawUI.WindowTitle += " - Exchange"
}
}
}
}
Else
{
$newPSSessionSplat = @{
ConfigurationName = 'Microsoft.Exchange'
ConnectionUri      = "https://ps.outlook.com/powershell/"
Authentication    = 'Basic'
Credential          = $Credential
AllowRedirection  = $true
}
Write-Host "Connecting to Exchange Online"
$EOSession = New-PSSession @newPSSessionSplat
Import-Module (Import-PSSession $EOSession -AllowClobber -DisableNameChecking) -Global
If ($Null -ne (Get-PSSession | Where-Object { $_.ConfigurationName -like "*Exchange*" }))
{
If (($host.ui.RawUI.WindowTitle) -notlike "*Connected To:*")
{
$host.ui.RawUI.WindowTitle += " - Connected To: Exchange"
}
Else
{
$host.ui.RawUI.WindowTitle += " - Exchange"
}
}
}
continue
}
MSOnline {
If ($null -eq (Get-Module @getModuleSplat -Name "MSOnline"))
{
Write-Error "MSOnline Module is not present!"
continue
}
Else
{
Write-Host "Connecting to MSOnline"
If ($MFA -eq $True)
{
Connect-MsolService
If ($Null -ne (Get-MsolCompanyInformation -ErrorAction SilentlyContinue))
{
If (($host.ui.RawUI.WindowTitle) -notlike "*Connected To:*")
{
$host.ui.RawUI.WindowTitle += " - Connected To: MSOnline"
}
Else
{
$host.ui.RawUI.WindowTitle += " - MSOnline"
}
}
}
Else
{
Connect-MsolService -Credential $Credential
If ($Null -ne (Get-MsolCompanyInformation -ErrorAction SilentlyContinue))
{
If (($host.ui.RawUI.WindowTitle) -notlike "*Connected To:*")
{
$host.ui.RawUI.WindowTitle += " - Connected To: MSOnline"
}
Else
{
$host.ui.RawUI.WindowTitle += " - MSOnline"
}
}
}
}
continue
}
SecurityAndCompliance {
If ($MFA -eq $True)
{
$getChildItemSplat = @{
Path = "$Env:LOCALAPPDATA\Apps\2.0\*\CreateExoPSSession.ps1"
Recurse = $true
ErrorAction = 'SilentlyContinue'
Verbose = $false
}
$MFAExchangeModule = ((Get-ChildItem @getChildItemSplat | Select-Object -ExpandProperty Target -First 1).Replace("CreateExoPSSession.ps1", ""))
If ($null -eq $MFAExchangeModule)
{
Write-Error "The Exchange Online MFA Module was not found!
https://docs.microsoft.com/en-us/powershell/exchange/exchange-online/connect-to-exchange-online-powershell/mfa-connect-to-exchange-online-powershell?view=exchange-ps"

continue
}
Else
{
Write-Host "Importing Exchange MFA Module (Required)"
. "$MFAExchangeModule\CreateExoPSSession.ps1"
Write-Host "Connecting to Security and Compliance Center"
Connect-IPPSSession
If ($Null -ne (Get-PSSession | Where-Object { $_.ConfigurationName -like "*Exchange*" }))
{
If (($host.ui.RawUI.WindowTitle) -notlike "*Connected To:*")
{
$host.ui.RawUI.WindowTitle += " - Connected To: Security and Compliance Center"
}
Else
{
$host.ui.RawUI.WindowTitle += " - Security and Compliance Center"
}
}
}
}
Else
{
$newPSSessionSplat = @{
ConfigurationName = 'Microsoft.SecurityAndCompliance'
ConnectionUri      = 'https://ps.compliance.protection.outlook.com/powershell-liveid/'
Authentication    = 'Basic'
Credential          = $Credential
AllowRedirection  = $true
}
$Session = New-PSSession @newPSSessionSplat
Write-Host "Connecting to SecurityAndCompliance"
Import-Module (Import-PSSession $Session -DisableNameChecking) -Global
If ($Null -ne (Get-PSSession | Where-Object { $_.ConfigurationName -like "*Exchange*" }))
{
If (($host.ui.RawUI.WindowTitle) -notlike "*Connected To:*")
{
$host.ui.RawUI.WindowTitle += " - Connected To: Security and Compliance Center"
}
Else
{
$host.ui.RawUI.WindowTitle += " - Security and Compliance Center"
}
}
}
continue
}
SharePoint {
If ($null -eq (Get-Module @getModuleSplat -Name Microsoft.Online.SharePoint.PowerShell))
{
Write-Error "Microsoft.Online.SharePoint.PowerShell Module is not present!"
continue
Write-Host "Installing SharePoint Module!"
Install-Module -Name Microsoft.Online.SharePoint.PowerShell -Confirm:$False -Force
}
Else
{
If (!$SharePointOrganizationName)
{
Write-Error 'Please provide a valid SharePoint organization name with the -SharePointOrganizationName parameter.'
continue
}
$SharePointURL = "https://{0}-admin.sharepoint.com" -f $SharePointOrganizationName
Write-Host "Connecting to SharePoint at $SharePointURL"
If ($MFA -eq $True)
{
$SPOSession =  Connect-SPOService -Url https://$SharePointOrganizationName-admin.sharepoint.com -credential $credential
$SPOSession
If ($Null -ne (Get-SPOTenant))
{
If (($host.ui.RawUI.WindowTitle) -notlike "*Connected To:*")
{
$host.ui.RawUI.WindowTitle += " - Connected To: SharePoint Online"
}
Else
{
$host.ui.RawUI.WindowTitle += " - SharePoint Online"
}
}
}
Else
{
$SPOSession = Connect-SPOService -Url https://$SharePointOrganizationName-admin.sharepoint.com -credential $credential
$SPOSession
If ($Null -ne (Get-SPOTenant))
{
If (($host.ui.RawUI.WindowTitle) -notlike "*Connected To:*")
{
$host.ui.RawUI.WindowTitle += " - Connected To: SharePoint Online"
}
Else
{
$host.ui.RawUI.WindowTitle += " - SharePoint Online"
}
}
}
}
continue
}
SkypeForBusiness {
Write-Host "Connecting to SkypeForBusiness"
If ($null -eq (Get-Module @getModuleSplat -Name "SkypeOnlineConnector"))
{
Write-Error "SkypeOnlineConnector Module is not present!"
}
Else
{
# Skype for Business module
Import-Module SkypeOnlineConnector
If ($MFA -eq $True)
{
$CSSession = New-CsOnlineSession
Import-Module (Import-PSSession $CSSession -AllowClobber) -Global
If ($Null -ne (Get-CsOnlineDirectoryTenant))
{
If (($host.ui.RawUI.WindowTitle) -notlike "*Connected To:*")
{
$host.ui.RawUI.WindowTitle += " - Connected To: Skype for Business"
}
Else
{
$host.ui.RawUI.WindowTitle += " - Skype for Business"
}
}
}
Else
{
$CSSession = New-CsOnlineSession -Credential $Credential
Import-Module (Import-PSSession $CSSession -AllowClobber) -Global
If ($Null -ne (Get-CsOnlineDirectoryTenant))
{
If (($host.ui.RawUI.WindowTitle) -notlike "*Connected To:*")
{
$host.ui.RawUI.WindowTitle += " - Connected To: Skype for Business"
}
Else
{
$host.ui.RawUI.WindowTitle += " - Skype for Business"
}
}
}
}
continue
}
Teams {
If ($null -eq (Get-Module @getModuleSplat -Name "MicrosoftTeams"))
{
Write-Error "MicrosoftTeams Module is not present!"
}
Else
{
Write-Host "Connecting to Teams"
If ($MFA -eq $True)
{
$TeamsConnect = Connect-MicrosoftTeams
If ($Null -ne ($TeamsConnect))
{
If (($host.ui.RawUI.WindowTitle) -notlike "*Connected To:*")
{
$host.ui.RawUI.WindowTitle += " - Connected To: Microsoft Teams"
}
Else
{
$host.ui.RawUI.WindowTitle += " - Microsoft Teams"
}
}
}
Else
{
$TeamsConnect = Connect-MicrosoftTeams -Credential $Credential
If ($Null -ne ($TeamsConnect))
{
If (($host.ui.RawUI.WindowTitle) -notlike "*Connected To:*")
{
$host.ui.RawUI.WindowTitle += " - Connected To: Microsoft Teams"
}
Else
{
$host.ui.RawUI.WindowTitle += " - Microsoft Teams"
}
}
}
}
continue
}
Default { }
}
}
Get-Commands
}
function Get-Office365Modules
{
#Description: Install AzureAD, MsOnline, and SharePoint modules
#Check if connected to a tenant
if (Get-Module -ListAvailable -Name AzureAD) {
Write-Host "AzureAD Module Installed!"
}
else {
Write-Host "Installing AzureAD Module!"
    Install-Module AzureAD -Confirm:$False -Force
}
if (Get-Module -ListAvailable -Name MsOnline) {
Write-Host "MsOnline Module Installed!"
}
else {
Write-Host "Installing MsOnline Module!"
    Install-Module MsOnline -Confirm:$False -Force
}
if (Get-Module -ListAvailable -Name Microsoft.Online.SharePoint.PowerShell) {
Write-Host "SharePoint Module Installed!"
}
else {
Write-Host "Installing SharePoint Module!"
    Install-Module -Name Microsoft.Online.SharePoint.PowerShell -Confirm:$False -Force
}
Get-Commands
}
function CO365
{
    Connect-Office365
}
function New-HTMLReport
{
#Description: Generate intractive HTML report on Office 365 Tenant
#Company logo that will be displayed on the left, can be URL or UNC
$CompanyLogo = "https://321moonshot.com/images/logo/moonshot-logo-200.gif"
#Logo that will be on the right side, UNC or URL
$RightLogo = ""
#Location the report will be saved to
$ReportSavePath = "$home\Downloads\"
#Variable to filter licenses out, in current state will only get licenses with a count less than 9,000 this will help filter free/trial licenses
$LicenseFilter = "5000"
#If you want to include users last logon mailbox timestamp, set this to true

#Set to $True if your global admin requires 2FA
$2FA = $False
########################################
try
{ $var = Get-AzureADTenantDetail }
catch [Microsoft.Open.Azure.AD.CommonLibrary.AadNeedAuthenticationException]
{$credential = Get-Credential -Message "Please enter your Office 365 credentials" -ForegroundColor Yellow
Import-Module MsOnline
Connect-AzureAD -Credential $credential
Connect-MsolService -Credential $credential
$exchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://outlook.office365.com/powershell-liveid/" -Credential $credential -Authentication "Basic" -AllowRedirection
Import-PSSession $exchangeSession -AllowClobber
}
if (Get-Module -ListAvailable -Name ReportHTML) {
}
else {
    Install-Module ReportHTML -Confirm:$False -Force
}

Write-Host 
Write-Host "Check Mailbox Size? (Note: This will increase report processing time)" -ForegroundColor Yellow
Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
$CheckMbxSize = Read-Host "[y/n]"
Write-Host 
Write-Host "Check Last Mailbox Logon Time?" -ForegroundColor Yellow
Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
$LogonTimeStamp = Read-Host "[y/n]"
Write-Host 
If($LogonTimeStamp -like "*y*"){
    $IncludeLastLogonTimestamp = $True
}Else{
    $IncludeLastLogonTimestamp = $False
}
Write-Host "Starting Report.... Please Wait." -ForegroundColor Green
$Table = New-Object 'System.Collections.Generic.List[System.Object]'
$LicenseTable = New-Object 'System.Collections.Generic.List[System.Object]'
$UserTable = New-Object 'System.Collections.Generic.List[System.Object]'
$SharedMailboxTable = New-Object 'System.Collections.Generic.List[System.Object]'
$GroupTypetable = New-Object 'System.Collections.Generic.List[System.Object]'
$IsLicensedUsersTable = New-Object 'System.Collections.Generic.List[System.Object]'
$ContactTable = New-Object 'System.Collections.Generic.List[System.Object]'
$MailUser = New-Object 'System.Collections.Generic.List[System.Object]'
$ContactMailUserTable = New-Object 'System.Collections.Generic.List[System.Object]'
$RoomTable = New-Object 'System.Collections.Generic.List[System.Object]'
$EquipTable = New-Object 'System.Collections.Generic.List[System.Object]'
$GlobalAdminTable = New-Object 'System.Collections.Generic.List[System.Object]'
$StrongPasswordTable = New-Object 'System.Collections.Generic.List[System.Object]'
$CompanyInfoTable = New-Object 'System.Collections.Generic.List[System.Object]'
$MessageTraceTable = New-Object 'System.Collections.Generic.List[System.Object]'
$DomainTable = New-Object 'System.Collections.Generic.List[System.Object]'
$Sku = @{
    "O365_BUSINESS_ESSENTIALS"      = "Office 365 Business Essentials"
    "O365_BUSINESS_PREMIUM"      = "Office 365 Business Premium"
    "DESKLESSPACK"      = "Office 365 (Plan K1)"
    "DESKLESSWOFFPACK"      = "Office 365 (Plan K2)"
    "LITEPACK"      = "Office 365 (Plan P1)"
    "EXCHANGESTANDARD"      = "Office 365 Exchange Online Only"
    "STANDARDPACK"      = "Office 365 E1"
    "STANDARDWOFFPACK"      = "Office 365 (Plan E2)"
    "ENTERPRISEPACK" = "Office 365 E3"
    "ENTERPRISEPACKLRG"      = "Office 365 E3"
    "ENTERPRISEWITHSCAL" = "Office 365 E4"
    "STANDARDPACK_STUDENT"      = "Office 365 (Plan A1) for Students"
    "STANDARDWOFFPACKPACK_STUDENT"      = "Office 365 (Plan A2) for Students"
    "ENTERPRISEPACK_STUDENT" = "Office 365 (Plan A3) for Students"
    "ENTERPRISEWITHSCAL_STUDENT" = "Office 365 (Plan A4) for Students"
    "STANDARDPACK_FACULTY"      = "Office 365 (Plan A1) for Faculty"
    "STANDARDWOFFPACKPACK_FACULTY"      = "Office 365 (Plan A2) for Faculty"
    "ENTERPRISEPACK_FACULTY" = "Office 365 (Plan A3) for Faculty"
    "ENTERPRISEWITHSCAL_FACULTY" = "Office 365 (Plan A4) for Faculty"
    "ENTERPRISEPACK_B_PILOT" = "Office 365 (Enterprise Preview)"
    "STANDARD_B_PILOT"      = "Office 365 (Small Business Preview)"
    "VISIOCLIENT"      = "Visio Pro Online"
    "POWER_BI_ADDON" = "Office 365 Power BI Addon"
    "POWER_BI_INDIVIDUAL_USE"      = "Power BI Individual User"
    "POWER_BI_STANDALONE"      = "Power BI Stand Alone"
    "POWER_BI_STANDARD"      = "Power-BI Standard"
    "PROJECTESSENTIALS"      = "Project Lite"
    "PROJECTCLIENT"      = "Project Professional"
    "PROJECTONLINE_PLAN_1"      = "Project Online"
    "PROJECTONLINE_PLAN_2"      = "Project Online and PRO"
    "ProjectPremium" = "Project Online Premium"
    "ECAL_SERVICES"      = "ECAL"
    "EMS"      = "Enterprise Mobility Suite"
    "RIGHTSMANAGEMENT_ADHOC" = "Windows Azure Rights Management"
    "MCOMEETADV" = "PSTN conferencing"
    "SHAREPOINTSTORAGE"      = "SharePoint storage"
    "PLANNERSTANDALONE"      = "Planner Standalone"
    "CRMIUR" = "CMRIUR"
    "BI_AZURE_P1"      = "Power BI Reporting and Analytics"
    "INTUNE_A"      = "Windows Intune Plan A"
    "PROJECTWORKMANAGEMENT"      = "Office 365 Planner Preview"
    "ATP_ENTERPRISE" = "Exchange Online Advanced Threat Protection"
    "EQUIVIO_ANALYTICS"      = "Office 365 Advanced eDiscovery"
    "AAD_BASIC"      = "Azure Active Directory Basic"
    "RMS_S_ENTERPRISE"      = "Azure Active Directory Rights Management"
    "AAD_PREMIUM"      = "Azure Active Directory Premium"
    "MFA_PREMIUM"      = "Azure Multi-Factor Authentication"
    "STANDARDPACK_GOV"      = "Microsoft Office 365 (Plan G1) for Government"
    "STANDARDWOFFPACK_GOV"      = "Microsoft Office 365 (Plan G2) for Government"
    "ENTERPRISEPACK_GOV" = "Microsoft Office 365 (Plan G3) for Government"
    "ENTERPRISEWITHSCAL_GOV" = "Microsoft Office 365 (Plan G4) for Government"
    "DESKLESSPACK_GOV"      = "Microsoft Office 365 (Plan K1) for Government"
    "ESKLESSWOFFPACK_GOV"      = "Microsoft Office 365 (Plan K2) for Government"
    "EXCHANGESTANDARD_GOV"      = "Microsoft Office 365 Exchange Online (Plan 1) only for Government"
    "EXCHANGEENTERPRISE_GOV" = "Microsoft Office 365 Exchange Online (Plan 2) only for Government"
    "SHAREPOINTDESKLESS_GOV" = "SharePoint Online Kiosk"
    "EXCHANGE_S_DESKLESS_GOV"      = "Exchange Kiosk"
    "RMS_S_ENTERPRISE_GOV"      = "Windows Azure Active Directory Rights Management"
    "OFFICESUBSCRIPTION_GOV" = "Office ProPlus"
    "MCOSTANDARD_GOV"      = "Lync Plan 2G"
    "SHAREPOINTWAC_GOV"      = "Office Online for Government"
    "SHAREPOINTENTERPRISE_GOV"      = "SharePoint Plan 2G"
    "EXCHANGE_S_ENTERPRISE_GOV"      = "Exchange Plan 2G"
    "EXCHANGE_S_ARCHIVE_ADDON_GOV"      = "Exchange Online Archiving"
    "EXCHANGE_S_DESKLESS"      = "Exchange Online Kiosk"
    "SHAREPOINTDESKLESS" = "SharePoint Online Kiosk"
    "SHAREPOINTWAC"      = "Office Online"
    "YAMMER_ENTERPRISE"      = "Yammer Enterprise"
    "EXCHANGE_L_STANDARD"      = "Exchange Online (Plan 1)"
    "MCOLITE"      = "Lync Online (Plan 1)"
    "SHAREPOINTLITE" = "SharePoint Online (Plan 1)"
    "OFFICE_PRO_PLUS_SUBSCRIPTION_SMBIZ" = "Office ProPlus"
    "EXCHANGE_S_STANDARD_MIDMARKET"      = "Exchange Online (Plan 1)"
    "MCOSTANDARD_MIDMARKET"      = "Lync Online (Plan 1)"
    "SHAREPOINTENTERPRISE_MIDMARKET" = "SharePoint Online (Plan 1)"
    "OFFICESUBSCRIPTION" = "Office ProPlus"
    "YAMMER_MIDSIZE" = "Yammer"
    "DYN365_ENTERPRISE_PLAN1"      = "Dynamics 365 Customer Engagement Plan Enterprise Edition"
    "ENTERPRISEPREMIUM_NOPSTNCONF"      = "Enterprise E5 (without Audio Conferencing)"
    "ENTERPRISEPREMIUM"      = "Enterprise E5 (with Audio Conferencing)"
    "MCOSTANDARD"      = "Skype for Business Online Standalone Plan 2"
    "PROJECT_MADEIRA_PREVIEW_IW_SKU" = "Dynamics 365 for Financials for IWs"
    "STANDARDWOFFPACK_IW_STUDENT"      = "Office 365 Education for Students"
    "STANDARDWOFFPACK_IW_FACULTY"      = "Office 365 Education for Faculty"
    "EOP_ENTERPRISE_FACULTY" = "Exchange Online Protection for Faculty"
    "EXCHANGESTANDARD_STUDENT"      = "Exchange Online (Plan 1) for Students"
    "OFFICESUBSCRIPTION_STUDENT" = "Office ProPlus Student Benefit"
    "STANDARDWOFFPACK_FACULTY"      = "Office 365 Education E1 for Faculty"
    "STANDARDWOFFPACK_STUDENT"      = "Microsoft Office 365 (Plan A2) for Students"
    "DYN365_FINANCIALS_BUSINESS_SKU" = "Dynamics 365 for Financials Business Edition"
    "DYN365_FINANCIALS_TEAM_MEMBERS_SKU" = "Dynamics 365 for Team Members Business Edition"
    "FLOW_FREE"      = "Microsoft Flow Free"
    "POWER_BI_PRO"      = "Power BI Pro"
    "O365_BUSINESS"      = "Office 365 Business"
    "DYN365_ENTERPRISE_SALES"      = "Dynamics Office 365 Enterprise Sales"
    "RIGHTSMANAGEMENT"      = "Rights Management"
    "PROJECTPROFESSIONAL"      = "Project Professional"
    "VISIOONLINE_PLAN1"      = "Visio Online Plan 1"
    "EXCHANGEENTERPRISE" = "Exchange Online Plan 2"
    "DYN365_ENTERPRISE_P1_IW"      = "Dynamics 365 P1 Trial for Information Workers"
    "DYN365_ENTERPRISE_TEAM_MEMBERS" = "Dynamics 365 For Team Members Enterprise Edition"
    "CRMSTANDARD"      = "Microsoft Dynamics CRM Online Professional"
    "EXCHANGEARCHIVE_ADDON"      = "Exchange Online Archiving For Exchange Online"
    "EXCHANGEDESKLESS"      = "Exchange Online Kiosk"
    "SPZA_IW"      = "App Connect"
    "WINDOWS_STORE"      = "Windows Store for Business"
    "MCOEV"      = "Microsoft Phone System"
    "PHONESYSTEM_VIRTUALUSER" = "Phone System - Virtual User"
    "VIDEO_INTEROP"      = "Polycom Skype Meeting Video Interop for Skype for Business"
    "SPE_E5" = "Microsoft 365 E5"
    "SPE_E3" = "Microsoft 365 E3"
    "ATA"      = "Advanced Threat Analytics"
    "MCOPSTN2"      = "Domestic and International Calling Plan"
    "FLOW_P1"      = "Microsoft Flow Plan 1"
    "FLOW_P2"      = "Microsoft Flow Plan 2"
    "CRMSTORAGE" = "Microsoft Dynamics CRM Online Additional Storage"
    "SMB_APPS"      = "Microsoft Business Apps"
    "MICROSOFT_BUSINESS_CENTER"      = "Microsoft Business Center"
    "DYN365_TEAM_MEMBERS"      = "Dynamics 365 Team Members"
    "STREAM" = "Microsoft Stream Trial"
    "EMSPREMIUM"                         = "Enterprise Mobility + Security E5"
    "SPB" = "Microsoft 365 Business"
    "MCOPSTN1" = "Domestic Calling Plan"
    "MEETING_ROOM" = "Teams Meeting Room"
    "POWERAPPS_PER_APP_IW" = "PowerApps Per App"
    "POWERAPPS_PER_APP" = "PowerApps Per App"
    "TEAMS_COMMERCIAL_TRIAL" = "Microsoft Teams"
    "POWERAPPS_PER_USER" = "PowerApps Per User"
    "FLOW_PER_USER" = "PowerAutomate Per User"
    "POWERFLOW_P1" = "Flow P1"
}
# Get all users right away. Instead of doing several lookups, we will use this object to look up all the information needed.
$AllUsers = get-azureaduser -All:$true
#Company Information
Write-Host " Processing Company Information.... Please Wait." -ForegroundColor Green
$CompanyInfo = Get-AzureADTenantDetail
$CompanyName = $CompanyInfo.DisplayName
$TechEmail = $CompanyInfo.TechnicalNotificationMails | Out-String
$DirSync = $CompanyInfo.DirSyncEnabled
$LastDirSync = $CompanyInfo.CompanyLastDirSyncTime
If ($DirSync -eq $Null)
{
$LastDirSync = "Not Available"
$DirSync = "Disabled"
}
If ($PasswordSync -eq $Null)
{
$LastPasswordSync = "Not Available"
}
$obj = [PSCustomObject]@{
'Name'                       = $CompanyName
'Technical E-mail'           = $TechEmail
'Directory Sync'           = $DirSync
'Last Directory Sync'       = $LastDirSync
}
$CompanyInfoTable.add($obj)
#Get Tenant Global Admins
$role = Get-AzureADDirectoryRole | Where-Object { $_.DisplayName -match "Company Administrator" }
$Admins = Get-AzureADDirectoryRoleMember -ObjectId $role.ObjectId
Foreach ($Admin in $Admins)
{
$Name = $Admin.DisplayName
$EmailAddress = $Admin.Mail
if (($admin.assignedlicenses.SkuID) -ne $Null)
{
$Licensed = $True
}
else
{
$Licensed = $False
}
$obj = [PSCustomObject]@{
'Name'                  = $Name
'Is Licensed'          = $Licensed
'E-Mail Address'      = $EmailAddress
}
$GlobalAdminTable.add($obj)
}
#Users with Strong Password Disabled
$LooseUsers = $AllUsers | Where-Object { $_.PasswordPolicies -eq "DisableStrongPassword" }
Foreach ($LooseUser in $LooseUsers)
{
$NameLoose = $LooseUser.DisplayName
$UPNLoose = $LooseUser.UserPrincipalName
$StrongPasswordLoose = "False"
if (($LooseUser.assignedlicenses.SkuID) -ne $Null)
{
$LicensedLoose = $true
}
else
{
$LicensedLoose = $false
}
$obj = [PSCustomObject]@{
'Name'                            = $NameLoose
'UserPrincipalName'                = $UPNLoose
'Is Licensed'                    = $LicensedLoose
'Strong Password Required'        = $StrongPasswordLoose
}
$StrongPasswordTable.add($obj)
}
If (($StrongPasswordTable).count -eq 0)
{
$StrongPasswordTable = [PSCustomObject]@{
'Information'  = 'Information: No Users were found with Strong Password Enforcement disabled'
}
}
#Message Trace / Recent Messages
$RecentMessages = Get-MessageTrace
Foreach ($RecentMessage in $RecentMessages)
{
$TraceDate = $RecentMessage.Received
$Sender = $RecentMessage.SenderAddress
$Recipient = $RecentMessage.RecipientAddress
$Subject = $RecentMessage.Subject
$Status = $RecentMessage.Status
$obj = [PSCustomObject]@{
'Received Date'           = $TraceDate
'E-Mail Subject'       = $Subject
'Sender'               = $Sender
'Recipient'               = $Recipient
'Status'               = $Status
}
$MessageTraceTable.add($obj)
}
If (($MessageTraceTable).count -eq 0)
{
$MessageTraceTable = [PSCustomObject]@{
'Information'  = 'Information: No recent E-Mails were found'
}
}
#Tenant Domain
$Domains = Get-AzureAdDomain
foreach ($Domain in $Domains)
{
$DomainName = $Domain.Name
$Verified = $Domain.IsVerified
$DefaultStatus = $Domain.IsDefault
$obj = [PSCustomObject]@{
'Domain Name'                  = $DomainName
'Verification Status'          = $Verified
'Default'                      = $DefaultStatus
}
$DomainTable.add($obj)
}
#Get groups and sort in alphabetical order
Write-Host " Processing Groups.... Please Wait." -ForegroundColor Green
$Groups = Get-AzureAdGroup -All $True | Sort-Object DisplayName
$DistroCount = ($Groups | Where-Object { $_.MailEnabled -eq $true -and $_.SecurityEnabled -eq $false }).Count
$obj1 = [PSCustomObject]@{
'Name'                          = 'Distribution Group'
'Count'                          = $DistroCount
}
$GroupTypetable.add($obj1)
$SecurityCount = ($Groups | Where-Object { $_.MailEnabled -eq $false -and $_.SecurityEnabled -eq $true }).Count
$obj1 = [PSCustomObject]@{
'Name'                          = 'Security Group'
'Count'                          = $SecurityCount
}
$GroupTypetable.add($obj1)
$SecurityMailEnabledCount = ($Groups | Where-Object { $_.MailEnabled -eq $true -and $_.SecurityEnabled -eq $true }).Count
$obj1 = [PSCustomObject]@{
'Name'                          = 'Mail Enabled Security Group'
'Count'                          = $SecurityMailEnabledCount
}
$GroupTypetable.add($obj1)
Foreach ($Group in $Groups)
{
$Type = New-Object 'System.Collections.Generic.List[System.Object]'
if ($group.MailEnabled -eq $True -and $group.SecurityEnabled -eq $False)
{
$Type = "Distribution Group"
}
if ($group.MailEnabled -eq $False -and $group.SecurityEnabled -eq $True)
{
$Type = "Security Group"
}
if ($group.MailEnabled -eq $True -and $group.SecurityEnabled -eq $True)
{
$Type = "Mail Enabled Security Group"
}
$Users = (Get-AzureADGroupMember -ObjectId $Group.ObjectID | Sort-Object DisplayName | Select-Object -ExpandProperty DisplayName) -join ", "
$GName = $Group.DisplayName
$hash = New-Object PSObject -property @{ Name = "$GName"; Type = "$Type"; Members = "$Users" }
$GEmail = $Group.Mail
$obj = [PSCustomObject]@{
'Name'                   = $GName
'Type'                   = $Type
'Members'               = $users
'E-mail Address'       = $GEmail
}
$table.add($obj)
}
If (($table).count -eq 0)
{
$table = [PSCustomObject]@{
'Information'  = 'Information: No Groups were found in the tenant'
}
}
Write-Host " Processing Licenses.... Please Wait." -ForegroundColor Green
#Get all licenses
$Licenses = Get-AzureADSubscribedSku
#Split licenses at colon
Foreach ($License in $Licenses)
{
$TextLic = $null
$ASku = ($License).SkuPartNumber
$TextLic = $Sku.Item("$ASku")
If (!($TextLic))
{
$OLicense = $License.SkuPartNumber
}
Else
{
$OLicense = $TextLic
}
$TotalAmount = $License.PrepaidUnits.enabled
$Assigned = $License.ConsumedUnits
$Unassigned = ($TotalAmount - $Assigned)
If ($TotalAmount -lt $LicenseFilter)
{
$obj = [PSCustomObject]@{
'Name'                        = $Olicense
'Total Amount'                = $TotalAmount
'Assigned Licenses'            = $Assigned
'Unassigned Licenses'        = $Unassigned
}
$licensetable.add($obj)
}
}
If (($licensetable).count -eq 0)
{
$licensetable = [PSCustomObject]@{
'Information'  = 'Information: No Licenses were found in the tenant'
}
}
$IsLicensed = ($AllUsers | Where-Object { $_.assignedlicenses.count -gt 0 }).Count
$objULic = [PSCustomObject]@{
'Name'       = 'Users Licensed'
'Count'    = $IsLicensed
}
$IsLicensedUsersTable.add($objULic)
$ISNotLicensed = ($AllUsers | Where-Object { $_.assignedlicenses.count -eq 0 }).Count
$objULic = [PSCustomObject]@{
'Name'       = 'Users Not Licensed'
'Count'    = $IsNotLicensed
}
$IsLicensedUsersTable.add($objULic)
If (($IsLicensedUsersTable).count -eq 0)
{
$IsLicensedUsersTable = [PSCustomObject]@{
'Information'  = 'Information: No Licenses were found in the tenant'
}
}
Write-Host " Processing Users.... Please Wait." -ForegroundColor Green
$LicensedAllUsers = $AllUsers | Where-Object { $_.assignedlicenses.count -gt 0 }
Foreach ($User in $LicensedAllUsers)
{
$ProxyA = New-Object 'System.Collections.Generic.List[System.Object]'
$NewObject02 = New-Object 'System.Collections.Generic.List[System.Object]'
$NewObject01 = New-Object 'System.Collections.Generic.List[System.Object]'
$UserLicenses = ($user | Select -ExpandProperty AssignedLicenses).SkuID
If (($UserLicenses).count -gt 1)
{
Foreach ($UserLicense in $UserLicenses)
{
$UserLicense = ($licenses | Where-Object { $_.skuid -match $UserLicense }).SkuPartNumber
$TextLic = $Sku.Item("$UserLicense")
If (!($TextLic))
{
$NewObject01 = [PSCustomObject]@{
'Licenses'       = $UserLicense
}
$NewObject02.add($NewObject01)
}
Else
{
$NewObject01 = [PSCustomObject]@{
'Licenses'       = $textlic
}
$NewObject02.add($NewObject01)
}
}
}
Elseif (($UserLicenses).count -eq 1)
{
$lic = ($licenses | Where-Object { $_.skuid -match $UserLicenses}).SkuPartNumber
$TextLic = $Sku.Item("$lic")
If (!($TextLic))
{
$NewObject01 = [PSCustomObject]@{
'Licenses'       = $lic
}
$NewObject02.add($NewObject01)
}
Else
{
$NewObject01 = [PSCustomObject]@{
'Licenses'       = $textlic
}
$NewObject02.add($NewObject01)
}
}
Else
{
$NewObject01 = [PSCustomObject]@{
'Licenses'       = $Null
}
$NewObject02.add($NewObject01)
}
$ProxyAddresses = ($User | Select-Object -ExpandProperty ProxyAddresses)
If ($ProxyAddresses -ne $Null)
{
Foreach ($Proxy in $ProxyAddresses)
{
$ProxyB = $Proxy -split ":" | Select-Object -Last 1
$ProxyA.add($ProxyB)
}
$ProxyC = $ProxyA -join ", "
}
Else
{
$ProxyC = $Null
}
$Name = $User.DisplayName
$UPN = $User.UserPrincipalName
$UserLicenses = ($NewObject02 | Select-Object -ExpandProperty Licenses) -join ", "
$Enabled = $User.AccountEnabled
$UserTotalSize = ""
$LastLogon = ""
if($CheckMbxSize -eq "y"){
    If($User.ProvisionedPlans.Service -Contains "exchange"){
        $TotalSize = (Get-MailboxStatistics -Identity "$Name" | Select-Object -ExpandProperty TotalItemSize)
        $MBsize = ([math]::Round(($TotalSize.ToString().Split("(")[1].Split(" ")[0].Replace(",","")/1MB),2)).ToString('N0')
        $UserTotalSize = "$MBsize MB"
    }Else{
        $UserTotalSize = ""
    }
}else{
    $UserTotalSize = ""
    }
If ($IncludeLastLogonTimestamp -eq $True){
    If($User.ProvisionedPlans.Service -Contains "exchange"){
        $LastLogon = Get-Mailbox $User.DisplayName -ErrorAction SilentlyContinue | Get-MailboxStatistics -ErrorAction SilentlyContinue  | Select-Object -ExpandProperty LastLogonTime -ErrorAction SilentlyContinue
    }Else{
        $LastLogon = ""
    }
        If ($CheckMbxSize -eq "y"){
        $obj = [PSCustomObject]@{
            'Name'                                   = $Name
            'UserPrincipalName'                       = $UPN
            'Licenses'                               = $UserLicenses
            'Last Mailbox Logon'                   = $LastLogon
            'Enabled'                               = $Enabled
            'Mailbox Size (MB)'                       = $UserTotalSize
            'E-mail Addresses'                       = $ProxyC
            }  
    }Else{
        $obj = [PSCustomObject]@{
            'Name'                                   = $Name
            'UserPrincipalName'                       = $UPN
            'Licenses'                               = $UserLicenses
            'Last Mailbox Logon'                   = $LastLogon
            'Enabled'                               = $Enabled
            'E-mail Addresses'                       = $ProxyC
        }
    }
}
Else
{
    If ($CheckMbxSize -eq "y"){
        $obj = [PSCustomObject]@{
            'Name'                                   = $Name
            'UserPrincipalName'                       = $UPN
            'Licenses'                               = $UserLicenses
            'Enabled'                               = $Enabled
            'Mailbox Size (MB)'                       = $UserTotalSize
            'E-mail Addresses'                       = $ProxyC
            }  
    }Else{
        $obj = [PSCustomObject]@{
            'Name'                                   = $Name
            'UserPrincipalName'                       = $UPN
            'Licenses'                               = $UserLicenses
            'Enabled'                               = $Enabled
            'E-mail Addresses'                       = $ProxyC
        }
    }
}
$usertable.add($obj)
}
If (($usertable).count -eq 0)
{
$usertable = [PSCustomObject]@{
'Information'  = 'Information: No Users were found in the tenant'
}
}
Write-Host " Processing Shared Mailboxes.... Please Wait." -ForegroundColor Green
#Get all Shared Mailboxes
$SharedMailboxes = Get-Recipient -Resultsize unlimited | Where-Object { $_.RecipientTypeDetails -eq "SharedMailbox" }
Foreach ($SharedMailbox in $SharedMailboxes)
{
$ProxyA = New-Object 'System.Collections.Generic.List[System.Object]'
$Name = $SharedMailbox.Name
$PrimEmail = $SharedMailbox.PrimarySmtpAddress
$ProxyAddresses = ($SharedMailbox | Where-Object { $_.EmailAddresses -notlike "*$PrimEmail*" } | Select-Object -ExpandProperty EmailAddresses)
If ($ProxyAddresses -ne $Null)
{
Foreach ($ProxyAddress in $ProxyAddresses)
{
$ProxyB = $ProxyAddress -split ":" | Select-Object -Last 1
If ($ProxyB -eq $PrimEmail)
{
$ProxyB = $Null
}
$ProxyA.add($ProxyB)
$ProxyC = $ProxyA
}
}
Else
{
$ProxyC = $Null
}
$ProxyF = ($ProxyC -join ", ").TrimEnd(", ")
$SharedTotalSize = ""
if($CheckMbxSize -eq "y"){
        $TotalSize = (Get-MailboxStatistics -Identity "$Name" | Select-Object -ExpandProperty TotalItemSize)
        $MBsize = ([math]::Round(($TotalSize.ToString().Split("(")[1].Split(" ")[0].Replace(",","")/1MB),2)).ToString('N0')
        $SharedTotalSize = "$MBsize MB"
    }else{
        $SharedTotalSize = ""
    }
If ($CheckMbxSize -eq "y"){
    $obj = [PSCustomObject]@{
        'Name'                   = $Name
        'Primary E-Mail'       = $PrimEmail
        'Mailbox Size (MB)'       = $SharedTotalSize
        'E-mail Addresses'       = $ProxyF
    }
}Else{
    $obj = [PSCustomObject]@{
        'Name'                   = $Name
        'Primary E-Mail'       = $PrimEmail
        'E-mail Addresses'       = $ProxyF
        }
}
$SharedMailboxTable.add($obj)
}
If (($SharedMailboxTable).count -eq 0)
{
$SharedMailboxTable = [PSCustomObject]@{
'Information'  = 'Information: No Shared Mailboxes were found in the tenant'
}
}
Write-Host " Processing Contacts.... Please Wait." -ForegroundColor Green
#Get all Contacts
$Contacts = Get-MailContact
#Split licenses at colon
Foreach ($Contact in $Contacts)
{
$ContactName = $Contact.DisplayName
$ContactPrimEmail = $Contact.PrimarySmtpAddress
$objContact = [PSCustomObject]@{
'Name'                 = $ContactName
'E-mail Address'     = $ContactPrimEmail
}
$ContactTable.add($objContact)
}
If (($ContactTable).count -eq 0)
{
$ContactTable = [PSCustomObject]@{
'Information'  = 'Information: No Contacts were found in the tenant'
}
}
#Get all Mail Users
$MailUsers = Get-MailUser
foreach ($MailUser in $mailUsers)
{
$MailArray = New-Object 'System.Collections.Generic.List[System.Object]'
$MailPrimEmail = $MailUser.PrimarySmtpAddress
$MailName = $MailUser.DisplayName
$MailEmailAddresses = ($MailUser.EmailAddresses | Where-Object { $_ -cnotmatch '^SMTP' })
foreach ($MailEmailAddress in $MailEmailAddresses)
{
$MailEmailAddressSplit = $MailEmailAddress -split ":" | Select-Object -Last 1
$MailArray.add($MailEmailAddressSplit)
}
$UserEmails = $MailArray -join ", "
$obj = [PSCustomObject]@{
'Name'                   = $MailName
'Primary E-Mail'       = $MailPrimEmail
'E-mail Addresses'       = $UserEmails
}
$ContactMailUserTable.add($obj)
}
If (($ContactMailUserTable).count -eq 0)
{
$ContactMailUserTable = [PSCustomObject]@{
'Information'  = 'Information: No Mail Users were found in the tenant'
}
}
Write-Host " Processing Resources.... Please Wait." -ForegroundColor Green
$Rooms = Get-Mailbox -ResultSize Unlimited -Filter '(RecipientTypeDetails -eq "RoomMailBox")'
Foreach ($Room in $Rooms)
{
$RoomArray = New-Object 'System.Collections.Generic.List[System.Object]'
$RoomName = $Room.DisplayName
$RoomPrimEmail = $Room.PrimarySmtpAddress
$RoomEmails = ($Room.EmailAddresses | Where-Object { $_ -cnotmatch '^SMTP' })
foreach ($RoomEmail in $RoomEmails)
{
$RoomEmailSplit = $RoomEmail -split ":" | Select-Object -Last 1
$RoomArray.add($RoomEmailSplit)
}
$RoomEMailsF = $RoomArray -join ", "
$obj = [PSCustomObject]@{
'Name'                   = $RoomName
'Primary E-Mail'       = $RoomPrimEmail
'E-mail Addresses'       = $RoomEmailsF
}
$RoomTable.add($obj)
}
If (($RoomTable).count -eq 0)
{
$RoomTable = [PSCustomObject]@{
'Information'  = 'Information: No Room Mailboxes were found in the tenant'
}
}
$EquipMailboxes = Get-Mailbox -ResultSize Unlimited -Filter '(RecipientTypeDetails -eq "EquipmentMailBox")'
Foreach ($EquipMailbox in $EquipMailboxes)
{
$EquipArray = New-Object 'System.Collections.Generic.List[System.Object]'
$EquipName = $EquipMailbox.DisplayName
$EquipPrimEmail = $EquipMailbox.PrimarySmtpAddress
$EquipEmails = ($EquipMailbox.EmailAddresses | Where-Object { $_ -cnotmatch '^SMTP' })
foreach ($EquipEmail in $EquipEmails)
{
$EquipEmailSplit = $EquipEmail -split ":" | Select-Object -Last 1
$EquipArray.add($EquipEmailSplit)
}
$EquipEMailsF = $EquipArray -join ", "
$obj = [PSCustomObject]@{
'Name'                   = $EquipName
'Primary E-Mail'       = $EquipPrimEmail
'E-mail Addresses'       = $EquipEmailsF
}
$EquipTable.add($obj)
}
If (($EquipTable).count -eq 0)
{
$EquipTable = [PSCustomObject]@{
'Information'  = 'Information: No Equipment Mailboxes were found in the tenant'
}
}
Write-Host "Generating Report File.... Please Wait." -ForegroundColor Green
$tabarray = @('Dashboard','Groups', 'Licenses', 'Users', 'Shared Mailboxes', 'Contacts', 'Resources')
#basic Properties
$PieObject2 = Get-HTMLPieChartObject
$PieObject2.Title = "Office 365 Total Licenses"
$PieObject2.Size.Height = 250
$PieObject2.Size.width = 250
$PieObject2.ChartStyle.ChartType = 'doughnut'
#These file exist in the module directoy, There are 4 schemes by default
$PieObject2.ChartStyle.ColorSchemeName = "ColorScheme4"
#There are 8 generated schemes, randomly generated at runtime
$PieObject2.ChartStyle.ColorSchemeName = "Generated7"
#you can also ask for a random scheme. Which also happens if you have too many records for the scheme
$PieObject2.ChartStyle.ColorSchemeName = 'Random'
#Data defintion you can reference any column from name and value from the dataset.
#Name and Count are the default to work with the Group func.
$PieObject2.DataDefinition.DataNameColumnName = 'Name'
$PieObject2.DataDefinition.DataValueColumnName = 'Total Amount'
#basic Properties
$PieObject3 = Get-HTMLPieChartObject
$PieObject3.Title = "Office 365 Assigned Licenses"
$PieObject3.Size.Height = 250
$PieObject3.Size.width = 250
$PieObject3.ChartStyle.ChartType = 'doughnut'
#These file exist in the module directoy, There are 4 schemes by default
$PieObject3.ChartStyle.ColorSchemeName = "ColorScheme4"
#There are 8 generated schemes, randomly generated at runtime
$PieObject3.ChartStyle.ColorSchemeName = "Generated5"
#you can also ask for a random scheme. Which also happens if you have too many records for the scheme
$PieObject3.ChartStyle.ColorSchemeName = 'Random'
#Data defintion you can reference any column from name and value from the dataset.
#Name and Count are the default to work with the Group func.
$PieObject3.DataDefinition.DataNameColumnName = 'Name'
$PieObject3.DataDefinition.DataValueColumnName = 'Assigned Licenses'
#basic Properties
$PieObject4 = Get-HTMLPieChartObject
$PieObject4.Title = "Office 365 Unassigned Licenses"
$PieObject4.Size.Height = 250
$PieObject4.Size.width = 250
$PieObject4.ChartStyle.ChartType = 'doughnut'
#These file exist in the module directoy, There are 4 schemes by default
$PieObject4.ChartStyle.ColorSchemeName = "ColorScheme4"
#There are 8 generated schemes, randomly generated at runtime
$PieObject4.ChartStyle.ColorSchemeName = "Generated4"
#you can also ask for a random scheme. Which also happens if you have too many records for the scheme
$PieObject4.ChartStyle.ColorSchemeName = 'Random'
#Data defintion you can reference any column from name and value from the dataset.
#Name and Count are the default to work with the Group func.
$PieObject4.DataDefinition.DataNameColumnName = 'Name'
$PieObject4.DataDefinition.DataValueColumnName = 'Unassigned Licenses'
#basic Properties
$PieObjectGroupType = Get-HTMLPieChartObject
$PieObjectGroupType.Title = "Office 365 Groups"
$PieObjectGroupType.Size.Height = 250
$PieObjectGroupType.Size.width = 250
$PieObjectGroupType.ChartStyle.ChartType = 'doughnut'
#These file exist in the module directoy, There are 4 schemes by default
$PieObjectGroupType.ChartStyle.ColorSchemeName = "ColorScheme4"
#There are 8 generated schemes, randomly generated at runtime
$PieObjectGroupType.ChartStyle.ColorSchemeName = "Generated8"
#you can also ask for a random scheme. Which also happens if you have too many records for the scheme
$PieObjectGroupType.ChartStyle.ColorSchemeName = 'Random'
#Data defintion you can reference any column from name and value from the dataset.
#Name and Count are the default to work with the Group func.
$PieObjectGroupType.DataDefinition.DataNameColumnName = 'Name'
$PieObjectGroupType.DataDefinition.DataValueColumnName = 'Count'
##--LICENSED AND UNLICENSED USERS PIE CHART--##
#basic Properties
$PieObjectULicense = Get-HTMLPieChartObject
$PieObjectULicense.Title = "License Status"
$PieObjectULicense.Size.Height = 250
$PieObjectULicense.Size.width = 250
$PieObjectULicense.ChartStyle.ChartType = 'doughnut'
#These file exist in the module directoy, There are 4 schemes by default
$PieObjectULicense.ChartStyle.ColorSchemeName = "ColorScheme3"
#There are 8 generated schemes, randomly generated at runtime
$PieObjectULicense.ChartStyle.ColorSchemeName = "Generated3"
#you can also ask for a random scheme. Which also happens if you have too many records for the scheme
$PieObjectULicense.ChartStyle.ColorSchemeName = 'Random'
#Data defintion you can reference any column from name and value from the dataset.
#Name and Count are the default to work with the Group func.
$PieObjectULicense.DataDefinition.DataNameColumnName = 'Name'
$PieObjectULicense.DataDefinition.DataValueColumnName = 'Count'
$rpt = New-Object 'System.Collections.Generic.List[System.Object]'
$rpt += get-htmlopenpage -TitleText ("Office 365 Tenant Report - " + $CompanyName) -LeftLogoString $CompanyLogo -RightLogoString $RightLogo 
$rpt += Get-HTMLTabHeader -TabNames $tabarray 
$rpt += get-htmltabcontentopen -TabName $tabarray[0] -TabHeading ("Report: " + (Get-Date -Format MM-dd-yyyy))
$rpt+= Get-HtmlContentOpen -HeaderText "Office 365 Dashboard"
$rpt += Get-HTMLContentOpen -HeaderText "Company Information"
$rpt += Get-HtmlContentTable $CompanyInfoTable 
$rpt += Get-HTMLContentClose
$rpt+= get-HtmlColumn1of2
$rpt+= Get-HtmlContentOpen -BackgroundShade 1 -HeaderText 'Global Administrators'
$rpt+= get-htmlcontentdatatable  $GlobalAdminTable -HideFooter
$rpt+= Get-HtmlContentClose
$rpt+= get-htmlColumnClose
$rpt+= get-htmlColumn2of2
$rpt+= Get-HtmlContentOpen -HeaderText 'Users With Strong Password Enforcement Disabled'
$rpt+= get-htmlcontentdatatable $StrongPasswordTable -HideFooter 
$rpt+= Get-HtmlContentClose
$rpt+= get-htmlColumnClose
$rpt += Get-HTMLContentOpen -HeaderText "Recent E-Mails"
$rpt += Get-HTMLContentDataTable $MessageTraceTable -HideFooter
$rpt += Get-HTMLContentClose
$rpt += Get-HTMLContentOpen -HeaderText "Domains"
$rpt += Get-HtmlContentTable $DomainTable 
$rpt += Get-HTMLContentClose
$rpt+= Get-HtmlContentClose 
$rpt += get-htmltabcontentclose
$rpt += get-htmltabcontentopen -TabName $tabarray[1] -TabHeading ("Report: " + (Get-Date -Format MM-dd-yyyy))
$rpt += Get-HTMLContentOpen -HeaderText "Office 365 Groups"
$rpt += get-htmlcontentdatatable $Table -HideFooter
$rpt += Get-HTMLContentClose
$rpt += Get-HTMLContentOpen -HeaderText "Office 365 Groups Chart"
$rpt += Get-HTMLPieChart -ChartObject $PieObjectGroupType -DataSet $GroupTypetable
$rpt += Get-HTMLContentClose
$rpt += get-htmltabcontentclose
$rpt += get-htmltabcontentopen -TabName $tabarray[2]  -TabHeading ("Report: " + (Get-Date -Format MM-dd-yyyy))
$rpt += Get-HTMLContentOpen -HeaderText "Office 365 Licenses"
$rpt += get-htmlcontentdatatable $LicenseTable -HideFooter
$rpt += Get-HTMLContentClose
$rpt += Get-HTMLContentOpen -HeaderText "Office 365 Licensing Charts"
$rpt += Get-HTMLColumnOpen -ColumnNumber 1 -ColumnCount 2
$rpt += Get-HTMLPieChart -ChartObject $PieObject2 -DataSet $licensetable
$rpt += Get-HTMLColumnClose
$rpt += Get-HTMLColumnOpen -ColumnNumber 2 -ColumnCount 2
$rpt += Get-HTMLPieChart -ChartObject $PieObject3 -DataSet $licensetable
$rpt += Get-HTMLColumnClose
$rpt += Get-HTMLContentclose
$rpt += get-htmltabcontentclose
$rpt += get-htmltabcontentopen -TabName $tabarray[3] -TabHeading ("Report: " + (Get-Date -Format MM-dd-yyyy))
$rpt += Get-HTMLContentOpen -HeaderText "Office 365 Users"
$rpt += get-htmlcontentdatatable $UserTable -HideFooter
$rpt += Get-HTMLContentClose
$rpt += Get-HTMLContentOpen -HeaderText "Licensed & Unlicensed Users Chart"
$rpt += Get-HTMLPieChart -ChartObject $PieObjectULicense -DataSet $IsLicensedUsersTable
$rpt += Get-HTMLContentClose
$rpt += get-htmltabcontentclose
$rpt += get-htmltabcontentopen -TabName $tabarray[4] -TabHeading ("Report: " + (Get-Date -Format MM-dd-yyyy)) 
$rpt += Get-HTMLContentOpen -HeaderText "Office 365 Shared Mailboxes"
$rpt += get-htmlcontentdatatable $SharedMailboxTable -HideFooter
$rpt += Get-HTMLContentClose
$rpt += get-htmltabcontentclose
$rpt += get-htmltabcontentopen -TabName $tabarray[5] -TabHeading ("Report: " + (Get-Date -Format MM-dd-yyyy)) 
$rpt += Get-HTMLContentOpen -HeaderText "Office 365 Contacts"
$rpt += get-htmlcontentdatatable $ContactTable -HideFooter
$rpt += Get-HTMLContentClose
$rpt += Get-HTMLContentOpen -HeaderText "Office 365 Mail Users"
$rpt += get-htmlcontentdatatable $ContactMailUserTable -HideFooter
$rpt += Get-HTMLContentClose
$rpt += get-htmltabcontentclose
$rpt += get-htmltabcontentopen -TabName $tabarray[6] -TabHeading ("Report: " + (Get-Date -Format MM-dd-yyyy)) 
$rpt += Get-HTMLContentOpen -HeaderText "Office 365 Room Mailboxes"
$rpt += get-htmlcontentdatatable $RoomTable -HideFooter
$rpt += Get-HTMLContentClose
$rpt += Get-HTMLContentOpen -HeaderText "Office 365 Equipment Mailboxes"
$rpt += get-htmlcontentdatatable $EquipTable -HideFooter
$rpt += Get-HTMLContentClose
$rpt += get-htmltabcontentclose
$rpt += Get-HTMLClosePage
$Day = (Get-Date).Day
$Month = (Get-Date).Month
$Year = (Get-Date).Year
$Date1 = Get-Date -Format "MM-dd-yyyy HH-mm"
$ReportName = ("$CompanyName" + " - O365 Tenant Report - " + "$Date1")
Save-HTMLReport -ReportContent $rpt -ShowReport -ReportName $ReportName -ReportPath $ReportSavePath
Write-Host
Write-Host " Report Saved in Downloads Folder:" -ForegroundColor Yellow
Write-Host " $ReportName.html" -ForegroundColor Green
Write-Host
Write-Host
Get-Commands
}
function New-365Report
{
#Description: Report on O365 tenant objects & generate migration scripts
$Sku = @{
  "O365_BUSINESS_ESSENTIALS"      = "Office 365 Business Essentials"
  "O365_BUSINESS_PREMIUM"      = "Office 365 Business Premium"
  "DESKLESSPACK"      = "Office 365 (Plan K1)"
  "DESKLESSWOFFPACK"      = "Office 365 (Plan K2)"
  "LITEPACK"      = "Office 365 (Plan P1)"
  "EXCHANGESTANDARD"      = "Office 365 Exchange Online Only"
  "STANDARDPACK"      = "Office 365 E1"
  "STANDARDWOFFPACK"      = "Office 365 (Plan E2)"
  "ENTERPRISEPACK" = "Office 365 E3"
  "ENTERPRISEPACKLRG"      = "Office 365 E3"
  "ENTERPRISEWITHSCAL" = "Office 365 E4"
  "STANDARDPACK_STUDENT"      = "Office 365 (Plan A1) for Students"
  "STANDARDWOFFPACKPACK_STUDENT"      = "Office 365 (Plan A2) for Students"
  "ENTERPRISEPACK_STUDENT" = "Office 365 (Plan A3) for Students"
  "ENTERPRISEWITHSCAL_STUDENT" = "Office 365 (Plan A4) for Students"
  "STANDARDPACK_FACULTY"      = "Office 365 (Plan A1) for Faculty"
  "STANDARDWOFFPACKPACK_FACULTY"      = "Office 365 (Plan A2) for Faculty"
  "ENTERPRISEPACK_FACULTY" = "Office 365 (Plan A3) for Faculty"
  "ENTERPRISEWITHSCAL_FACULTY" = "Office 365 (Plan A4) for Faculty"
  "ENTERPRISEPACK_B_PILOT" = "Office 365 (Enterprise Preview)"
  "STANDARD_B_PILOT"      = "Office 365 (Small Business Preview)"
  "VISIOCLIENT"      = "Visio Pro Online"
  "POWER_BI_ADDON" = "Office 365 Power BI Addon"
  "POWER_BI_INDIVIDUAL_USE"      = "Power BI Individual User"
  "POWER_BI_STANDALONE"      = "Power BI Stand Alone"
  "POWER_BI_STANDARD"      = "Power-BI Standard"
  "PROJECTESSENTIALS"      = "Project Lite"
  "PROJECTCLIENT"      = "Project Professional"
  "PROJECTONLINE_PLAN_1"      = "Project Online"
  "PROJECTONLINE_PLAN_2"      = "Project Online and PRO"
  "ProjectPremium" = "Project Online Premium"
  "ECAL_SERVICES"      = "ECAL"
  "EMS"      = "Enterprise Mobility Suite"
  "RIGHTSMANAGEMENT_ADHOC" = "Windows Azure Rights Management"
  "MCOMEETADV" = "PSTN conferencing"
  "SHAREPOINTSTORAGE"      = "SharePoint storage"
  "PLANNERSTANDALONE"      = "Planner Standalone"
  "CRMIUR" = "CMRIUR"
  "BI_AZURE_P1"      = "Power BI Reporting and Analytics"
  "INTUNE_A"      = "Windows Intune Plan A"
  "PROJECTWORKMANAGEMENT"      = "Office 365 Planner Preview"
  "ATP_ENTERPRISE" = "Exchange Online Advanced Threat Protection"
  "EQUIVIO_ANALYTICS"      = "Office 365 Advanced eDiscovery"
  "AAD_BASIC"      = "Azure Active Directory Basic"
  "RMS_S_ENTERPRISE"      = "Azure Active Directory Rights Management"
  "AAD_PREMIUM"      = "Azure Active Directory Premium"
  "MFA_PREMIUM"      = "Azure Multi-Factor Authentication"
  "STANDARDPACK_GOV"      = "Microsoft Office 365 (Plan G1) for Government"
  "STANDARDWOFFPACK_GOV"      = "Microsoft Office 365 (Plan G2) for Government"
  "ENTERPRISEPACK_GOV" = "Microsoft Office 365 (Plan G3) for Government"
  "ENTERPRISEWITHSCAL_GOV" = "Microsoft Office 365 (Plan G4) for Government"
  "DESKLESSPACK_GOV"      = "Microsoft Office 365 (Plan K1) for Government"
  "ESKLESSWOFFPACK_GOV"      = "Microsoft Office 365 (Plan K2) for Government"
  "EXCHANGESTANDARD_GOV"      = "Microsoft Office 365 Exchange Online (Plan 1) only for Government"
  "EXCHANGEENTERPRISE_GOV" = "Microsoft Office 365 Exchange Online (Plan 2) only for Government"
  "SHAREPOINTDESKLESS_GOV" = "SharePoint Online Kiosk"
  "EXCHANGE_S_DESKLESS_GOV"      = "Exchange Kiosk"
  "RMS_S_ENTERPRISE_GOV"      = "Windows Azure Active Directory Rights Management"
  "OFFICESUBSCRIPTION_GOV" = "Office ProPlus"
  "MCOSTANDARD_GOV"      = "Lync Plan 2G"
  "SHAREPOINTWAC_GOV"      = "Office Online for Government"
  "SHAREPOINTENTERPRISE_GOV"      = "SharePoint Plan 2G"
  "EXCHANGE_S_ENTERPRISE_GOV"      = "Exchange Plan 2G"
  "EXCHANGE_S_ARCHIVE_ADDON_GOV"      = "Exchange Online Archiving"
  "EXCHANGE_S_DESKLESS"      = "Exchange Online Kiosk"
  "SHAREPOINTDESKLESS" = "SharePoint Online Kiosk"
  "SHAREPOINTWAC"      = "Office Online"
  "YAMMER_ENTERPRISE"      = "Yammer Enterprise"
  "EXCHANGE_L_STANDARD"      = "Exchange Online (Plan 1)"
  "MCOLITE"      = "Lync Online (Plan 1)"
  "SHAREPOINTLITE" = "SharePoint Online (Plan 1)"
  "OFFICE_PRO_PLUS_SUBSCRIPTION_SMBIZ" = "Office ProPlus"
  "EXCHANGE_S_STANDARD_MIDMARKET"      = "Exchange Online (Plan 1)"
  "MCOSTANDARD_MIDMARKET"      = "Lync Online (Plan 1)"
  "SHAREPOINTENTERPRISE_MIDMARKET" = "SharePoint Online (Plan 1)"
  "OFFICESUBSCRIPTION" = "Office ProPlus"
  "YAMMER_MIDSIZE" = "Yammer"
  "DYN365_ENTERPRISE_PLAN1"      = "Dynamics 365 Customer Engagement Plan Enterprise Edition"
  "ENTERPRISEPREMIUM_NOPSTNCONF"      = "Enterprise E5 (without Audio Conferencing)"
  "ENTERPRISEPREMIUM"      = "Enterprise E5 (with Audio Conferencing)"
  "MCOSTANDARD"      = "Skype for Business Online Standalone Plan 2"
  "PROJECT_MADEIRA_PREVIEW_IW_SKU" = "Dynamics 365 for Financials for IWs"
  "STANDARDWOFFPACK_IW_STUDENT"      = "Office 365 Education for Students"
  "STANDARDWOFFPACK_IW_FACULTY"      = "Office 365 Education for Faculty"
  "EOP_ENTERPRISE_FACULTY" = "Exchange Online Protection for Faculty"
  "EXCHANGESTANDARD_STUDENT"      = "Exchange Online (Plan 1) for Students"
  "OFFICESUBSCRIPTION_STUDENT" = "Office ProPlus Student Benefit"
  "STANDARDWOFFPACK_FACULTY"      = "Office 365 Education E1 for Faculty"
  "STANDARDWOFFPACK_STUDENT"      = "Microsoft Office 365 (Plan A2) for Students"
  "DYN365_FINANCIALS_BUSINESS_SKU" = "Dynamics 365 for Financials Business Edition"
  "DYN365_FINANCIALS_TEAM_MEMBERS_SKU" = "Dynamics 365 for Team Members Business Edition"
  "FLOW_FREE"      = "Microsoft Flow Free"
  "POWER_BI_PRO"      = "Power BI Pro"
  "O365_BUSINESS"      = "Office 365 Business"
  "DYN365_ENTERPRISE_SALES"      = "Dynamics Office 365 Enterprise Sales"
  "RIGHTSMANAGEMENT"      = "Rights Management"
  "PROJECTPROFESSIONAL"      = "Project Professional"
  "VISIOONLINE_PLAN1"      = "Visio Online Plan 1"
  "EXCHANGEENTERPRISE" = "Exchange Online Plan 2"
  "DYN365_ENTERPRISE_P1_IW"      = "Dynamics 365 P1 Trial for Information Workers"
  "DYN365_ENTERPRISE_TEAM_MEMBERS" = "Dynamics 365 For Team Members Enterprise Edition"
  "CRMSTANDARD"      = "Microsoft Dynamics CRM Online Professional"
  "EXCHANGEARCHIVE_ADDON"      = "Exchange Online Archiving For Exchange Online"
  "EXCHANGEDESKLESS"      = "Exchange Online Kiosk"
  "SPZA_IW"      = "App Connect"
  "WINDOWS_STORE"      = "Windows Store for Business"
  "MCOEV"      = "Microsoft Phone System"
  "VIDEO_INTEROP"      = "Polycom Skype Meeting Video Interop for Skype for Business"
  "SPE_E5" = "Microsoft 365 E5"
  "SPE_E3" = "Microsoft 365 E3"
  "ATA"      = "Advanced Threat Analytics"
  "MCOPSTN2"      = "Domestic and International Calling Plan"
  "FLOW_P1"      = "Microsoft Flow Plan 1"
  "FLOW_P2"      = "Microsoft Flow Plan 2"
  "CRMSTORAGE" = "Microsoft Dynamics CRM Online Additional Storage"
  "SMB_APPS"      = "Microsoft Business Apps"
  "MICROSOFT_BUSINESS_CENTER"      = "Microsoft Business Center"
  "DYN365_TEAM_MEMBERS"      = "Dynamics 365 Team Members"
  "STREAM" = "Microsoft Stream Trial"
  "EMSPREMIUM"                         = "ENTERPRISE MOBILITY + SECURITY E5"
  "SPB" = "Microsoft 365 Business"
  "MCOPSTN1" = "Domestic Calling Plan"
  "MEETING_ROOM" = "Teams Meeting Room"
  "POWERAPPS_PER_APP_IW" = "PowerApps Per App"
  "TEAMS_COMMERCIAL_TRIAL" = "Microsoft Teams"
  "POWERAPPS_PER_USER" = "PowerApps Per User"
  "FLOW_PER_USER" = "PowerAutomate Per User"
  "POWERFLOW_P1" = "Flow P1"
 }
 $PrimaryLicenses = @(
    'Office 365 Business Essentials',
    'Office 365 Business Premium',
    'Office 365 (Plan K1)',
    'Office 365 (Plan K2)',
    'Office 365 (Plan P1)',
    'Office 365 Exchange Online Only',
    'Office 365 E1',
    'Office 365 (Plan E2)',
    'Office 365 E3',
    'Office 365 E4',
    'Office 365 (Plan A1) for Students',
    'Office 365 (Plan A2) for Students',
    'Office 365 (Plan A3) for Students',
    'Office 365 (Plan A4) for Students',
    'Office 365 (Plan A1) for Faculty',
    'Office 365 (Plan A2) for Faculty',
    'Office 365 (Plan A3) for Faculty',
    'Office 365 (Plan A4) for Faculty',
    'Office 365 (Enterprise Preview)',
    'Office 365 (Small Business Preview)',
    'Microsoft Office 365 (Plan G1) for Government',
    'Microsoft Office 365 (Plan G2) for Government',
    'Microsoft Office 365 (Plan G3) for Government',
    'Microsoft Office 365 (Plan G4) for Government',
    'Microsoft Office 365 (Plan K1) for Government',
    'Microsoft Office 365 (Plan K2) for Government',
    'Office ProPlus',
    'Enterprise E5 (without Audio Conferencing)',
    'Enterprise E5 (with Audio Conferencing)',
    'Office 365 Education E1 for Faculty',
    'Microsoft Office 365 (Plan A2) for Students',
    'Office 365 Business',
    'Microsoft 365 E5',
    'Microsoft 365 E3',
    'Microsoft 365 Business',
    'Teams Meeting Room'
)
#Check if connected to a tenant
if (Get-Module -ListAvailable -Name AzureAD) {
}
else {
    Install-Module AzureAD -Confirm:$False -Force
}
if (Get-Module -ListAvailable -Name MsOnline) {
}
else {
    Install-Module MsOnline -Confirm:$False -Force
}

Write-Host ""
Write-Host ""
Write-Host "============================================" -ForegroundColor Yellow
Write-Host "Welcome to the Office 365 Report Builder!" -ForegroundColor Yellow
Write-Host " Starting module connection checks." -ForegroundColor Yellow
Write-Host "============================================" -ForegroundColor Yellow
try
{ $var = Get-AzureADTenantDetail }

catch [Microsoft.Open.Azure.AD.CommonLibrary.AadNeedAuthenticationException]
{$credential = Get-Credential -Message "Please enter your Office 365 credentials" -ForegroundColor Yellow
Import-Module MsOnline
Connect-AzureAD -Credential $credential
Connect-MsolService -Credential $credential
$exchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://outlook.office365.com/powershell-liveid/" -Credential $credential -Authentication "Basic" -AllowRedirection
Import-PSSession $exchangeSession -AllowClobber
}
$CreateUsers = ""
$CreateGroups = ""
$CreateShared = ""
$CreateResources = ""
$CreateDomains = ""
$CreateScripts = ""
$CreateAllReports = ""
$CreateContacts = ""
$MigrationTF = ""
$CheckOneDrive = ""
$CreateGroupScripts = ""
Write-Host ""
Write-Host ""
Write-Host "Connected to Azure and Exchange Online!" -ForegroundColor Yellow

Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host "========================================================" -ForegroundColor Yellow
Write-Host "Identify the Module Reports to generate." -ForegroundColor Yellow
Write-Host "========================================================" -ForegroundColor Yellow
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host "Generate All Reports?" -ForegroundColor Yellow
Write-Host "Including Users, Groups, Shared Mailboxes, Resource Mailboxes, Contacts, & Domains" -ForegroundColor Yellow
Write-Host ""
Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
$CreateAllReports = Read-Host "[y/n]"
If ($CreateAllReports -eq "y")
  {
    Write-Host ""
    Write-Host ""
    Write-Host "Check Mailbox Size?" -ForegroundColor Yellow
    Write-Host ""
    Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
    $CheckMbxSize = Read-Host "[y/n]"
    Write-Host ""
    Write-Host ""
    Write-Host "Check Archive Size?" -ForegroundColor Yellow
    Write-Host ""
    Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
    $CheckArchive = Read-Host "[y/n]"
    Write-Host ""
    Write-Host ""
    Write-Host "Check Mailbox Full Access Permissions? This will increase report time." -ForegroundColor Yellow
    Write-Host ""
    Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
    $MailboxPermissionsGet = Read-Host "[y/n]"
    Write-Host ""
    Write-Host "Check OneDrive Storage Usage? This will increase report time." -ForegroundColor Yellow
    Write-Host ""
    Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
    $CheckOneDrive = Read-Host "[y/n]"
    Write-Host ""
    Write-Host ""

    if($CheckOneDrive -eq "y"){
      Write-Host "Enter Tenant Name (Found in <Tenant Name>.onmicrosoft.com)" -ForegroundColor Yellow
      $TenantName = Read-Host "Name"
    if (Get-Module -ListAvailable -Name Microsoft.Online.SharePoint.PowerShell) {
    Write-Host "SharePoint Module Installed!" -ForegroundColor Yellow
    }
    else {
    Write-Host "Installing SharePoint Module!" -ForegroundColor Yellow
        Install-Module -Name Microsoft.Online.SharePoint.PowerShell -Confirm:$False -Force
    }
    try
    { $var = Get-SPOsite

    Write-Host ""
    Write-Host ""
    Write-Host "Connected to SharePoint Online!" -ForegroundColor Yellow
    }
    catch
    {
      Write-Host ""
      Write-Host ""
      Write-Host "Connecting to SharePoint Online..." -ForegroundColor Yellow
      Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
      Connect-SPOService -Url https://$TenantName-admin.sharepoint.com -credential $credential
      Write-Host ""
      Write-Host "Connected!" -ForegroundColor Yellow
      Write-Host ""
      Write-Host "========================================================" -ForegroundColor Yellow
    }
    }
    Write-Host ""
    Write-Host ""
    Write-Host "Check Shared Mailbox Full Access Permissions? This will increase report time." -ForegroundColor Yellow
    Write-Host ""
    Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
    $SharedPermissionsGet = Read-Host "[y/n]"
    $CreateUsers = "y"
    $CreateGroups = "y"
    $CreateShared = "y"
    $CreateResources = "y"
    $CreateDomains = "y"
    $CreateScripts = ""
    $CreateContacts = "y"
    Write-Host ""
    Write-Host ""
    Write-Host ""
    Write-Host "Generate scripts to perform a migration to another Office 365 Tenant?" -ForegroundColor Yellow
    Write-Host ""
    Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
    $CreateScripts = Read-Host "[y/n]"
    Write-Host ""
    If ($CreateScripts -eq "y")
    {
      Write-Host "Please enter the @<domain>.onmicrosoft.com prefix name for destination Tenant" -ForegroundColor Yellow
      Write-Host "(ex: 'comp123' for comp123.onmicrosoft.com)" -ForegroundColor Yellow
      $MigrationOMSFT = Read-Host "Prefix Name"
      Write-Host ""
      Write-Host "Enter the full default email & username domain users should have in destination Tenant" -ForegroundColor Yellow
      Write-Host "(ex: company.com)" -ForegroundColor Yellow
      $MigrationPrimeDomain = Read-Host "Default Domain"
      $CreateGroupScripts = "y"
    }
  }Else
  {
    $CreateUsers = ""
    $CreateGroups = ""
    $CreateShared = ""
    $CreateResources = ""
    $CreateDomains = ""
    $CreateScripts = ""
    $CreateContacts = ""
    $MigrationTF = ""
    $CheckOneDrive = ""
    $CreateGroupScripts = ""
    Write-Host ""
    Write-Host "========================================================" -ForegroundColor Yellow
    Write-Host "Specify Indivudal Module Reports" -ForegroundColor Yellow
    Write-Host "========================================================" -ForegroundColor Yellow
    Write-Host ""
    Write-Host "Generate report for Users?" -ForegroundColor Yellow
    Write-Host ""
    Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
    $CreateUsers = Read-Host "[y/n]"
    If($CreateUsers -eq "y")
    {
      Write-Host ""
      Write-Host ""
      Write-Host "Check Mailbox Size?" -ForegroundColor Yellow
      Write-Host ""
      Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
      $CheckMbxSize = Read-Host "[y/n]"
      Write-Host ""
      Write-Host ""
      Write-Host "Check Archive Size?" -ForegroundColor Yellow
      Write-Host ""
      Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
      $CheckArchive = Read-Host "[y/n]"
      Write-Host ""
      Write-Host ""
      Write-Host "Check Mailbox Full Access Permissions? This will increase report time." -ForegroundColor Yellow
      Write-Host ""
      Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
      $MailboxPermissionsGet = Read-Host "[y/n]"
    Write-Host ""
    Write-Host ""
    Write-Host "Check OneDrive Storage Usage? This will increase time when parsing Users." -ForegroundColor Yellow
    Write-Host ""
    Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
    $CheckOneDrive = Read-Host "[y/n]"
    Write-Host ""

    if($CheckOneDrive -eq "y"){
      Write-Host "<> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <>" -ForegroundColor Yellow
      Write-Host "OneDrive Connection Info:" -ForegroundColor Yellow
      Write-Host "Enter Tenant Name (Found in <Tenant Name>.onmicrosoft.com)" -ForegroundColor Yellow
      $TenantName = Read-Host "Name"
    if (Get-Module -ListAvailable -Name Microsoft.Online.SharePoint.PowerShell) {
    Write-Host "SharePoint Module Installed!" -ForegroundColor Yellow
    }
    else {
    Write-Host "Installing SharePoint Module!" -ForegroundColor Yellow
        Install-Module -Name Microsoft.Online.SharePoint.PowerShell -Confirm:$False -Force
    }
    try
    { $var = Get-SPOsite

    Write-Host ""
    Write-Host ""
    Write-Host "Connected to SharePoint Online!" -ForegroundColor Yellow
    }
    catch
    {
      Write-Host ""
      Write-Host ""
      Write-Host "Connecting to SharePoint Online..." -ForegroundColor Yellow
      Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
      Connect-SPOService -Url https://$TenantName-admin.sharepoint.com -credential $credential
      Write-Host ""
      Write-Host "Connected!" -ForegroundColor Yellow
      Write-Host ""
      Write-Host "========================================================" -ForegroundColor Yellow
    }
    }
    }

    Write-Host ""
    Write-Host ""
    Write-Host "Generate report for Groups?" -ForegroundColor Yellow
    Write-Host ""
    Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
    $CreateGroups = Read-Host "[y/n]"
    if($CreateGroups -eq "y"){
      Write-Host ""
      Write-Host "Create Group Migration Scripts?" -ForegroundColor Yellow
      Write-Host ""
      Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
      $CreateGroupScripts = Read-Host "[y/n]"
      Write-Host ""
      Write-Host ""
    }
    Write-Host ""
    Write-Host ""
    Write-Host "Generate report for Shared Mailboxes?" -ForegroundColor Yellow
    Write-Host ""
    Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
    $CreateShared = Read-Host "[y/n]"
    If($CreateShared -eq "y"){
      Write-Host ""
      Write-Host ""
      Write-Host "Check Shared Mailbox Full Access Permissions? This will increase report time." -ForegroundColor Yellow
      Write-Host ""
      Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
      $SharedPermissionsGet = Read-Host "[y/n]"
    }
    Write-Host ""
    Write-Host ""
    Write-Host "Generate report for Resource Mailboxes?" -ForegroundColor Yellow
    Write-Host ""
    Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
    $CreateResources = Read-Host "[y/n]"
    Write-Host ""
    Write-Host ""
    Write-Host "Generate report for Contacts?" -ForegroundColor Yellow
    Write-Host ""
    Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
    $CreateContacts = Read-Host "[y/n]"
    Write-Host ""
    Write-Host ""
    Write-Host "Generate report for Domains?" -ForegroundColor Yellow
    Write-Host ""
    Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
    $CreateDomains = Read-Host "[y/n]"
    Write-Host ""
    Write-Host ""
    Write-Host "Generate scripts to perform a migration to another Office 365 Tenant?" -ForegroundColor Yellow
    Write-Host ""
    Write-Host "Type y for Yes, n for No" -ForegroundColor Yellow
    $CreateScripts = Read-Host "[y/n]"
    Write-Host ""
    If ($CreateScripts -eq "y")
    {
      Write-Host "Please enter the @<domain>.onmicrosoft.com prefix name for destination Tenant." -ForegroundColor Yellow
      Write-Host "(ex: company123 for company123.onmicrosoft.com)" -ForegroundColor Yellow
      $MigrationOMSFT = Read-Host "Prefix Name"
      Write-Host ""
      Write-Host "Enter the full default email & username domain users should have in destination Tenant" -ForegroundColor Yellow
      Write-Host "(ex: company.com)" -ForegroundColor Yellow
      $MigrationPrimeDomain = Read-Host "Default Domain"
    }
}
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""

$TenantDisplay = Get-AzureAdTenantDetail | Select -ExpandProperty DisplayName
$Date1 = Get-Date -Format "MM-dd-yyyy HH-mm"
$SelectedReports = ""
if($CreateUsers -eq "y"){
  $SelectedReports = -join ($SelectedReports," Users -")
}
if($CreateGroups -eq "y"){
  $SelectedReports = -join ($SelectedReports," Groups -")
}
if($CreateShared -eq "y"){
  $SelectedReports = -join ($SelectedReports," Shared -")
}
if($CreateResources -eq "y"){
  $SelectedReports = -join ($SelectedReports," Resources -")
}
if($CreateContacts -eq "y"){
  $SelectedReports = -join ($SelectedReports," Contacts -")
}
if($CreateDomains -eq "y"){
  $SelectedReports = -join ($SelectedReports," Domains -")
}
if($CreateScripts -eq "y"){
  $SelectedReports = -join ($SelectedReports," Scripts -")
}

$FileName = "$TenantDisplay -$SelectedReports $Date1.csv"
$OutputPath = "$home\Downloads\$FileName"
$CSVpath = $OutputPath

$XFileName = "$TenantDisplay -$SelectedReports $Date1.xlsx"
$XOutputPath = "$home\Downloads\$XFileName"
$XLSpath = $XOutputPath


$excel = New-Object -ComObject Excel.Application
#Create the workbook
$workbook = $excel.Workbooks.Add()
$workbook.SaveAs($XOutputPath)
$InitalWorksheet = $workbook.Worksheets.Item(1)
$InitalWorksheet.Name = "Generating"
#$Worksheet = $Workbook.Worksheets.Add()
#$Worksheet.Name = "Public Folders"
if($CreateScripts -eq "y"){
$Worksheet = $Workbook.Worksheets.Add()
$Worksheet.Name = "Scripts"
$Sheet_Scripts = $Workbook.Worksheets.Item("Scripts")
}
if($CreateDomains -eq "y"){
$Worksheet = $Workbook.Worksheets.Add()
$Worksheet.Name = "Domains"
$Sheet_Domains = $Workbook.Worksheets.Item("Domains")
}
if($CreateResources -eq "y"){
$Worksheet = $Workbook.Worksheets.Add()
$Worksheet.Name = "Resources"
$Sheet_Resources = $Workbook.Worksheets.Item("Resources")
}
if($CreateContacts -eq "y"){
$Worksheet = $Workbook.Worksheets.Add()
$Worksheet.Name = "Contacts"
$Sheet_Contacts = $Workbook.Worksheets.Item("Contacts")
}
if($CreateShared -eq "y"){
$Worksheet = $Workbook.Worksheets.Add()
$Worksheet.Name = "Shared Mailboxes"
$Sheet_SharedMailboxes = $Workbook.Worksheets.Item("Shared Mailboxes")
}
if($CreateGroups -eq "y"){
$Worksheet = $Workbook.Worksheets.Add()
$Worksheet.Name = "Groups"
$Sheet_Group = $Workbook.Worksheets.Item("Groups")
}
if($CreateUsers -eq "y"){
$Worksheet = $Workbook.Worksheets.Add()
$Worksheet.Name = "Licensed Mailboxes"
$Sheet_LicensedMailboxes = $Workbook.Worksheets.Item("Licensed Mailboxes")
}
$Workbook.Worksheets.Item("Generating").Delete()


#Report on Licensed Mailboxes
if($CreateUsers -eq "y"){

    $FileName = "$TenantDisplay - Users - $Date1.csv"
    $OutputPath = "$home\Downloads\$FileName"
    $CSVpath = $OutputPath

$Users = Get-MsolUser -All | Where-Object {$_.islicensed} | Sort-Object DisplayName
$UsersCount = $Users.count
$LicenseName = @()

Write-Host "============================================" -ForegroundColor Yellow
Write-Host "Processing Users. Please Wait" -ForegroundColor Yellow
Write-Host "============================================" -ForegroundColor Yellow
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
$Counter = 0
$UsersArray = @()
Foreach ($User in $Users){
    $DisplayName = ($User).DisplayName
    $Counter++
    $EmailAddresses = @()
    $primaryemailaddress = try{($User | Select-Object -ExpandProperty proxyaddresses | Where-Object { $_ -cmatch '^SMTP' }).Trim("SMTP:")}catch{}
    $EmailAddresses = @(($User | Select-Object -ExpandProperty proxyaddresses | Where-Object { $_ -cnotmatch "^SMTP:$primaryemailaddress" }) -replace "smtp:")
    if($CheckMbxSize -eq "y"){
      $TotalSize = (Get-MailboxStatistics -Identity "$Name" | Select-Object -ExpandProperty TotalItemSize)
      $MBsize = ([math]::Round(($TotalSize.ToString().Split("(")[1].Split(" ")[0].Replace(",","")/1MB),2)).ToString('N0')
      $TotalSize = "$MBsize MB"
    }else{
        $TotalSize = ""
    }
    if($CheckArchive -eq "y"){
        $ArchiveCheck = (Get-MailboxStatistics -Archive $DisplayName -ErrorAction SilentlyContinue | Select-Object -Property TotalItemSize -ErrorAction SilentlyContinue | ft -hidetableheaders | Out-String).Trim()
    }else{
        $ArchiveCheck = ""
    }
    $SignInName = ($User).SignInName

Write-Host
Write-Host "Processing: $DisplayName..."  -ForegroundColor Green
Write-Host "User $Counter of $UsersCount" -ForegroundColor Yellow
Write-Host

if($CheckOneDrive -eq "y")
{
if($SignInName.Contains('@'))
{
    $SignInName=$SignInName.Replace('@','_')
    $SignInName=$SignInName.Replace('.','_')
    $SignInName=$SignInName.Replace('.','_')
    $SignInName="https://$tenantname-my.sharepoint.com/personal/"+$SignInName
    $OneDriveTotal = try{(Get-SPOSite -Identity $SignInName -ErrorAction SilentlyContinue | Select-Object -expandproperty StorageUsageCurrent).ToString('N0')}catch{$OneDriveTotal = "0"}
    $OneDriveSize = "$OneDriveTotal MB"
}
}else{
    $OneDriveSize = ""
}

#Lookup for friendly license name
$LicenseName = @()
$licenseString = ""
$PrimaryLicenseArray = @()
$PrimaryLicenseName = ""
$Licenses = (($User).Licenses).AccountSkuID
If (($Licenses).Count -gt 0)
{
Foreach ($License in $Licenses)
{
    $LicenseItem = $License -split ":" | Select-Object -Last 1
    $TextLic = $Sku.Item("$LicenseItem")
    If (!($TextLic))
    {
        $fallback_Licenses = $LicenseItem
        $LicenseName += $fallback_Licenses
        
    }
    Else
    {
        If($PrimaryLicenses.Contains($TextLic)){
            $PrimaryLicenseArray += $TextLic
        }else{
            $LicenseName += $TextLic
        }
    }
}
}
$licenseString = ($LicenseName | Sort) -join ", "
$PrimaryLicenseName = ($PrimaryLicenseArray | Sort) -join ", "
$AllEmailAddresses = $EmailAddresses -join ", "

#Get Delegation Permissions of Mailbox
$FullAccessNames = @()
If($MailboxPermissionsGet -eq "y"){
  $MPerms = Get-MailboxPermission "$DisplayName" | Where {($_.AccessRights -like "*FullAccess*") -and ($_.User -notlike "*\*") -and ($_.User -notlike "S-*")}
  $FullAccessNames = @()
  $FullAccessArray = @()
  ForEach ($PermUser in $MPerms){
      $PermUserDisplayName = $null
      $GetDisplayUser = Get-MsolUser -userprincipalname $PermUser.user -ErrorAction Ignore
      $PermUserDisplayName = $GetDisplayUser.DisplayName
      If(!$PermUserDisplayName){
          $GetDisplayGroup = Get-Group $PermUser.user -ErrorAction Ignore
          $PermUserDisplayName = $GetDisplayGroup.DisplayName
      }
  $FullAccessArray += $PermUserDisplayName
  }
  $FullAccessNames = $FullAccessArray -join ", "
}

$UserProperties = [pscustomobject][ordered]@{
  'Display Name' = $DisplayName
  'Primary License' = $PrimaryLicenseName
  'Additional Licenses' = $LicenseString
  'User Principal Name' = $User.UserPrincipalName
  'Primary Email' = $primaryemailaddress
  'Additional Addresses' = $AllEmailAddresses
  'Mailbox Size' = $TotalSize
  'Archive Site' = $ArchiveCheck
  'OneDrive Size' = $OneDriveSize
  'Full Access Permissions' = $FullAccessNames        
}
$UsersArray += $UserProperties
$UserProperties | Export-CSV -Path $CSVpath -Append -NoTypeInformation   
}

### Set input and output path
$inputCSV = "$CSVPath"
$outputXLSX = "$XLSPath"

### Create a new Excel Workbook with one empty sheet

$Sheet_LicensedMailboxes.Activate()
$Sheet_LicensedMailboxes.ActiveSheet
$worksheet = $Sheet_LicensedMailboxes

### Build the QueryTables.Add command
### QueryTables does the same as when clicking "Data » From Text" in Excel
$TxtConnector = ("TEXT;" + $inputCSV)
$Connector = $worksheet.QueryTables.add($TxtConnector,$worksheet.Range("A1"))
$query = $worksheet.QueryTables.item($Connector.name)

### Set the delimiter (, or ;) according to your regional settings
$query.TextFileOtherDelimiter = $Excel.Application.International(5)

### Set the format to delimited and text for every column
### A trick to create an array of 2s is used with the preceding comma
$query.TextFileParseType  = 1
$query.TextFileColumnDataTypes = ,2 * $worksheet.Cells.Columns.Count
$query.AdjustColumnWidth = 1
### Execute & delete the import query
$query.Refresh()
$query.Delete()

$list = $excel.ActiveSheet.ListObjects.Add(
    [Microsoft.Office.Interop.Excel.XlListObjectSourceType]::xlSrcRange, # Add a range
    $excel.ActiveCell.CurrentRegion, # Get the current region, by default A1 is selected so it'll select all contiguous rows
    $null,
    [Microsoft.Office.Interop.Excel.XlYesNoGuess]::xlYes # Yes, we have a header row
)

$xlShiftDown = -4121
$objRange = $worksheet.Range("A1").EntireRow
[void]$objRange.Insert($xlShiftDown)

$row = 1
$Column = 1
$worksheet.Cells.Item($row, $column) = 'Licensed Users'
$worksheet.Cells.Item($row, $column).Font.Size = 26
$worksheet.Cells.Item($row, $column).Font.Name = "Cambria"
$worksheet.Cells.Item($row, $column).Font.ThemeFont = 1
$worksheet.Cells.Item($row, $column).Font.ThemeColor = 4
$worksheet.Cells.Item($row, $column).Font.ColorIndex = 55
$worksheet.Cells.Item($row, $column).Font.Color = 8210719
$range = $Sheet_LicensedMailboxes.Range("a1", "c1")
$range.Style = 'Title'
$range.Font.Size = 26
$range = $Sheet_LicensedMailboxes.Range("a1", "c1")
$range.Merge() | Out-Null
$range.VerticalAlignment = -4160

### Save & close the Workbook as XLSX. Change the output extension for Excel 2003
$excel.DisplayAlerts = $False
$workbook.SaveAs($outputXLSX)
$excel.DisplayAlerts = $True

Remove-Item -path "$inputCSV"
}

#Report on Groups
if($CreateGroups -eq "y"){
    
    $FileName = "$TenantDisplay - Groups - $Date1.csv"
    $OutputPath = "$home\Downloads\$FileName"
    $CSVpath = $OutputPath

$Groups = Get-MsolGroup | Sort-Object DisplayName
$UnifiedGroups = Get-UnifiedGroup | Sort-Object DisplayName
$UGlist = @()
$GroupsArray = @()
foreach($UnifiedGroup in $UnifiedGroups){
  $UGlist += @($UnifiedGroup.DisplayName)
}
$GroupsCount = $Groups.count
$Sheet_Groups_Y = 3
$RowNumber = 0

Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host "============================================" -ForegroundColor Yellow
Write-Host "Processing Groups. Please Wait..." -ForegroundColor Yellow
Write-Host "============================================" -ForegroundColor Yellow
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
$Counter = 0
Foreach ($Group in $Groups)
{
$RowNumber++
$Counter++
$Row = $Sheet_Groups_Y++
$GroupDirSyncStatus = ""
$DisplayName = $Group.DisplayName
Write-Host
Write-Host "Processing: $DisplayName..."  -ForegroundColor Green
Write-Host "Group $Counter of $GroupsCount" -ForegroundColor Yellow
Write-Host
if($UGlist -contains $Group.DisplayName){
$GroupType = "UnifiedGroup"
}else{
$GroupType = $Group.GroupType
}

$GroupEmail = $Group.EmailAddress
$Members = (Get-AzureADGroupMember -ObjectId $Group.ObjectID -ErrorAction SilentlyContinue | Sort-Object DisplayName | Select-Object -ExpandProperty DisplayName) -join ", "

$GroupTypeString = $GroupType | Out-String
$GroupTypeStringTrimEnd = $GroupTypeString.TrimEnd()
$Aliases = @()
$Aliases = @(($Group | Select-Object -ExpandProperty ProxyAddresses | Where-Object { $_ -cnotmatch "^SMTP:$GroupEmail"}) -replace "smtp:")
$AllAliases = $Aliases -join ", "

#Group Script Creation
if($CreateGroupScripts -eq "y"){
  $GroupCreate = ""
  $GTypeStandard = ""
  $GroupSettingsUpdate = ""
  $GroupMemberAdd = ""
  $GroupProxyAddresses = ""
  $IndvMemberList = (Get-AzureADGroupMember -ObjectId $Group.ObjectID -ErrorAction SilentlyContinue | Sort-Object DisplayName)
  if($GroupType -eq "MailEnabledSecurity"){$GTypeStandard = "Security"}
  if($GroupType -eq "Security"){$GTypeStandard = "Security"}
  if($GroupType -eq "DistributionList"){$GTypeStandard = "Distribution"}
  if($GroupType -eq "UnifiedGroup"){$GTypeStandard = "Office 365"}
  if($GroupType -ne "Security"){
    $GroupProxyAddresses = '"' + (($Group | Select-Object -Expand ProxyAddresses) -join '","') + '"'
    Foreach ($IndvMember in $IndvMemberList)
    {
    $IndvMemberCreate = @()
    $IndvMemberCreate = @(($IndvMember | Select-Object -ExpandProperty DisplayName))
    $GroupMemberAdd = -join ($GroupMemberAdd," Add-DistributionGroupMember -Identity ""$DisplayName"" -Member ""$IndvMemberCreate"";")
    }
    if($GTypeStandard -eq "Office 365"){
      $UGMembs = '"' + ((@(Get-AzureADGroupMember -ObjectId $Group.ObjectID -ErrorAction SilentlyContinue | Select-Object -expandproperty DisplayName)) -join '","') + '"'
      $UGAliasstring = $GroupEmail | Out-String
      $UGAlias = ($UGAliasstring).split('@')[0]
      $GroupCreate = "New-UnifiedGroup -Displayname ""$DisplayName"" -Alias ""$UGAlias"""
      $GroupMemberAdd = "Add-UnifiedGroupLinks -Identity ""$DisplayName"" -LinkType Members -Links $UGMembs"
      $GroupSettingsUpdate = ""
    }else{
    $GroupSenderAuth = (Get-DistributionGroup $DisplayName).RequireSenderAuthenticationEnabled
    $GroupCreate = "New-DistributionGroup -Name ""$DisplayName"" -Type ""$GTypeStandard"""
    $GroupSettingsUpdate = "Set-DistributionGroup -Identity ""$DisplayName"" -RequireSenderAuthenticationEnabled:"+"$"+"$GroupSenderAuth -EmailAddresses $GroupProxyAddresses"
    }
  }else{
    Foreach ($IndvMember in $IndvMemberList)
    {
    $IndvMemberCreate = @()
    $IndvMemberCreate = @(($IndvMember | Select-Object -ExpandProperty DisplayName))
    $GroupMemberAdd = -join ($GroupMemberAdd," Add-DistributionGroupMember -Identity ""$DisplayName"" -Member ""$IndvMemberCreate"";")
    }
    $GroupCreate = "New-DistributionGroup -Name ""$DisplayName"" -Type ""Security"""
  }

}

If($CreateGroupScripts -eq "y"){
$GroupProperties = [pscustomobject][ordered]@{
    'Display Name' = $DisplayName
    'Group Type' = $GroupTypeStringTrimEnd
    'Email' = $GroupEmail
    'Aliases' = $AllAliases
    'Members' = $Members
    'Group Create' = $GroupCreate
    'Group Member Add' = $GroupMemberAdd
    'GroupSettingsUpdate' = $GroupSettingsUpdate
  }
  $GroupsArray += $GroupProperties
  $GroupProperties | Export-CSV -Path $CSVpath -Append -NoTypeInformation   
}Else{
  $GroupProperties = [pscustomobject][ordered]@{
    'Display Name' = $DisplayName
    'Group Type' = $GroupTypeStringTrimEnd
    'Email' = $GroupEmail
    'Aliases' = $AllAliases
    'Members' = $Members    
  }
  $GroupsArray += $GroupProperties
  $GroupProperties | Export-CSV -Path $CSVpath -Append -NoTypeInformation   
}
}
### Set input and output path
$inputCSV = "$CSVPath"
$outputXLSX = "$XLSPath"

#Groups Worksheet
$Sheet_Group.Activate()
$Sheet_Group.ActiveSheet
$worksheet = $Sheet_Group

### Build the QueryTables.Add command
### QueryTables does the same as when clicking "Data » From Text" in Excel
$TxtConnector = ("TEXT;" + $inputCSV)
$Connector = $worksheet.QueryTables.add($TxtConnector,$worksheet.Range("A1"))
$query = $worksheet.QueryTables.item($Connector.name)

### Set the delimiter (, or ;) according to your regional settings
$query.TextFileOtherDelimiter = $Excel.Application.International(5)

### Set the format to delimited and text for every column
### A trick to create an array of 2s is used with the preceding comma
$query.TextFileParseType  = 1
$query.TextFileColumnDataTypes = ,2 * $worksheet.Cells.Columns.Count
$query.AdjustColumnWidth = 1
### Execute & delete the import query
$query.Refresh()
$query.Delete()

$list = $excel.ActiveSheet.ListObjects.Add(
    [Microsoft.Office.Interop.Excel.XlListObjectSourceType]::xlSrcRange, # Add a range
    $excel.ActiveCell.CurrentRegion, # Get the current region, by default A1 is selected so it'll select all contiguous rows
    $null,
    [Microsoft.Office.Interop.Excel.XlYesNoGuess]::xlYes # Yes, we have a header row
)

$xlShiftDown = -4121
$objRange = $worksheet.Range("A1").EntireRow
[void]$objRange.Insert($xlShiftDown)

#Create a Title for the first worksheet and adjust the font
$row = 1
$Column = 1
$worksheet.Cells.Item($row, $column) = 'Groups'
$worksheet.Cells.Item($row, $column).Font.Size = 26
$worksheet.Cells.Item($row, $column).Font.Name = "Cambria"
$worksheet.Cells.Item($row, $column).Font.ThemeFont = 1
$worksheet.Cells.Item($row, $column).Font.ThemeColor = 4
$worksheet.Cells.Item($row, $column).Font.ColorIndex = 55
$worksheet.Cells.Item($row, $column).Font.Color = 8210719
$range = $Sheet_Group.Range("a1", "c1")
$range.Style = 'Title'
$range.Font.Size = 26
$range = $Sheet_Group.Range("a1", "c1")
$range.Merge() | Out-Null
$range.VerticalAlignment = -4160

### Save & close the Workbook as XLSX. Change the output extension for Excel 2003
$excel.DisplayAlerts = $False
$workbook.SaveAs($outputXLSX)
$excel.DisplayAlerts = $True

Remove-Item -path "$inputCSV"
}

#Report on Shared
if($CreateShared -eq "y"){

    $FileName = "$TenantDisplay - Shared - $Date1.csv"
    $OutputPath = "$home\Downloads\$FileName"
    $CSVpath = $OutputPath

$SharedMailboxes = Get-mailbox -RecipientTypeDetails sharedmailbox -Resultsize unlimited | Sort-Object Name
$SharedCount = $SharedMailboxes.count
$Sheet_SharedMailboxes_Y = 3
$RowNumber = 0
$SharedArray = @()
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host "============================================" -ForegroundColor Yellow
Write-Host "Processing Shared Mailboxes. Please Wait..." -ForegroundColor Yellow
Write-Host "============================================" -ForegroundColor Yellow
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
$Counter = 0
Foreach ($SharedMailbox in $SharedMailboxes)
{
$RowNumber++
$Counter++
$Row = $Sheet_SharedMailboxes_Y++
$DisplayName = ($SharedMailbox).Name
$PrimarySmtpAddress = ($SharedMailbox).PrimarySmtpAddress

Write-Host
Write-Host "Processing: $DisplayName..."  -ForegroundColor Green
Write-Host "Mailbox $Counter of $SharedCount" -ForegroundColor Yellow
Write-Host

$TotalSize = (Get-MailboxStatistics -Identity "$Name" | Select-Object -ExpandProperty TotalItemSize)
$MBsize = ([math]::Round(($TotalSize.ToString().Split("(")[1].Split(" ")[0].Replace(",","")/1MB),2)).ToString('N0')
$TotalSize = "$MBsize MB"
$SecondarySmtpAddresses = @()
$SecondarySmtpAddresses = @(($SharedMailbox | Select-Object -ExpandProperty EmailAddresses | Where-Object { $_ -cnotmatch "^SMTP:$PrimarySmtpAddress" }) -replace "smtp:")
$SharedAliases = $SecondarySmtpAddresses -join ", "

#Get Delegation Permissions of Shared Mailbox
$FullAccessNames = @()
If($SharedPermissionsGet -eq "y"){
  $SMPerms = Get-MailboxPermission "$DisplayName" | Where {($_.AccessRights -like "*FullAccess*") -and ($_.User -notlike "*\*") -and ($_.User -notlike "S-*")}
  $FullAccessNames = @()
  $FullAccessArray = @()
  ForEach ($PermUser in $SMPerms){
      $PermUserDisplayName = $null
      $GetDisplayUser = Get-MsolUser -userprincipalname $PermUser.user -ErrorAction Ignore
      $PermUserDisplayName = $GetDisplayUser.DisplayName
      If(!$PermUserDisplayName){
          $GetDisplayGroup = Get-Group $PermUser.user -ErrorAction Ignore
          $PermUserDisplayName = $GetDisplayGroup.DisplayName
      }
  $FullAccessArray += $PermUserDisplayName
  }
  $FullAccessNames = $FullAccessArray -join ", "
}


$SharedProperties = [pscustomobject][ordered]@{
    'Display Name' = $DisplayName
    'Primary Address' = $PrimarySmtpAddress
    'Aliases' = $SharedAliases
    'Total Size' = $TotalSize 
    'Full Access Permissions' = $FullAccessNames
  }
  $SharedArray += $SharedProperties
  $SharedProperties | Export-CSV -Path $CSVpath -Append -NoTypeInformation 

}


### Set input and output path
$inputCSV = "$CSVPath"
$outputXLSX = "$XLSPath"

#Groups Worksheet
$Sheet_SharedMailboxes.Activate()
$Sheet_SharedMailboxes.ActiveSheet
$worksheet = $Sheet_SharedMailboxes

### Build the QueryTables.Add command
### QueryTables does the same as when clicking "Data » From Text" in Excel
$TxtConnector = ("TEXT;" + $inputCSV)
$Connector = $worksheet.QueryTables.add($TxtConnector,$worksheet.Range("A1"))
$query = $worksheet.QueryTables.item($Connector.name)

### Set the delimiter (, or ;) according to your regional settings
$query.TextFileOtherDelimiter = $Excel.Application.International(5)

### Set the format to delimited and text for every column
### A trick to create an array of 2s is used with the preceding comma
$query.TextFileParseType  = 1
$query.TextFileColumnDataTypes = ,2 * $worksheet.Cells.Columns.Count
$query.AdjustColumnWidth = 1
### Execute & delete the import query
$query.Refresh()
$query.Delete()

$list = $excel.ActiveSheet.ListObjects.Add(
    [Microsoft.Office.Interop.Excel.XlListObjectSourceType]::xlSrcRange, # Add a range
    $excel.ActiveCell.CurrentRegion, # Get the current region, by default A1 is selected so it'll select all contiguous rows
    $null,
    [Microsoft.Office.Interop.Excel.XlYesNoGuess]::xlYes # Yes, we have a header row
)

$xlShiftDown = -4121
$objRange = $worksheet.Range("A1").EntireRow
[void]$objRange.Insert($xlShiftDown)

#Create a Title for the first worksheet and adjust the font
$row = 1
$Column = 1
$worksheet.Cells.Item($row, $column) = 'Shared Mailboxes'
$worksheet.Cells.Item($row, $column).Font.Size = 26
$worksheet.Cells.Item($row, $column).Font.Name = "Cambria"
$worksheet.Cells.Item($row, $column).Font.ThemeFont = 1
$worksheet.Cells.Item($row, $column).Font.ThemeColor = 4
$worksheet.Cells.Item($row, $column).Font.ColorIndex = 55
$worksheet.Cells.Item($row, $column).Font.Color = 8210719
$range = $worksheet.Range("a1", "c1")
$range.Style = 'Title'
$range.Font.Size = 26
$range = $worksheet.Range("a1", "c1")
$range.Merge() | Out-Null
$range.VerticalAlignment = -4160

### Save & close the Workbook as XLSX. Change the output extension for Excel 2003
$excel.DisplayAlerts = $False
$workbook.SaveAs($outputXLSX)
$excel.DisplayAlerts = $True

Remove-Item -path "$inputCSV"
}

#Report on Contacts
if($CreateContacts -eq "y"){

  $FileName = "$TenantDisplay - Contacts - $Date1.csv"
  $OutputPath = "$home\Downloads\$FileName"
  $CSVpath = $OutputPath

  $Contacts = Get-Contact | Sort-Object DisplayName
  $ContactsCount = $Contacts.count
  $Sheet_Contacts_Y = 3
  $RowNumber = 0
  $ContactsArray = @()
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host "============================================" -ForegroundColor Yellow
Write-Host "Processing Contacts. Please Wait..." -ForegroundColor Yellow
Write-Host "============================================" -ForegroundColor Yellow
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
$Counter = 0
Foreach ($Contact in $Contacts)
{
$RowNumber++
$Counter++
$Row = $Sheet_Contacts_Y++
$DisplayName = ($Contact).DisplayName
Write-Host
Write-Host "Processing: $DisplayName..."  -ForegroundColor Green
Write-Host "Contact $Counter of $ContactsCount" -ForegroundColor Yellow
Write-Host
$ContactEmail = ($Contact).WindowsEmailAddress


$ContactProperties = [pscustomobject][ordered]@{
  'Display Name' = $DisplayName
  'Contact Email' = $ContactEmail
}
$ContactsArray += $ContactProperties
$ContactProperties | Export-CSV -Path $CSVpath -Append -NoTypeInformation   
}

### Set input and output path
$inputCSV = "$CSVPath"
$outputXLSX = "$XLSPath"

#Groups Worksheet
$Sheet_Contacts.Activate()
$Sheet_Contacts.ActiveSheet
$worksheet = $Sheet_Contacts

### Build the QueryTables.Add command
### QueryTables does the same as when clicking "Data » From Text" in Excel
$TxtConnector = ("TEXT;" + $inputCSV)
$Connector = $worksheet.QueryTables.add($TxtConnector,$worksheet.Range("A1"))
$query = $worksheet.QueryTables.item($Connector.name)

### Set the delimiter (, or ;) according to your regional settings
$query.TextFileOtherDelimiter = $Excel.Application.International(5)

### Set the format to delimited and text for every column
### A trick to create an array of 2s is used with the preceding comma
$query.TextFileParseType  = 1
$query.TextFileColumnDataTypes = ,2 * $worksheet.Cells.Columns.Count
$query.AdjustColumnWidth = 1
### Execute & delete the import query
$query.Refresh()
$query.Delete()

$list = $excel.ActiveSheet.ListObjects.Add(
    [Microsoft.Office.Interop.Excel.XlListObjectSourceType]::xlSrcRange, # Add a range
    $excel.ActiveCell.CurrentRegion, # Get the current region, by default A1 is selected so it'll select all contiguous rows
    $null,
    [Microsoft.Office.Interop.Excel.XlYesNoGuess]::xlYes # Yes, we have a header row
)

$xlShiftDown = -4121
$objRange = $worksheet.Range("A1").EntireRow
[void]$objRange.Insert($xlShiftDown)

#Create a Title for the first worksheet and adjust the font
$row = 1
$Column = 1
$Sheet_Contacts.Cells.Item($row, $column) = 'Contacts'
$Sheet_Contacts.Cells.Item($row, $column).Font.Size = 26
#$Sheet_Contacts.Cells.Item($row,$column).Font.Bold=$True
$Sheet_Contacts.Cells.Item($row, $column).Font.Name = "Cambria"
$Sheet_Contacts.Cells.Item($row, $column).Font.ThemeFont = 1
$Sheet_Contacts.Cells.Item($row, $column).Font.ThemeColor = 4
$Sheet_Contacts.Cells.Item($row, $column).Font.ColorIndex = 55
$Sheet_Contacts.Cells.Item($row, $column).Font.Color = 8210719
$range = $Sheet_Contacts.Range("a1", "c1")
$range.Style = 'Title'
$range.Font.Size = 26
$range = $Sheet_Contacts.Range("a1", "c1")
$range.Merge() | Out-Null
$range.VerticalAlignment = -4160

Start-Sleep -Seconds 1
}

#Report on Resources
if($CreateResources -eq "y"){

  $FileName = "$TenantDisplay - Resources - $Date1.csv"
  $OutputPath = "$home\Downloads\$FileName"
  $CSVpath = $OutputPath


$Resources = Get-Mailbox -ResultSize Unlimited -Filter '(RecipientTypeDetails -eq "RoomMailBox")' | Sort-Object Name
$ResourcesCount = $Resources.count
$Sheet_Resources_Y = 3
$RowNumber = 0
$ResourcesArray = @()
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host "==================================================" -ForegroundColor Yellow
Write-Host "Processing Resource & Room Mailboxes. Please Wait." -ForegroundColor Yellow
Write-Host "==================================================" -ForegroundColor Yellow
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
$Counter = 0
Foreach ($Room in $Resources)
{
$RowNumber++
$Counter++
$Row = $Sheet_Resources_Y++
$DisplayName = ($Room).Name
Write-Host
Write-Host "Processing: $DisplayName..."  -ForegroundColor Green
Write-Host "Resource $Counter of $ResourcesCount" -ForegroundColor Yellow
Write-Host
$PrimarySmtpAddress = ($Room).PrimarySmtpAddress
$TotalSize = (Get-MailboxStatistics $DisplayName -ErrorAction SilentlyContinue | Select-Object -Property TotalItemSize -ErrorAction SilentlyContinue | ft -hidetableheaders | Out-String).Trim()
$SecondarySmtpAddresses = @()
$SecondarySmtpAddresses = @(($Room | Select-Object -ExpandProperty EmailAddresses | Where-Object { $_ -cnotmatch "^SMTP:$PrimarySmtpAddress" }) -replace "smtp:")
$SecondarySmtpAddresses = $SecondarySmtpAddresses -join ", "

$Details = ""
$Details = (Get-CalendarProcessing $PrimarySmtpAddress | fl | Out-String).Trim()

$ResourceProperties = [pscustomobject][ordered]@{
  'Display Name' = $DisplayName
  'Primary SMTP Address' = $PrimarySmtpAddress
  'Secondary SMTP Addresses' = $SecondarySmtpAddresses
}
$ResourcesArray += $ResourceProperties
$ResourceProperties | Export-CSV -Path $CSVpath -Append -NoTypeInformation   
}

### Set input and output path
$inputCSV = "$CSVPath"
$outputXLSX = "$XLSPath"

#Groups Worksheet
$Sheet_Resources.Activate()
$Sheet_Resources.ActiveSheet
$worksheet = $Sheet_Resources

### Build the QueryTables.Add command
### QueryTables does the same as when clicking "Data » From Text" in Excel
$TxtConnector = ("TEXT;" + $inputCSV)
$Connector = $worksheet.QueryTables.add($TxtConnector,$worksheet.Range("A1"))
$query = $worksheet.QueryTables.item($Connector.name)

### Set the delimiter (, or ;) according to your regional settings
$query.TextFileOtherDelimiter = $Excel.Application.International(5)

### Set the format to delimited and text for every column
### A trick to create an array of 2s is used with the preceding comma
$query.TextFileParseType  = 1
$query.TextFileColumnDataTypes = ,2 * $worksheet.Cells.Columns.Count
$query.AdjustColumnWidth = 1
### Execute & delete the import query
$query.Refresh()
$query.Delete()

$list = $excel.ActiveSheet.ListObjects.Add(
    [Microsoft.Office.Interop.Excel.XlListObjectSourceType]::xlSrcRange, # Add a range
    $excel.ActiveCell.CurrentRegion, # Get the current region, by default A1 is selected so it'll select all contiguous rows
    $null,
    [Microsoft.Office.Interop.Excel.XlYesNoGuess]::xlYes # Yes, we have a header row
)

$xlShiftDown = -4121
$objRange = $worksheet.Range("A1").EntireRow
[void]$objRange.Insert($xlShiftDown)

#Create a Title for the first worksheet and adjust the font
$row = 1
$Column = 1
$Sheet_Resources.Cells.Item($row, $column) = 'Resources'
$Sheet_Resources.Cells.Item($row, $column).Font.Size = 26
#$Sheet_Resources.Cells.Item($row,$column).Font.Bold=$True
$Sheet_Resources.Cells.Item($row, $column).Font.Name = "Cambria"
$Sheet_Resources.Cells.Item($row, $column).Font.ThemeFont = 1
$Sheet_Resources.Cells.Item($row, $column).Font.ThemeColor = 4
$Sheet_Resources.Cells.Item($row, $column).Font.ColorIndex = 55
$Sheet_Resources.Cells.Item($row, $column).Font.Color = 8210719
$range = $Sheet_Resources.Range("a1", "c1")
$range.Style = 'Title'
$range.Font.Size = 26
$range = $Sheet_Resources.Range("a1", "c1")
$range.Merge() | Out-Null
$range.VerticalAlignment = -4160

Start-Sleep -Seconds 1
}

#Report on Domains
if($CreateDomains -eq "y"){

  $FileName = "$TenantDisplay - Domains - $Date1.csv"
  $OutputPath = "$home\Downloads\$FileName"
  $CSVpath = $OutputPath

$Domains = Get-MsolDomain | Sort-Object Name
$Domainscount = $Domains.count
$Sheet_Domains_Y = 3
$RowNumber = 0
$DomainsArray = @()
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host "============================================" -ForegroundColor Yellow
Write-Host "Processing Domains. Please Wait..." -ForegroundColor Yellow
Write-Host "============================================" -ForegroundColor Yellow
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
$Counter = 0
Foreach ($Domain in $Domains)
{
$Row = $Sheet_Domains_Y++
$RowNumber++
$Counter++
$DisplayName = ($Domain).Name
Write-Host
Write-Host "Processing: $DisplayName..."  -ForegroundColor Green
Write-Host "Domain $Counter of $Domainscount" -ForegroundColor Yellow
Write-Host
$DefaultStatus = ($Domain).IsDefault
$Verified = (($Domain).Status | Out-String).TrimEnd()

$DomainProperties = [pscustomobject][ordered]@{
  'Display Name' = $DisplayName
  'Default' = $DefaultStatus
  'Verified' = $Verified
}
$DomainsArray += $DomainProperties
$DomainProperties | Export-CSV -Path $CSVpath -Append -NoTypeInformation   
}

### Set input and output path
$inputCSV = "$CSVPath"
$outputXLSX = "$XLSPath"

#Groups Worksheet
$Sheet_Domains.Activate()
$Sheet_Domains.ActiveSheet
$worksheet = $Sheet_Domains

### Build the QueryTables.Add command
### QueryTables does the same as when clicking "Data » From Text" in Excel
$TxtConnector = ("TEXT;" + $inputCSV)
$Connector = $worksheet.QueryTables.add($TxtConnector,$worksheet.Range("A1"))
$query = $worksheet.QueryTables.item($Connector.name)

### Set the delimiter (, or ;) according to your regional settings
$query.TextFileOtherDelimiter = $Excel.Application.International(5)

### Set the format to delimited and text for every column
### A trick to create an array of 2s is used with the preceding comma
$query.TextFileParseType  = 1
$query.TextFileColumnDataTypes = ,2 * $worksheet.Cells.Columns.Count
$query.AdjustColumnWidth = 1
### Execute & delete the import query
$query.Refresh()
$query.Delete()

$list = $excel.ActiveSheet.ListObjects.Add(
    [Microsoft.Office.Interop.Excel.XlListObjectSourceType]::xlSrcRange, # Add a range
    $excel.ActiveCell.CurrentRegion, # Get the current region, by default A1 is selected so it'll select all contiguous rows
    $null,
    [Microsoft.Office.Interop.Excel.XlYesNoGuess]::xlYes # Yes, we have a header row
)

$xlShiftDown = -4121
$objRange = $worksheet.Range("A1").EntireRow
[void]$objRange.Insert($xlShiftDown)

#Create a Title for the first worksheet and adjust the font
$row = 1
$Column = 1
$Sheet_Domains.Cells.Item($row, $column) = 'Domains'
$Sheet_Domains.Cells.Item($row, $column).Font.Size = 26
#$Sheet_Domains.Cells.Item($row,$column).Font.Bold=$True
$Sheet_Domains.Cells.Item($row, $column).Font.Name = "Cambria"
$Sheet_Domains.Cells.Item($row, $column).Font.ThemeFont = 1
$Sheet_Domains.Cells.Item($row, $column).Font.ThemeColor = 4
$Sheet_Domains.Cells.Item($row, $column).Font.ColorIndex = 55
$Sheet_Domains.Cells.Item($row, $column).Font.Color = 8210719
$range = $Sheet_Domains.Range("a1", "c1")
$range.Style = 'Title'
$range.Font.Size = 26
$range = $Sheet_Domains.Range("a1", "c1")
$range.Merge() | Out-Null
$range.VerticalAlignment = -4160

Start-Sleep -Seconds 1
}

#Create Scripts
if($CreateScripts -eq "y"){
#Scripts Worksheet

$FileName = "$TenantDisplay - Scripts - $Date1.csv"
$OutputPath = "$home\Downloads\$FileName"
$CSVpath = $OutputPath

$Mailboxes = Get-Mailbox -ResultSize Unlimited -ErrorAction SilentlyContinue | Sort-Object Name
$MailboxesCount = $Mailboxes.Count
$Sheet_Scripts_Y = 3
$RowNumber = 0
$ScriptsArray = @()
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host "============================================" -ForegroundColor Yellow
Write-Host "Generating Scripts. Please Wait..." -ForegroundColor Yellow
Write-Host "============================================" -ForegroundColor Yellow
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
$Counter = 0
Start-Sleep -Seconds 2
Foreach ($Mailbox in $Mailboxes)
{
  $RowNumber++
  $Counter++
  $Row = $Sheet_Scripts_Y++
  $DisplayName = ($Mailbox).DisplayName
  Write-Host
  Write-Host "Processing: $DisplayName..."  -ForegroundColor Green
  Write-Host "Mailbox Script $Counter of $MailboxesCount" -ForegroundColor Yellow
  Write-Host

#Mailbox Properties
  $MailboxProp = Get-Mailbox $Displayname -ErrorAction SilentlyContinue
  $MailboxPropString = ""
    $curUPN = ""
    $MailPropPrimary  = $null
    $DeliverForward  = $null
    $LitHold  = $null
    $ForwardingAddress  = $null
    $ForwardingSmtpAddress  = $null
    $MailPropUPN  = $null
    $WinLiveID  = $null
    $MSOSID  = $null
    $ArchiveStatus  = $null
    $MailPropAlias  = $null
    $MailPropSecondaryAddresses  = $null
    $MailPropShared  = $null
    $MailPropRecipientType  = $null
    $MailPropRecipientTypeDetails  = $null
    $ResourceType  = $null
    $RoomEnabled  = $null
    $MailPropPrimary = ($MailboxProp).PrimarySmtpAddress
    $DeliverForward = ($MailboxProp).DeliverToMailboxAndForward
    $LitHold = ($MailboxProp).LitigationHoldEnabled
    $ForwardingAddress = ($MailboxProp).ForwardingAddress
    $ForwardingSmtpAddress = ($MailboxProp).ForwardingSmtpAddress
    $MailPropUPN = ($MailboxProp).UserPrincipalName
    $MailPropUPNAlias = ($MailboxProp).UserPrincipalName.split('@')[0]
    $WinLiveID = ($MailboxProp).WindowsLiveID
    $MSOSID = ($MailboxProp).MicrosoftOnlineServicesID
    $ArchiveStatus = ($MailboxProp).ArchiveStatus
    $ArchiveName = ($MailboxProp).ArchiveName
    $MailPropAlias = ($MailboxProp).Alias
    $MailPropSecondaryAddresses = '"' + ((Get-Mailbox $DisplayName | Select-Object -Expand EmailAddresses) -join '","') + '"'
    $MailPropShared = ($MailboxProp).IsShared
    $MailPropRecipientType = ($MailboxProp).RecipientType
    $MailPropRecipientTypeDetails = ($MailboxProp).RecipientTypeDetails
    $GrantSendOnBehalfTo = ($MailboxProp).GrantSendOnBehalfTo
    $ResourceType = ($MailboxProp).ResourceType
    $RoomEnabled = ($MailboxProp).RoomMailboxAccountEnabled

$MailboxPropString = "Set-Variable -Name ""curUPN"" -Value ((Get-MsolUser | Where-Object {"+"$"+"_"+".DisplayName -eq ""$DisplayName""} | Select UserPrincipalName | ft -hide | Out-String).Trim()); Set-Mailbox -Identity ""$DisplayName"""
  If (!$DeliverForward) { } else { $MailboxPropString = -join ($MailboxPropString," ","-DeliverToMailboxAndForward ",$DeliverForward) }
  If (!$LitHold) { } else { $MailboxPropString = -join ($MailboxPropString," ","-LitigationHoldEnabled ",$LitHold) }
  If (!$ForwardingAddress) { } else { $MailboxPropString = -join ($MailboxPropString," ","-ForwardingAddress ",$ForwardingAddress) }
  If (!$ForwardingSmtpAddress) { } else { $MailboxPropString = -join ($MailboxPropString," ","-ForwardingSmtpAddress ",$ForwardingSmtpAddress) }
  If (!$MailPropAlias) { } else { $MailboxPropString = -join ($MailboxPropString," ","-Alias ",$MailPropAlias) }
  If (!$MailPropSecondaryAddresses) { } else { $MailboxPropString = -join ($MailboxPropString, " ","-EmailAddresses @{Add=",$MailPropSecondaryAddresses,"}") }
  If (!$MailPropPrimary) { } else { $MailboxPropString = -join ($MailboxPropString, " ","-WindowsEmailAddress ",$MailPropPrimary) }
  If (!$MailPropShared) { } else { $MailboxPropString = -join ($MailboxPropString," ","-IsShared ",$MailPropShared) }
  If (!$ResourceType) { } else { $MailboxPropString = -join ($MailboxPropString," ","-ResourceType ",$ResourceType) }
$MailboxPropString = -join ($MailboxPropString,"; ","Set-MsolUserPrincipalName -UserPrincipalName $"+"curUPN -NewUserPrincipalName ""$MailPropPrimary""")

  #Room Mailbox Settings
  If($MailPropRecipientTypeDetails -eq "RoomMailbox")
  {
    $CalProc = Get-CalendarProcessing $Displayname -ErrorAction SilentlyContinue
    $CalAutomateProcessing = ($CalProc).AutomateProcessing
    $CalAllowConflicts = ($CalProc).AllowConflicts
    $CalBookingWindowInDays = ($CalProc).BookingWindowInDays
    $CalMaximumDurationInMinutes = ($CalProc).MaximumDurationInMinutes
    $CalAllowRecurringMeetings = ($CalProc).AllowRecurringMeetings
    $CalScheduleOnlyDuringWorkHours = ($CalProc).ScheduleOnlyDuringWorkHours
    $CalConflictPercentageAllowed = ($CalProc).ConflictPercentageAllowed
    $CalMaximumConflictInstances = ($CalProc).MaximumConflictInstances
    $CalForwardRequestsToDelegates = ($CalProc).ForwardRequestsToDelegates
    $CalDeleteAttachments = ($CalProc).DeleteAttachments
    $CalDeleteComments = ($CalProc).DeleteComments
    $CalRemovePrivateProperty = ($CalProc).RemovePrivateProperty
    $CalDeleteSubject = ($CalProc).DeleteSubject
    $CalAddOrganizerToSubject = ($CalProc).AddOrganizerToSubject
    $RoomCalProcSet = "Set-CalendarProcessing ""$DisplayName"" -AutomateProcessing $CalAutomateProcessing -AllowConflicts $CalAllowConflicts -BookingWindowInDays $CalBookingWindowInDays -MaximumDurationInMinutes $CalMaximumDurationInMinutes -AllowRecurringMeetings $CalAllowRecurringMeetings -ScheduleOnlyDuringWorkHours $CalScheduleOnlyDuringWorkHours -ConflictPercentageAllowed $CalConflictPercentageAllowed -MaximumConflictInstances $CalMaximumConflictInstances -ForwardRequestsToDelegates $CalForwardRequestsToDelegates -DeleteAttachments $CalDeleteAttachments -DeleteComments $CalDeleteComments -RemovePrivateProperty $CalRemovePrivateProperty -DeleteSubject $CalDeleteSubject -AddOrganizerToSubject $CalAddOrganizerToSubject"
    $MailboxPropString = -join ($MailboxPropString,"; ",$RoomCalProcSet)
  }

  #Mailbox Permissions
  $Permissions = Get-MailboxPermission $DisplayName -ErrorAction SilentlyContinue | Where {$_.user.tostring() -ne "NT AUTHORITY\SELF" -and $_.IsInherited -eq $False}
  $PermArray = ""
  Foreach ($Permission in $Permissions)
  {
  $AccessRightsArray = @()
  $AccessRightsArray = @(($Permission | Select-Object -ExpandProperty AccessRights))
  $PermissionUser = ($Permission | Select-Object -ExpandProperty User)
  $PermArray = -join ($PermArray," Add-MailboxPermission -Identity ""$DisplayName"" -User $PermissionUser -AccessRights $AccessRightsArray -InheritanceType All -Confirm:"+"$"+"False);")
  }
  $RecipientPermissions = Get-RecipientPermission $DisplayName -ErrorAction SilentlyContinue | Where {$_.trustee.tostring() -ne "NT AUTHORITY\SELF" -and $_.IsInherited -eq $False}
  $RecipPermArray = ""
  Foreach ($RecipPermission in $RecipientPermissions)
  {
  $RecipAccessRightsArray = @()
  $RecipAccessRightsArray = @(($RecipPermission | Select-Object -ExpandProperty AccessRights))
  $Trustee = ($RecipPermission | Select-Object -ExpandProperty Trustee)
  $PermArray = -join ($PermArray," Add-RecipientPermission ""$DisplayName"" -Trustee $PermissionUser -AccessRights $RecipAccessRightsArray -Confirm:"+"$"+"False);")
  }

#Create Mailboxes
  $CreateUser = Get-User $DisplayName
  $CreateFirstName = ($CreateUser).FirstName
  $CreateLastName = ($CreateUser).LastName
  If($MailPropRecipientTypeDetails -eq "SharedMailbox")
  {
  $MailboxCreationScript = ""
  $MailboxCreationScript =    "New-Mailbox -Alias $MailPropAlias -Name ""$displayname"" -Shared -PrimarySmtpAddress $MailPropAlias@$MigrationOMSFT.onmicrosoft.com"
  }else
  {
    if($MailPropRecipientTypeDetails -eq "RoomMailbox")
    {
      $MailboxCreationScript = ""
      $MailboxCreationScript =    "New-Mailbox -Alias $MailPropAlias -Name ""$displayname"" -Room -PrimarySmtpAddress $MailPropAlias@$MigrationOMSFT.onmicrosoft.com"
    }Else
    {
      $MailboxCreationScript = ""
      $MailboxCreationScript = "New-Mailbox -Alias $MailPropAlias -Name ""$DisplayName"" -FirstName ""$CreateFirstName"" -LastName ""$CreateLastName"" -DisplayName ""$DisplayName"" -MicrosoftOnlineServicesID $MailPropUPNAlias@$MigrationOMSFT.onmicrosoft.com -Password $($SecurePassword) -ResetPasswordOnNextLogon $($false)"
    }
  }

$ScriptProperties = [pscustomobject][ordered]@{
  'User Display Name' = $DisplayName
  'Mailbox Creation Script' = $MailboxCreationScript
  'UPN and Settings Script' = $MailboxPropString
  'Mailbox Permissions Script' = $PermArray
  'Additional Script' = $AdditionalScripts
}
$ScriptsArray += $ScriptProperties
$ScriptProperties | Export-CSV -Path $CSVpath -Append -NoTypeInformation   
}

### Set input and output path
$inputCSV = "$CSVPath"
$outputXLSX = "$XLSPath"

#Groups Worksheet
$Sheet_Scripts.Activate()
$Sheet_Scripts.ActiveSheet
$worksheet = $Sheet_Scripts

### Build the QueryTables.Add command
### QueryTables does the same as when clicking "Data » From Text" in Excel
$TxtConnector = ("TEXT;" + $inputCSV)
$Connector = $worksheet.QueryTables.add($TxtConnector,$worksheet.Range("A1"))
$query = $worksheet.QueryTables.item($Connector.name)

### Set the delimiter (, or ;) according to your regional settings
$query.TextFileOtherDelimiter = $Excel.Application.International(5)

### Set the format to delimited and text for every column
### A trick to create an array of 2s is used with the preceding comma
$query.TextFileParseType  = 1
$query.TextFileColumnDataTypes = ,2 * $worksheet.Cells.Columns.Count
$query.AdjustColumnWidth = 1
### Execute & delete the import query
$query.Refresh()
$query.Delete()

$list = $excel.ActiveSheet.ListObjects.Add(
    [Microsoft.Office.Interop.Excel.XlListObjectSourceType]::xlSrcRange, # Add a range
    $excel.ActiveCell.CurrentRegion, # Get the current region, by default A1 is selected so it'll select all contiguous rows
    $null,
    [Microsoft.Office.Interop.Excel.XlYesNoGuess]::xlYes # Yes, we have a header row
)

$xlShiftDown = -4121
$objRange = $worksheet.Range("A1").EntireRow
[void]$objRange.Insert($xlShiftDown)

#Create a Title for the first worksheet and adjust the font
$row = 1
$Column = 1
$Sheet_Scripts.Cells.Item($row, $column) = 'Scripts'
$Sheet_Scripts.Cells.Item($row, $column).Font.Size = 26
#$Sheet_Scripts.Cells.Item($row,$column).Font.Bold=$True
$Sheet_Scripts.Cells.Item($row, $column).Font.Name = "Cambria"
$Sheet_Scripts.Cells.Item($row, $column).Font.ThemeFont = 1
$Sheet_Scripts.Cells.Item($row, $column).Font.ThemeColor = 4
$Sheet_Scripts.Cells.Item($row, $column).Font.ColorIndex = 55
$Sheet_Scripts.Cells.Item($row, $column).Font.Color = 8210719
$range = $Sheet_Scripts.Range("a1", "c1")
$range.Style = 'Title'
$range.Font.Size = 26
$range = $Sheet_Scripts.Range("a1", "c1")
$range.Merge() | Out-Null
$range.VerticalAlignment = -4160
}


#$Sheet_LicensedMailboxes.Activate()
#$Sheet_LicensedMailboxes.ActiveSheet
$workbook.Sheets(1).Select()
$excel.DisplayAlerts = $False
$workbook.SaveAs($outputXLSX)
$excel.DisplayAlerts = $True
$excel.Quit()
Write-Host


Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host "===================================================================" -ForegroundColor Yellow
Write-Host "Report Completed!" -ForegroundColor Yellow
Write-Host ""
Write-Host "Saved to Downloads as:" -ForegroundColor Yellow
Write-Host "'$XFileName'" -ForegroundColor Yellow
Write-Host "===================================================================" -ForegroundColor Yellow
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""

Get-Commands
}
function Read-InputBoxDialog([string]$Message, [string]$WindowTitle, [string]$DefaultText)
{
    Add-Type -AssemblyName Microsoft.VisualBasic
    return [Microsoft.VisualBasic.Interaction]::InputBox($Message, $WindowTitle, $DefaultText)

    <# Example #>
    <#
        $textEntered = Read-InputBoxDialog -Message "Please enter the word 'Banana'" -WindowTitle "Input Box Example" -DefaultText "Apple"
        if ($textEntered -eq $null) { Write-Host "You clicked Cancel" }
        elseif ($textEntered -eq "Banana") { Write-Host "Thanks for typing Banana" }
        else { Write-Host "You entered $textEntered" }
    #>

}

function Read-MessageBoxDialog([string]$Message, [string]$WindowTitle, [System.Windows.Forms.MessageBoxButtons]$Buttons = [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]$Icon = [System.Windows.Forms.MessageBoxIcon]::None)
{
    Add-Type -AssemblyName System.Windows.Forms
    return [System.Windows.Forms.MessageBox]::Show($Message, $WindowTitle, $Buttons, $Icon)

    <# Example #>
    <#
        $buttonClicked = Read-MessageBoxDialog -Message "Please press the OK button." -WindowTitle "Message Box Example" -Buttons OKCancel -Icon Exclamation
        if ($buttonClicked -eq "OK") { Write-Host "Thanks for pressing OK" }
        else { Write-Host "You clicked $buttonClicked" }
    #>

}
function Read-OpenFileDialog([string]$WindowTitle, [string]$InitialDirectory, [string]$Filter = "All files (*.*)|*.*", [switch]$AllowMultiSelect)
{
    Add-Type -AssemblyName System.Windows.Forms
    $openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $openFileDialog.Title = $WindowTitle
    if (![string]::IsNullOrWhiteSpace($InitialDirectory)) { $openFileDialog.InitialDirectory = $InitialDirectory }
    $openFileDialog.Filter = $Filter
    if ($AllowMultiSelect) { $openFileDialog.MultiSelect = $true }
    $openFileDialog.ShowHelp = $true    # Without this line the ShowDialog() func may hang depending on system configuration and running from console vs. ISE.
    $openFileDialog.ShowDialog() > $null
    if ($AllowMultiSelect) { return $openFileDialog.Filenames } else { return $openFileDialog.Filename }

    <# Example #>
    <#
        $filePath = Read-OpenFileDialog -WindowTitle "Select Text File Example" -InitialDirectory 'C:\' -Filter "Text files (*.txt)|*.txt"
        if (![string]::IsNullOrEmpty($filePath)) { Write-Host "You selected the file: $filePath" }
        else { "You did not select a file." }
    #>

}
function Send-EmailWithSendGrid-PS {
    Param
   (
        [Parameter(Mandatory=$true)]
        [string] $From,

        [Parameter(Mandatory=$true)]
        [String] $Recipients,

        [Parameter(Mandatory=$true)]
        [string] $Subject,

        [Parameter(Mandatory=$true)]
        [string] $Body,

        [Parameter(Mandatory=$false)]
        [string] $AttachmentPath
   )
    #Send with Send-MailMessage
    [string[]]$To = $recipients.Split(',')
    $SMTPServer = "smtp.sendgrid.net"
    $SMTPPort = "587"
    $EmailUsername = "Moonshot-MSP"
    $EmailPassword = ConvertTo-SecureString "Telco123!" -AsPlainText -Force
    $psCred = New-Object System.Management.Automation.PSCredential -ArgumentList ($EmailUsername, $EmailPassword)
    If($AttachmentPath -ne ""){
        Send-MailMessage -From $From -to $To -Subject $Subject -Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl -Credential $psCred -Attachments "$AttachmentPath" â€“DeliveryNotificationOption OnSuccess

    }Else{
        Send-MailMessage -From $From -to $To -Subject $Subject -Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl -Credential $psCred â€“DeliveryNotificationOption OnSuccess
    }
}
function Send-EmailWithSendGrid-Manual
{
#Splat for Function Below
Write-Host "Enter 'From' Display Name: " -ForegroundColor Yellow -NoNewline; $FromDisplayName = Read-Host
Write-Host "Enter 'From' Address: " -ForegroundColor Yellow -NoNewline; $FromAddress = Read-Host
Write-Host "Enter Recipients (comma separated, no space): " -ForegroundColor Yellow -NoNewline; $Recipients = Read-Host
Write-Host "Enter Email Subject: " -ForegroundColor Yellow -NoNewline; $SubjectSet = Read-Host
Write-Host "Enter Email Body: " -ForegroundColor Yellow -NoNewline; $BodySet = Read-Host
Write-Host "Include an Attachment?:" -ForegroundColor Yellow
Write-Host "Yes or No: " -ForegroundColor Yellow -NoNewLine; $AttachmentYN = ""; $AttachmentYN = Read-Host
If($AttachmentYN -like "*y*"){
    Write-Host "Enter path to Attachment: " -ForegroundColor Yellow -NoNewline; $AttachmentPathEnter = Read-Host  
}Else{
    $AttachmentPathEnter = ""
}
$Global:MailParams = @{ 
    From = "$FromDisplayName <$FromAddress>"
    Recipients = "$Recipients"
    Subject = "$SubjectSet"
    Body = "$BodySet"
    AttachmentPath = "$AttachmentPathEnter"
}
If($AttachmentPathEnter -ne ""){
    Send-EmailWithSendGrid-PS @MailParams  
}Else{
Write-Host "Send with PowerShell (Send-MailMessage) or API call (Invoke-RestMethod)?" -ForegroundColor Yellow
Write-Host "PS or API: " -ForegroundColor Yellow -NoNewLine; $SendType = ""; $SendType = Read-Host
If($SendType -like "*ps*"){
    Send-EmailWithSendGrid-PS @MailParams
}
If($SendType -like "*api*"){
    Send-EmailWithSendGrid-API @MailParams
}
}
$Global:MailParams = @{ 
    FromFull = ""
    Recipients = ""
    Subject = ""
    Body = ""
    AttachmentPath = ""
    
}
}
function Send-EmailWithSendGrid-API {
    Param
   (
        [Parameter(Mandatory=$true)]
        [string] $From,

        [Parameter(Mandatory=$true)]
        [String] $Recipients,

        [Parameter(Mandatory=$true)]
        [string] $Subject,

        [Parameter(Mandatory=$false)]
        [string] $AttachmentPath,

        [Parameter(Mandatory=$true)]
        [string] $Body
   )
    $apiKey = "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"
    $headers = @{}
    $headers.Add("Authorization","Bearer $apiKey")
    $headers.Add("Content-Type", "application/json")

    $jsonRequest = [ordered]@{
                           personalizations= @(@{to = @(@{email =  "$Recipients"})
                               subject = "$SubJect" })
                               from = @{email = "$From"}
                               content = @( @{ type = "text/plain"
                                           value = "$Body" }
                               )} | ConvertTo-Json -Depth 10
    Invoke-RestMethod   -Uri "https://api.sendgrid.com/v3/mail/send" -Method Post -Headers $headers -Body $jsonRequest 
}
function Start-MailboxChecks
{
#Description: Mailbox scripts to get permissions and other information
function Sub-Check-FullAccess
{
    $FunctionName = "Mailbox Full Access Check"
    Write-Host
    Write-Host "======== $FunctionName ========" -ForegroundColor Yellow
    Write-Host
    Write-Host " Enter Full Name, Alias, or primary address of mailbox to check permissions." -ForegroundColor Yellow
    Write-Host " Mailbox: " -Foregroundcolor Green -NoNewLine; $MailboxSearch = Read-Host
    
    $Valid = "0"
    Do{
        Try{
            $SelectedUser = Get-Mailbox "$MailboxSearch" -ErrorAction Stop
            $SelectedMailboxName = (Get-Mailbox "$MailboxSearch").DisplayName
            $Valid = "1"
            Write-Host "`n"
            Write-Host " Found user $($SelectedUser.Displayname)!" -ForegroundColor Green
            Start-Sleep -Milliseconds 250
            Write-Host ""
            Start-Sleep -Milliseconds 500
        }Catch{
            $Valid = "0"
            Write-Host
            Write-Host " Mailbox " -ForegroundColor Red -NoNewLine; Write-Host "$MailboxSearch" -ForegroundColor White -NoNewLine; Write-Host " not found! Please try again." -ForegroundColor Red -NoNewLine
            Start-Sleep -Seconds 1.5
            Write-Host "`r Enter Full Name, Alias, or primary address of mailbox to check permissions." -ForegroundColor Yellow
            Write-Host " Mailbox: " -Foregroundcolor Green -NoNewLine; $MailboxSearch = Read-Host
        }
    }Until ($Valid -eq "1")
    Write-Host
    Write-Host " Continue check of mailbox $($SelectedUser.DisplayName)?" -ForegroundColor Yellow
    $ContinueCheck = Read-Host " Yes or No"
    If($ContinueCheck -like "*no*"){
        break
    }
    Write-Host
    Write-Host " Checking Full Access permissions on $($SelectedUser.DisplayName). Please Wait..." -ForegroundColor Green
    $MPerms = Get-MailboxPermission "$mailboxSearch" | Where {($_.AccessRights -like "*FullAccess*") -and ($_.User -notlike "*\*") -and ($_.User -notlike "S-*")}
    $Results = @()
    ForEach ($PermUser in $MPerms){
        $PermUserDisplayName = $null
        $GetDisplayUser = Get-MsolUser -userprincipalname $PermUser.user -ErrorAction Ignore
        $PermUserDisplayName = $GetDisplayUser.DisplayName
        If(!$PermUserDisplayName){
            $GetDisplayGroup = Get-Group $PermUser.user -ErrorAction Ignore
            $PermUserDisplayName = $GetDisplayGroup.DisplayName
        }
        $PermissionUser = [pscustomobject][ordered]@{
            'Mailbox Name' = $PermUser.Identity
            'Full Access User or Group' = $PermUserDisplayName      
        }
        $Results += $PermissionUser
    }
    Write-Host
    $Results | Out-Host
    Write-Host
    Write-Host "===== Export Results? =====" -ForegroundColor Yellow
    Write-Host " Press 1 for XLSX table" -ForegroundColor Green
    Write-Host " Press 2 to copy to Clipboard (Not Formatted)" -ForegroundColor Green
    Write-Host " Press any other key to end" -ForegroundColor Green
    Write-Host
    $ExportPress = Read-Host " Selection"
        If($ExportPress -eq '2'){
            $Results | Clip
            Start-Sleep -Seconds 1
        }
        If($ExportPress -eq '1'){
            $TenantDisplay = Get-AzureAdTenantDetail | Select -ExpandProperty DisplayName
            $Date1 = Get-Date -Format "MM-dd-yyyy HH-mm"
            $Global:FileName = "$TenantDisplay - $FunctionName - $SelectedMailboxName - $Date1.csv"
            $OutputPath = "$home\Downloads\$FileName"
            $Global:CSVpath = $OutputPath
            $Global:XFileName = "$TenantDisplay - $FunctionName - $SelectedMailboxName - $Date1.xlsx"
            $Global:XLSpath = "$home\Downloads\$XFileName"
            $Results | Export-CSV -Path $CSVpath -Append -NoTypeInformation
            Sub-Create-XLS
            $Global:FileName = $null
            $Global:XFileName = $null
            $Global:CSVpath = $null
            $Global:XLSpath = $null
        }
}
function Sub-Check-UserFullAccess
{
    $FunctionName = "User Full Access Check"
    Write-Host
    Write-Host "======== $FunctionName ========" -ForegroundColor Yellow
    Write-Host
    Write-Host " Enter Display Name, Alias, or UPN of the user to check." -ForegroundColor Yellow
    Write-Host " User: " -Foregroundcolor Green -NoNewLine; $MailboxSearch = Read-Host
    $Valid = "0"
    Do{
        Try{
            $SelectedUser = Get-Mailbox "$MailboxSearch" -ErrorAction Stop
            $Valid = "1"
            Write-Host ""
            Write-Host " Found user $($SelectedUser.Displayname)!" -ForegroundColor Green
            Start-Sleep -Milliseconds 250
            Write-Host ""
            Start-Sleep -Milliseconds 500
        }Catch{
            $Valid = "0"
            Write-Host
            Write-Host " User " -ForegroundColor Red -NoNewLine; Write-Host "$MailboxSearch" -ForegroundColor White -NoNewLine; Write-Host " not found! Please try again." -ForegroundColor Red -NoNewLine
            Start-Sleep -Seconds 1.5
            Write-Host "`r Enter Display Name, Alias, or UPN of the user to check." -ForegroundColor Yellow
            Write-Host " User: " -Foregroundcolor Green -NoNewLine; $MailboxSearch = Read-Host
        }
    }Until ($Valid -eq "1")
    
    Write-Host
    Write-Host " Processing Full Access permissions check for $($SelectedUser.DisplayName)." -ForegroundColor Green
    Write-Host " Identifying all Mailboxes. Please Wait..." -ForegroundColor Gray -NoNewLine
    $Mbxs = Get-Mailbox -ResultSize Unlimited
    $MbxCount = $Mbxs.Count
    Write-Host "`r All Mailboxes Identified. $MbxCount in Total. "  -ForegroundColor Gray
    Start-Sleep -Milliseconds 500
    $ContinueCheck = ""
    $EstimatedTime = [math]::Round(($MbxCount * .60) / 60)
    If($EstimatedTime -lt 2){
        Write-Host
        Write-Host " Check estimated to take less than 2 minutes." -ForegroundColor Yellow
        $ContinueCheck = "yes"
        Start-Sleep -Milliseconds 500
        Write-Host
    }Else{
        Write-Host
    Write-Host " Check estimated to take $EstimatedTime minutes. Continue?" -ForegroundColor Yellow
    $ContinueCheck = Read-Host " Yes or No"
    Write-Host
    }
    If($ContinueCheck -like "*n*"){
        break
    }
    Write-Host " Checking Permissions.... "  -ForegroundColor Gray -NoNewLine
    Start-Sleep -Milliseconds 250
    $Counter = 1
    $Results = @()
    ForEach ($Mbx in $Mbxs){
        Write-Progress -Activity "Checking Permissions" -Status "$Counter of $MbxCount" -PercentComplete ((($Counter)/ $MbxCount) * 100) -CurrentOperation "$($Mbx.DisplayName)"
        $Permission = $null
        $Permission = $Mbx | Get-MailboxPermission -User $SelectedUser.Alias
        If(!$Permission){
        }Else{
            $PermissionUser = [pscustomobject][ordered]@{
                'User Name' = $SelectedUser.DisplayName
                'Full Access Mailbox Name' = $Mbx.DisplayName
            }
            $Results += $PermissionUser
        }
        $Permission = $null
        $Counter++
    }
    Write-Host "`r Complete! Writing Table. Press Up arrow if screen does not update after 10 seconds."  -ForegroundColor Gray
    Write-Host
    $Results | Out-Host
    Write-Host
    Write-Host "===== Export Results? =====" -ForegroundColor Yellow
    Write-Host " Press 1 for XLSX table" -ForegroundColor Green
    Write-Host " Press 2 to copy to Clipboard (Not Formatted)" -ForegroundColor Green
    Write-Host " Press any other key to end" -ForegroundColor Green
    Write-Host
    $ExportPress = Read-Host " Selection"
        If($ExportPress -eq '2'){
            $Results | Clip
            Start-Sleep -Seconds 1
        }
        If($ExportPress -eq '1'){
            $TenantDisplay = Get-AzureAdTenantDetail | Select -ExpandProperty DisplayName
            $Date1 = Get-Date -Format "MM-dd-yyyy HH-mm"
            $Global:FileName = "$TenantDisplay - $FunctionName - $($SelectedUser.DisplayName) - $Date1.csv"
            $OutputPath = "$home\Downloads\$FileName"
            $Global:CSVpath = $OutputPath
            $Global:XFileName = "$TenantDisplay - $FunctionName - $($SelectedUser.DisplayName) - $Date1.xlsx"
            $Global:XLSpath = "$home\Downloads\$XFileName"
            $Results | Export-CSV -Path $CSVpath -Append -NoTypeInformation
            Sub-Create-XLS
            $Global:FileName = $null
            $Global:XFileName = $null
            $Global:CSVpath = $null
            $Global:XLSpath = $null
        }
}
function Sub-Create-XLS
{
    #$OutputArray | Out-GridView
    ### Set input and output path
    $inputCSV = "$CSVPath"
    $outputXLSX = "$XLSPath"

    ### Create a new Excel Workbook with one empty sheet
    $excel = New-Object -ComObject excel.application 
    $workbook = $excel.Workbooks.Add(1)
    $worksheet = $workbook.worksheets.Item(1)

    ### Build the QueryTables.Add command
    ### QueryTables does the same as when clicking "Data » From Text" in Excel
    $TxtConnector = ("TEXT;" + $inputCSV)
    $Connector = $worksheet.QueryTables.add($TxtConnector,$worksheet.Range("A1"))
    $query = $worksheet.QueryTables.item($Connector.name)

    ### Set the delimiter (, or ;) according to your regional settings
    $query.TextFileOtherDelimiter = $Excel.Application.International(5)

    ### Set the format to delimited and text for every column
    ### A trick to create an array of 2s is used with the preceding comma
    $query.TextFileParseType  = 1
    $query.TextFileColumnDataTypes = ,2 * $worksheet.Cells.Columns.Count
    $query.AdjustColumnWidth = 1
    ### Execute & delete the import query
    $query.Refresh()
    $query.Delete()
    $list = $excel.ActiveSheet.ListObjects.Add(
        [Microsoft.Office.Interop.Excel.XlListObjectSourceType]::xlSrcRange, # Add a range
        $excel.ActiveCell.CurrentRegion, # Get the current region, by default A1 is selected so it'll select all contiguous rows
        $null,
        [Microsoft.Office.Interop.Excel.XlYesNoGuess]::xlYes # Yes, we have a header row
    )
    ### Save & close the Workbook as XLSX. Change the output extension for Excel 2003
    $Workbook.SaveAs($outputXLSX,51)
    $excel.Quit()
    Remove-Item -path "$inputCSV"

    Start-Sleep -Seconds 1
    Write-Host
    Write-Host 
    Write-Host "==============================================================" -ForegroundColor Yellow
    Write-Host " Done! See report in your Downloads folder:" -ForegroundColor Yellow
    Write-Host " $XFileName" -ForegroundColor Green
    Write-Host "==============================================================" -ForegroundColor Yellow
    Write-Host
    Start-Sleep -Seconds 1
}
function Sub-Check-Size
{
    $FunctionName = "Check and Modify Mailbox Size"
    Write-Host
    Write-Host "======== $FunctionName ========" -ForegroundColor Yellow
    Write-Host
    Write-Host " Enter Full Name, Alias, or primary address of mailbox to check size." -ForegroundColor Yellow
    Write-Host " Mailbox: " -Foregroundcolor Green -NoNewLine; $MailboxSearch = Read-Host
    
    $Valid = "0"
    Do{
        Try{
            $SelectedUser = Get-Mailbox "$MailboxSearch" -ErrorAction Stop
            $SelectedMailboxName = (Get-Mailbox "$MailboxSearch").DisplayName
            $Valid = "1"
            Write-Host "`n"
            Write-Host " Found mailbox $($SelectedUser.Displayname)!" -ForegroundColor Green
            Start-Sleep -Milliseconds 250
            Write-Host ""
            Start-Sleep -Milliseconds 500
        }Catch{
            $Valid = "0"
            Write-Host
            Write-Host " Mailbox " -ForegroundColor Red -NoNewLine; Write-Host "$MailboxSearch" -ForegroundColor White -NoNewLine; Write-Host " not found! Please try again." -ForegroundColor Red -NoNewLine
            Start-Sleep -Seconds 1.5
            Write-Host "`r Enter Full Name, Alias, or primary address of mailbox to check size." -ForegroundColor Yellow
            Write-Host " Mailbox: " -Foregroundcolor Green -NoNewLine; $MailboxSearch = Read-Host
        }
    }Until ($Valid -eq "1")
    Write-Host
    $TotalSize = (Get-MailboxStatistics $SelectedUser.Alias -ErrorAction SilentlyContinue | Select-Object -Property TotalItemSize -ErrorAction SilentlyContinue | ft -hidetableheaders | Out-String).Trim()
    $QuotaMax = ($SelectedUser | Select-Object -Property ProhibitSendQuota -ErrorAction SilentlyContinue | ft -hidetableheaders | Out-String).Trim()
    Write-Host "Current Size: " -ForegroundColor Yellow -NoNewline; Write-Host "$TotalSize" -ForegroundColor White
    Write-Host "Max Mbx Size: " -ForegroundColor Yellow -NoNewline; Write-Host "$QuotaMax" -ForegroundColor White
    Write-Host
    Write-Host "===== Actions =====" -ForegroundColor Yellow
    Write-Host " Press 1 to increase mailbox size. (Make sure license already applied!)" -ForegroundColor Green
    Write-Host " Press 2 to " -ForegroundColor Green
    Write-Host " Press any other key to end" -ForegroundColor Green
    Write-Host
    $ActionPress = Read-Host " Selection"
        If($ActionPress -eq '1'){
            Write-Host
            Start-Sleep -Milliseconds 500
            Write-Host " Setting Mailbox Quota to 100GB..." -ForegroundColor Gray -NoNewline
            $SelectedUser | Set-Mailbox -ProhibitSendQuota 99GB -ProhibitSendReceiveQuota 100GB -IssueWarningQuota 97GB
            Start-Sleep -Milliseconds 500
            Write-Host "`r Quota Set to 100GB. " -ForegroundColor Gray
        }
        If($ActionPress -eq '2'){
        }
}
function Sub-Show-MailboxActionMenu
{
    Write-Host 
    Write-Host "====================== Mailbox Check Scripts ==========================" -ForegroundColor Yellow
    Write-Host
    Write-Host " Action Options:" -ForegroundColor Yellow
    Write-Host ""
    Write-Host " 1. Mailbox Full Access Check" -ForegroundColor Green
    Write-Host " See who has Full Access to a mailbox" -ForegroundColor Yellow
    Write-Host " 2. User Full Access Check" -ForegroundColor Green
    Write-Host " List all mailboxes a user has Full Access to" -ForegroundColor Yellow
    Write-Host " Note: This can take a while depending on total mailboxes" -ForegroundColor Yellow
    Write-Host " 3. Check and Modify Mailbox Size" -ForegroundColor Green
    Write-Host " See mailbox size, current cap, and expand cap if licensed" -ForegroundColor Yellow
    Write-Host " 4. " -ForegroundColor Green
    Write-Host " -" -ForegroundColor Yellow
    Write-Host " 5. " -ForegroundColor Green
    Write-Host " -" -ForegroundColor Yellow
    Write-Host " 6. " -ForegroundColor Green
    Write-Host " -" -ForegroundColor Yellow
    Write-Host " 7. " -ForegroundColor Green
    Write-Host " -" -ForegroundColor Yellow
    Write-Host " 8. " -ForegroundColor Green
    Write-Host " -" -ForegroundColor Yellow
    Write-Host " 9. " -ForegroundColor Green
    Write-Host " -" -ForegroundColor Yellow
    Write-Host " 0. Exit Script" -ForegroundColor Green
    Write-Host
    Write-Host "===========================================================================" -ForegroundColor Yellow
}
Write-Host ""
Write-Host "================================================================" -ForegroundColor Yellow
Write-Host "" -ForegroundColor Yellow
Write-Host " Welcome to the Mailbox Check Scripts!" -ForegroundColor Yellow
Write-Host "" -ForegroundColor Yellow
Write-Host "================================================================" -ForegroundColor Yellow
Write-Host ""
Do{
    Write-Host ""
    Sub-Show-MailboxActionMenu
    Write-Host ""
    $Selection = ""
    Write-Host " Enter Action Number: " -ForegroundColor Yellow -NoNewLine; $Selection = Read-Host
    Switch ($Selection)
    {
        '1' {
            Sub-Check-FullAccess
        }
        '2' {
            Sub-Check-UserFullAccess
        }
        '3' {
            
        }
        '4' {
            
        }
        '5' {
            
        }
        '6' {
            
        }
        '7' {
        }
        '8' {
        }
        '9' {
        }
        '0' {
            Write-Host
            Write-Host "Exiting Checks Scripts!" -ForegroundColor Green
            Write-Host
        }
    }
}Until ($Selection -eq '0')
Get-Commands
}
function Get-MFAStatus
{
#Description: Generate report of users and their MFA status
Clear-Host
Write-Host "" -ForegroundColor Yellow
Write-Host "===============================MFA Status Report===============================" -ForegroundColor Yellow
Write-Host ""
Write-Host " Starting MFA Report generation..." -ForegroundColor Yellow
Write-Host ""
Write-Host "===============================================================================" -ForegroundColor Yellow
Start-Sleep -seconds 2

try
{ $var = Get-AzureADTenantDetail }

catch [Microsoft.Open.Azure.AD.CommonLibrary.AadNeedAuthenticationException]
{
Clear-Host
Write-Host "" -ForegroundColor Yellow
Write-Host "===============================MFA Status Report===============================" -ForegroundColor Yellow
Write-Host " You must be connected to Office 365 MSOnline and Exchange for this report!" -ForegroundColor Yellow
Write-Host "" -ForegroundColor Yellow
Write-Host " Run Connect-Office365 and selection options 2 and 3" -ForegroundColor Yellow
Write-Host "===============================================================================" -ForegroundColor Yellow
Read-Host " Press any key to continue"
break
}
Clear-Host
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host "============================================" -ForegroundColor Yellow
Write-Host "Generating Report. Please Wait" -ForegroundColor Yellow
Write-Host "============================================" -ForegroundColor Yellow
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Progress -Activity 'Creating Report File!' -Status "Please wait."
Start-Sleep -Seconds 2
$TenantDisplay = Get-AzureAdTenantDetail | Select -ExpandProperty DisplayName
$Date1 = Get-Date -Format "MM-dd-yyyy HH-mm"
$FileName = "$TenantDisplay - MFA Status - $Date1.xlsx"
$OutputPath = "$home\Desktop\$FileName"
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $true
#Create the workbook
$workbook = $excel.Workbooks.Add()
$workbook.SaveAs($OutputPath)
$InitalWorksheet = $workbook.Worksheets.Item(1)
$InitalWorksheet.Name = "MFAStatus"
#$Worksheet = $Workbook.Worksheets.Add()
#$Worksheet.Name = "Public Folders"
#$Worksheet = $Workbook.Worksheets.Add()
#$Worksheet.Name = "MFAStatus"
$Sheet_MFAStatus = $Workbook.Worksheets.Item("MFAStatus")



#MFA Status Sheet
$Sheet_MFAStatus.Activate()
$Sheet_MFAStatus.ActiveSheet
#Create a Title for the first worksheet and adjust the font
$row = 1
$Column = 1
$Sheet_MFAStatus.Cells.Item($row, $column) = 'MFA Status'
$Sheet_MFAStatus.Cells.Item($row, $column).Font.Size = 26
#$Sheet_MFAStatus.Cells.Item($row,$column).Font.Bold=$True
$Sheet_MFAStatus.Cells.Item($row, $column).Font.Name = "Cambria"
$Sheet_MFAStatus.Cells.Item($row, $column).Font.ThemeFont = 1
$Sheet_MFAStatus.Cells.Item($row, $column).Font.ThemeColor = 4
$Sheet_MFAStatus.Cells.Item($row, $column).Font.ColorIndex = 55
$Sheet_MFAStatus.Cells.Item($row, $column).Font.Color = 8210719
$range = $Sheet_MFAStatus.Range("a1", "c1")
$range.Style = 'Title'
$range.Font.Size = 26
$range = $Sheet_MFAStatus.Range("a1", "c1")
$range.Merge() | Out-Null
$range.VerticalAlignment = -4160
$row = 2
$Column = 1
$Sheet_MFAStatus.Cells.Item($row, $column) = '#'
$Sheet_MFAStatus.Cells.Item($row, $Column).Font.Bold = $True
$Sheet_MFAStatus.Cells.Item($row, $Column).Interior.ColorIndex = 55
$Sheet_MFAStatus.Cells.Item($row, $Column).HorizontalAlignment = -4108
$Sheet_MFAStatus.Cells.Item($row, $column).Font.Name = "Cambria"
$Sheet_MFAStatus.Cells.Item($row, $column).Font.ColorIndex = 2
$Sheet_MFAStatus.Cells.Item($row, $column).Font.ThemeFont = 1
$row = 2
$Column = 2
$Sheet_MFAStatus.Cells.Item($row, $column) = 'Display Name'
$Sheet_MFAStatus.Cells.Item($row, $Column).Font.Bold = $True
$Sheet_MFAStatus.Cells.Item($row, $Column).Interior.ColorIndex = 55
$Sheet_MFAStatus.Cells.Item($row, $Column).HorizontalAlignment = -4108
$Sheet_MFAStatus.Cells.Item($row, $column).Font.Name = "Cambria"
$Sheet_MFAStatus.Cells.Item($row, $column).Font.ColorIndex = 2
$Sheet_MFAStatus.Cells.Item($row, $column).Font.ThemeFont = 1
$row = 2
$Column = 3
$Sheet_MFAStatus.Cells.Item($row, $column) = 'User Principal Name'
$Sheet_MFAStatus.Cells.Item($row, $Column).Font.Bold = $True
$Sheet_MFAStatus.Cells.Item($row, $Column).Interior.ColorIndex = 55
$Sheet_MFAStatus.Cells.Item($row, $Column).HorizontalAlignment = -4108
$Sheet_MFAStatus.Cells.Item($row, $column).Font.Name = "Cambria"
$Sheet_MFAStatus.Cells.Item($row, $column).Font.ColorIndex = 2
$Sheet_MFAStatus.Cells.Item($row, $column).Font.ThemeFont = 1
$row = 2
$Column = 4
$Sheet_MFAStatus.Cells.Item($row, $column) = 'MFA Enforced'
$Sheet_MFAStatus.Cells.Item($row, $Column).Font.Bold = $True
$Sheet_MFAStatus.Cells.Item($row, $Column).Interior.ColorIndex = 55
$Sheet_MFAStatus.Cells.Item($row, $Column).HorizontalAlignment = -4108
$Sheet_MFAStatus.Cells.Item($row, $column).Font.Name = "Cambria"
$Sheet_MFAStatus.Cells.Item($row, $column).Font.ColorIndex = 2
$Sheet_MFAStatus.Cells.Item($row, $column).Font.ThemeFont = 1
$row = 2
$Column = 5
$Sheet_MFAStatus.Cells.Item($row, $column) = 'Auth Phone Number'
$Sheet_MFAStatus.Cells.Item($row, $Column).Font.Bold = $True
$Sheet_MFAStatus.Cells.Item($row, $Column).Interior.ColorIndex = 55
$Sheet_MFAStatus.Cells.Item($row, $Column).HorizontalAlignment = -4108
$Sheet_MFAStatus.Cells.Item($row, $column).Font.Name = "Cambria"
$Sheet_MFAStatus.Cells.Item($row, $column).Font.ColorIndex = 2
$Sheet_MFAStatus.Cells.Item($row, $column).Font.ThemeFont = 1
$row = 2
$Column = 6
$Sheet_MFAStatus.Cells.Item($row, $column) = 'Auth Methods (Not Always Accurate)'
$Sheet_MFAStatus.Cells.Item($row, $Column).Font.Bold = $True
$Sheet_MFAStatus.Cells.Item($row, $Column).Interior.ColorIndex = 55
$Sheet_MFAStatus.Cells.Item($row, $Column).HorizontalAlignment = -4108
$Sheet_MFAStatus.Cells.Item($row, $column).Font.Name = "Cambria"
$Sheet_MFAStatus.Cells.Item($row, $column).Font.ColorIndex = 2
$Sheet_MFAStatus.Cells.Item($row, $column).Font.ThemeFont = 1

$UserMailboxes = Get-Mailbox | Where {$_.RecipientTypeDetails -eq "UserMailbox"} | Sort-Object -Property DisplayName
$UserArrayEnabled = @()
$UserArrayDisabled = @()
$UsersCount = $UserMailboxes.count
$counter = 0
ForEach ($user in $UserMailboxes){
    $UDN = $user.DisplayName
    $Counter++
    Write-Progress -Activity 'Processing Users' -Status "User $counter of $UsersCount" -CurrentOperation "$UDN" -PercentComplete (($Counter / $UsersCount) * 100)
    $OID = $user.ExternalDirectoryObjectID
    $Msol = Get-MsolUser -ObjectID $OID -ErrorAction SilentlyContinue | Where {$_.IsLicensed -eq $true} | Where {$_.UserType -ne 'Guest'}
    $Methods = @()
    ForEach ($method in $Msol.StrongAuthenticationmethods){
        $Type = $method.MethodType
        if($method.IsDefault -eq $true){$Default = " (Default)"}else{$Default = ""}
        $Methods += "$Type$Default"
        }
        
    $item = New-Object PSObject -Property @{
        DisplayName = $Msol.DisplayName;
        UPN = $Msol.UserPrincipalName;
        AuthPhone = $Msol.StrongAuthenticationUserDetails.PhoneNumber;
        OTPDevice = $Methods -join ", ";
        Status = if($Msol.StrongAuthenticationRequirements.State -ne $null){$Msol.StrongAuthenticationRequirements.State} else {"Disabled"}
        }
        
    if($Msol.StrongAuthenticationRequirements.State -ne $null){
        $UserArrayEnabled += $item
    }else{
        $UserArrayDisabled += $item
    }
}

$UserArray = $UserArrayEnabled + $UserArrayDisabled
$Sheet_MFAStatus_Y = 3
$RowNumber = 0
$Counter = 0

ForEach ($item in $UserArray){
        $RowNumber++
        $Counter++
        $Row = $Sheet_MFAStatus_Y++
        $DisplayName = $item.DisplayName
        $UPN = $item.UPN
        $AuthPhone = $item.AuthPhone
        $OTPDevice = $item.OTPDevice
        $Status = $item.Status
 Write-Progress -Activity 'Writing to Report' -Status "User $counter of $UsersCount" -CurrentOperation "$DisplayName" -PercentComplete (($Counter / $UsersCount) * 100)

        

$Sheet_MFAStatus.Cells.Item($Row, 1) = $RowNumber
$Sheet_MFAStatus.Cells.Item($row, 1).Font.Bold = $True
$Sheet_MFAStatus.Cells.Item($row, 1).Interior.ColorIndex = 55
$Sheet_MFAStatus.Cells.Item($row, 1).HorizontalAlignment = -4108
$Sheet_MFAStatus.Cells.Item($row, 1).VerticalAlignment = -4108
$Sheet_MFAStatus.Cells.Item($row, 1).Font.Name = "Cambria"
$Sheet_MFAStatus.Cells.Item($row, 1).Font.ColorIndex = 2
$Sheet_MFAStatus.Cells.Item($row, 1).Font.ThemeFont = 1
$Even = $RowNumber % 2
If ($Even -eq 0)
{
$Sheet_MFAStatus.Cells.Item($Row, 1).Font.Bold = $True
$Sheet_MFAStatus.Cells.Item($Row, 2) = $DisplayName
$Sheet_MFAStatus.Cells.Item($row, 2).Interior.ColorIndex = 15
$Sheet_MFAStatus.Cells.Item($Row, 3) = $UPN
$Sheet_MFAStatus.Cells.Item($row, 3).Interior.ColorIndex = 15
$Sheet_MFAStatus.Cells.Item($Row, 4) = $Status
$Sheet_MFAStatus.Cells.Item($row, 4).Interior.ColorIndex = 15
$Sheet_MFAStatus.Cells.Item($Row, 5) = $AuthPhone
$Sheet_MFAStatus.Cells.Item($row, 5).Interior.ColorIndex = 15
$Sheet_MFAStatus.Cells.Item($Row, 6) = $OTPDevice
$Sheet_MFAStatus.Cells.Item($row, 6).Interior.ColorIndex = 15
}
Else
{
$Sheet_MFAStatus.Cells.Item($Row, 1).Font.Bold = $True
$Sheet_MFAStatus.Cells.Item($Row, 2) = $DisplayName
$Sheet_MFAStatus.Cells.Item($row, 2).Interior.ColorIndex = 2
$Sheet_MFAStatus.Cells.Item($Row, 3) = $UPN
$Sheet_MFAStatus.Cells.Item($row, 3).Interior.ColorIndex = 2
$Sheet_MFAStatus.Cells.Item($Row, 4) = $Status
$Sheet_MFAStatus.Cells.Item($row, 4).Interior.ColorIndex = 2
$Sheet_MFAStatus.Cells.Item($Row, 5) = $AuthPhone
$Sheet_MFAStatus.Cells.Item($row, 5).Interior.ColorIndex = 2
$Sheet_MFAStatus.Cells.Item($Row, 6) = $OTPDevice
$Sheet_MFAStatus.Cells.Item($row, 6).Interior.ColorIndex = 2
}

$Sheet_MFAStatus.Columns.AutoFit() | Out-Null
$Sheet_MFAStatus.Rows.AutoFit() | Out-Null
}

$Workbook.Sheets(1).Select()
$excel.DisplayAlerts = $False
$workbook.SaveAs($OutputPath)
$excel.DisplayAlerts = $True
Start-Sleep -Seconds 2
Clear-Host
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host "===================================================================" -ForegroundColor Yellow
Write-Host "===================================================================" -ForegroundColor Yellow
Write-Host "Report Completed!" -ForegroundColor Yellow
Write-Host ""
Write-Host "Saved to Desktop as:" -ForegroundColor Yellow
Write-Host "'$FileName'" -ForegroundColor Yellow
Write-Host "===================================================================" -ForegroundColor Yellow
Write-Host "===================================================================" -ForegroundColor Yellow
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Write-Host ""
Get-Commands
}
function New-PartnerUserReport
{
#Description: Report on user across Partner Tenants
    $Sku = @{
        "O365_BUSINESS_ESSENTIALS"      = "Office 365 Business Essentials"
        "O365_BUSINESS_PREMIUM"      = "Office 365 Business Premium"
        "DESKLESSPACK"      = "Office 365 (Plan K1)"
        "DESKLESSWOFFPACK"      = "Office 365 (Plan K2)"
        "LITEPACK"      = "Office 365 (Plan P1)"
        "EXCHANGESTANDARD"      = "Office 365 Exchange Online Only"
        "STANDARDPACK"      = "Enterprise Plan E1"
        "STANDARDWOFFPACK"      = "Office 365 (Plan E2)"
        "ENTERPRISEPACK" = "Enterprise Plan E3"
        "ENTERPRISEPACKLRG"      = "Enterprise Plan E3"
        "ENTERPRISEWITHSCAL" = "Enterprise Plan E4"
        "STANDARDPACK_STUDENT"      = "Office 365 (Plan A1) for Students"
        "STANDARDWOFFPACKPACK_STUDENT"      = "Office 365 (Plan A2) for Students"
        "ENTERPRISEPACK_STUDENT" = "Office 365 (Plan A3) for Students"
        "ENTERPRISEWITHSCAL_STUDENT" = "Office 365 (Plan A4) for Students"
        "STANDARDPACK_FACULTY"      = "Office 365 (Plan A1) for Faculty"
        "STANDARDWOFFPACKPACK_FACULTY"      = "Office 365 (Plan A2) for Faculty"
        "ENTERPRISEPACK_FACULTY" = "Office 365 (Plan A3) for Faculty"
        "ENTERPRISEWITHSCAL_FACULTY" = "Office 365 (Plan A4) for Faculty"
        "ENTERPRISEPACK_B_PILOT" = "Office 365 (Enterprise Preview)"
        "STANDARD_B_PILOT"      = "Office 365 (Small Business Preview)"
        "VISIOCLIENT"      = "Visio Pro Online"
        "POWER_BI_ADDON" = "Office 365 Power BI Addon"
        "POWER_BI_INDIVIDUAL_USE"      = "Power BI Individual User"
        "POWER_BI_STANDALONE"      = "Power BI Stand Alone"
        "POWER_BI_STANDARD"      = "Power-BI Standard"
        "PROJECTESSENTIALS"      = "Project Lite"
        "PROJECTCLIENT"      = "Project Professional"
        "PROJECTONLINE_PLAN_1"      = "Project Online"
        "PROJECTONLINE_PLAN_2"      = "Project Online and PRO"
        "ProjectPremium" = "Project Online Premium"
        "ECAL_SERVICES"      = "ECAL"
        "EMS"      = "Enterprise Mobility Suite"
        "RIGHTSMANAGEMENT_ADHOC" = "Windows Azure Rights Management"
        "MCOMEETADV" = "PSTN conferencing"
        "SHAREPOINTSTORAGE"      = "SharePoint storage"
        "PLANNERSTANDALONE"      = "Planner Standalone"
        "CRMIUR" = "CMRIUR"
        "BI_AZURE_P1"      = "Power BI Reporting and Analytics"
        "INTUNE_A"      = "Windows Intune Plan A"
        "PROJECTWORKMANAGEMENT"      = "Office 365 Planner Preview"
        "ATP_ENTERPRISE" = "Exchange Online Advanced Threat Protection"
        "EQUIVIO_ANALYTICS"      = "Office 365 Advanced eDiscovery"
        "AAD_BASIC"      = "Azure Active Directory Basic"
        "RMS_S_ENTERPRISE"      = "Azure Active Directory Rights Management"
        "AAD_PREMIUM"      = "Azure Active Directory Premium"
        "MFA_PREMIUM"      = "Azure Multi-Factor Authentication"
        "STANDARDPACK_GOV"      = "Microsoft Office 365 (Plan G1) for Government"
        "STANDARDWOFFPACK_GOV"      = "Microsoft Office 365 (Plan G2) for Government"
        "ENTERPRISEPACK_GOV" = "Microsoft Office 365 (Plan G3) for Government"
        "ENTERPRISEWITHSCAL_GOV" = "Microsoft Office 365 (Plan G4) for Government"
        "DESKLESSPACK_GOV"      = "Microsoft Office 365 (Plan K1) for Government"
        "ESKLESSWOFFPACK_GOV"      = "Microsoft Office 365 (Plan K2) for Government"
        "EXCHANGESTANDARD_GOV"      = "Microsoft Office 365 Exchange Online (Plan 1) only for Government"
        "EXCHANGEENTERPRISE_GOV" = "Microsoft Office 365 Exchange Online (Plan 2) only for Government"
        "SHAREPOINTDESKLESS_GOV" = "SharePoint Online Kiosk"
        "EXCHANGE_S_DESKLESS_GOV"      = "Exchange Kiosk"
        "RMS_S_ENTERPRISE_GOV"      = "Windows Azure Active Directory Rights Management"
        "OFFICESUBSCRIPTION_GOV" = "Office ProPlus"
        "MCOSTANDARD_GOV"      = "Lync Plan 2G"
        "SHAREPOINTWAC_GOV"      = "Office Online for Government"
        "SHAREPOINTENTERPRISE_GOV"      = "SharePoint Plan 2G"
        "EXCHANGE_S_ENTERPRISE_GOV"      = "Exchange Plan 2G"
        "EXCHANGE_S_ARCHIVE_ADDON_GOV"      = "Exchange Online Archiving"
        "EXCHANGE_S_DESKLESS"      = "Exchange Online Kiosk"
        "SHAREPOINTDESKLESS" = "SharePoint Online Kiosk"
        "SHAREPOINTWAC"      = "Office Online"
        "YAMMER_ENTERPRISE"      = "Yammer Enterprise"
        "EXCHANGE_L_STANDARD"      = "Exchange Online (Plan 1)"
        "MCOLITE"      = "Lync Online (Plan 1)"
        "SHAREPOINTLITE" = "SharePoint Online (Plan 1)"
        "OFFICE_PRO_PLUS_SUBSCRIPTION_SMBIZ" = "Office ProPlus"
        "EXCHANGE_S_STANDARD_MIDMARKET"      = "Exchange Online (Plan 1)"
        "MCOSTANDARD_MIDMARKET"      = "Lync Online (Plan 1)"
        "SHAREPOINTENTERPRISE_MIDMARKET" = "SharePoint Online (Plan 1)"
        "OFFICESUBSCRIPTION" = "Office ProPlus"
        "YAMMER_MIDSIZE" = "Yammer"
        "DYN365_ENTERPRISE_PLAN1"      = "Dynamics 365 Customer Engagement Plan Enterprise Edition"
        "ENTERPRISEPREMIUM_NOPSTNCONF"      = "Enterprise E5 (without Audio Conferencing)"
        "ENTERPRISEPREMIUM"      = "Enterprise E5 (with Audio Conferencing)"
        "MCOSTANDARD"      = "Skype for Business Online Standalone Plan 2"
        "PROJECT_MADEIRA_PREVIEW_IW_SKU" = "Dynamics 365 for Financials for IWs"
        "STANDARDWOFFPACK_IW_STUDENT"      = "Office 365 Education for Students"
        "STANDARDWOFFPACK_IW_FACULTY"      = "Office 365 Education for Faculty"
        "EOP_ENTERPRISE_FACULTY" = "Exchange Online Protection for Faculty"
        "EXCHANGESTANDARD_STUDENT"      = "Exchange Online (Plan 1) for Students"
        "OFFICESUBSCRIPTION_STUDENT" = "Office ProPlus Student Benefit"
        "STANDARDWOFFPACK_FACULTY"      = "Office 365 Education E1 for Faculty"
        "STANDARDWOFFPACK_STUDENT"      = "Microsoft Office 365 (Plan A2) for Students"
        "DYN365_FINANCIALS_BUSINESS_SKU" = "Dynamics 365 for Financials Business Edition"
        "DYN365_FINANCIALS_TEAM_MEMBERS_SKU" = "Dynamics 365 for Team Members Business Edition"
        "FLOW_FREE"      = "Microsoft Flow Free"
        "POWER_BI_PRO"      = "Power BI Pro"
        "O365_BUSINESS"      = "Office 365 Business"
        "DYN365_ENTERPRISE_SALES"      = "Dynamics Office 365 Enterprise Sales"
        "RIGHTSMANAGEMENT"      = "Rights Management"
        "PROJECTPROFESSIONAL"      = "Project Professional"
        "VISIOONLINE_PLAN1"      = "Visio Online Plan 1"
        "EXCHANGEENTERPRISE" = "Exchange Online Plan 2"
        "DYN365_ENTERPRISE_P1_IW"      = "Dynamics 365 P1 Trial for Information Workers"
        "DYN365_ENTERPRISE_TEAM_MEMBERS" = "Dynamics 365 For Team Members Enterprise Edition"
        "CRMSTANDARD"      = "Microsoft Dynamics CRM Online Professional"
        "EXCHANGEARCHIVE_ADDON"      = "Exchange Online Archiving For Exchange Online"
        "EXCHANGEDESKLESS"      = "Exchange Online Kiosk"
        "SPZA_IW"      = "App Connect"
        "WINDOWS_STORE"      = "Windows Store for Business"
        "MCOEV"      = "Microsoft Phone System"
        "VIDEO_INTEROP"      = "Polycom Skype Meeting Video Interop for Skype for Business"
        "SPE_E5" = "Microsoft 365 E5"
        "SPE_E3" = "Microsoft 365 E3"
        "ATA"      = "Advanced Threat Analytics"
        "MCOPSTN2"      = "Domestic and International Calling Plan"
        "FLOW_P1"      = "Microsoft Flow Plan 1"
        "FLOW_P2"      = "Microsoft Flow Plan 2"
        "CRMSTORAGE" = "Microsoft Dynamics CRM Online Additional Storage"
        "SMB_APPS"      = "Microsoft Business Apps"
        "MICROSOFT_BUSINESS_CENTER"      = "Microsoft Business Center"
        "DYN365_TEAM_MEMBERS"      = "Dynamics 365 Team Members"
        "STREAM" = "Microsoft Stream Trial"
        "EMSPREMIUM"                         = "ENTERPRISE MOBILITY + SECURITY E5"
        "SPB" = "Microsoft 365 Business"
        "MCOPSTN1" = "Domestic Calling Plan"
        "MEETING_ROOM" = "Teams Meeting Room"
        "POWERAPPS_PER_APP_IW" = "PowerApps Per App"
        "TEAMS_COMMERCIAL_TRIAL" = "Microsoft Teams"
        "POWERAPPS_PER_USER" = "PowerApps Per User"
        "FLOW_PER_USER" = "PowerAutomate Per User"
        "POWERFLOW_P1" = "Flow P1"
        
    }
    #Establish a PowerShell session with Office 365. You'll be prompted for your Delegated Admin credentials

    try {
        $var = Get-MsolPartnerContract -ErrorAction Stop
    } 
    catch [Microsoft.Online.Administration.Automation.MicrosoftOnlineException] {
        Write-Host "Not connected to Partner account!" -ForegroundColor Yellow
        Connect-MsolService
    }

    Write-Host
    Write-Host
    Write-Host "==============================================================" -ForegroundColor Yellow
    Write-Host " Identified Customer Tenants" -ForegroundColor Yellow
    Get-MsolPartnerContract | Select Name, DefaultDomainName | FT
    Write-Host "==============================================================" -ForegroundColor Yellow
    Write-Host
    Write-Host "Get User Report On Specific Customer?" -ForegroundColor Yellow
    $GetSpecificYN = Read-Host "Yes or No"
    Write-Host
    $customers = ""
    if($GetSpecificYN -like "*yes*"){
        Write-Host "Enter Default Domain Name of customer from above list" -ForegroundColor Yellow
        $TenantDomain = Read-Host "Default Domain"
        Write-Host
        $customers = Get-MsolPartnerContract -DomainName $TenantDomain
        $CustomerName = $customers.name
        Write-Host "Okay! Reporting on Users from $CustomerName." -ForegroundColor Yellow
        Write-Host
        Start-Sleep -seconds 1
        $Date1 = Get-Date -Format "MM-dd-yyyy HH-mm"
        $FileName = "$CustomerName User Report - $Date1.csv"
        $CSVpath = "$home\Downloads\$FileName"
        $XFileName = "$CustomerName User Report - $Date1.xlsx"
        $XLSpath = "$home\Downloads\$XFileName"
    }else{
        Write-Host 
        Write-Host "Okay! Reporting on Users from all Customers." -ForegroundColor Yellow
        Write-Host
        $customers = Get-MsolPartnerContract -All
        Start-Sleep -Milliseconds 500
        $Date1 = Get-Date -Format "MM-dd-yyyy HH-mm"
        $FileName = "All Customer User Report - $Date1.csv"
        $CSVpath = "$home\Downloads\$FileName"
        $XFileName = "All Customer User Report - $Date1.xlsx"
        $XLSpath = "$home\Downloads\$XFileName"
    }
    $OutputArray = @()

    #Get Users from Primary Tenant
    if($GetSpecificYN -like "*no*"){
        $customer = Get-MsolCompanyInformation
        Write-Host ""
        Write-Host "Retrieving license info for $($customer.DisplayName)" -ForegroundColor Green
        $licensedUsers = Get-MsolUser -All | Where-Object {$_.islicensed} | Sort-Object DisplayName
        Start-Sleep -Milliseconds 500
        foreach ($user in $licensedUsers) {
            Write-Host "$($user.displayname)" -ForegroundColor Yellow  
            $LicenseName = @()
            $licenseString = ""
            $Licenses = (($User).Licenses).AccountSkuID
            If (($Licenses).Count -gt 0)
            {
            Foreach ($License in $Licenses)
            {
            $LicenseItem = $License -split ":" | Select-Object -Last 1
            $TextLic = $Sku.Item("$LicenseItem")
            If (!($TextLic))
            {
            $fallback_Licenses = $LicenseItem
            $LicenseName += $fallback_Licenses
            }
            Else
            {
            $LicenseName += $TextLic
            }
            }
            }
            $licenseString = $LicenseName -join ", "

            Write-Host "$($user.displayname) has $licenseString" -ForegroundColor Blue

            $licensedSharedMailboxProperties = [pscustomobject][ordered]@{
                'Customer Name'     = $customer.DisplayName
                'Display Name'       = $user.DisplayName
                'First Name'        = $user.FirstName
                'Last Name'        = $user.LastName
                Office            = $user.Office
                Title             = $user.Title
                UserPrincipalName = $user.UserPrincipalName
                Licenses          = $licenseString
                TenantId          = $customer.ObjectID              
            }
            $OutputArray += $licensedSharedMailboxProperties
            $licensedSharedMailboxProperties | Export-CSV -Path $CSVpath -Append -NoTypeInformation   
        }  
    }

    #Get Users from Customer Tenant
    foreach ($customer in $customers) {
        Write-Host ""
        Write-Host "Retrieving license info for $($customer.name)" -ForegroundColor Green
        $licensedUsers = Get-MsolUser -TenantId $customer.TenantId -All | Where-Object {$_.islicensed} | Sort-Object DisplayName
        Start-Sleep -Milliseconds 500
        foreach ($user in $licensedUsers) {
            Write-Host "$($user.displayname)" -ForegroundColor Yellow  
            $LicenseName = @()
            $licenseString = ""
            $Licenses = (($User).Licenses).AccountSkuID
            If (($Licenses).Count -gt 0)
            {
            Foreach ($License in $Licenses)
            {
            $LicenseItem = $License -split ":" | Select-Object -Last 1
            $TextLic = $Sku.Item("$LicenseItem")
            If (!($TextLic))
            {
            $fallback_Licenses = $LicenseItem
            $LicenseName += $fallback_Licenses
            }
            Else
            {
            $LicenseName += $TextLic
            }
            }
            }
            $licenseString = $LicenseName -join ", "

            Write-Host "$($user.displayname) has $licenseString" -ForegroundColor Blue

            $licensedSharedMailboxProperties = [pscustomobject][ordered]@{
                'Customer Name'     = $customer.Name
                'Display Name'       = $user.DisplayName
                'First Name'        = $user.FirstName
                'Last Name'        = $user.LastName
                Office            = $user.Office
                Title             = $user.Title
                UserPrincipalName = $user.UserPrincipalName
                Licenses          = $licenseString
                TenantId          = $customer.TenantId              
            }
            $OutputArray += $licensedSharedMailboxProperties
            $licensedSharedMailboxProperties | Export-CSV -Path $CSVpath -Append -NoTypeInformation   
        }
    }
    #$OutputArray | Out-GridView
    ### Set input and output path
    $inputCSV = "$CSVPath"
    $outputXLSX = "$XLSPath"

    ### Create a new Excel Workbook with one empty sheet
    $excel = New-Object -ComObject excel.application 
    $workbook = $excel.Workbooks.Add(1)
    $worksheet = $workbook.worksheets.Item(1)

    ### Build the QueryTables.Add command
    ### QueryTables does the same as when clicking "Data » From Text" in Excel
    $TxtConnector = ("TEXT;" + $inputCSV)
    $Connector = $worksheet.QueryTables.add($TxtConnector,$worksheet.Range("A1"))
    $query = $worksheet.QueryTables.item($Connector.name)

    ### Set the delimiter (, or ;) according to your regional settings
    $query.TextFileOtherDelimiter = $Excel.Application.International(5)

    ### Set the format to delimited and text for every column
    ### A trick to create an array of 2s is used with the preceding comma
    $query.TextFileParseType  = 1
    $query.TextFileColumnDataTypes = ,2 * $worksheet.Cells.Columns.Count
    $query.AdjustColumnWidth = 1
    ### Execute & delete the import query
    $query.Refresh()
    $query.Delete()
    $list = $excel.ActiveSheet.ListObjects.Add(
        [Microsoft.Office.Interop.Excel.XlListObjectSourceType]::xlSrcRange, # Add a range
        $excel.ActiveCell.CurrentRegion, # Get the current region, by default A1 is selected so it'll select all contiguous rows
        $null,
        [Microsoft.Office.Interop.Excel.XlYesNoGuess]::xlYes # Yes, we have a header row
    )
    ### Save & close the Workbook as XLSX. Change the output extension for Excel 2003
    $Workbook.SaveAs($outputXLSX,51)
    $excel.Quit()
    Remove-Item -path "$inputCSV"


    Write-Host
    Write-Host 
    Write-Host "==============================================================" -ForegroundColor Yellow
    Write-Host " Done! See report in $XLSPath" -ForegroundColor Yellow
    Write-Host "==============================================================" -ForegroundColor Yellow
    Write-Host
    Get-Commands
}
function Start-RoomScripts
{
#Description: Various scripts for managing Room Mailboxes
function Sub-New-RoomMailbox
{

Write-Host ""
$RoomName = Read-Host "Room Mailbox Display Name"
$RoomAlias = Read-Host "Room Alias to be used in email address(ex: conf.chiefs)"
$RoomDomain = Read-Host "Room email domain (ex: 321moonshot.com)"
$RoomAddress = "$RoomAlias@$RoomDomain"
$RoomPass = Read-Host "Room Mailbox Password"
New-Mailbox -Name "$RoomName" -Alias $RoomAlias -Room -EnableRoomMailboxAccount $true -MicrosoftOnlineServicesID $RoomAddress -RoomMailboxPassword (ConvertTo-SecureString -String '$RoomPass' -AsPlainText -Force)
Write-Host ""
}
function Sub-Get-RoomLists
{

Get-DistributionGroup -ResultSize Unlimited | Where-Object {$_.RecipientTypeDetails -eq "RoomList"} | Format-Table DisplayName,PrimarySmtpAddress -AutoSize
}
function Sub-New-RoomList
{

$NewListName = Read-Host "Display Name for New Room List"
New-DistributionGroup -Name "$NewListName" -RoomList
}
function Sub-Add-RoomListMember
{

$RoomAddress = Read-Host "Room Mailbox email address or alias"
$ListName = Read-Host "Display Name of Room List"
Add-DistributionGroupMember -Identity "$ListName" -Member "$RoomAddress"
}
function Sub-Set-RoomSettings
{

Write-Host "Allow recurring meetings to schedule with some conflicts?"
$ConflictAllow = Read-Host "Yes or No"
$ConflictAllowed = ""
if($ConflictAllow -like "*yes*"){
$ConflictAllowed = $True
}else{
$ConflictAllowed = $False}
If ($ConflictAllowed -eq $True)
{
    Write-Host ""
    #Allow some Recurring conflicts
    Write-Host ""
    $rm = Read-Host "Room Mailbox Alias"
    $ConflictPercent = Read-Host "Max percent (as number) of occurances that can conflict over series"
    $ConflictMax = Read-Host "Max number of conflicting occurances before series is declined"
    Set-CalendarProcessing "$rm" -AutomateProcessing AutoAccept -AllowConflicts $false -BookingWindowInDays 365 -MaximumDurationInMinutes 1440 -AllowRecurringMeetings $true -ConflictPercentageAllowed $ConflictPercent -MaximumConflictInstances $ConflictMax -ForwardRequestsToDelegates $true -DeleteAttachments $false -DeleteComments $false -RemovePrivateProperty $false -DeleteSubject $false -AddOrganizerToSubject $false -DeleteNonCalendarItems $true -TentativePendingApproval $true -EnableResponseDetails $true -OrganizerInfo $true -AllRequestOutOfPolicy $false -AllBookInPolicy $true -AllRequestInPolicy $false -AddNewRequestsTentatively $true -ProcessExternalMeetingMessages $true -RemoveForwardedMeetingNotifications $false
}else{
    Write-Host ""
    #Decline Recurring if any conflicts
    Write-Host ""
    $rm = Read-Host "Room Mailbox Alias"
    Set-CalendarProcessing "$rm" -AutomateProcessing AutoAccept -AllowConflicts $false -BookingWindowInDays 365 -MaximumDurationInMinutes 1440 -AllowRecurringMeetings $true -ConflictPercentageAllowed 0 -MaximumConflictInstances 0 -ForwardRequestsToDelegates $true -DeleteAttachments $false -DeleteComments $false -RemovePrivateProperty $false -DeleteSubject $false -AddOrganizerToSubject $false -DeleteNonCalendarItems $true -TentativePendingApproval $true -EnableResponseDetails $true -OrganizerInfo $true -AllRequestOutOfPolicy $false -AllBookInPolicy $true -AllRequestInPolicy $false -AddNewRequestsTentatively $true -ProcessExternalMeetingMessages $true -RemoveForwardedMeetingNotifications $false
}
}
function Sub-Set-MTRConfig
{

    Clear-Host
    try 
    { 
    $var = Get-CsOnlineSipDomain -ErrorAction SilentlyContinue
    Write-Host ""
    Write-Host "Connected to S4B Online"
    Write-Host ""
    $rm = Read-Host "Meeting Room Alias"
    $RoomPass = Read-Host "Mailbox Password"
    Set-Mailbox -Identity "$rm" -EnableRoomMailboxAccount $true -RoomMailboxPassword (ConvertTo-SecureString -String '$RoomPass' -AsPlainText -Force)
    $SIPPool = Get-CsOnlineUser -Identity "$rm" | Select -Expand RegistrarPool
    Enable-CsMeetingRoom -Identity "$rm" -RegistrarPool "$SIPPool" -SipAddressType EmailAddress
    } 
    catch [System.Exception] 
    { 
    Write-Host ""
    Write-Host "--------------------------------------------------------------------------------------"
    Write-Host " Please make sure you are connected to the Skype for Business Online module."
    Write-Host " In a new window, connect via the Connect-Office365 command and re-run script"
    Write-Host " If that command can not be found, follow the Helpdesk Solutions > M365 PowerShell"
    Write-Host " article titled ""Create & Set PowerShell Profile"" on the Moonshot Helpdesk."
    Write-Host "--------------------------------------------------------------------------------------"
    Write-Host ""
    }
}
function Sub-Show-RoomActionMenu
{
    Write-Host 
    Write-Host "====================== Room Mailbox Setup Helper ==========================" -ForegroundColor Yellow
    Write-Host
    Write-Host " Action Options:" -ForegroundColor Yellow
    Write-Host ""
    Write-Host " 1. New-RoomMailbox" -ForegroundColor Green
    Write-Host " Create a new Room Mailbox" -ForegroundColor Yellow
    Write-Host " 2. Get-RoomLists" -ForegroundColor Green
    Write-Host " Show existing Room Lists" -ForegroundColor Yellow
    Write-Host " 3. New-RoomList" -ForegroundColor Green
    Write-Host " Create a new Room List" -ForegroundColor Yellow
    Write-Host " 4. Add-RoomListMember" -ForegroundColor Green
    Write-Host " Add Room to Room List" -ForegroundColor Yellow
    Write-Host " 5. Set-RoomSettings" -ForegroundColor Green
    Write-Host " Configure default Scheduling settings" -ForegroundColor Yellow
    Write-Host " 6. Set-MTRConfig" -ForegroundColor Green
    Write-Host " Enable default requirements for Teams Room" -ForegroundColor Yellow
    Write-Host " 7. " -ForegroundColor Green
    Write-Host " -" -ForegroundColor Yellow
    Write-Host " 8. " -ForegroundColor Green
    Write-Host " -" -ForegroundColor Yellow
    Write-Host " 9. " -ForegroundColor Green
    Write-Host " -" -ForegroundColor Yellow
    Write-Host " 0. Exit Room Script" -ForegroundColor Green
    Write-Host
    Write-Host "===========================================================================" -ForegroundColor Yellow
}
Write-Host ""
Write-Host "================================================================" -ForegroundColor Yellow
Write-Host "" -ForegroundColor Yellow
Write-Host " Welcome to the Room Mailbox Setup Helper!" -ForegroundColor Yellow
Write-Host "" -ForegroundColor Yellow
Write-Host "================================================================" -ForegroundColor Yellow
Write-Host ""
Do{
    Write-Host ""
    Sub-Show-RoomActionMenu
    Write-Host ""
    $Selection = ""
    Write-Host " Enter Action Number" -ForegroundColor Yellow
    $Selection = Read-Host " Number"
    Switch ($Selection)
    {
        '1' {
            Sub-New-RoomMailbox
        }
        '2' {
            Sub-Get-RoomLists
        }
        '3' {
            Sub-New-RoomList
        }
        '4' {
            Sub-Add-RoomListMember
        }
        '5' {
            Sub-Set-RoomSettings
        }
        '6' {
            Sub-Set-MTRConfig
        }
        '7' {
        }
        '8' {
        }
        '9' {
        }
        '0' {
            Write-Host
            Write-Host "Exiting Script!" -ForegroundColor Green
            Write-Host
        }
    }
}Until ($Selection -eq '0')
Get-Commands
}
function Update-Moonshot365
{
#Description: Update the Moonshot365 Module
Write-Host "Checking Moonshot365 Version...."
$Installed = Get-Module -Name Moonshot365
$online = Find-Module -Name Moonshot365
$online | Where-Object {$installed.name -contains $_.name} |
                Select-Object -property Name,
            @{Name = "OnlineVersion"; Expression = {$_.Version}},
            @{Name = "InstalledVersion"; Expression = {
                    #save the name from the incoming online object
                    $name = $_.Name
                    $installed.Where( {$_.name -eq $name}).Version -join ","}
            },
            PublishedDate,
            @{Name = "UpdateNeeded"; Expression = {
                    $name = $_.Name
                    #there could me multiple versions installed
                    $installedVersions = $installed.Where( {$_.name -eq $name}).Version | Sort-Object
                    foreach ($item in $installedVersions) {
                        If ($_.Version -gt [version]$item) {
                            $result = $True
                            $ModManifestPath = "$PSScriptRoot\Moonshot365.psd1"
                            $ModManifest = Import-PowerShellDataFile $ModManifestPath
                            $NewVer = $ModManifest.ModuleVersion
                            $UpdateVer = ""
                            $WebVersion = Find-Module -Name Moonshot365 | Select -expandproperty Version
                            if($WebVersion -eq $NewVer){$UpdateVer = "$WebVersion"}else{$UpdateVer = "$WebVersion - Please Update"}
                            Write-Host ""
                            Write-Host "---------------------------------------->" -ForegroundColor Yellow
                            Write-Host " Installed Version: $NewVer" -ForegroundColor Yellow
                            Write-Host " Latest Version: $UpdateVer" -ForegroundColor Yellow
                            Write-Host " Version Bad. Updating!" -ForegroundColor Yellow
                            Write-Host "---------------------------------------->" -ForegroundColor Yellow
                            Remove-Module Moonshot365
                            Start-Sleep -Seconds 1
                            Update-Module Moonshot365
                            Write-Host "Updated!"
                            Write-Host ""
                            Write-Host ""
                            Import-Module Moonshot365
                            
                        }
                        else {
                            $result = $False
                            
                            Write-Host "Version good!"
                            Write-Host ""
                            Write-Host ""
                            Import-Module Moonshot365
                            
                        }
                    }
                    $result
                }
            } | Out-Null
}
function Start-UserDisable
{
#Description: Various scripts for disabling users
function Sub-Show-DisableUserSelection
{
    Start-Sleep -Milliseconds 250
    Write-Host " Select Option:" -ForegroundColor Yellow
    Write-Host " 1. Single or Multiple Mailbox Users from Out-GridView" -ForegroundColor Yellow
    Write-Host " 2. Individual User (Manually Enter)" -ForegroundColor Yellow
    Write-Host " 3. Multiple Users (Manually Enter)" -ForegroundColor Yellow
    Write-Host " 4. Bulk from CSV" -ForegroundColor Yellow
    Write-Host ""
    $OptionNumber = Read-Host " Selection Number"
    Write-Host ""
    If($OptionNumber -eq "1"){
        $Script:UserArray = @()
        $Script:UserArray = Get-Mailbox -Resultsize Unlimited | Select DisplayName,Alias,UserPrincipalName | Out-GridView -Title "Select User - Select multiple by holding Ctrl" -PassThru | Select-Object -ExpandProperty UserPrincipalName
    }
    If($OptionNumber -eq "2"){
        $Script:UserArray = @()
        Write-Host
        Write-Host " User to Disable" -ForegroundColor Yellow
        $UserToDisable = Read-Host " Provide UPN, Alias, or Display Name"
        $MbxValid = "0"
        Do{
            Try{
                $MbxCheck = Get-Mailbox -Identity "$UserToDisable" -ErrorAction Stop
                $MbxValid = "1"
                Write-Host ""
                Write-Host " Found user $($MbxCheck.Displayname)!" -ForegroundColor Green
                $MbxUPN = $MbxCheck.UserPrincipalName
                $Script:UserArray += @("$MbxUPN")
                Start-Sleep -Milliseconds 250
                Write-Host ""
                Start-Sleep -Milliseconds 500
            }Catch{
                $MbxValid = "0"
                Write-Host
                Write-Host " User $UserToDisable not found! Please try again." -ForegroundColor Red
                $UserToDisable = Read-Host " Provide UPN, Alias, or Display Name"
            }
        }Until ($MbxValid -eq "1")
        Write-Host ""
    }
    If($OptionNumber -eq "3"){
        $Script:UserArray = @()
        $AddMore = ""
        Write-Host
        Write-Host " First user to Disable" -ForegroundColor Yellow
        $UserToDisable = Read-Host " Provide UPN, Alias, or Display Name"
        $MbxValid = "0"
        Do{
            Try{
                $MbxCheck = Get-Mailbox -Identity "$UserToDisable" -ErrorAction Stop
                $MbxValid = "1"
                Write-Host ""
                Write-Host " Found user $($MbxCheck.Displayname)!" -ForegroundColor Green
                $MbxUPN = $MbxCheck.UserPrincipalName
                $Script:UserArray += @("$MbxUPN")
                Start-Sleep -Milliseconds 250
                Write-Host ""
                Start-Sleep -Milliseconds 500
            }Catch{
                $MbxValid = "0"
                Write-Host
                Write-Host " User $UserToDisable not found! Please try again." -ForegroundColor Red
                $UserToDisable = Read-Host " Provide UPN, Alias, or Display Name"
            }
        }Until ($MbxValid -eq "1")
        Do{
            Write-Host " Add another user?" -ForegroundColor Yellow
            $AddMore = Read-Host " Yes or No"
    
            If($AddMore -like "*yes*"){
                Write-Host
                $UserToDisable = Read-Host " Provide UPN, Alias, or Display Name"
                $MbxValid = "0"
                Do{
                    Try{
                        $MbxCheck = Get-Mailbox -Identity "$UserToDisable" -ErrorAction Stop
                        $MbxValid = "1"
                        Write-Host ""
                        Write-Host " Found user $($MbxCheck.Displayname)!" -ForegroundColor Green
                        $MbxUPN = $MbxCheck.UserPrincipalName
                        $Script:UserArray += @("$MbxUPN")
                        Start-Sleep -Milliseconds 250
                        Write-Host ""
                        Start-Sleep -Milliseconds 500
                    }Catch{
                        $MbxValid = "0"
                        Write-Host
                        Write-Host " User $UserToDisable not found! Please try again." -ForegroundColor Red
                        $UserToDisable = Read-Host " Provide UPN, Alias, or Display Name"
                    }
                }Until ($MbxValid -eq "1")
            }
        }Until ($AddMore -like "*no*") 
    }
    If($OptionNumber -eq "4"){
        $Script:UserArray = @()
        Write-Host
        Write-Host "=== Bulk CSV Import ===" -ForegroundColor Yellow
        Write-Host "CSV should include column named 'UPN' that contains the user's logon address" -ForegroundColor Yellow
        Write-Host
        Write-Host "Select CSV file in popup window!" -ForegroundColor Yellow

        $filePath = Read-OpenFileDialog -WindowTitle "Select CSV File" -InitialDirectory 'C:\' -Filter "CSV files (*.csv)|*.csv"
        If(![string]::IsNullOrEmpty($filePath)){
            Write-Host
            Write-Host "You selected the file: $filePath" -ForegroundColor Green
            Write-Host
        }Else{
            Write-Host
            Write-Host "You did not select a file!" -ForegroundColor Red
            Write-Host
            Sub-Show-DisableUserSelection
        }

        $CSVData = Import-CSV $filePath
        ForEach($BatchUser in $CSVData){
            $BatchUPN = $BatchUser.UPN
            Try{
                $MbxCheck = Get-Mailbox -Identity "$BatchUPN" -ErrorAction Stop
                Write-Host ""
                Write-Host " Found user $($MbxCheck.Displayname)!" -ForegroundColor Green
                $MbxUPN = $MbxCheck.UserPrincipalName
                $Script:UserArray += @("$MbxUPN")
                Start-Sleep -Milliseconds 250
                Write-Host ""
                Start-Sleep -Milliseconds 500
            }Catch{
                Write-Host
                Write-Host " User $BatchUPN not found!" -ForegroundColor Red
            }
        }
    }
}
function Sub-Show-DisableActionMenu
{
    Write-Host
    Write-Host "Selected Users:" -ForegroundColor Green
    $SelectedUsers = $UserArray -join ", "
    Write-Host "$SelectedUsers" -ForegroundColor DarkGreen
    Start-Sleep -Milliseconds 500
    Write-Host "================================================================" -ForegroundColor Yellow
    Write-Host " Action Options:" -ForegroundColor Yellow
    Write-Host
    Write-Host " 1. Convert Mailbox to Shared" -ForegroundColor Yellow
    Write-Host " 2. Reset Password" -ForegroundColor Yellow
    Write-Host " 3. Revoke Active Sessions and Reset Password" -ForegroundColor Yellow
    Write-Host " 4. Block Sign In" -ForegroundColor Yellow
    Write-Host " 5. Put Mailbox on Hold" -ForegroundColor Yellow
    Write-Host " 6. Delete O365 User Entirely" -ForegroundColor Yellow
    Write-Host " 7. " -ForegroundColor Yellow
    Write-Host " 8. " -ForegroundColor Yellow
    Write-Host " 9. Return to User Selection" -ForegroundColor Yellow
    Write-Host " 0. Exit Script" -ForegroundColor Yellow
    Write-Host
    Write-Host "================================================================" -ForegroundColor Yellow
    Write-Host ""
}
#Check Connected to Tenant
try
{ $var = Get-AzureADTenantDetail }
catch [Microsoft.Open.Azure.AD.CommonLibrary.AadNeedAuthenticationException]
{
    Write-Host
    Write-Progress -Activity 'Connecting to Tenant' -Status "Gathering Credentials..." 
    Write-Host "Connecting to Office 365 and Exchange Online PowerShell..." -ForegroundColor Red
    Write-Host
    $credential = Get-Credential -Message "Please enter your Office 365 credentials"
    Import-Module MsOnline
    Write-Progress -Activity ' Connecting to Tenant' -Status " AzureAD..." 
    Connect-AzureAD -Credential $credential | Out-Null
    Write-Progress -Activity ' Connecting to Tenant' -Status " MsolService..." 
    Connect-MsolService -Credential $credential | Out-Null
    Write-Progress -Activity ' Connecting to Tenant' -Status " Exchange Online..." 
    $exchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://outlook.office365.com/powershell-liveid/" -Credential $credential -Authentication "Basic" -AllowRedirection
    Import-PSSession $exchangeSession -AllowClobber | Out-Null
    Write-Progress -Activity ' Connecting to Tenant' -Status " Successful!"
    Write-Host
    Write-Host
}

#Script Start
Write-Progress -Activity ' Welcome to the User Disabling Helper!' -Status " Starting..."
Write-Host ""
Write-Host "================================================================" -ForegroundColor Yellow
Write-Host "" -ForegroundColor Yellow
Write-Host " Welcome to the User Disabling Helper!" -ForegroundColor Yellow
Write-Host "" -ForegroundColor Yellow
Write-Host "================================================================" -ForegroundColor Yellow
Write-Host ""

Sub-Show-DisableUserSelection

Do{
    Sub-Show-DisableActionMenu
    $ActionsIndex = ""
    $ActionsArray = @()
    Write-Host " Which actions do you want to perform? Type the numbers, separated by a comma." -ForegroundColor Yellow
    $ActionsIndex = Read-Host " Actions"
    Write-Host ""

    if($ActionsIndex -like "*1*"){
        $ActionsArray += @("1")
    }
    if($ActionsIndex -like "*2*"){
        $ActionsArray += @("2")
    }
    if($ActionsIndex -like "*3*"){
        $ActionsArray += @("3")
    }
    if($ActionsIndex -like "*4*"){
        $ActionsArray += @("4")
    }
    if($ActionsIndex -like "*5*"){
        $ActionsArray += @("5")
    }
    if($ActionsIndex -like "*6*"){
        $ActionsArray += @("6")
    }
    if($ActionsIndex -like "*7*"){
        $ActionsArray += @("7")
    }
    if($ActionsIndex -like "*8*"){
        $ActionsArray += @("8")
    }
    if($ActionsIndex -like "*9*"){
        $ActionsArray += @("9")
    }
    if($ActionsIndex -like "*0*"){
        $ActionsArray += @("0")
    }

    ForEach ($Action in $ActionsArray){
        $ErrorActionPreference = "Stop"
        Switch ($Action)
        {
            '1' #Convert to Shared
            {
                ForEach($User in $UserArray){
                    Start-Sleep -Milliseconds 500
                    $MbxIdentity = Get-Mailbox -Identity "$User"
                    If($MbxIdentity.RecipientTypeDetails -eq "UserMailbox"){
                        Try{
                            Write-Host
                            Write-Host "Converting $($MbxIdentity.DisplayName) to Shared Mailbox..." -ForegroundColor Yellow
                            $MbxIdentity | Set-Mailbox -Type Shared
                            Start-Sleep -Milliseconds 250
                            Write-Host "Converted $($MbxIdentity.DisplayName) to Shared!" -ForegroundColor Green
                            Write-Host
                        }Catch{
                            Write-Host
                            Write-Host "Unable to convert $($MbxIdentity.DisplayName) to Shared Mailbox!" -ForegroundColor Red
                            Write-Host
                        }  
                    }Else{
                        Write-Host
                        Write-Host "Mailbox is already Shared!" -ForegroundColor Red
                    }
                }
            }
            '2' #Reset Password
            {
                ForEach($User in $UserArray){
                    Start-Sleep -Milliseconds 500
                    $MbxIdentity = Get-Mailbox -Identity "$User"
                    Write-Host
                    Write-Host "Enter new password for $($MbxIdentity.DisplayName)" -ForegroundColor Yellow
                    $NewPassword = Read-Host "New Password"
                    $PWSuccess = "0"
                    Do{
                        Try{
                            Start-Sleep -Milliseconds 250
                            Write-Host
                            Write-Host "Resetting password..." -ForegroundColor Yellow
                            Set-MsolUserPassword -UserPrincipalName $MbxIdentity.UserPrincipalName -NewPassword "$NewPassword" -ErrorAction Stop
                            Start-Sleep -Milliseconds 500
                            Write-Host "Password for $($MbxIdentity.DisplayName) has been reset!" -ForegroundColor Green
                            Write-Host
                            $PWSuccess = "1"
                        }Catch{
                            $PWSuccess = "0"
                            Start-Sleep -Milliseconds 500
                            Write-Host
                            Write-Host "Unable to reset $($MbxIdentity.DisplayName)'s password!" -ForegroundColor Red
                            Write-Host
                            Write-Host "$($_.Exception.Message)" -ForegroundColor Red
                            If($_.Exception.Message -like "*Choose another password and try again*"){
                                $NewPassword = Read-Host "Enter new Password or leave blank for Random"
                            }Else{
                                break
                            }
                        }
                    }Until ($PWSuccess -eq "1")
                }
            }
            '3' #Revoke Sessions and Reset Password
            {
                ForEach($User in $UserArray){
                    Start-Sleep -Milliseconds 500
                    $MbxIdentity = Get-Mailbox -Identity "$User"
                    Write-Host
                    Write-Host "Enter new password for $($MbxIdentity.DisplayName)" -ForegroundColor Yellow
                    $NewPassword = Read-Host "New Password"
                    $PWSuccess = "0"
                    Do{
                        Try{
                            Start-Sleep -Milliseconds 250
                            Write-Host
                            Write-Host "Resetting password..." -ForegroundColor Yellow
                            Set-MsolUserPassword -UserPrincipalName $MbxIdentity.UserPrincipalName -NewPassword "$NewPassword" -ErrorAction Stop
                            Start-Sleep -Milliseconds 500
                            Write-Host "Password for $($MbxIdentity.DisplayName) has been reset!" -ForegroundColor Green
                            Write-Host
                            $PWSuccess = "1"
                        }Catch{
                            $PWSuccess = "0"
                            Start-Sleep -Milliseconds 500
                            Write-Host
                            Write-Host "Unable to reset $($MbxIdentity.DisplayName)'s password!" -ForegroundColor Red
                            Write-Host
                            Write-Host "$($_.Exception.Message)" -ForegroundColor Red
                            If($_.Exception.Message -like "*Choose another password and try again*"){
                                $NewPassword = Read-Host "Enter new Password or leave blank for Random"
                            }Else{
                                break
                            }
                        }
                    }Until ($PWSuccess -eq "1")

                    Start-Sleep -Milliseconds 500
                    Write-Host
                    Write-Host "Attempting to revoke active sessions for $($MbxIdentity.DisplayName). . ." -ForegroundColor Yellow
                    Start-Sleep -Milliseconds 500
                    Try{
                        Get-AzureADUser -SearchString $MbxIdentity.UserPrincipalName | Revoke-AzureADUserAllRefreshToken
                        Write-Host
                        Write-Host "Sessions for $($MbxIdentity.DisplayName) has been revoked!" -ForegroundColor Green
                    }Catch{
                        Write-Host
                        Write-Host "Unable to revoke sessions for $($MbxIdentity.DisplayName)!" -ForegroundColor Red
                    }
                }
            }
            '4' #Block Login
            {
                ForEach($User in $UserArray){
                    Start-Sleep -Milliseconds 500
                    $MbxIdentity = Get-Mailbox -Identity "$User"
                    Write-Host
                    Write-Host "Attempting to block login for $($MbxIdentity.DisplayName). . ." -ForegroundColor Yellow
                    Start-Sleep -Milliseconds 300
                    Try{
                        Set-AzureADUser -ObjectID $MbxIdentity.UserPrincipalName -AccountEnabled $false
                        Write-Host
                        Write-Host "Login blocked for $($MbxIdentity.DisplayName)!" -ForegroundColor Green
                    }Catch{
                        Write-Host
                        Write-Host "Unable to block login for $($MbxIdentity.DisplayName)!" -ForegroundColor Red
                    }
                }
            }
            '5' #Place Mailbox on Lit Hold
            {
                ForEach($User in $UserArray){
                    Start-Sleep -Milliseconds 500
                    $MbxIdentity = Get-Mailbox -Identity "$User"
                    Write-Host
                    Write-Host "Attempting to place $($MbxIdentity.DisplayName) on Lit Hold. . ." -ForegroundColor Yellow
                    Start-Sleep -Milliseconds 300
                    Try{
                        Set-Mailbox $MbxIdentity.UserPrincipalName -LitigationHoldEnabled $true
                        Write-Host
                        Write-Host "Lit Hold enabled for $($MbxIdentity.DisplayName)!" -ForegroundColor Green
                    }Catch{
                        Write-Host
                        Write-Host "Unable to place $($MbxIdentity.DisplayName) on Lit Hold!" -ForegroundColor Red
                    } 
                }             
            }
            '6' #Delete User
            {
                ForEach($User in $UserArray){
                    Start-Sleep -Milliseconds 500
                    $MbxIdentity = Get-Mailbox -Identity "$User"
                    Write-Host
                    Write-Host "Attempting to delete $($MbxIdentity.DisplayName). . ." -ForegroundColor Yellow
                    $DisplayN = $MbxIdentity.DisplayName
                    Start-Sleep -Milliseconds 300
                    Try{
                        Remove-MsolUser -UserPrincipalName $MbxIdentity.UserPrincipalName
                        Write-Host
                        Write-Host "$DisplayN has been deleted!" -ForegroundColor Green
                    }Catch{
                        Write-Host
                        Write-Host "Unable to delete $($MbxIdentity.DisplayName)!" -ForegroundColor Red
                    }
                }
            }
            '7' #Test 7
            {
                ForEach($User in $UserArray){
                    Start-Sleep -Milliseconds 500
                    Write-Host
                    Write-Host "Test Action 7 - $($MbxIdentity.DisplayName)" -ForegroundColor Green
                    Write-Host
                }
            }
            '8' #Test 8
            {
                ForEach($User in $UserArray){
                    Start-Sleep -Milliseconds 500
                    Write-Host
                    Write-Host "Test Action 8 - $($MbxIdentity.DisplayName)" -ForegroundColor Green
                    Write-Host
                }
            }
            '9' #Change User Selection
            {
                Start-Sleep -Milliseconds 500
                Sub-Show-DisableUserSelection
            }
            '0' #Exit Script
            {
                Write-Host
                Write-Host "Exiting Script!" -ForegroundColor Green
                Write-Host
            }
        }
        $ErrorActionPreference = "Continue"
        Start-Sleep -Milliseconds 250
    }
}Until ($ActionsArray -eq "0")
Get-Commands
}
function Get-Commands
{
#Description: List available commands in Moonshot 365 Module
Write-Host ""
Write-Host "======================= Moonshot 365 Module Commands =======================>" -ForegroundColor Yellow
Write-Host ""
Write-Host " Current Moonshot365 Commands: " -ForegroundColor Yellow
Write-Host ""
Write-Host " 1. Connect-Office365" -ForegroundColor Green
Write-Host " Connect to Office 365 PowerShell services. Alt: CO365" -ForegroundColor Yellow
Write-Host " 2. Get-Office365Modules" -ForegroundColor Green
Write-Host " Install AzureAD, MsOnline, and SharePoint modules" -ForegroundColor Yellow
Write-Host " 3. New-HTMLReport" -ForegroundColor Green
Write-Host " Generate intractive HTML report on Office 365 Tenant" -ForegroundColor Yellow
Write-Host " 4. New-365Report" -ForegroundColor Green
Write-Host " Report on O365 tenant objects & generate migration scripts" -ForegroundColor Yellow
Write-Host " 5. Start-MailboxChecks" -ForegroundColor Green
Write-Host " Mailbox scripts to get permissions and other information" -ForegroundColor Yellow
Write-Host " 6. Get-MFAStatus" -ForegroundColor Green
Write-Host " Generate report of users and their MFA status" -ForegroundColor Yellow
Write-Host " 7. New-PartnerUserReport" -ForegroundColor Green
Write-Host " Report on user across Partner Tenants" -ForegroundColor Yellow
Write-Host " 8. Start-RoomScripts" -ForegroundColor Green
Write-Host " Various scripts for managing Room Mailboxes" -ForegroundColor Yellow
Write-Host " 9. Update-Moonshot365" -ForegroundColor Green
Write-Host " Update the Moonshot365 Module" -ForegroundColor Yellow
Write-Host " 10. Start-UserDisable" -ForegroundColor Green
Write-Host " Various scripts for disabling users" -ForegroundColor Yellow
Write-Host " 11. Get-Commands" -ForegroundColor Green
Write-Host " List available commands in Moonshot 365 Module" -ForegroundColor Yellow
Write-Host ""
Write-Host "============================================================================>" -ForegroundColor Yellow
If($SwitchEnabled -eq 0){Sub-Command-Switch}


}
function Sub-Command-Switch
{
$SwitchEnabled = 1

Do{
    Write-Host " Enter 'x' below to exit Command Selection. Run 'Get-Commands' to return." -ForegroundColor Gray
    $MainSelection = ""
    Write-Host "" Enter Command Number: "" -ForegroundColor Yellow -NoNewLine; $MainSelection = Read-Host
    Switch ($MainSelection)
    {
'1' { Connect-Office365 }
'2' { Get-Office365Modules }
'3' { New-HTMLReport }
'4' { New-365Report }
'5' { Start-MailboxChecks }
'6' { Get-MFAStatus }
'7' { New-PartnerUserReport }
'8' { Start-RoomScripts }
'9' { Update-Moonshot365 }
'10' { Start-UserDisable }
'11' { Get-Commands }
'x' {
    Write-Host
    Write-Host " Run 'Get-Commands' to return to selection." -ForegroundColor Gray
    Write-Host
$SwitchEnabled = 0
}
}
}Until ($MainSelection -like "*x*")
}
Export-ModuleMember -Function Connect-Office365, Get-Office365Modules, CO365, New-HTMLReport, New-365Report, Read-InputBoxDialog, Read-MessageBoxDialog, Read-OpenFileDialog, Send-EmailWithSendGrid-PS, Send-EmailWithSendGrid-Manual, Send-EmailWithSendGrid-API, Start-MailboxChecks, Sub-Check-FullAccess, Sub-Check-UserFullAccess, Sub-Create-XLS, Sub-Check-Size, Sub-Show-MailboxActionMenu, Get-MFAStatus, New-PartnerUserReport, Start-RoomScripts, Sub-New-RoomMailbox, Sub-Get-RoomLists, Sub-New-RoomList, Sub-Add-RoomListMember, Sub-Set-RoomSettings, Sub-Set-MTRConfig, Sub-Show-RoomActionMenu, Update-Moonshot365, Start-UserDisable, Sub-Show-DisableUserSelection, Sub-Show-DisableActionMenu, Get-Commands
$ModManifestPath = "$PSScriptRoot\Moonshot365.psd1"
$ModManifest = Import-PowerShellDataFile $ModManifestPath
$NewVer = $ModManifest.ModuleVersion
$UpdateVer = ""
$WebVersion = Find-Module -Name Moonshot365 | Select -expandproperty Version
if($WebVersion -eq $NewVer){$UpdateVer = $WebVersion}else{$UpdateVer = "$WebVersion - Please Update"}
Write-Host ""
Write-Host "======================= Moonshot 365 Module Commands =======================>" -ForegroundColor Yellow
Write-Host " Installed Version: $NewVer" -ForegroundColor Yellow
Write-Host " Latest Version: $UpdateVer" -ForegroundColor Yellow
Write-Host ""
Write-Host " Current Moonshot365 Commands: " -ForegroundColor Yellow
Write-Host ""
Write-Host " 1. Connect-Office365" -ForegroundColor Green
Write-Host " Connect to Office 365 PowerShell services. Alt: CO365" -ForegroundColor Yellow
Write-Host " 2. Get-Office365Modules" -ForegroundColor Green
Write-Host " Install AzureAD, MsOnline, and SharePoint modules" -ForegroundColor Yellow
Write-Host " 3. New-HTMLReport" -ForegroundColor Green
Write-Host " Generate intractive HTML report on Office 365 Tenant" -ForegroundColor Yellow
Write-Host " 4. New-365Report" -ForegroundColor Green
Write-Host " Report on O365 tenant objects & generate migration scripts" -ForegroundColor Yellow
Write-Host " 5. Start-MailboxChecks" -ForegroundColor Green
Write-Host " Mailbox scripts to get permissions and other information" -ForegroundColor Yellow
Write-Host " 6. Get-MFAStatus" -ForegroundColor Green
Write-Host " Generate report of users and their MFA status" -ForegroundColor Yellow
Write-Host " 7. New-PartnerUserReport" -ForegroundColor Green
Write-Host " Report on user across Partner Tenants" -ForegroundColor Yellow
Write-Host " 8. Start-RoomScripts" -ForegroundColor Green
Write-Host " Various scripts for managing Room Mailboxes" -ForegroundColor Yellow
Write-Host " 9. Update-Moonshot365" -ForegroundColor Green
Write-Host " Update the Moonshot365 Module" -ForegroundColor Yellow
Write-Host " 10. Start-UserDisable" -ForegroundColor Green
Write-Host " Various scripts for disabling users" -ForegroundColor Yellow
Write-Host " 11. Get-Commands" -ForegroundColor Green
Write-Host " List available commands in Moonshot 365 Module" -ForegroundColor Yellow
Write-Host ""
Write-Host "============================================================================>" -ForegroundColor Yellow
$SwitchEnabled = 0
Sub-Command-Switch