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 |