MyPSFunctions.EXO.ps1
<#
=========================================================================== Created with: SAPIEN Technologies, Inc., PowerShell Studio 2021 v5.8.196 Created on: 10/26/2023 7:12 PM Created by: John@MyPSFunctions.com Organization: MyPSFunctions Filename: MyPSFunctions.EXO.psm1 ------------------------------------------------------------------------- Module Name: MyPSFunctions.EXO =========================================================================== #> #region EXO #################################################### ################# Exchange Online (EXO) #################### ################################################### Function Grant-EXOApplicationAccessToMailboxUsingGroup { param ( [Parameter(Mandatory = $true, Position = 1)] [String]$Mailbox, [Parameter(Mandatory = $true, Position = 2)] [String]$AppRegistrationName ) # Find Application $AllMgApps = Get-MgServicePrincipal -All $FoundMgApp = $AllMgApps | where { $_.DisplayName -eq $AppRegistrationName } If ($FoundMgApp) { $MgAppID = $FoundMgApp.AppId $MgAppObjectID = $FoundMgApp.ID Write-Log Warning -Message "Found AppRegistration: $AppRegistrationName" # Grant Application FullAccess to Mailbox New-ServicePrincipal -AppId $MgAppID -ObjectId $MgAppObjectID Add-MailboxPermission -identity $Mailbox -user $MgAppID -AccessRights FullAccess # Create Security Group $DG = Get-DistributionGroup $AppRegistrationName If (!($DG)) { $DG = New-DistributionGroup -Name $AppRegistrationName -Type security } $DG_Primary = $DG.PrimarySmtpAddress $DG_Alias = $DG.Alias # Add Mailbox to DG Add-DistributionGroupMember -Identity $DG_Primary -Member $Mailbox # Create Application Access Policy $Description = "Application Restriction for AppRegistration: $AppRegistrationName to $DG_Alias" New-ApplicationAccessPolicy -AppId $MgAppID -PolicyScopeGroupId $DG_Primary -AccessRight RestrictAccess -Description $Description # Set Authentication Policy Write-Log Warning -Message "The script will provide a list of available Authentication Policy allows Basic Authentication for SMTP" $AuthenticationPolicyAllowBasicSMTPs = Get-AuthenticationPolicy | where { $_.AllowBasicAuthSmtp -eq $True } $SelectedAuthenticationPolicyAllowBasicSMTP = $AuthenticationPolicyAllowBasicSMTPs | select Name, AllowBasicauthSmtp | Out-GridView -PassThru $SelectedAuthenticationPolicyAllowBasicSMTPName = $SelectedAuthenticationPolicyAllowBasicSMTP.Name Write-Log Info -Message "The script selected the following Authentication Policy: $SelectedAuthenticationPolicyAllowBasicSMTPName" # Assign Authentication Policy $BeforeUser = Get-User $Mailbox $BeforeAuthenticationPolicy = $BeforeUser.AuthenticationPolicy Write-Log Warning -Message "$Mailbox is currently using the following Authentication Policy: $BeforeAuthenticationPolicy" Read-Host "Please press enter to change the Authentication policy to $SelectedAuthenticationPolicyAllowBasicSMTPName" Set-User $Mailbox -AuthenticationPolicy $SelectedAuthenticationPolicyAllowBasicSMTPName -Confirm: $False Write-Log Warning -Message "$Mailbox is set with the following Authentication Policy: $BeforeAuthenticationPolicy" #Enable SMTP Client Authentication $BeforeCASMailbox = Get-CASMailbox $Mailbox $BeforeSmtpClientAuthenticationDisabled = $BeforeCASMailbox.SmtpClientAuthenticationDisabled $BeforeImapEnabled = $BeforeCASMailbox.ImapEnabled Write-Log Warning -Message "The $Mailbox SmtpClientAuthenticationDisabled is: $BeforeSmtpClientAuthenticationDisabled & ImapEnabled $BeforeImapEnabled" Set-CASMailbox $Mailbox -SmtpClientAuthenticationDisabled $false -Confirm: $False Set-CASMailbox $Mailbox -ImapEnabled $true -Confirm: $False $AfterCASMailbox = Get-CASMailbox $Mailbox $AfterSmtpClientAuthenticationDisabled = $AfterCASMailbox.SmtpClientAuthenticationDisabled $AfterImapEnabled = $AfterCASMailbox.ImapEnabled Write-Log Warning -Message "The $Mailbox SmtpClientAuthenticationDisabled is: $AfterSmtpClientAuthenticationDisabled & ImapEnabled $AfterImapEnabled" Set-MailboxRegionalConfiguration -Identity $Mailbox -Language en-us -LocalizeDefaultFolderName Get-MailboxRegionalConfiguration -Identity $Mailbox | fl Language, *date*, *folder* Write-Log Error -Message "Please add the $Mailbox to Conditional Access policy MFA Exclusion" } Else { Write-Log Error -Message "App Registration None Found : $AppRegistrationName" } } Function Generate-EXOUsersCustodianHoldReport { ############################################################################################################################################################################### #################################################################### Variable ##################################################################### ############################################################################################################################################################################### $Date = get-date -UFormat %d%m%Y $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ServerName = [Environment]::MachineName ###### Create Root Folder $RootFolder = $psscriptRoot + "\CasesHolds_Reports" ###### Create folder Variable $LogPathFolder = $RootFolder + "\Log\" $LogFile = $LogPathFolder + "Progress_" + $Date + ".log" $ReportPathFolder = $RootFolder + "\Reports\" ###### Create Folder Create-Folder $RootFolder Create-Folder $LogPathFolder Create-Folder $ReportPathFolder $Transcript_File = $LogPathFolder + "Transcript_" + $Date + ".txt" $ReportFile = $ReportPathFolder + "UsersCustodianHolds_" + $DateFull + ".xlsx" Start-Transcript -Path $Transcript_File -Append -Force ########### Initiate the Process log file when the script started ############ $Initiat_LogA = "#################### starting the Script #####################" $Startat = "### The Script has been launch at $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")" $Startwith = "The Script has been start with the following Account:" + [Environment]::UserName $Starton = "The Script has been start on the following Computer:" + [Environment]::MachineName $Initiat_LogB = "##############################################################" $Initiat_LogB | Out-File -FilePath $LogFile -Append $Initiat_LogB | Out-File -FilePath $LogFile -Append $Initiat_LogA | Out-File -FilePath $LogFile -Append $Startat | Out-File -FilePath $LogFile -Append $Startwith | Out-File -FilePath $LogFile -Append $Starton | Out-File -FilePath $LogFile -Append $Initiat_LogB | Out-File -FilePath $LogFile -Append $Initiat_LogB | Out-File -FilePath $LogFile -Append ############################################################################################################################################################################### #################################################################### Main Script ##################################################################### ############################################################################################################################################################################### # Connecting to Security & Compliance Center Read-Host "Are you connected to Security & Compliance Center module?" # Retreive all Ediscovery Cases Try { Write-Log warning -Message "The script will retreive all Ediscovery Cases (Standard)" $eDiscoveryCases = Get-ComplianceCase -ErrorAction SilentlyContinue Write-Log warning -Message "The script will retreive all Ediscovery Cases (Premium)" $eDiscoveryCases += Get-ComplianceCase -CaseType Advanced -ErrorAction SilentlyContinue } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to retreive all Ediscovery Cases (Standard & Premium)" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" Read-Host "Exit the script" Exit } #Initiate the Hash Table [Int]$i = 1 $Table = $Null $Table = @() $Count = ($eDiscoveryCases | Measure).count Write-Log Info -Message "The script retreived all Ediscovery Cases (Standard & Premium): $Count Cases" ForEach ($eDiscoveryCase in $eDiscoveryCases) { $eDiscoveryCase_Name = $Null $eDiscoveryCase_Status = $Null $eDiscoveryCase_Members = $Null $eDiscoveryCase_CaseType = $Null $eDiscoveryCase_ClosedDateTime = $Null $eDiscoveryCase_Enabled = $Null $eDiscoveryCase_CreatedDateTime = $Null $eDiscoveryCase_Policy_Name = "No Policy found" $eDiscoveryCase_Policy_Enabled = "No Policy found" $eDiscoveryCase_Policy_CreatedBy = "No Policy found" $eDiscoveryCase_Policy_LastModifiedBy = "No Policy found" $eDiscoveryCase_Policy_WhenCreatedUTC = "No Policy found" $eDiscoveryCase_Policy_WhenChangedUTC = "No Policy found" $eDiscoveryCase_Policy_DistributionStatus = "No Policy found" $eDiscoveryCase_Policy_DistributionResults = "No Policy found" $eDiscoveryCase_Policy_ExchangeLocations = "No Policy found" $eDiscoveryCase_Policy_SharepointLocations = "No Policy found" $eDiscoveryCase_Policy_ExchangeLocations_Count = "No Policy found" $eDiscoveryCase_Policy_SharepointLocations_Count = "No Policy found" $eDiscoveryCase_Policy_Rule_ContentMatchQuery = "No Rule Policy found" $eDiscoveryCase_Name = $eDiscoveryCase.Name $eDiscoveryCase_Status = $eDiscoveryCase.Status $eDiscoveryCase_CaseType = $eDiscoveryCase.CaseType $eDiscoveryCase_ClosedDateTime = $eDiscoveryCase.ClosedDateTime $eDiscoveryCase_Members = ((Get-ComplianceCaseMember -Case $eDiscoveryCase_Name).windowsLiveID) -join ';' Write-log Warning -message "The script is analyzing $eDiscoveryCase_Name ….. --- $i/$Count" if ($eDiscoveryCase_Status -eq 'Closed') { Write-log Warning -message "$eDiscoveryCase_Name is closed" $Table += New-object PSobject -Property ([Ordered] @{ eDiscoveryCase_Name = $eDiscoveryCase_Name; eDiscoveryCase_Members = $eDiscoveryCase_Members; eDiscoveryCase_CaseType = $eDiscoveryCase_CaseType; eDiscoveryCase_Status = $eDiscoveryCase_Status; eDiscoveryCase_CreatedDateTime = $eDiscoveryCase_CreatedDateTime; eDiscoveryCase_ClosedDateTime = $eDiscoveryCase_ClosedDateTime; eDiscoveryCase_Enabled = $eDiscoveryCase_Enabled; eDiscoveryCase_Policy_Name = $eDiscoveryCase_Policy_Name; eDiscoveryCase_Policy_Enabled = $eDiscoveryCase_Policy_Enabled; eDiscoveryCase_Policy_CreatedBy = $eDiscoveryCase_Policy_CreatedBy; eDiscoveryCase_Policy_LastModifiedBy = $eDiscoveryCase_Policy_LastModifiedBy; eDiscoveryCase_Policy_WhenCreatedUTC = $eDiscoveryCase_Policy_WhenCreatedUTC; eDiscoveryCase_Policy_WhenChangedUTC = $eDiscoveryCase_Policy_WhenChangedUTC; eDiscoveryCase_Policy_DistributionStatus = $eDiscoveryCase_Policy_DistributionStatus; eDiscoveryCase_Policy_DistributionResults = $eDiscoveryCase_Policy_DistributionResults; eDiscoveryCase_Policy_ExchangeLocations = $eDiscoveryCase_Policy_ExchangeLocations; eDiscoveryCase_Policy_ExchangeLocations_Count = $eDiscoveryCase_Policy_ExchangeLocations_Count; eDiscoveryCase_Policy_SharepointLocations = $eDiscoveryCase_Policy_SharepointLocations; eDiscoveryCase_Policy_SharepointLocations_Count = $eDiscoveryCase_Policy_SharepointLocations_Count; eDiscoveryCase_Policy_Rule_ContentMatchQuery = $eDiscoveryCase_Policy_Rule_ContentMatchQuery; }) } else { Write-log Warning -message "$eDiscoveryCase_Name is $eDiscoveryCase_Status" $eDiscoveryCase_Policies = $Null $eDiscoveryCase_Policies = Get-CaseHoldPolicy -Case $eDiscoveryCase_Name | % { Get-CaseHoldPolicy $_.Name -Case $_.CaseId -DistributionDetail } if ($eDiscoveryCase_Policies -ne $Null) { foreach ($eDiscoveryCase_Policy in $eDiscoveryCase_Policies) { $eDiscoveryCase_Policy_Name = $Null $eDiscoveryCase_Policy_Name = $eDiscoveryCase_Policy.Name $eDiscoveryCase_Policy_Rule = $Null $eDiscoveryCase_Policy_Rule = Get-CaseHoldRule -Policy $eDiscoveryCase_Policy_Name $eDiscoveryCase_Enabled = $eDiscoveryCase.Enabled $eDiscoveryCase_CreatedDateTime = $eDiscoveryCase.CreatedDateTime $eDiscoveryCase_Policy_Name = $eDiscoveryCase_Policy.Name $eDiscoveryCase_Policy_Enabled = $eDiscoveryCase_Policy.Enabled $eDiscoveryCase_Policy_CreatedBy = $eDiscoveryCase_Policy.CreatedBy $eDiscoveryCase_Policy_LastModifiedBy = $eDiscoveryCase_Policy.LastModifiedBy $eDiscoveryCase_Policy_ExchangeLocations = (($eDiscoveryCase_Policy.exchangelocation.name) -join ';') $eDiscoveryCase_Policy_SharepointLocations = (($eDiscoveryCase_Policy.sharePointlocation.name) -join ';') $eDiscoveryCase_Policy_ExchangeLocations_Count = (($eDiscoveryCase_Policy.exchangelocation.name) | Measure).count $eDiscoveryCase_Policy_SharepointLocations_Count = (($eDiscoveryCase_Policy.sharePointlocation.name) | Measure).count $eDiscoveryCase_Policy_WhenCreatedUTC = $eDiscoveryCase_Policy.WhenCreatedUTC $eDiscoveryCase_Policy_WhenChangedUTC = $eDiscoveryCase_Policy.WhenChangedUTC $eDiscoveryCase_Policy_DistributionStatus = $eDiscoveryCase_Policy.DistributionStatus $eDiscoveryCase_Policy_DistributionResults = $eDiscoveryCase_Policy.DistributionResults.ResultCode.Value $Table += New-object PSobject -Property ([Ordered] @{ eDiscoveryCase_Name = $eDiscoveryCase_Name; eDiscoveryCase_Members = $eDiscoveryCase_Members; eDiscoveryCase_CaseType = $eDiscoveryCase_CaseType; eDiscoveryCase_Status = $eDiscoveryCase_Status; eDiscoveryCase_CreatedDateTime = $eDiscoveryCase_CreatedDateTime; eDiscoveryCase_ClosedDateTime = $eDiscoveryCase_ClosedDateTime; eDiscoveryCase_Enabled = $eDiscoveryCase_Enabled; eDiscoveryCase_Policy_Name = $eDiscoveryCase_Policy_Name; eDiscoveryCase_Policy_Enabled = $eDiscoveryCase_Policy_Enabled; eDiscoveryCase_Policy_CreatedBy = $eDiscoveryCase_Policy_CreatedBy; eDiscoveryCase_Policy_LastModifiedBy = $eDiscoveryCase_Policy_LastModifiedBy; eDiscoveryCase_Policy_WhenCreatedUTC = $eDiscoveryCase_Policy_WhenCreatedUTC; eDiscoveryCase_Policy_WhenChangedUTC = $eDiscoveryCase_Policy_WhenChangedUTC; eDiscoveryCase_Policy_DistributionStatus = $eDiscoveryCase_Policy_DistributionStatus; eDiscoveryCase_Policy_DistributionResults = $eDiscoveryCase_Policy_DistributionResults; eDiscoveryCase_Policy_ExchangeLocations = $eDiscoveryCase_Policy_ExchangeLocations; eDiscoveryCase_Policy_ExchangeLocations_Count = $eDiscoveryCase_Policy_ExchangeLocations_Count; eDiscoveryCase_Policy_SharepointLocations = $eDiscoveryCase_Policy_SharepointLocations; eDiscoveryCase_Policy_SharepointLocations_Count = $eDiscoveryCase_Policy_SharepointLocations_Count; eDiscoveryCase_Policy_Rule_ContentMatchQuery = $eDiscoveryCase_Policy_Rule_ContentMatchQuery; }) } } else { Write-log Warning -message "No hold policies found in case: $eDiscoveryCase_Name" $Table += New-object PSobject -Property ([Ordered] @{ eDiscoveryCase_Name = $eDiscoveryCase_Name; eDiscoveryCase_Members = $eDiscoveryCase_Members; eDiscoveryCase_CaseType = $eDiscoveryCase_CaseType; eDiscoveryCase_Status = $eDiscoveryCase_Status; eDiscoveryCase_CreatedDateTime = $eDiscoveryCase_CreatedDateTime; eDiscoveryCase_ClosedDateTime = $eDiscoveryCase_ClosedDateTime; eDiscoveryCase_Enabled = $eDiscoveryCase_Enabled; eDiscoveryCase_Policy_Name = $eDiscoveryCase_Policy_Name; eDiscoveryCase_Policy_Enabled = $eDiscoveryCase_Policy_Enabled; eDiscoveryCase_Policy_CreatedBy = $eDiscoveryCase_Policy_CreatedBy; eDiscoveryCase_Policy_LastModifiedBy = $eDiscoveryCase_Policy_LastModifiedBy; eDiscoveryCase_Policy_WhenCreatedUTC = $eDiscoveryCase_Policy_WhenCreatedUTC; eDiscoveryCase_Policy_WhenChangedUTC = $eDiscoveryCase_Policy_WhenChangedUTC; eDiscoveryCase_Policy_DistributionStatus = $eDiscoveryCase_Policy_DistributionStatus; eDiscoveryCase_Policy_DistributionResults = $eDiscoveryCase_Policy_DistributionResults; eDiscoveryCase_Policy_ExchangeLocations = $eDiscoveryCase_Policy_ExchangeLocations; eDiscoveryCase_Policy_ExchangeLocations_Count = $eDiscoveryCase_Policy_ExchangeLocations_Count; eDiscoveryCase_Policy_SharepointLocations = $eDiscoveryCase_Policy_SharepointLocations; eDiscoveryCase_Policy_SharepointLocations_Count = $eDiscoveryCase_Policy_SharepointLocations_Count; eDiscoveryCase_Policy_Rule_ContentMatchQuery = $eDiscoveryCase_Policy_Rule_ContentMatchQuery; }) } } $i++ } $Table | Export-Excel $ReportFile -TableName "EdiscoveryCasesReport" -Title "Ediscovery Cases Report" -TitleBold -WorksheetName "EdiscoveryCasesReport" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFile" } Function Generate-EXOBasicSMTPSettingsAllMailboxes { $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ExcelFile = ".\Report_Settings_Allowing_BasicAuth_SMTP_" + $DateFull + ".xlsx" # Check Tenant SmtpClientAuthenticationDisabled Try { Write-Log warning -Message "The script is checking the SMTP authentication settings at the tenant level" $TransportConfig_SmtpClientAuthenticationDisabled = (Get-TransportConfig).SmtpClientAuthenticationDisabled Write-Log Info -Message "SmtpClientAuthenticationDisabled is set to: $TransportConfig_SmtpClientAuthenticationDisabled" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to check the SMTP authentication settings at the tenant level" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $TransportConfig_SmtpClientAuthenticationDisabled = "Failed with Error:$ErrorMessage" } # Search for Authentication Policy allowing Basic SMTP: Try { Write-Log warning -Message "The script is searching for Authentication Policy Allowing Basic Authentication for SMTP" $AuthenticationPolicyAllowBasicSMTPs = Get-AuthenticationPolicy | where { $_.AllowBasicAuthSmtp -eq $True } $Count = ($AuthenticationPolicyAllowBasicSMTPs | Measure).count Write-Log Info -Message "The script found $Count Authentication Policies allowing Basic SMTP" if ($Count -gt 1) { $FoundAuthenticationPolicyAllowBasicSMTPs = $AuthenticationPolicyAllowBasicSMTPs.Name -join "," } Else { $FoundAuthenticationPolicyAllowBasicSMTPs = $AuthenticationPolicyAllowBasicSMTPs.Name } } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to find Authentication Policy Allowing Basic Authentication for SMTP" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundAuthenticationPolicyAllowBasicSMTPs = "Failed with Error:$ErrorMessage" } $TenantSMTPSettings = $Null $TenantSMTPSettings = @() $TenantSMTPSettings += New-object PSobject -Property ([Ordered] @{ TransportConfig_SmtpClientAuthenticationDisabled = $TransportConfig_SmtpClientAuthenticationDisabled; AuthenticationPolicyAllowBasicSMTPs = $FoundAuthenticationPolicyAllowBasicSMTPs; }) $TenantSMTPSettings | Export-Excel -Path $ExcelFile -Append -WorksheetName "Tenant SMTP Settings" -Title "Tenant Level SMTP Settings" -TitleBold -TableName "TenantSMTPSettings" -TableStyle Medium9 -AutoSize # Check CAS Mailboxes SmtpClientAuthenticationDisabled Try { Write-Log warning -Message "The script is checking the SmtpClientAuthenticationDisabled for all Mailboxes" $CASMailboxes = Get-CASMailbox -ResultSize unlimited $CASMailboxesCount = ($CASMailboxes | Measure).count } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to check the SmtpClientAuthenticationDisabled for all Mailboxes" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" } #Report Write-Log Info -Message "Found CAS Mailboxes: $CASMailboxesCount" $CASMailboxes = $CASMailboxes | Select DisplayName, PrimarySmtpAddress, SmtpClientAuthenticationDisabled $CASMailboxes | Export-Excel -Path $ExcelFile -Append -WorksheetName "AllCASMailboxes" -Title "All CAS Mailboxes" -TitleBold -TableName "AllCASMailboxes" -TableStyle Medium9 -AutoSize $CASMailboxes | Group-Object -Property SmtpClientAuthenticationDisabled | Sort-Object -Property Count -Descending $ExcelChart = New-ExcelChartDefinition -XRange Name -YRange Count -ChartType Pie -Title "SmtpClientAuthenticationDisabled Usage" $CASMailboxes | Group-Object -Property SmtpClientAuthenticationDisabled | Sort-Object -Property Count -Descending | Select Count, Name | Export-Excel -Path $ExcelFile -Append -WorksheetName "PieChart-SmtpClientAuthenticationDisabled" -ExcelChartDefinition $ExcelChart -AutoNameRange -Title "SmtpClientAuthenticationDisabled Usage" -AutoSize # Check for Authentication Policy for all Users Try { Write-Log warning -Message "The script is checking AuthenticationPolicy for all Mailboxes" $Users = Get-User -ResultSize unlimited $UsersCount = ($Users | Measure).count } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to check AuthenticationPolicy for all Mailboxes" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" } # Reports: Write-Log Info -Message "Found Users: $UsersCount" $Users = $Users | Select DisplayName, UserPrincipalName, AuthenticationPolicy $Users | Export-Excel -Path $ExcelFile -Append -WorksheetName "AuthenticationPolicy AllUsers" -Title "AuthenticationPolicy AllUsers" -TitleBold -TableName "AuthenticationPolicy AllUsers" -TableStyle Medium9 -AutoSize $Users | Group-Object -Property AuthenticationPolicy | Sort-Object -Property Count -Descending $ExcelChart = New-ExcelChartDefinition -XRange Name -YRange Count -ChartType Pie -Title "AuthenticationPolicy Usage" $Users | Group-Object -Property AuthenticationPolicy | Sort-Object -Property Count -Descending | Select Count, Name | Export-Excel -Path $ExcelFile -Append -WorksheetName "PieChart-AuthenticationPolicy" -ExcelChartDefinition $ExcelChart -AutoNameRange -Title "AuthenticationPolicy Usage" -AutoSize Write-Log Info -Message "The script generate the following report: $ExcelFile " } Function Check-EXOMailboxSMTPBasicAuthSettings { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$PrimarySmtpAddress ) # Check Tenant SmtpClientAuthenticationDisabled Try { Write-Log warning -Message "The script is checking the SMTP authentication settings at the tenant level" $TransportConfig_SmtpClientAuthenticationDisabled = (Get-TransportConfig).SmtpClientAuthenticationDisabled Write-Log Info -Message "SmtpClientAuthenticationDisabled is set to: $TransportConfig_SmtpClientAuthenticationDisabled" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to check the SMTP authentication settings at the tenant level" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $TransportConfig_SmtpClientAuthenticationDisabled = "Failed with Error:$ErrorMessage" } # Check User Mailbox SmtpClientAuthenticationDisabled Try { Write-Log warning -Message "The script is checking the SmtpClientAuthenticationDisabled for: $PrimarySmtpAddress" $CASMailbox_SmtpClientAuthenticationDisabled = (Get-CASMailbox $PrimarySmtpAddress).SmtpClientAuthenticationDisabled Write-Log Info -Message "$PrimarySmtpAddress SmtpClientAuthenticationDisabled is set:$CASMailbox_SmtpClientAuthenticationDisabled" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to check the SmtpClientAuthenticationDisabled for: $PrimarySmtpAddress" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $CASMailbox_SmtpClientAuthenticationDisabled = "Failed with Error:$ErrorMessage" } # Search for Authentication Policy allowing Basic SMTP: Try { Write-Log warning -Message "The script is searching for Authentication Policy Allowing Basic Authentication for SMTP" $AuthenticationPolicyAllowBasicSMTPs = Get-AuthenticationPolicy | where { $_.AllowBasicAuthSmtp -eq $True } $Count = ($AuthenticationPolicyAllowBasicSMTPs | Measure).count Write-Log Info -Message "The script found $Count Authentication Policies allowing Basic SMTP" if ($Count -gt 1) { $FoundAuthenticationPolicyAllowBasicSMTPs = $AuthenticationPolicyAllowBasicSMTPs.Name -join "," } Else { $FoundAuthenticationPolicyAllowBasicSMTPs = $AuthenticationPolicyAllowBasicSMTPs.Name } } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to find Authentication Policy Allowing Basic Authentication for SMTP" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundAuthenticationPolicyAllowBasicSMTPs = "Failed with Error:$ErrorMessage" } # Check for Authentication Policy assign to User Mailbox Try { Write-Log warning -Message "The script is check AuthenticationPolicy for $PrimarySmtpAddress" $UserAuthenticationPolicy = (Get-User $PrimarySmtpAddress).AuthenticationPolicy if ($UserAuthenticationPolicy -eq $Null) { $UserAuthenticationPolicy = "Using Tenant Setting" } Write-Log Info -Message "$PrimarySmtpAddress AuthenticationPolicy is set: $UserAuthenticationPolicy" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to check AuthenticationPolicy for $PrimarySmtpAddress" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $UserAuthenticationPolicy = "Failed with Error:$ErrorMessage" } # Check Conditional Access Policy Write-Log warning -Message "Please check if $PrimarySmtpAddress is allow to use legacy/Basic Authentication in Conditional access or Secure Default is disabled" $UserMailboxData = $Null $UserMailboxData = @() $UserMailboxData += New-object PSobject -Property ([Ordered] @{ PrimarySmtpAddress = $PrimarySmtpAddress; TransportConfig_SmtpClientAuthenticationDisabled = $TransportConfig_SmtpClientAuthenticationDisabled; CASMailbox_SmtpClientAuthenticationDisabled = $CASMailbox_SmtpClientAuthenticationDisabled; TenantAuthenticationPolicyAllowBasicSMTPs = $AuthenticationPolicyAllowBasicSMTPs; UserAuthenticationPolicy = $UserAuthenticationPolicy; ConditionalAccessPolicy = "Review Conditional Access Policy for Exception"; }) Return $UserMailboxData } Function Generate-EXOMailboxesRetentionReport { [CmdletBinding()] param () $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ExcelFile = ".\Report_AllMailboxes_RetentionPolicies_" + $DateFull + ".xlsx" $Mailboxes = Get-Mailbox -ResultSize Unlimited $Mailboxes = $Mailboxes | Select DisplayName, PrimarySmtpAddress, RetentionPolicy, LitigationHoldEnabled, LitigationHoldDate, LitigationHoldOwner, LitigationHoldDuration $Mailboxes | Export-Excel -Path $ExcelFile -WorksheetName "AllMailboxes" -Title "Retention All Mailboxes" -TitleBold -TableName "AllMailboxes" -TableStyle Medium9 $Mailboxes | Group-Object -Property RetentionPolicy | Sort-Object -Property Count -Descending $ExcelChart = New-ExcelChartDefinition -XRange Name -YRange Count -ChartType Pie -Title "Retention Policy Usage" $Mailboxes | Group-Object -Property RetentionPolicy | Sort-Object -Property Count -Descending | Select Count, Name | Export-Excel -Path $ExcelFile -Append -WorksheetName "PieChart-Retention" -ExcelChartDefinition $ExcelChart -AutoNameRange -Title "Retention Policy Usage" $ExcelChart = New-ExcelChartDefinition -XRange Name -YRange Count -ChartType Pie -Title "Litigation Hold Enabled" $Mailboxes | Group-Object -Property LitigationHoldEnabled | Sort-Object -Property Count -Descending | Select Count, Name | Export-Excel -Path $ExcelFile -Append -WorksheetName "PieChart-LitigationHoldEnabled" -ExcelChartDefinition $ExcelChart -AutoNameRange -Title "Litigation Hold Enabled" $ExcelChart = New-ExcelChartDefinition -XRange Name -YRange Count -ChartType Pie -Title "Litigation Hold Owner" $Mailboxes | Group-Object -Property LitigationHoldOwner | Sort-Object -Property Count -Descending | Select Count, Name | Export-Excel -Path $ExcelFile -Append -WorksheetName "PieChart-LitigationHoldOwner" -ExcelChartDefinition $ExcelChart -AutoNameRange -Title "Litigation Hold Owner" Write-log INFO -Message "Generate the following Report: $ExcelFile" } Function Generate-EXORecipientReportBySMTPDomain { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$Domain ) $Filter = '{ EmailAddresses -like "*' + $Domain + '*" }' $FilteredRecipients = Get-Recipient -Filter $Filter | select Name, DisplayName, SamAccountName, PrimarySmtpAddress, WindowsLiveID, WhenMailboxCreated, RecipientType, RecipientTypeDetails, SKUAssigned $FilteredRecipients | group RecipientType | ft Count, Name $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ExcelFile = "Report_AllRecipients_" + $Domain + "_" + $DateFull + ".xlsx" $FilteredRecipients | Export-Excel $ExcelFile -TableName "AllRecipients" -Title "All Recipients" -TitleBold -WorksheetName "AllRecipients" -TableStyle Medium9 -AutoSize -AutoFilter Write-Log Warning -Message "The CSV File has been generated: $ExcelFile" } Function Find-UserMailboxUsingEmailFromCSV { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$CSVFile ) Try { Read-Host "Expected CSV Column: Mail" $Users = Import-Csv $CSVFile Write-Log -Level INFO -Message "The script import successfully :$CSVFile" $ImportStatus = "Yes" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to import $CSVFile " Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" Write-Log -Level Error -Message "The Script will stop" $ImportStatus = "No" } If ($ImportStatus -eq "Yes") { #Initiate the Hash Table [Int]$i = 1 $Table = $Null $Table = @() $Count = ($Users | Measure).count ForEach ($User in $Users) { $EmailAddress = $Null $EmailAddress = $User.Mail $RecipientTypeDetails = $Null $WhenSoftDeleted = $Null $WhenCreated = $Null $PrimarySmtpAddress = $Null $LitigationHoldEnabled = $Null $FoundStatus = "No" Write-log Warning -message "The script is analyzing $EmailAddress ….. --- $i/$Count" Try { Write-log Warning -message "The script is searching for $EmailAddress as recipient" $Recipient = $Null $Recipient = Get-Recipient $EmailAddress -IncludeSoftDeletedRecipients -ErrorAction Stop Write-Log -Level INFO -Message "The script found $EmailAddress as recipient in EXO" $FoundStatus = "Yes" $RecipientTypeDetails = $Recipient.RecipientTypeDetails $WhenSoftDeleted = $Recipient.WhenSoftDeleted $WhenCreated = $Recipient.WhenCreated $PrimarySmtpAddress = $Recipient.PrimarySmtpAddress $LitigationHoldEnabled = $Recipient.LitigationHoldEnabled } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to find $EmailAddress" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $FoundStatus = "No" $RecipientTypeDetails = "Not Found" $RecipientTypeDetails = "Not Found" $WhenSoftDeleted = "Not Found" $WhenCreated = "Not Found" $PrimarySmtpAddress = "Not Found" $LitigationHoldEnabled = "Not Found" } $Table += New-object PSobject -Property ([Ordered] @{ EmailAddress = $EmailAddress; PrimarySmtpAddress = $PrimarySmtpAddress; RecipientTypeDetails = $RecipientTypeDetails; WhenCreated = $WhenCreated; WhenSoftDeleted = $WhenSoftDeleted; LitigationHoldEnabled = $LitigationHoldEnabled; }) $i++ } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = ".\Report_Recipients_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx -TableName "Recipients" -Title "Recipients" -TitleBold -WorksheetName "Recipients" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } } Function Find-UserUsingEmailFromCSV { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$CSVFile ) Try { Read-Host "Expected CSV Column: EmailAddress" $Users = Import-Csv $CSVFile Write-Log -Level INFO -Message "The script import successfully :$CSVFile" $ImportStatus = "Yes" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to import $CSVFile " Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" Write-Log -Level Error -Message "The Script will stop" $ImportStatus = "No" } If ($ImportStatus -eq "Yes") { #Initiate the Hash Table [Int]$i = 1 $Table = $Null $Table = @() $Count = ($Users | Measure).count ForEach ($User in $Users) { $EmailAddress = $Null $EmailAddress = $User.EmailAddress $FirstName = $Null $LastName = $Null $DisplayName = $Null $WindowsLiveID = $Null $DistinguishedName = $Null $RecipientTypeDetails = $Null $AuthenticationType = $Null $Capabilities = $Null $WhenCreated = $Null $WhenMailboxCreated = $Null $Title = $Null $Department = $Null $IsDirSynced = $Null $Office = $Null $Manager = $Null $CountryOrRegion = $Null $City = $Null $Alias = $Null Write-log Warning -message "The script is analyzing $EmailAddress ….. --- $i/$Count" Try { Write-log Warning -message "The script is searching for $EmailAddress as recipient" $Recipient = $Null $Recipient = Get-Recipient $EmailAddress -ErrorAction Stop Write-Log -Level INFO -Message "The script found $EmailAddress as recipient in EXO" $FoundStatus = "Yes" $FirstName = $Recipient.FirstName $LastName = $Recipient.LastName $DisplayName = $Recipient.DisplayName $WindowsLiveID = $Recipient.WindowsLiveID $DistinguishedName = $Recipient.DistinguishedName $RecipientTypeDetails = $Recipient.RecipientTypeDetails $AuthenticationType = $Recipient.AuthenticationType $Capabilities = $Recipient.Capabilities $WhenCreated = $Recipient.WhenCreated $WhenMailboxCreated = $Recipient.WhenMailboxCreated $Title = $Recipient.Title $Department = $Recipient.Department $IsDirSynced = $Recipient.IsDirSynced $Office = $Recipient.Office $Manager = $Recipient.Manager $CountryOrRegion = $Recipient.CountryOrRegion $City = $Recipient.City $Alias = $Recipient.Alias } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to find $EmailAddress" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $FoundStatus = "No" $FirstName = "Not Found" $LastName = "Not Found" $DisplayName = "Not Found" $WindowsLiveID = "Not Found" $DistinguishedName = "Not Found" $RecipientTypeDetails = "Not Found" $AuthenticationType = "Not Found" $Capabilities = "Not Found" $WhenCreated = "Not Found" $WhenMailboxCreated = "Not Found" $Title = "Not Found" $Department = "Not Found" $IsDirSynced = "Not Found" $Office = "Not Found" $Manager = "Not Found" $CountryOrRegion = "Not Found" $City = "Not Found" $Alias = "Not Found" } $Table += New-object PSobject -Property ([Ordered] @{ EmailAddress = $EmailAddress; FirstName = $FirstName; LastName = $LastName; DisplayName = $DisplayName; Title = $Title; Department = $Department; Office = $Office; City = $City; CountryOrRegion = $CountryOrRegion; Manager = $Manager; WindowsLiveID = $WindowsLiveID; Alias = $Alias; DistinguishedName = $DistinguishedName; RecipientTypeDetails = $RecipientTypeDetails; AuthenticationType = $AuthenticationType; IsDirSynced = $IsDirSynced; Capabilities = $Capabilities; WhenCreated = $WhenCreated; WhenMailboxCreated = $WhenMailboxCreated; }) $i++ } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = ".\Report_Recipients_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx -TableName "AllRecipients" -Title "All Recipients" -TitleBold -WorksheetName "AllRecipients" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } } Function Generate-AllAcceptedDomainsDMARCReport { [CmdletBinding()] param () $Domains = Get-AcceptedDomain #Initiate the Hash Table [Int]$i = 1 $Table = $Null $Table = @() $Count = ($Domains | Measure).count Foreach ($Domain in $Domains) { $Identity = $Null $Identity = $Domain.Identity Write-log Warning -message "The script is analyzing The domain: $Identity ….. --- $i/$Count" #Check SPF Record Try { $TXTRecords = $Null $TXTRecords = $Null $TXTRecords = Resolve-DnsName -Name $Identity -Type TXT -ErrorAction SilentlyContinue $SPFRecord = $TXTRecords | where { $_.Strings -like "*spf*" } $SPFRecordName = $Null $SPFRecordName = $SPFRecord.Name $SPFRecordValue = $Null $SPFRecordValue = $SPFRecord.Strings -join ";" } Catch { Write-log Error -Message "Failed to find SPF record" } # Check DMARC Try { $DMARCTXTRecordName= $Null $DMARC = $Null $DMARCName = $Null $DMARCValue = $Null $DMARCTXTRecordName = "_dmarc." + $Identity $DMARC = Resolve-DnsName -Name $DMARCTXTRecordName -Type TXT -ErrorAction SilentlyContinue $DMARCName = $DMARC.Name $DMARCValue = $DMARC.Text -join ";" } Catch { $ErrorMessage = $Error[0].Exception.Message Write-log Error -Message "Failed to find DMARC - $ErrorMessage" } # Check MX Record Try { $MXRecords = $Null $MXRecords = Resolve-DnsName -Name $Identity -Type MX -ErrorAction SilentlyContinue $MXRecords = $MXRecords | where { $_.Type -eq "MX" } $MXRecordValue = $Null $MXRecordValue = @() foreach ($MXRecord in $MXRecords) { $MXRecordName = $MXRecord.NameExchange $MXRecordPreference = $MXRecord.Preference $MXRecordValue += $MXRecordName + ':' + $MXRecordPreference } $MXRecordValue = $MXRecordValue -Join " - " } Catch { $ErrorMessage = $Error[0].Exception.Message Write-log Error -Message "Failed to find MX Record - $ErrorMessage" } $Table += New-object PSobject -Property ([Ordered] @{ Domain = $Identity; MXRecord = $MXRecordValue; SPFRecord = $SPFRecordValue; DMARC = $DMARCValue; }) $i++ } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = "AllAcceptedDomains_DMARCReports_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx -TableName "DMARCAcceptedDomains" -Title "DMARC Accepted Domains" -TitleBold -WorksheetName "DMARCAcceptedDomains" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } Function Get-EXODDGroupMembership { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$EmailAddress ) $DDG = Get-DynamicDistributionGroup -Identity $EmailAddress $Members = Get-Recipient -RecipientPreviewFilter ($DDG.RecipientFilter) | Select DisplayName, PrimarySmtpAddress $LocalPart = $EmailAddress.Substring(0, $EmailAddress.LastIndexOf("@")) $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ExcelFile = "Members_Of_" + $LocalPart + "_" + $DateFull + ".xlsx" $Members | Export-Excel $ExcelFile -TableName "MemberOf" -Title "MemberOf" -TitleBold -WorksheetName "MemberOf" -TableStyle Medium9 -AutoSize -AutoFilter $Members | Ft Write-Log Warning -Message "The following file was generated: $ExcelFile" } Function Change-EXORetentionPolicy { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$Email, [Parameter(Mandatory = $true, Position = 2)] [String]$RetentionPolicy ) # Check if the mailbox has a Online Archive $ArchiveName = $Null $Mailbox = $Null $ArchiveName2 = $Null $Mailbox2 = $Null $CurrentRetentionPolicy = $Null $CurrentRetentionPolicy2 = $Null $Mailbox = Get-Mailbox $Email $ArchiveName = $Mailbox.ArchiveName $CurrentRetentionPolicy = $Mailbox.RetentionPolicy Write-Log -Level Warning -Message "$Email has the following settings:" Write-Log -Level Warning -Message "--- Online Archive Name: $ArchiveName" Write-Log -Level Warning -Message "--- RetentionPolicy: $CurrentRetentionPolicy" if ($ArchiveName) { Write-Log -Level Warning -Message "The script will assign the following Retention policy: $RetentionPolicy" # Assign Retention Set-Mailbox $Email -RetentionPolicy $RetentionPolicy #sleep 10 Start-ManagedFolderAssistant -Identity $Email #sleep 10 $Mailbox2 = Get-Mailbox $Email $ArchiveName2 = $Mailbox2.ArchiveName $CurrentRetentionPolicy2 = $Mailbox2.RetentionPolicy Write-Log -Level Warning -Message "$Email has the following settings:" Write-Log -Level Warning -Message "--- Online Archive Name: $ArchiveName2" Write-Log -Level Warning -Message "--- RetentionPolicy: $CurrentRetentionPolicy2" } Else { Write-Log -Level -Level Error -Message "Online Archive was NOT found" Write-Log -Level Warning -Message "Online Archive maiblox will be enabled for $Email" Enable-Mailbox -Identity $Email -Archive } } Function Create-EXOSharedMailboxWithSG { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$LocalPart, [Parameter(Mandatory = $true, Position = 2)] [String]$Domain ) #Variable $SecurityGroupName = "MBX_" + $LocalPart + "_FP" $SecurityGroupEmailAddress = $SecurityGroupName + "@" + $Domain $PrimaryEmailAddress = $LocalPart + "@" + $Domain $CreateSharedMBXStatus = "Failed" $CreateSGStatus = "Failed" $GrantSendAsStatus = "Failed" # Create Security Group Try { Write-Log -Level Info -Message "The script will try to create the Mail-Enabled Security Group $SecurityGroupName ($SecurityGroupEmailAddress)" New-DistributionGroup -Name $SecurityGroupName -Alias $SecurityGroupName -Type security -PrimarySmtpAddress $SecurityGroupEmailAddress Write-Log -Level warning -Message "The script successfully created the Mail-Enabled Security Group $SecurityGroupName ($SecurityGroupEmailAddress)" $CreateSGStatus = "Success" # Create Shared Mailbox Try { Write-Log -Level Info -Message "The script will try to create the Shared Mailbox $LocalPart ($PrimaryEmailAddress)" New-Mailbox -Shared -Name $LocalPart -DisplayName $LocalPart -Alias $LocalPart -PrimarySmtpAddress $PrimaryEmailAddress Write-Log -Level warning -Message "The script successfully created the Shared Mailbox $LocalPart ($PrimaryEmailAddress)" $CreateSharedMBXStatus = "Success" #Assign SendAs Permission to Security Group Try { Write-Log -Level Info -Message "The script will try to grant SendAs Permission $PrimaryEmailAddress to $SecurityGroupEmailAddress" Add-RecipientPermission -Identity $PrimaryEmailAddress -Trustee $SecurityGroupEmailAddress -AccessRights SendAs -confirm:$false Write-Log -Level warning -Message "The script successfully grant SendAs Permission $PrimaryEmailAddress to $SecurityGroupEmailAddress" $GrantSendAsStatus = "Success" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to grant SendAs Permission $PrimaryEmailAddress to $SecurityGroupEmailAddress" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" } #Assign FullAccess Permission to Security Group Try { Write-Log -Level Info -Message "The script will try to grant FullAccess $PrimaryEmailAddress to $SecurityGroupEmailAddress" Add-MailboxPermission -Identity $PrimaryEmailAddress -User $SecurityGroupEmailAddress -AccessRights FullAccess -InheritanceType All Write-Log -Level warning -Message "The script successfully grant FullAccess $PrimaryEmailAddress to $SecurityGroupEmailAddress" $GrantFullAccessStatus = "Success" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to grant FullAccess $PrimaryEmailAddress to $SecurityGroupEmailAddress" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $GrantFullAccessStatus = "Failed" } } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to create the Shared Mailbox $LocalPart ($PrimaryEmailAddress)" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" } } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to create the Mail-Enabled Security Group $SecurityGroupName ($SecurityGroupEmailAddress)" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" } # Output $OutPut = $null $OutPut = @() $OutPut += New-object PSobject -Property ([Ordered] @{ SharedMailboxPrimaryEmailAddress = $PrimaryEmailAddress; SecurityGroupName = $SecurityGroupName; CreateSharedMBXStatus = $CreateSharedMBXStatus; GrantSendAsStatus = $GrantSendAsStatus; GrantFullAccessStatus = $GrantFullAccessStatus; }) Return $OutPut } Function Get-EXODynamicDGMembers { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$EmailAddress ) $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $LocalPart = $EmailAddress.Substring(0, $EmailAddress.LastIndexOf("@")) $ReportFile = ".\Membership_Of_" + $LocalPart + "_" + $DateFull + ".csv" $DL = Get-DynamicDistributionGroup -Identity $EmailAddress $DLMembers = Get-Recipient -RecipientPreviewFilter ($DL.RecipientFilter) $DLMembers | Select DisplayName, PrimarySmtpAddress $DLMembers | Select DisplayName, PrimarySmtpAddress | Export-csv $ReportFile -NoTypeInformation -Encoding UTF8 sleep 1 Write-host "Generate the following Report: $ReportFile" -ForegroundColor Yellow } Function Check-SharedMailboxPermission { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$SharedAddress ) $Mailbox = $Null $Mailbox = Get-Mailbox $SharedAddress If ($Mailbox) { $DisplayName = $Mailbox.DisplayName $PrimarySMTPAddress = $Mailbox.PrimarysmtpAddress Write-host "Mailbox found $DisplayName ($PrimarySMTPAddress)" $Permissions = $Null $Permissions = Get-MailboxPermission $PrimarySMTPAddress If ($Permissions) { $FoundGroup = $Permissions | where { $_.User -like "MBX_*" } If ($FoundGroup) { $Securitygroup = $Null $Securitygroup = $FoundGroup.User Write-host "groupName is: $Securitygroup " Get-DistributionGroupMember $Securitygroup | Select DisplayName, PrimarySmtpAddress } } } Else { Write-host "Mailbox NOT found $SharedAddress" } } Function Generate-EXOMailboxesUsingAcceptedDomain { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$SMTPDomain ) # Get all mailboxes with the specified SMTP domain $SMTPDomain = "@" + $SMTPDomain $Mailboxes = Get-Mailbox -ResultSize Unlimited -Filter "EmailAddresses -like '*$SMTPDomain'" | select DisplayName, WindowsEmailAddress, PrimarySmtpAddress # Output the results $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = ".\Report_" + $SMTPDomain +"_" + $DateFull + ".xlsx" $Mailboxes | Export-Excel $ReportFilexlsx -TableName $SMTPDomain -Title $SMTPDomain -TitleBold -WorksheetName $SMTPDomain -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" $Mailboxes } Function Restrict-EXOUnifiedGroupbySender { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$Identity, [Parameter(Mandatory = $false, Position = 2)] [String]$AuthorizedSenders, [Parameter(Position = 3)] [String]$RejectedSenders ) If ($AuthorizedSenders) { Try { Write-Log -Level INFO -Message "The script will configure the Office 365 to only accept messages from the following sender: $AuthorizedSenders" Write-Log -Level warning -Message "--- Current Permission:" $UnifiedGroup = $Null $UnifiedGroup = Get-UnifiedGroup -Identity $Identity $UnifiedGroup | select -ExpandProperty AcceptMessagesOnlyFromSendersOrMembers Read-Host "Are you sure you want to add $AuthorizedSenders Press <Enter> to continue or <Ctrl+C> to Cancel" Set-UnifiedGroup -Identity $Identity -AcceptMessagesOnlyFromSendersOrMembers @{ add = $AuthorizedSenders } Write-Log -Level Warning -Message "The script successfully configured the Office 365 to only accept messages from the following sender: $AuthorizedSenders" Write-Log -Level warning -Message "--- Current Permission:" $UnifiedGroup = $Null $UnifiedGroup = Get-UnifiedGroup -Identity $Identity $UnifiedGroup | select -ExpandProperty AcceptMessagesOnlyFromSendersOrMembers } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to Add Authorized Sender: $AuthorizedSenders" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $Status = "Failed" } } If ($RejectedSenders) { Try { Write-Log -Level INFO -Message "The script will configure the Office 365 to Reject messages from the following sender: $RejectedSenders" Write-Log -Level warning -Message "--- Current Permission:" $UnifiedGroup = $Null $UnifiedGroup = Get-UnifiedGroup -Identity $Identity $UnifiedGroup | select -ExpandProperty RejectMessagesFromSendersOrMembers Read-Host "Are you sure you want to add $RejectedSenders Press <Enter> to continue or <Ctrl+C> to Cancel" Set-UnifiedGroup -Identity $Identity -RejectMessagesFromSendersOrMembers @{ add = $RejectedSenders } Write-Log -Level Warning -Message "The script successfully configured the Office 365 to Reject messages from the following sender: $RejectedSenders " Write-Log -Level warning -Message "--- Current Permission:" $UnifiedGroup = $Null $UnifiedGroup = Get-UnifiedGroup -Identity $Identity $UnifiedGroup | select -ExpandProperty RejectMessagesFromSendersOrMembers } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to Add Authorized Sender: $AuthorizedSenders" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $Status = "Failed" } } } Function Get-EXOAllDGRoomList { [CmdletBinding()] param () Get-DistributionGroup -RecipientTypeDetails Roomlist | Select Name, PrimarySMTPAddress } Function Add-EXORoomToRoomList { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$RoomListName, [Parameter(Mandatory = $true, Position = 2)] [String]$RoomName ) Write-Host "Check for Room list Members before change: " -ForegroundColor Yellow Get-DistributionGroupMember -identity $RoomListName | Ft Name, PrimarySmtpAddress Add-DistributionGroupMember -Identity $RoomListName -Member $RoomName sleep 10 Write-Host "Check for Room list Members after change: " -ForegroundColor Green Get-DistributionGroupMember -identity $RoomListName | Ft Name, PrimarySmtpAddress } Function Cleanup-EXORecipientsUsingSMTPDomain { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$SMTPDomain ) $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" Try { $AADObjects = Get-AzureADDomainNameReference -Name $SMTPDomain $DomainIsFederated = "Not" $Count = ($AADObjects | Measure).count Write-Log -Level Info -Message "The script found $Count of Object using $SMTPDomain" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "The domain is federated" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $DomainIsFederated = $Null Write-Log -Level Error -Message "Do you want to continue and update only the EmailAddresses for Cloud Only accounts" Read-Host "Press <Enter> to continue or <CTRL +C> to cancel" } Write-Log -Level warning -Message "The script is searching for Recipients using $SMTPDomain (which is $DomainIsFederated federated)" $Filter = "(EmailAddresses -like " + '"*@' + $SMTPDomain + '"' + ")" $Recipients = Get-Recipient -ResultSize unlimited -filter $Filter $OnMicrosoftDefaultDomain = (Get-AcceptedDomain | where { ($_.domainName -like "*.onmicrosoft.com") -and ($_.domainName -notlike "*mail.onmicrosoft.com") } | select -First 1).DomainName #Initiate the Hash Table [Int]$i = 1 $Table = $Null $Table = @() $Count = ($Recipients | Measure).count ForEach ($Recipient in $Recipients) { $PrimarySmtpAddress = $Null $PrimarySmtpAddress = $Recipient.PrimarySmtpAddress $Alias = $Null $Alias = $Recipient.Alias $DisplayName = $Null $DisplayName = $Recipient.DisplayName $RecipientTypeDetails = $Null $RecipientTypeDetails = $Recipient.RecipientTypeDetails $RecipientType = $Null $RecipientType = $Recipient.RecipientType $WindowsLiveID = $Null $WindowsLiveID = $Recipient.WindowsLiveID $EmailAddresses = $Null $EmailAddresses = $Recipient.EmailAddresses $RecipientStatus = $Null $RecipientStatus = @() Write-Log -Level Warning -message "The script is analyzing $DisplayName ($RecipientTypeDetails : $PrimarySmtpAddress) ….. --- $i/$Count" #Find Onmicrosoft Email Address $OnMicrosoft = $Null $OnMicrosoft = $EmailAddresses | where { $_ -match "onmicrosoft.com" } | where { $_ -match "smtp:" } | select -First 1 If ($OnMicrosoft) { $OnMicrosoft = $OnMicrosoft.Substring(5) } else { $OnMicrosoft = $Null $OnMicrosoft = $Alias + "@" + $OnMicrosoftDefaultDomain } $UpdatePrimarySMTPAddress = $Null Write-Log -Level Info -message "Checking if UPN $WindowsLiveID is using the $SMTPDomain" If (($RecipientType -eq "UserMailbox") -and ($WindowsLiveID -match $SMTPDomain)) { Write-Log -Level warning -message "UPN $WindowsLiveID is using the $SMTPDomain" Write-Log -Level Info -message "Try to update UserPrincipalName From $WindowsLiveID to $OnMicrosoft" Set-MsolUserPrincipalName -UserPrincipalName $WindowsLiveID -NewUserPrincipalName $OnMicrosoft Write-Log -Level Warning -message "Updated UserPrincipalName From $WindowsLiveID to $OnMicrosoft" sleep 2 } $i++ } Write-Log -Level warning -Message "After UPN changes, the script will pause for 15 mins, then update remove proxy address" sleep 900 #Read-Host "Continue" ForEach ($Recipient in $Recipients) { $PrimarySmtpAddress = $Null $PrimarySmtpAddress = $Recipient.PrimarySmtpAddress $Alias = $Null $Alias = $Recipient.Alias $DisplayName = $Null $DisplayName = $Recipient.DisplayName $RecipientTypeDetails = $Null $RecipientTypeDetails = $Recipient.RecipientTypeDetails $RecipientType = $Null $RecipientType = $Recipient.RecipientType $WindowsLiveID = $Null $WindowsLiveID = $Recipient.WindowsLiveID $EmailAddresses = $Null $EmailAddresses = $Recipient.EmailAddresses $RecipientStatus = $Null $RecipientStatus = @() Write-Log -Level Warning -message "The script is analyzing $DisplayName ($RecipientTypeDetails : $PrimarySmtpAddress) ….. --- $i/$Count" #Find Onmicrosoft Email Address $OnMicrosoft = $Null $OnMicrosoft = $EmailAddresses | where { $_ -match "onmicrosoft.com" } | where { $_ -match "smtp:" } | select -First 1 If ($OnMicrosoft) { $OnMicrosoft = $OnMicrosoft.Substring(5) } else { $OnMicrosoft = $Null $OnMicrosoft = $Alias + "@" + $OnMicrosoftDefaultDomain } $UpdatePrimarySMTPAddress = $Null switch ($RecipientType) { UserMailbox { # Update PrimarySMTPAddress Try { Write-Log -Level Info -message "Try to update the WindowsEmailAddress and PrimarySMTPAddress with $OnMicrosoft" Set-mailbox -Identity $Alias -WindowsEmailAddress $OnMicrosoft -MicrosoftOnlineServicesID $OnMicrosoft Write-Log -Level Warning -message "Updated the WindowsEmailAddress and PrimarySMTPAddress with $OnMicrosoft" $UpdatePrimarySMTPAddress = "Updated with: $OnMicrosoft" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to update the WindowsEmailAddress and PrimarySMTPAddress with $OnMicrosoft" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $UpdatePrimarySMTPAddress = "Fail to update with: $OnMicrosoft" } $DomainEmailAddresses = $EmailAddresses | where { $_ -match $SMTPDomain } foreach ($DomainEmailAddress in $DomainEmailAddresses) { # Remove ProxyAddress Try { Write-Log -Level Info -Message "Try to remove ProxyAddress: $DomainEmailAddress" Set-Mailbox -identity $Alias -EmailAddresses @{ Remove = $DomainEmailAddress } Write-Log -Level Warning -Message "Removed ProxyAddress: $DomainEmailAddress" $RemoveProxyAddress = "Removed : $DomainEmailAddress" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to remove ProxyAddress: $DomainEmailAddress" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $RemoveProxyAddress = "Fail to remove : $DomainEmailAddress" } $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; RecipientType = $RecipientType; PrimarySmtpAddress = $PrimarySmtpAddress; WindowsLiveID = $WindowsLiveID; UpdatePrimarySMTPAddress = $UpdatePrimarySMTPAddress; RemoveProxyAddress = $RemoveProxyAddress; }) } } DynamicDistributionGroup { # Update PrimarySMTPAddress Try { Write-Log -Level Info -message "Try to update the PrimarySMTPAddress with $OnMicrosoft" Set-DynamicDistributionGroup -Identity $Alias -PrimarySmtpAddress $OnMicrosoft Write-Log -Level Warning -message "Updated the WindowsEmailAddress and PrimarySMTPAddress with $OnMicrosoft" $UpdatePrimarySMTPAddress = "Updated with: $OnMicrosoft" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to update PrimarySMTPAddress with $OnMicrosoft" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $UpdatePrimarySMTPAddress = "Fail to update with: $OnMicrosoft" } $DomainEmailAddresses = $EmailAddresses | where { $_ -match $SMTPDomain } foreach ($DomainEmailAddress in $DomainEmailAddresses) { # Remove ProxyAddress Try { Write-Log -Level Info -Message "Try to remove ProxyAddress: $DomainEmailAddress" Set-DynamicDistributionGroup -identity $Alias -EmailAddresses @{ Remove = $DomainEmailAddress } Write-Log -Level Warning -Message "Removed ProxyAddress: $DomainEmailAddress" $RemoveProxyAddress = "Removed : $DomainEmailAddress" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to remove ProxyAddress: $DomainEmailAddress" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $RemoveProxyAddress = "Fail to remove : $DomainEmailAddress" } $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; RecipientType = $RecipientType; PrimarySmtpAddress = $PrimarySmtpAddress; WindowsLiveID = $WindowsLiveID; UpdatePrimarySMTPAddress = $UpdatePrimarySMTPAddress; RemoveProxyAddress = $RemoveProxyAddress; }) } } MailNonUniversalGroup { # Update PrimarySMTPAddress Try { Write-Log -Level Info -Message "Try to update the PrimarySMTPAddress with $OnMicrosoft" Set-DistributionGroup -Identity $Alias -PrimarySmtpAddress $OnMicrosoft Write-Log -Level Warning -Message "Updated PrimarySMTPAddress with $OnMicrosoft" $UpdatePrimarySMTPAddress = "Updated with: $OnMicrosoft" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to update PrimarySMTPAddress with $OnMicrosoft" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $UpdatePrimarySMTPAddress = "Fail to update with: $OnMicrosoft" } $DomainEmailAddresses = $EmailAddresses | where { $_ -match $SMTPDomain } foreach ($DomainEmailAddress in $DomainEmailAddresses) { # Remove ProxyAddress Try { Write-Log -Level Info -Message "Try to remove ProxyAddress: $DomainEmailAddress" Set-DistributionGroup -identity $Alias -EmailAddresses @{ Remove = $DomainEmailAddress } Write-Log -Level Warning -Message "Removed ProxyAddress: $DomainEmailAddress" $RemoveProxyAddress = "Removed : $DomainEmailAddress" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to remove ProxyAddress: $DomainEmailAddress" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $RemoveProxyAddress = "Fail to remove : $DomainEmailAddress" } $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; RecipientType = $RecipientType; PrimarySmtpAddress = $PrimarySmtpAddress; WindowsLiveID = $WindowsLiveID; UpdatePrimarySMTPAddress = $UpdatePrimarySMTPAddress; RemoveProxyAddress = $RemoveProxyAddress; }) } } MailUniversalDistributionGroup { # Update PrimarySMTPAddress Try { Write-Log -Level Info -message "Try to update the PrimarySMTPAddress with $OnMicrosoft" Set-DistributionGroup -Identity $Alias -PrimarySmtpAddress $OnMicrosoft Write-Log -Level Warning -message "Updated PrimarySMTPAddress with $OnMicrosoft" $UpdatePrimarySMTPAddress = "Updated with: $OnMicrosoft" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to update PrimarySMTPAddress with $OnMicrosoft" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $UpdatePrimarySMTPAddress = "Fail to update with: $OnMicrosoft" } $DomainEmailAddresses = $EmailAddresses | where { $_ -match $SMTPDomain } foreach ($DomainEmailAddress in $DomainEmailAddresses) { # Remove ProxyAddress Try { Write-Log -Level Info -message "Try to remove ProxyAddress: $DomainEmailAddress" Set-DistributionGroup -identity $Alias -EmailAddresses @{ Remove = $DomainEmailAddress } Write-Log -Level Warning -message "Removed ProxyAddress: $DomainEmailAddress" $RemoveProxyAddress = "Removed : $DomainEmailAddress" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to remove ProxyAddress: $DomainEmailAddress" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $RemoveProxyAddress = "Fail to remove : $DomainEmailAddress" } $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; RecipientType = $RecipientType; PrimarySmtpAddress = $PrimarySmtpAddress; WindowsLiveID = $WindowsLiveID; UpdatePrimarySMTPAddress = $UpdatePrimarySMTPAddress; RemoveProxyAddress = $RemoveProxyAddress; }) } } MailUniversalSecurityGroup { # Update PrimarySMTPAddress Try { Write-Log -Level Info -message "Try to update the PrimarySMTPAddress with $OnMicrosoft" Set-DistributionGroup -Identity $Alias -PrimarySmtpAddress $OnMicrosoft Write-Log -Level Warning -message "Updated PrimarySMTPAddress with $OnMicrosoft" $UpdatePrimarySMTPAddress = "Updated with: $OnMicrosoft" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to update PrimarySMTPAddress with $OnMicrosoft" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $UpdatePrimarySMTPAddress = "Fail to update with: $OnMicrosoft" } $DomainEmailAddresses = $EmailAddresses | where { $_ -match $SMTPDomain } foreach ($DomainEmailAddress in $DomainEmailAddresses) { # Remove ProxyAddress Try { Write-Log -Level Info -message "Try to remove ProxyAddress: $DomainEmailAddress" Set-DistributionGroup -identity $Alias -EmailAddresses @{ Remove = $DomainEmailAddress } Write-Log -Level Warning -message "Removed ProxyAddress: $DomainEmailAddress" $RemoveProxyAddress = "Removed : $DomainEmailAddress" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to remove ProxyAddress: $DomainEmailAddress" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $RemoveProxyAddress = "Fail to remove : $DomainEmailAddress" } $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; RecipientType = $RecipientType; PrimarySmtpAddress = $PrimarySmtpAddress; WindowsLiveID = $WindowsLiveID; UpdatePrimarySMTPAddress = $UpdatePrimarySMTPAddress; RemoveProxyAddress = $RemoveProxyAddress; }) } } MailUser { # Update PrimarySMTPAddress Try { Write-Log -Level Info -message "Try to update PrimarySMTPAddress with $OnMicrosoft" Set-MailUser -Identity $Alias -PrimarySmtpAddress $OnMicrosoft Write-Log -Level Warning -message "Updated PrimarySMTPAddress with $OnMicrosoft" $UpdatePrimarySMTPAddress = "Updated with: $OnMicrosoft" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to update PrimarySMTPAddress with $OnMicrosoft" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $UpdatePrimarySMTPAddress = "Fail to update with: $OnMicrosoft" } $DomainEmailAddresses = $EmailAddresses | where { $_ -match $SMTPDomain } foreach ($DomainEmailAddress in $DomainEmailAddresses) { # Remove ProxyAddress Try { Write-Log -Level Info -message "Try to remove ProxyAddress: $DomainEmailAddress" Set-MailUser -identity $Alias -EmailAddresses @{ Remove = $DomainEmailAddress } Write-Log -Level Warning -message "Removed ProxyAddress: $DomainEmailAddress" $RemoveProxyAddress = "Removed : $DomainEmailAddress" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to remove ProxyAddress: $DomainEmailAddress" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $RemoveProxyAddress = "Fail to remove : $DomainEmailAddress" } $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; RecipientType = $RecipientType; PrimarySmtpAddress = $PrimarySmtpAddress; WindowsLiveID = $WindowsLiveID; UpdatePrimarySMTPAddress = $UpdatePrimarySMTPAddress; RemoveProxyAddress = $RemoveProxyAddress; }) } } PublicFolder { # Update PrimarySMTPAddress Try { Write-Log -Level Info -message "Try to update PrimarySMTPAddress with $OnMicrosoft" Set-MailPublicFolder -Identity $Alias -PrimarySmtpAddress $OnMicrosoft Write-Log -Level Warning -message "Updated PrimarySMTPAddress with $OnMicrosoft" $UpdatePrimarySMTPAddress = "Updated with: $OnMicrosoft" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to update PrimarySMTPAddress with $OnMicrosoft" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $UpdatePrimarySMTPAddress = "Fail to update with: $OnMicrosoft" } $DomainEmailAddresses = $EmailAddresses | where { $_ -match $SMTPDomain } foreach ($DomainEmailAddress in $DomainEmailAddresses) { # Remove ProxyAddress Try { Write-Log -Level Info -message "Try to remove ProxyAddress: $DomainEmailAddress" Set-MailPublicFolder -identity $Alias -EmailAddresses @{ Remove = $DomainEmailAddress } Write-Log -Level Warning -message "Removed ProxyAddress: $DomainEmailAddress" $RemoveProxyAddress = "Removed : $DomainEmailAddress" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to remove ProxyAddress: $DomainEmailAddress" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $RemoveProxyAddress = "Fail to remove : $DomainEmailAddress" } $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; RecipientType = $RecipientType; PrimarySmtpAddress = $PrimarySmtpAddress; WindowsLiveID = $WindowsLiveID; UpdatePrimarySMTPAddress = $UpdatePrimarySMTPAddress; RemoveProxyAddress = $RemoveProxyAddress; }) } } } $i++ } Write-Log -Level warning -Message "After updating the proxyAddresses, the script will pause for 15 mins, then run a second check" sleep 900 If ($DomainIsFederated -eq "Not") { $AADObjects = $Null $AADObjects = Get-AzureADDomainNameReference -Name $SMTPDomain $Count = ($AADObjects | Measure).count Write-Log -Level Info -Message "The script found $Count of Objects still using $SMTPDomain" If ($Count -gt 0) { foreach ($AADObject in $AADObjects) { $AAD_ObjectType = $Null $AAD_ObjectType = $AADObject.ObjectType $AAD_UserPrincipalName = $Null $AAD_UserPrincipalName = $AADObject.UserPrincipalName $AAD_Mail = $Null $AAD_Mail = $AADObject.Mail $AAD_MailNickName = $Null $AAD_MailNickName = $AADObject.MailNickName $AAD_OnMicrosoft = $Null $AAD_OnMicrosoft = $AAD_MailNickName + "@" + $OnMicrosoftDefaultDomain If (($AAD_UserPrincipalName -match $SMTPDomain) -and ($AAD_ObjectType -eq "User")) { Write-Log -Level warning -message "UPN $AAD_UserPrincipalName is using the $SMTPDomain" Write-Log -Level Info -message "Try to update UserPrincipalName From $AAD_UserPrincipalName to $AAD_OnMicrosoft" Set-MsolUserPrincipalName -UserPrincipalName $AAD_UserPrincipalName -NewUserPrincipalName $AAD_OnMicrosoft Write-Log -Level Warning -message "Updated UserPrincipalName From $AAD_UserPrincipalName to $AAD_OnMicrosoft" } } Write-Log -Level warning -Message "After second cleanup, the script will pause for 15 mins, then run the last check" sleep 900 $AADObjects2 = $Null $AADObjects2 = Get-AzureADDomainNameReference -Name $SMTPDomain $Count = ($AADObjects | Measure).count Write-Log -Level Info -Message "The script found $Count of Objects still using $SMTPDomain" $RemainingReportFile = ".\RemainingObjects_withDomain_" + $SMTPDomain + "_" + $DateFull + ".csv" $AADObjects2 | Select DisplayName, Mail, UserPrincipalName, MailNickName, ObjectType, ProxyAddresses | Export-Csv $RemainingReportFile -NoTypeInformation -Encoding UTF8 Write-Log -Level INFO -Message "Generate the following Report: $RemainingReportFile " } } $ReportFile = ".\Domain_Recipients_CleanUp_" + $SMTPDomain + "_" + $DateFull + ".csv" $Table | Export-Csv $ReportFile -NoTypeInformation -Encoding UTF8 Write-Log -Level INFO -Message "Generate the following Report: $ReportFile " } Function Enable-EXOMailboxForwardingusingCSVFile { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$CSVFile ) Try { Read-Host "Expected CSV Column: MailboxEmailAddress,ForwardingSMTPEmailAddress" $Mailboxes = Import-Csv $CSVFile Write-Log -Level INFO -Message "The script import successfully :$CSVFile" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to import $CSVFile " Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" Write-Log -Level Error -Message "The Script will stop" # Exit the script Exit } #Initiate the Hash Table [Int]$i = 1 $Table = $Null $Table = @() $MailboxesCount = ($Mailboxes | Measure).count ForEach ($Mailbox in $Mailboxes) { $MailboxEmailAddress = $Null $MailboxEmailAddress = $Mailbox.MailboxEmailAddress $ForwardingSMTPAddress = $Null $ForwardingSMTPAddress = $Mailbox.ForwardingSMTPEmailAddress Try { Write-Log -Level INFO -Message "The script will try to Enable automatic forwarding from $MailboxEmailAddress to $ForwardingSMTPAddress….. --- $i/$MailboxesCount" Set-Mailbox -Identity $MailboxEmailAddress -ForwardingSmtpAddress $ForwardingSMTPAddress -DeliverToMailboxAndForward $True Write-Log -Level warning -Message "The script Enable automatic forwarding from $MailboxEmailAddress to $ForwardingSMTPAddress" $Status = "Success" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to Enable automatic forwarding from $MailboxEmailAddress to $ForwardingSMTPAddress" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $Status = "Failed - Error $ErrorMessage" } $Table += New-object PSobject -Property ([Ordered] @{ MailboxEmailAddress = $MailboxEmailAddress; $ForwardingSMTPAddress = $ForwardingSMTPAddress; Status = $Status; }) $i++ } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = ".\Report_UserMailboxesForwarding_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx -TableName "UserMailboxesForwarding" -Title "UserMailboxes Forwarding" -TitleBold -WorksheetName "UserMailboxesForwarding" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } Function Update-EXOPrimarySMTPAddressForUnifiedGroup { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$Identity, [Parameter(Mandatory = $true, Position = 2)] [String]$NewPrimarySMTPAddress ) $O365Group1 = Get-UnifiedGroup -Identity $Identity Write-Log -Level Warning -Message "$Identity Emailaddresses are: " $EmailAddresses1 = $O365Group1.EmailAddresses $EmailAddresses1 | ft # Update Office 365 group Set-UnifiedGroup -Identity $Identity -PrimarySMTPAddress $NewPrimarySMTPAddress # Check New Primary SMTP Address $O365Group2 = Get-UnifiedGroup -Identity $Identity Write-Log -Level Warning -Message "$Identity Emailaddresses are: " $EmailAddresses2 = $O365Group2.EmailAddresses $EmailAddresses2 | ft } Function Add-EXOUsersToOneDGCSV { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$GroupEmailAddress, [Parameter(Mandatory = $true, Position = 2)] [String]$CSVFile ) Read-Host "Expected CSV Column: EmailAddress" $Users = Import-Csv $CSVFile $Count = ($Users | Measure).count [Int]$i = 1 $Table = $Null $Table = @() Foreach ($User in $Users) { $UserEmailAddress = $Null $UserEmailAddress = $User.EmailAddress Write-Host "User $UserEmailAddress will be added to Group $GroupEmailAddress --- $i/$Count" Try { Add-DistributionGroupMember -Identity $GroupEmailAddress -Member $UserEmailAddress -ErrorAction Stop $Status = "Success" } Catch { $ErrorMessage = $Error[0].Exception.Message If ($ErrorMessage -like "*member*") { $Status = "Failed - already members" } Else { $Status = "Failed - $ErrorMessage" } } $Table += New-object PSobject -Property ([Ordered] @{ GroupEmailAddress = $GroupEmailAddress; UserName = $UserEmailAddress; Action = "Add"; Status = $Status; }) $i++ } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = ".\Report_Users_Added_To_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx -TableName "AddedUsers" -Title "Added Users" -TitleBold -WorksheetName "AddedUsers" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } Function Update-EXODGMemberwithRepsUsingCSV { param ( [Parameter(Mandatory = $true, Position = 1)] [String]$CSVFile ) Read-Host "Expected CSV Column: DGName,Email" Try { Write-Log -Level Warning -Message "Trying to import $CSVFile" $Members = $Null $Members = Import-Csv $CsvFile Write-Log -Level INFO -Message "Successfully import $CSVFile" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to Import $CSVFile" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" #Exit } Read-Host "Are you sure you want to clear the Distribituion group? - <Enter> to Continue or Ctrl+C to Cancel" # Rep $All_Reps = Get-Recipient -resultsize unlimited -Filter { (RecipientTypeDetails -eq "UserMailbox") -and (Title -like "*repre*") } $OUs = $null $OUs = @() $Reps = $null $Reps = @() $Table = $Null $Table = @() foreach ($Rep in $All_Reps) { $Reps_Customattribute13 = $Null $Reps_Customattribute13 = $Rep.Customattribute13 $Customattribute13 = $Null $Customattribute13 = $Reps_Customattribute13 -replace ("CEECIS", "ECAR") -replace ("TACR", "LACR") $OUs += $Customattribute13 $Reps_PrimarySmtpAddress = $Null $Reps_PrimarySmtpAddress = $Rep.primarysmtpaddress $Reps += New-object PSobject -Property ([Ordered] @{ PrimarySmtpAddress = $Reps_PrimarySmtpAddress; CustomAttribute13 = $Customattribute13; }) } # Remove duplicates $OUs = $OUs | select -Unique # Loop with all OUs foreach ($OU in $OUs) { $Office = $Null $Office = ($OU.split(","))[0] $Region = $Null $Region = ($OU.split(","))[1] $ML_Name = $Null $ML_Name = "ML-CM-$Region-$Office" $ML_Members = $Null $CurrentML_Members = Get-DistributionGroupMember $ML_Name #Remove Members ForEach ($CurrentML_Member in $CurrentML_Members) { $CurrentPrimarySMTPAddress = $Null $CurrentPrimarySMTPAddress = $CurrentML_Member.primarysmtpaddress Write-Log -Level INFO -Message "Removing user $CurrentPrimarySMTPAddress from $ML_Name" Try { Remove-DistributionGroupMember $ML_Name -Member $CurrentPrimarySMTPAddress -Confirm:$false -ErrorAction Stop $RemoveStatus = "Successful" } Catch { $ErrorMessage = $Error[0].Exception.Message $RemoveStatus = "Failed with Error:$ErrorMessage " } $Table += New-object PSobject -Property ([Ordered] @{ Email = $CurrentPrimarySMTPAddress; Action = "Removed - " + $RemoveStatus; DGName = $ML_Name; }) } # Add Reps $OUFilter = $Null $OUFilter = '*' + $OU + '*' Write-Log -Level INFO -Message " The filter is : $OUFilter" $NewML_Reps = $Null $NewML_Reps = $Reps | Where-Object { $_.CustomAttribute13 -like $OUFilter } $NewML_Reps_Count = $Null $NewML_Reps_Count = ($NewML_Reps | Measure).count Write-Log -Level INFO -Message " Number of Reps: $NewML_Reps_Count for $ML_Name" foreach ($NewML_Rep in $NewML_Reps) { $NewPrimarySMTPAddress = $Null $NewPrimarySMTPAddress = $NewML_Rep.primarysmtpaddress Write-Log -Level INFO -Message "adding user $NewPrimarySMTPAddress from $ML_Name" Try { Add-DistributionGroupMember -Identity $ML_Name -Member $NewPrimarySMTPAddress -ErrorAction Stop $AddStatus = "Successful" } Catch { $ErrorMessage = $Error[0].Exception.Message $AddStatus = "Failed with Error:$ErrorMessage " } $Table += New-object PSobject -Property ([Ordered] @{ Email = $NewPrimarySMTPAddress; Action = "Added - " + $AddStatus; DGName = $ML_Name; }) } # Add members from CSV $NewML_Members = $Null $NewML_Members = $Members | Where-Object { $_.DGName -eq $ML_Name } $NewML_Members_Count = $Null $NewML_Members_Count = ($NewML_Members | Measure).count Write-Log -Level INFO -Message " Number of Members: $NewML_Members_Count for $ML_Name" # Add members foreach ($NewML_Member in $NewML_Members) { $NewPrimarySMTPAddress = $Null $NewPrimarySMTPAddress = $NewML_Member.Email Write-Log -Level INFO -Message "adding user $NewPrimarySMTPAddress from $ML_Name" Try { Add-DistributionGroupMember -Identity $ML_Name -Member $NewPrimarySMTPAddress -ErrorAction Stop $AddStatus = "Successful" } Catch { $ErrorMessage = $Error[0].Exception.Message $AddStatus = "Failed with Error:$ErrorMessage " } $Table += New-object PSobject -Property ([Ordered] @{ Email = $NewPrimarySMTPAddress; Action = "Added - " + $AddStatus; DGName = $ML_Name; }) } #Read-Host "Break" } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = ".\Report_Groups_Members_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx -TableName "GroupMembers" -Title "Group Members" -TitleBold -WorksheetName "GroupMembers" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } Function Add-EXOUsersToDGsusingCSV { param ( [Parameter(Mandatory = $true, Position = 1)] [String]$CSVFile ) $Table = $Null $Table = @() Read-Host "Expected CSV Column: DGName,Email" Try { Write-Log -Level Warning -Message "Trying to import $CSVFile" $Members = $Null $Members = Import-Csv $CsvFile Write-Log -Level INFO -Message "Successfully import $CSVFile" $Count = ($Members | Measure).count } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to Import $CSVFile" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" #Exit } # Add members [Int]$i = 1 foreach ($Member in $Members) { $NewPrimarySMTPAddress = $Null $NewPrimarySMTPAddress = $Member.Email $ML_Name = $Null $ML_Name = $Member.DGName Write-Log -Level INFO -Message "adding user $NewPrimarySMTPAddress to $ML_Name --- $i/$Count" Try { Add-DistributionGroupMember -Identity $ML_Name -Member $NewPrimarySMTPAddress -ErrorAction Stop $AddStatus = "Successful" } Catch { $ErrorMessage = $Error[0].Exception.Message $AddStatus = "Failed with Error:$ErrorMessage " } $Table += New-object PSobject -Property ([Ordered] @{ Email = $NewPrimarySMTPAddress; Action = "Added - " + $AddStatus; DGName = $ML_Name; }) $i++ } #Read-Host "Break" $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = ".\Report_Groups_Members_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx -TableName "GroupMembers" -Title "Group Members" -TitleBold -WorksheetName "GroupMembers" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } Function Create-EXOMailContactUsingCSV { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$CSVFile ) Read-Host "Expected CSV Column: EmailAddress,Name" $MailContacts = Import-Csv $CSVFile $Count = ($MailContacts | Measure).count [Int]$i = 1 $Table = $Null $Table = @() Foreach ($MailContact in $MailContacts) { $UserEmailAddress = $Null $UserEmailAddress = $MailContact.EmailAddress $UserName = $Null $UserName = $MailContact.Name Write-Host "User $UserName ($UserEmailAddress) --- $i/$Count" Try { Write-Host "The script will try to create the following user: $UserName ($UserEmailAddress) --- $i/$Count" New-MailContact -Name $UserName -ExternalEmailAddress $UserEmailAddress Write-Host "The script created the following user: $UserName ($UserEmailAddress)" $Status = "Success" } Catch { $ErrorMessage = $Error[0].Exception.Message Write-Log -Level Error -Message "Failed to Create Contact with error: $ErrorMessage " $Status = "Failed" } $Table += New-object PSobject -Property ([Ordered] @{ Name = $UserName; EmailAddress = $UserEmailAddress; Status = $Status; }) $i++ } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = ".\Report_CreatedContacts_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx -TableName "CreatedContacts" -Title "Created Contacts" -TitleBold -WorksheetName "CreatedContacts" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } Function Check-EXOMessageMaxSize { [CmdletBinding()] param () Write-Log -Level Info -Message "--- Transport Configuration:" Get-TransportConfig | ft maxreceivesize, maxsendsize Write-Log -Level Info -Message "--- Mailbox Plan:" Get-MailboxPlan | ft name, maxsendsize, maxreceivesize, isdefault Write-Log -Level Warning -Message "Transport Configuration cannot be updated" Write-Log -Level Warning -Message "Mailbox Plan can be increase to 150MB" Write-Log -Level Warning -Message "Base64 encoding increases the size of messages by approximately 33%, so specify a value that's 33% larger than the actual maximum message size that you want to enforce. For example, the value 64 MB results in a maximum message size of approximately 48 MB." } Function Add-EXOUnifiedGroupMemberusingCSV { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$GroupEmailAddress, [Parameter(Mandatory = $true, Position = 2)] [String]$CSVFile ) Read-Host "Expected CSV Column: EmailAddress" # Import CSV File Try { Write-Log -Level warning -Message "The script will try to import the CSV File $CSVFile" $Members = Import-Csv $CSVFile Write-Log -Level warning -Message "The script successfully Import the CSV File : $CSVFile" #Initiate the Hash Table [Int]$i = 1 $Table = $Null $Table = @() $Count = ($Members | Measure).count } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to Import CSV File: $CSVFile " Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" Exit } # Disable Welcome Message notification on the group Try { Write-Log -Level Warning -Message "The script will disable Unified Group Welcome message" Set-UnifiedGroup $GroupEmailAddress -UnifiedGroupWelcomeMessageEnabled:$false Write-Log -Level Warning -Message "The script disabled Unified Group Welcome message" sleep 10 } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to disable Group Welcome Message" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" Exit } Foreach ($Member in $Members) { # add member to the group $MemberID = $null $MemberID = $Member.EmailAddress Try { Write-Log -Level Warning -Message "The script will try to add $MemberID to $GroupEmailAddress - $i/$Count" Add-UnifiedGroupLinks -Identity $GroupEmailAddress -LinkType Members -Links $MemberID Write-Log -Level Warning -Message "The script added $MemberID to $GroupEmailAddress" $Status = "Added" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to disable Group Welcome Message" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $Status = "Failed - Error: $ErrorMessage" } $Table += New-object PSobject -Property ([Ordered] @{ GroupEmailAddress = $GroupEmailAddress; Member = $MemberID; Status = $Status; }) $i++ } sleep 10 Try { Write-Log -Level Warning -Message "The script will enable Unified Group Welcome message" Set-UnifiedGroup $GroupEmailAddress -UnifiedGroupWelcomeMessageEnabled Write-Log -Level Warning -Message "The script enabled Unified Group Welcome message" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to enable Group Welcome Message" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" Exit } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = ".\Add_Office365groupMembers_" + $GroupEmailAddress + "_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx -TableName "O365GroupMembers" -Title "O365 Group Members" -TitleBold -WorksheetName "O365GroupMembers" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } Function Generate-EXOUnifiedGroupsStorageReportInMB { [CmdletBinding()] param () Write-Log -Level Warning -Message "Are you connect to EXO Module and SPO Module?" Try { Write-Log -Level INFO -Message "The script will retreive the information for all Office 365 Groups" $Office365Groups = Get-UnifiedGroup -Resultsize Unlimited $Count = ($Office365Groups | Measure).count Write-Log -Level INFO -Message "The Script found $Count Office 365 Groups on the tenant" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to retrieve Office 365 groups information" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" Exit } [Int]$i = 1 $Table = $Null $Table = @() ForEach ($Office365Group in $Office365Groups) { $PrimarySmtpAddress = $Null $PrimarySmtpAddress = $Office365Group.PrimarySmtpAddress $DisplayName = $Null $DisplayName = $Office365Group.DisplayName Write-Host "============================================================" Write-Log -Level INFO -Message "The script is analysis the Office 365 Group : $DisplayName --- $i/$Count" $ManagedBy = $Null $ManagedBy = $Office365Group.ManagedBy $GroupMemberCount = $Null $GroupMemberCount = $Office365Group.GroupMemberCount $Alias = $Null $Alias = $Office365Group.Alias $SharePointSiteUrl = $Null $SharePointSiteUrl = $Office365Group.SharePointSiteUrl #Mailbox Statistics Write-Log -Level Warning -Message "The script is analysis the Office 365 Group Mailbox Usage : $DisplayName ($PrimarySmtpAddress) " Try { $MailboxStatistics = Get-MailboxStatistics -Identity $PrimarySmtpAddress $TotalItemSize = $Null $TotalItemSize = ConvertTo-MB -size $MailboxStatistics.TotalItemSize.ToString().Split("(")[0] } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to retrieve Office 365 group Mailbox Statistics" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $TotalItemSize = "Failed to retrieve info" } #Sharepoint Statistic Write-Log -Level Warning -Message "The script is analysis the Office 365 Group Sharepoint Usage : $DisplayName ($SharePointSiteUrl) " If ($SharePointSiteUrl -ne $Null) { Try { $SPOSite = Get-SPOSite $SharePointSiteUrl $StorageUsageCurrentInMB = $Null $StorageUsageCurrentInMB = $SPOSite.StorageUsageCurrent } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to retrieve Office 365 group Sharepoint usage" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $StorageUsageCurrentInGB = "Failed to retrieve info" } } Else { $StorageUsageCurrentInGB = "No Sharepoint Site" } Write-Log -Level Warning -Message "The script is compiling Office 365 Group information : $DisplayName" $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; Owner = $ManagedBy; GroupMemberCount = $GroupMemberCount; PrimarySmtpAddress = $PrimarySmtpAddress; MailboxSize = $TotalItemSize; SharePointSiteUrl = $SharePointSiteUrl; SharepointStorageUsageInGB = $StorageUsageCurrentInMB; }) Write-Host "============================================================" Write-Host "" $i++ } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = ".\Report_Office365Group_StorageUsage_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx -TableName "O365GroupStorageUsage" -Title "O365 Group Storage Usage" -TitleBold -WorksheetName "O365GroupStorageUsage" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } Function Generate-EXOUnifiedGroupsStorageReportInGB { [CmdletBinding()] param () Write-Log -Level Warning -Message "Are you connect to EXO Module and SPO Module?" Try { Write-Log -Level INFO -Message "The script will retreive the information for all Office 365 Groups" $Office365Groups = Get-UnifiedGroup -Resultsize Unlimited $Count = ($Office365Groups | Measure).count Write-Log -Level INFO -Message "The Script found $Count Office 365 Groups on the tenant" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to retrieve Office 365 groups information" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" Exit } [Int]$i = 1 $Table = $Null $Table = @() ForEach ($Office365Group in $Office365Groups) { $PrimarySmtpAddress = $Null $PrimarySmtpAddress = $Office365Group.PrimarySmtpAddress $DisplayName = $Null $DisplayName = $Office365Group.DisplayName Write-Host "============================================================" Write-Log -Level INFO -Message "The script is analysis the Office 365 Group : $DisplayName --- $i/$Count" $ManagedBy = $Null $ManagedBy = $Office365Group.ManagedBy $GroupMemberCount = $Null $GroupMemberCount = $Office365Group.GroupMemberCount $Alias = $Null $Alias = $Office365Group.Alias $SharePointSiteUrl = $Null $SharePointSiteUrl = $Office365Group.SharePointSiteUrl #Mailbox Statistics Write-Log -Level Warning -Message "The script is analysis the Office 365 Group Mailbox Usage : $DisplayName ($PrimarySmtpAddress) " Try { $MailboxStatistics = Get-MailboxStatistics -Identity $PrimarySmtpAddress $TotalItemSize = $Null $TotalItemSize = ConvertTo-Gb -size $MailboxStatistics.TotalItemSize.ToString().Split("(")[0] } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to retrieve Office 365 group Mailbox Statistics" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $TotalItemSize = "Failed to retrieve info" } #Sharepoint Statistic Write-Log -Level Warning -Message "The script is analysis the Office 365 Group Sharepoint Usage : $DisplayName ($SharePointSiteUrl) " If ($SharePointSiteUrl -ne $Null) { Try { $SPOSite = Get-SPOSite $SharePointSiteUrl $StorageUsageCurrentInMB = $Null $StorageUsageCurrentInMB = $SPOSite.StorageUsageCurrent $StorageUsageCurrentInGB = ($StorageUsageCurrentInMB/ 1024) $StorageUsageCurrentInGB = [Math]::Round($StorageUsageCurrentInGB, 4, [MidPointRounding]::AwayFromZero) } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to retrieve Office 365 group Sharepoint usage" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $StorageUsageCurrentInGB = "Failed to retrieve info" } } Else { $StorageUsageCurrentInGB = "No Sharepoint Site" } Write-Log -Level Warning -Message "The script is compiling Office 365 Group information : $DisplayName" $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; Owner = $ManagedBy; GroupMemberCount = $GroupMemberCount; PrimarySmtpAddress = $PrimarySmtpAddress; MailboxSize = $TotalItemSize; SharePointSiteUrl = $SharePointSiteUrl; SharepointStorageUsageInGB = $StorageUsageCurrentInGB; }) Write-Host "============================================================" Write-Host "" $i++ } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = ".\Report_Office365Group_StorageUsage_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx -TableName "O365GroupStorageUsage" -Title "O365Group Storage Usage" -TitleBold -WorksheetName "O365GroupStorageUsage" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } Function Enable-EXORetentionFeatures { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$EmailAddress ) Try { Write-Log -Level -Level INFO -Message "Retreiving mailbox data for: $EmailAddress" $Mailbox = Get-Mailbox $EmailAddress $FindMailbox = "True" } Catch { $ErrorMessage = $Error[0].Exception.Message Write-Log -Level -Level Error -Message "Failed to find the mailbox: $EmailAddress with the following error: $ErrorMessage" $FindMailbox = "Failed to find the mailbox: $EmailAddress with the following error: $ErrorMessage" } Try { $ArchiveStatus = $Mailbox.ArchiveStatus If ($ArchiveStatus -eq "Active") { $EnableArchive = "True" Write-Log -Level -Level INFO -Message "Archive mailbox alread enabled for $EmailAddress" } Else { Enable-Mailbox -identity $EmailAddress -Archive Write-Log -Level -Level INFO -Message "Successfully Enable Archive mailbox for $EmailAddress" $EnableArchive = "True" } } Catch { $ErrorMessage = $Error[0].Exception.Message Write-Log -Level -Level Error -Message "Failed to enable Archive mailbox for $EmailAddress with the following error: $ErrorMessage" $EnableArchive = "Failed to enable Archive mailbox for $EmailAddress with the following error: $ErrorMessage" } Try { $LitigationHoldEnabled = $Mailbox.LitigationHoldEnabled $LitigationHoldDuration = $Mailbox.LitigationHoldDuration If (($LitigationHoldEnabled -eq $true) -and ($LitigationHoldDuration -eq "1825.00:00:00")) { $EnableLigitationHold = "True" Write-Log -Level -Level INFO -Message "Litigation Hold (1825 days) is already enabled for $EmailAddress" } Else { Set-Mailbox $EmailAddress -LitigationHoldEnabled $True -LitigationHoldDuration 1825 Write-Log -Level -Level INFO -Message "Successfully Enable Litigation Hold (1825 days) for $EmailAddress" $EnableLigitationHold = "True" } } Catch { $ErrorMessage = $Error[0].Exception.Message Write-Log -Level -Level Error -Message "Failed to enable Litigation Hold (1825 days) for $EmailAddress with the following error: $ErrorMessage" $EnableLigitationHold = "Failed to enable Litigation Hold (1825 days) for $EmailAddress with the following error: $ErrorMessage" } $OutPutMessage = $null $OutPutMessage = @() $OutPutMessage += New-object PSobject -Property ([Ordered] @{ EmailAddress = $EmailAddress; FindMailbox = $FindMailbox; EnableArchive = $EnableArchive; EnableLitigationHold = $EnableLitigationHold; }) Return $OutPutMessage } Function Enable-EXOMailboxesRetentionUsingCSV { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$CSVFile ) Read-Host "Expected CSV Column: PrimarySmtpAddress" $Mailboxes = Import-Csv $CSVFile $Count = ($Mailboxes | Measure).count [Int]$i = 1 $Table = $Null $Table = @() Foreach ($Mailbox in $Mailboxes) { $UserEmailAddress = $Null $UserEmailAddress = $Mailbox.PrimarySmtpAddress Write-Log -Level Warning -Message "Enabling Retention feature for $UserEmailAddress --- $i/$Count" $UserOutput = $Null $UserOutput = @() $UserOutput = Enable-RetentionFeatures -EmailAddress $UserEmailAddress $Table += New-object PSobject -Property ([Ordered] @{ EmailAddress = $UserOutput.EmailAddress; FindMailbox = $UserOutput.FindMailbox; EnableArchive = $UserOutput.EnableArchive; EnableLigitationHold = $UserOutput.EnableLigitationHold; }) $i++ } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = ".\Report_Mailboxes_RetentionFeatures_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx -TableName "MailboxRetentionFeatures" -Title "Mailbox Retention Features" -TitleBold -WorksheetName "MailboxRetentionFeatures" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } Function Add-EXOTrustedSenderToAllMailboxes { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$TrustedSenderEmailAddress ) $mailboxes = Get-Mailbox -Filter { RecipientTypeDetails -eq "UserMailbox" } -ResultSize unlimited [Int]$i = 1 $Table = $Null $Table = @() $Count = ($mailboxes | Measure).count Foreach ($Mailbox in $mailboxes) { $DisplayName = $Mailbox.displayname $PrimarySMTPAddress = $Mailbox.PrimarySMTPAddress Write-Log -Level Warning -message "The script is updating Trusted domain for $DisplayName ($PrimarySMTPAddress) ….. --- $i/$Count" try { Set-MailboxJunkEmailConfiguration $PrimarySMTPAddress -TrustedSendersAndDomains @{ Add = $TrustedSenderEmailAddress } -ErrorAction Stop $Status = "Success" } Catch { $Status = "Failed" } $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; PrimarySMTPAddress = $PrimarySMTPAddress; Status = $Status; }) $i++ } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = ".\Report_User_Mailboxes_JunkConfiguration_Add_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx -TableName "MailboxJunkConfiguration" -Title "Mailbox JunkConfiguration" -TitleBold -WorksheetName "MailboxJunkConfiguration" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } Function Remove-EXOTrustedSenderToAllMailboxes { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$TrustedSenderEmailAddress ) $mailboxes = Get-Mailbox -Filter { RecipientTypeDetails -eq "UserMailbox" } -ResultSize unlimited #$mailboxes = Get-Mailbox -Filter { RecipientTypeDetails -eq "UserMailbox" } -ResultSize 10 [Int]$i = 1 $Table = $Null $Table = @() $Count = ($mailboxes | Measure).count Foreach ($Mailbox in $mailboxes) { $DisplayName = $Mailbox.displayname $PrimarySMTPAddress = $Mailbox.PrimarySMTPAddress Write-Log -Level Warning -message "The script is updating Trusted domain for $DisplayName ($PrimarySMTPAddress) ….. --- $i/$Count" try { Set-MailboxJunkEmailConfiguration $PrimarySMTPAddress -TrustedSendersAndDomains @{ Remove = $TrustedSenderEmailAddress } -ErrorAction Stop $Status = "Success" } Catch { $Status = "Failed" } $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; PrimarySMTPAddress = $PrimarySMTPAddress; Status = $Status; }) $i++ } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = ".\Report_User_Mailboxes_JunkConfiguration_Remove_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx -TableName "MailboxJunkConfigurationRemove" -Title "Mailbox JunkConfiguration Removal" -TitleBold -WorksheetName "MailboxJunkConfigurationRemove" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } Function Get-EXOUserAllMembership { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$EmailAddress ) #Find user DistinguishedName $Recipients = Get-Recipient $EmailAddress $Count = ($Recipients | Measure).count Write-Log -Level Warning -Message "Found $Count Object(s) with $EmailAddress" foreach ($Recipient in $Recipients) { #Initiate the Hash Table [Int]$i = 0 $Table = $Null $Table = @() $DistinguishedName = $Null $EXO_Membership = $Null $EXO_DynamicGroup = $Null $AAD_Membership = $Null $RecipientTypeDetails = $Null $ExternalDirectoryObjectId = $Null $DistinguishedName = $Recipient.DistinguishedName $RecipientTypeDetails = $Recipient.RecipientTypeDetails $ExternalDirectoryObjectId = $Recipient.ExternalDirectoryObjectId Write-Log -Level Warning -Message "$EmailAddress ($RecipientTypeDetails) DistinguishedName is: $DistinguishedName" $EXO_Membership = Get-Recipient -Filter "Members -eq '$DistinguishedName'" -RecipientTypeDetails GroupMailbox, MailUniversalDistributionGroup, MailUniversalSecurityGroup ForEach ($EXO_Group in $EXO_Membership) { $EXO_displayName = $Null $EXO_PrimarySmtpAddress = $Null $EXO_RecipientTypeDetails = $Null $EXO_displayName = $EXO_Group.DisplayName $EXO_PrimarySmtpAddress = $EXO_Group.PrimarySmtpAddress $EXO_RecipientTypeDetails = $EXO_Group.RecipientTypeDetails $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $EXO_displayName; PrimarySmtpAddress = $EXO_PrimarySmtpAddress; Type = $EXO_RecipientTypeDetails; }) $i++ } $EXO_DynamicGroup = Get-Group -Filter "Members -eq '$DistinguishedName'" ForEach ($EXO_DGroup in $EXO_DynamicGroup) { $EXO_DdisplayName = $Null $EXO_DPrimarySmtpAddress = $Null $EXO_DRecipientTypeDetails = $Null $EXO_DdisplayName = $EXO_DGroup.Name $EXO_DPrimarySmtpAddress = $EXO_DGroup.WindowsEmailAddress $EXO_DRecipientTypeDetails = $EXO_DGroup.GroupType $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $EXO_DdisplayName; B = $EXO_DPrimarySmtpAddress; Type = $EXO_DRecipientTypeDetails; }) $i++ } If ($RecipientTypeDetails -ne "MailContact") { #$AAD_Membership = Get-AzureADUser -SearchString $UPN | Get-AzureADUserMembership | ? { $_.ObjectType -ne "Role" } | % { Get-AzureADGroup -ObjectId $_.ObjectId | select DisplayName, ObjectType, MailEnabled, SecurityEnabled, ObjectId } | ft #$AAD_Membership = Get-AzureADUser -SearchString $UPN | Get-AzureADUserMembership | % { Get-AzureADGroup -ObjectId $_.ObjectId | select DisplayName, ObjectType, MailEnabled, SecurityEnabled, ObjectId } | ft $AAD_Membership = Get-AzureADUser -ObjectID $ExternalDirectoryObjectId | Get-AzureADUserMembership | % { Get-AzureADGroup -ObjectId $_.ObjectId } ForEach ($EXO_AADGroup in $AAD_Membership) { $AAD_displayName = $Null $ADD_PrimarySmtpAddress = $Null $ADD_RecipientTypeDetails = $Null $AAD_displayName = $EXO_AADGroup.DisplayName $ADD_PrimarySmtpAddress = $EXO_AADGroup.Mail $ADD_RecipientTypeDetails = $EXO_AADGroup.ObjectType $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $AAD_displayName; PrimarySmtpAddress = $ADD_PrimarySmtpAddress; Type = $ADD_RecipientTypeDetails; }) $i++ } } $Table | ft Write-Log -Level Warning -Message "$UPN ($RecipientTypeDetails) is member of: $i Groups" } } Function Get-EXORecipientInformationFromCSV { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$CsvFile ) Read-Host "Expected CSV Column: UPN" Try { Write-Log -Level warning -Message "Trying to import $CSVFile" $Users = Import-Csv $CsvFile Write-Log -Level INFO -Message "Successfully import $CSVFile" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to Import $CsvFile" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" Exit } #Initiate the Hash Table [Int]$i = 1 $Table = $Null $Table = @() $Count = ($Users | Measure).count ForEach ($User in $Users) { $UserPrincipalName = $null $UserPrincipalName = $User.UPN Write-Log -Level INFO -Message "The script is analyzing $UserPrincipalName….. --- $i/$Count" $Recipient = $Null $Recipient = Get-Recipient $UserPrincipalName $City = $Recipient.City $Department = $Recipient.Department $FirstName = $Null $FirstName = $Recipient.FirstName $LastName = $Null $LastName = $Recipient.LastName $Office = $Null $Office = $Recipient.Office $Title = $Null $Title = $Recipient.Title $CustomAttribute5 = $Null $CustomAttribute5 = $Recipient.CustomAttribute5 $CustomAttribute7 = $Null $CustomAttribute7 = $Recipient.CustomAttribute7 $CustomAttribute13 = $Null $CustomAttribute13 = $Recipient.CustomAttribute13 $CustomAttribute14 = $Null $CustomAttribute14 = $Recipient.CustomAttribute14 $CustomAttribute15 = $Null $CustomAttribute15 = $Recipient.CustomAttribute15 $Table += New-object PSobject -Property ([Ordered] @{ UserPrincipalName = $UserPrincipalName; FirstName = $FirstName; LastName = $LastName; Office = $Office; City = $City; Title = $Title; CustomAttribute5 = $CustomAttribute5; CustomAttribute7 = $CustomAttribute7; CustomAttribute13 = $CustomAttribute13; CustomAttribute14 = $CustomAttribute14; CustomAttribute15 = $CustomAttribute15; }) $i++ } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = ".\Report_Recipient_Users_Details_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx -TableName "Recipients" -Title "Recipients" -TitleBold -WorksheetName "Recipients" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } Function Get-EXOMailContactGroupMembership { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$EmailAddress ) $ContactDN = (Get-MailContact $EmailAddress).DistinguishedName $Groups = Get-Recipient -Filter "Members -eq '$ContactDN'" $Groups | ft DisplayName, PrimarySmtpAddress, RecipientTypeDetails } Function Find-EXOAllDisconnectedMailboxes { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$Folder ) # Find Every Disconnected Mailboxes $Folder = "H:\PST\RecoverySharedMailbox\" $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ExchangeServers = $Null $ExchangeServers = Get-ExchangeServer | where { $_.ServerRole -like "*Mailbox*" } $Mailboxes = $Null $FullMailboxes = $Null foreach ($ExchangeServer in $ExchangeServers) { $ServerName = $null $ServerName = $ExchangeServer.Name $CSVFile = $null $CSVFile = $Folder + "Disconnected_Mailboxes_" + $ServerName + "_" + $DateFull + ".csv" $Mailboxes = $Null $Mailboxes = Get-MailboxStatistics -Server $ServerName | Where { $_.DisconnectDate -ne $null } | select DisplayName, ItemCount, DeletedItemCount, DisconnectDate, DisconnectReason, LastLoggedOnUserAccount, LastLogoffTime, LastLogonTime, LegacyDN, MailboxGuid, TotalItemSize, Database, ServerName $Mailboxes | Export-Csv $CSVFile -NoTypeInformation -Encoding UTF8 $FullMailboxes += $Mailboxes } $GlobalCSVFile = $Folder + "All_Disconnected_Mailboxes_" + $DateFull + ".csv" $FullMailboxes | Export-Csv $GlobalCSVFile -NoTypeInformation -Encoding UTF8 } Function Retreive-EXOMailboxPermission { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$Mailbox ) $MailboxPermissions = Get-MailboxPermission $Mailbox | where { $_.User -like "*@*" } | select User $Permissions = $MailboxPermissions.user -join ";" Write-Host $Mailbox -NoNewline -ForegroundColor Red; Write-Host " --- " -NoNewline; Write-Host $Permissions -ForegroundColor Yellow } Function Add-EXOCalendarPermission { [CmdletBinding()] Param ([Parameter(Mandatory = $true)] [string]$Ressource, [Parameter(Mandatory = $true)] [string]$Delegate, [Parameter(Mandatory = $true)] [string]$Permission) Write-host "Checking the Calendar permission currenlty assigned to $Ressource " $Calendar = $Null $Calendar = $Ressource + ":\Calendar" Get-MailboxFolderPermission $Calendar Write-Host "Give $Delegate permission: $Permission to $Ressource " Add-MailboxFolderPermission -identity $Calendar -User $Delegate -AccessRights $Permission Write-host "Checking the Calendar permission currenlty assigned to $Ressource " Get-MailboxFolderPermission -Identity $Calendar -User $Delegate } Function Move-EXOMailboxContent { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$SourceAlias, [Parameter(Mandatory = $true, Position = 2)] [string]$TargetAlias, [Parameter(Mandatory = $false, Position = 3)] [string]$TargetFolder, [Parameter(Position = 4)] [string]$StartDate, [Parameter(Position = 5)] [string]$EndDate ) $BatchName = "Move_From_" + $SourceAlias + "_To_" + $TargetAlias If ($StartDate -and $EndDate) { Write-Host "The Script will copy mail contents from $SourceAlias using Date Range: from $StartDate to $EndDate" Read-Host "Press Enter to Continue or CTRL + C to Cancel" If ($TargetFolder) { Write-Host "The Script will Export contents from $SourceAlias to $TargetAlias but to the specific Folder: $TargetFolder" Search-Mailbox -Identity $SourceAlias -TargetMailbox $TargetAlias -TargetFolder $TargetFolder -SearchQuery "(sent>=$StartDate AND Sent<=$EndDate) OR (received>=$StartDate AND received<=$EndDate)" } Else { Write-Host "The Script will Export contents from $SourceAlias to $TargetAlias" Search-Mailbox -Identity $SourceAlias -TargetMailbox $TargetAlias -SearchQuery "(sent>=$StartDate AND Sent<=$EndDate) OR (received>=$StartDate AND received<=$EndDate)" } } ElseIf ($StartDate) { Write-Host "The Script will copy mail contents from $SourceAlias Received\Sent After: $StartDate" Read-Host "Press Enter to Continue or CTRL + C to Cancel" If ($TargetFolder) { Write-Host "The Script will Export contents from $SourceAlias to $TargetAlias but to the specific Folder: $TargetFolder" Search-Mailbox -Identity $SourceAlias -TargetMailbox $TargetAlias -TargetFolder $TargetFolder -SearchQuery "sent>=$StartDate OR received>=$StartDate" } Else { Write-Host "The Script will Export contents from $SourceAlias to $TargetAlias" Search-Mailbox -Identity $SourceAlias -TargetMailbox $TargetAlias -SearchQuery "sent>=$StartDate OR received>=$StartDate" } } ElseIf ($EndDate) { Write-Host "The Script will copy mail contents from $SourceAlias old than: $EndDate" Read-Host "Press Enter to Continue or CTRL + C to Cancel" If ($TargetFolder) { Write-Host "The Script will Export contents from $SourceAlias to $TargetAlias but to the specific Folder: $TargetFolder" Search-Mailbox -Identity $SourceAlias -TargetMailbox $TargetAlias -TargetFolder $TargetFolder -SearchQuery "sent<=$EndDate OR received<=$EndDate" } Else { Write-Host "The Script will Export contents from $SourceAlias to $TargetAlias" Search-Mailbox -Identity $SourceAlias -TargetMailbox $TargetAlias -SearchQuery "sent<=$EndDate OR received<=$EndDate" } } Else { Write-Host "No Date Range has been provide" Write-Host "The Script will stop" Exit } } Function Add-EXOMembersToDistributionGroupUsingCSV { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$DG_EmailAddress, [Parameter(Mandatory = $true, Position = 2)] [string]$CSVFile ) Try { Read-Host "Expected CSV Column: EmailAddress" $Members = Import-Csv $CSVFile Write-Log -Level Info -Message "The script imported $CSVFile" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to Import $CSVFile" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" Exit } #Initiate the Hash Table [Int]$i = 1 $Table = $Null $Table = @() $Count = ($Members | Measure).count foreach ($Member in $Members) { Try { $MemberEmailAddress = $Null $MemberEmailAddress = $Member.EmailAddress Write-Log -Level warning -Message "The script will try to add $MemberEmailAddress --- $i/$Count" Add-DistributionGroupMember -Identity $DG_EmailAddress -Member $MemberEmailAddress Write-Log -Level Info -Message "The script added $MemberEmailAddress --- $i/$Count" $Status = "Added" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to add $MemberEmailAddress to $DG_EmailAddress" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" $Status = "Failed to Add with Error: $ErrorMessage" } $Table += New-object PSobject -Property ([Ordered] @{ MemberEmailAddress = $MemberEmailAddress; Status = $Status; }) $i++ } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFile = ".\adding_Members_" + $DG_EmailAddress + "_" + $DateFull + ".csv" $Table | Export-Csv $ReportFile -NoTypeInformation -Encoding UTF8 Write-Log -Level INFO -Message "Generate the following Report: $ReportFile" } Function Remove-EXOCalendarInvite { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$EmailAddress, [Parameter(Mandatory = $true, Position = 2)] [datetime]$Date, [Parameter(Mandatory = $true, Position = 3)] [int]$DurationInDays ) Remove-CalendarEvents -Identity $EmailAddress -CancelOrganizedMeetings -QueryStartDate $Date -QueryWindowInDays $DurationInDays -PreviewOnly -confirm: $False Write-Host "Are you sure you want to remove all these meetings? - all recurrent meetings during this period will be cancelled" -NoNewline -ForegroundColor Red; Read-Host "<Press Enter to continue> or <ctrl + c> To cancel" Remove-CalendarEvents -Identity $EmailAddress -CancelOrganizedMeetings -QueryStartDate $Date -QueryWindowInDays $DurationInDays } Function Create-EXORestrictedSharedMailbox { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$DisplayName, [Parameter(Mandatory = $true, Position = 2)] [String]$EmailAddress ) $LocalPart = $EmailAddress.Substring(0, $EmailAddress.LastIndexOf("@")) $UserName = $LocalPart + $TenantOnMicrosoft # Create & Update Shared Mailbox Settings New-Mailbox -Shared -DisplayName $DisplayName -Name $DisplayName -Alias $LocalPart -PrimarySmtpAddress $UserName Write-Host " $DisplayName - $EmailAddress was " -NoNewline; Write-host "created" -ForegroundColor Green $PrimarySMTPAddress = 'SMTP:' + $EmailAddress Set-Mailbox -identity $UserName -EmailAddresses $PrimarySMTPAddress Set-CASMailbox -Identity $UserName -ActiveSyncEnabled $False -EwsEnabled $False -ImapEnabled $False -MacOutlookEnabled $False -MAPIEnabled $False -OutlookMobileEnabled $False -OWAEnabled $False -OWAforDevicesEnabled $False -PopEnabled $False -SmtpClientAuthenticationDisabled $False -UniversalOutlookEnabled $False Write-Host "$DisplayName - $EmailAddress Settings was " -NoNewline; Write-host "updated - Restriction" -ForegroundColor Green $UserNameFilter = "'" + $UserName + "'" Write-Host "The script will wait 30 seconds for replication between EXO & AAD" -ForegroundColor Yellow sleep 30 $AADSharedMailbox = Get-AzureADUser -Filter "UserPrincipalName eq $UserNameFilter" $AADSharedMailboxObjectId = $AADSharedMailbox.ObjectId Write-Host "$DisplayName - $EmailAddress : ObjectID is: " -NoNewline; Write-host "$AADSharedMailboxObjectId" -ForegroundColor Green # Add user back to exclusion group: # MFA exclusion using SG-MFA-Special-Accounts (AAD Group) $MFAExclusionGroup = $Null $MFAExclusionGroup = Get-AzureADGroup -SearchString "SG-MFA-Special-Accounts" $MFAExclusionGroup_ObjectId = $Null $MFAExclusionGroup_ObjectId = $MFAExclusionGroup.ObjectId Add-AzureADGroupMember -ObjectId $MFAExclusionGroup_ObjectId -RefObjectId $AADSharedMailboxObjectId Write-Host "$DisplayName - $EmailAddress was added to the group :" -NoNewline; Write-host "SG-MFA-Special-Accounts" -ForegroundColor Green # Legacy authentication exclusion using SG-BlockLegacyAuth-Exceptions (AAD Group) $LegacyExclusionGroup = Get-AzureADGroup -SearchString "SG-BlockLegacyAuth-Exceptions" $LegacyExclusionGroup_ObjectId = $Null $LegacyExclusionGroup_ObjectId = $LegacyExclusionGroup.ObjectId Add-AzureADGroupMember -ObjectId $LegacyExclusionGroup_ObjectId -RefObjectId $AADSharedMailboxObjectId Write-Host "$DisplayName - $EmailAddress was added to the group :" -NoNewline; Write-host "SG-BlockLegacyAuth-Exceptions" -ForegroundColor Green } Function Convert-EXOUserMailboxToRestrictedSharedMailbox { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$EmailAddress ) # Create & Update Shared Mailbox Settings Set-Mailbox $EmailAddress -Type Shared $Mailbox = $Null $Mailbox = Get-Mailbox $EmailAddress $DisplayName = $Null $DisplayName = $Mailbox.DisplayName Set-CASMailbox -Identity $EmailAddress -ActiveSyncEnabled $False -EwsEnabled $False -ImapEnabled $False -MacOutlookEnabled $False -MAPIEnabled $False -OutlookMobileEnabled $False -OWAEnabled $False -OWAforDevicesEnabled $False -PopEnabled $False -SmtpClientAuthenticationDisabled $False -UniversalOutlookEnabled $False Write-Host "$DisplayName - $EmailAddress Settings was " -NoNewline; Write-host "updated - Restriction" -ForegroundColor Green $UserNameFilter = "'" + $EmailAddress + "'" Write-Host "The script will wait 30 seconds for replication between EXO & AAD" -ForegroundColor Yellow sleep 30 $AADSharedMailbox = Get-AzureADUser -Filter "UserPrincipalName eq $UserNameFilter" $AADSharedMailboxObjectId = $AADSharedMailbox.ObjectId Write-Host "$DisplayName - $EmailAddress : ObjectID is: " -NoNewline; Write-host "$AADSharedMailboxObjectId" -ForegroundColor Green # Add user back to exclusion group: # MFA exclusion using SG-MFA-Special-Accounts (AAD Group) $MFAExclusionGroup = $Null $MFAExclusionGroup = Get-AzureADGroup -SearchString "SG-MFA-Special-Accounts" $MFAExclusionGroup_ObjectId = $Null $MFAExclusionGroup_ObjectId = $MFAExclusionGroup.ObjectId Add-AzureADGroupMember -ObjectId $MFAExclusionGroup_ObjectId -RefObjectId $AADSharedMailboxObjectId Write-Host "$DisplayName - $EmailAddress was added to the group :" -NoNewline; Write-host "SG-MFA-Special-Accounts" -ForegroundColor Green # Legacy authentication exclusion using SG-BlockLegacyAuth-Exceptions (AAD Group) $LegacyExclusionGroup = Get-AzureADGroup -SearchString "SG-BlockLegacyAuth-Exceptions" $LegacyExclusionGroup_ObjectId = $Null $LegacyExclusionGroup_ObjectId = $LegacyExclusionGroup.ObjectId Add-AzureADGroupMember -ObjectId $LegacyExclusionGroup_ObjectId -RefObjectId $AADSharedMailboxObjectId Write-Host "$DisplayName - $EmailAddress was added to the group :" -NoNewline; Write-host "SG-BlockLegacyAuth-Exceptions" -ForegroundColor Green } Function Open-EXOConferenceRoom { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$Identity ) Write-Host "Checking for configuration before change ( $Identity) :" Get-CalendarProcessing -Identity $Identity | fl AutomateProcessing, DeleteComments, DeleteSubject, ResourceDelegates, BookInPolicy, AllBookInPolicy Set-CalendarProcessing -Identity $Identity -AutomateProcessing AutoAccept -DeleteSubject:$False -DeleteComments:$false -AllBookInPolicy $True -BookInPolicy $Null -ResourceDelegates $Null sleep 10 Write-Host "Checking for configuration post change ( $Identity) :" Get-CalendarProcessing -Identity $Identity | fl AutomateProcessing, DeleteComments, DeleteSubject, ResourceDelegates, BookInPolicy, AllBookInPolicy } Function Update-EXOCalendarProcessingSettingsForConferenceRoom { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$EmailAddress ) Write-Host "Settings before the change:" Get-CalendarProcessing $EmailAddress | fl AutomateProcessing, DeleteComments, DeleteSubject Set-CalendarProcessing $EmailAddress -DeleteSubject:$False -DeleteComments:$False sleep 2 Write-Host "Settings after the change:" Get-CalendarProcessing $EmailAddress | fl AutomateProcessing, DeleteComments, DeleteSubject #$Calendar = $EmailAddress + ":\Calendar" #Write-Host "Updating permission for $Calendar :" #Add-MailboxFolderPermission -Identity $Calendar -User "User1@company.com" -AccessRights "Reviewer" } Function Get-EXOUnifiedGroupMembers { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$Identity ) Get-UnifiedGroupLinks -Identity $Identity -LinkType Members -ResultSize unlimited } Function Expand-EXOGroup { param ( [Parameter(Mandatory = $true, Position = 1)] [String]$GroupName ) $Users = $Null $Users = @() $Members = Get-DistributionGroupMember -Identity $GroupName foreach ($Member in $Members) { $RecipientType = $Member.RecipientType #$member.Name + "`t`t`t" + $RecipientType if ($RecipientType -like "*DistributionGroup*") { # Found an child group - calling myself to expand the group Expand-Group -GroupName $member.Alias } # Create a PSCustomObject of the current member $MemberObject = [PSCustomObject] @{ FirstName = "$($member.FirstName)" LastName = "$($member.LastName)" Name = "$($member.Name)" Title = "$($member.Title)" Department = "$($member.Department)" Email = "$($member.PrimarySMTPAddress)" Memberof = "$GroupName" RecipientType = "$RecipientType" } # Store the member object to Users array $Users += $MemberObject } Return $Users } Function Expand-EXODirectADGroup { param ( [Parameter(Mandatory = $true, Position = 1)] [String]$GroupName ) $Users = $Null $Users = @() $Members = Get-ADGroupMember -Identity $GroupName foreach ($Member in $Members) { $UserDN = $Member.DistinguishedName $ADuser = $Null $ADuser = Get-ADUser -Identity $UserDN -Properties * # Create a PSCustomObject of the current member $MemberObject = [PSCustomObject] @{ FirstName = "$($ADuser.FirstName)" LastName = "$($ADuser.LastName)" Name = "$($ADuser.Name)" Title = "$($ADuser.Title)" Department = "$($ADuser.Department)" Email = "$($ADuser.PrimarySMTPAddress)" Memberof = "$GroupName" } # Store the member object to Users array $Users += $MemberObject } Return $Users } Function Replace-EXODistributionListMembers { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$EmailAddress, [Parameter(Mandatory = $true, Position = 2)] [String]$File ) Update-DistributionGroupMember -Identity $EmailAddress -Members $Null -confirm:$False $Members = Get-Content $File foreach ($Member in $Members) { Add-DistributionGroupMember -Identity $EmailAddress -Member $Member -confirm:$False } } Function Count-EXOForwardToRecipientOfInboxRules { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$EmailAddress ) [Int]$i = 1 $Table = $Null $Table = @() $InboxRules = $Null $InboxRules = Get-inboxRule -Mailbox $EmailAddress $Count = ($InboxRules | Measure).count foreach ($InboxRule in $InboxRules) { $RuleName = $Null $RuleName = $InboxRule.Name $ForwardTo = $Null $ForwardTo = $InboxRule.ForwardTo $Priority = $Null $Priority = $InboxRule.Priority $ForwardToCount = ($ForwardTo | Measure).count #Write-Log -Level INFO -message "Checking Rule $RuleName --- $i/$Count " $Table += New-object PSobject -Property ([Ordered] @{ RuleName = $RuleName; Priority = $Priority; ForwardToCount = $ForwardToCount; }) $i++ } $Table | Ft } Function Create-EXOTransportRuleforBlockingIncomingMessagewithException { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$RecipientEmailAddress, [Parameter(Mandatory = $true, Position = 2)] [String]$Exception ) $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $Name = "Block Incoming Messages: " + $RecipientEmailAddress $RejectMessageEnhancedStatusCode = "5.7.1" $RejectMessageReasonText = "Your message has been blocked" $Comments = "Block Incoming Messages with Exceptions for $RecipientEmailAddress - Date: $DateFull" New-TransportRule -Name $Name -FromScope "NotInOrganization" -RejectMessageEnhancedStatusCode $RejectMessageEnhancedStatusCode -RejectMessageReasonText $RejectMessageReasonText -ExceptIfFrom $Exception -AnyOfToHeader $RecipientEmailAddress -Comments $Comments -Enabled $False } Function Run-EXOMessageTraceLast2Days { [CmdletBinding()] param ( [Parameter(Mandatory = $false, Position = 1)] [String]$Sender, [Parameter(Position = 1)] [String]$Recipient ) $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" if ($Sender) { $MessageTraceFile = $Sender + "_Last2Days_MessageTrace_Sender_Search_" + $DateFull + ".csv" } if ($Recipient) { $MessageTraceFile = $Recipient + "_Last2Days_MessageTrace_Recipient_Search_" + $DateFull + ".csv" } $Table = $Null $Table = @() $StartDate = (Get-Date).AddDays(-2) $EndDate = Get-Date $Messages = $null $Messages = @() [Int]$i = 1 [Int]$MessageCount = 1 Do { If ($Sender) { $AllMessages = Get-MessageTrace -SenderAddress $Sender -EndDate $EndDate -StartDate $StartDate -PageSize 5000 -Page $i } If ($Recipient) { $AllMessages = Get-MessageTrace -RecipientAddress $Recipient -EndDate $EndDate -StartDate $StartDate -PageSize 5000 -Page $i } $MessageCount = ($AllMessages | Measure).count $Messages += $AllMessages $i++ } While ($MessageCount -ne 0) foreach ($Message in $Messages) { $MessageTraceID = $Null $MessageTraceID = $Message.MessageTraceId.Guid $SenderAddress = $Null $SenderAddress = $Message.SenderAddress $Received = $Null $Received = $Message.Received $RecipientAddress = $Null $RecipientAddress = $Message.RecipientAddress $Subject = $Null $Subject = $Message.Subject $Status = $Null $Status = $Message.Status $Table += New-object PSobject -Property ([Ordered] @{ SenderAddress = $SenderAddress; RecipientAddress = $RecipientAddress; Subject = $Subject; ReceivedDate = $Received; Status = $Status; MessageTraceID = $MessageTraceID; }) } $Table | Export-Csv $MessageTraceFile -NoTypeInformation -Encoding UTF8 Write-Host "The following CSV File was generated:" -NoNewline; Write-Host -ForegroundColor Green "$MessageTraceFile" # Open File $Openfile = Read-Host "Do you want to open the file? Y for Yes and N for No" If ($Openfile -eq "Y") { Invoke-Item $MessageTraceFile } Else { Write-Log -Level Warning -Message "End of the script" } } Function Run-EXOMessageTraceLast7Days { [CmdletBinding()] param ( [Parameter(Mandatory = $false, Position = 1)] [String]$Sender, [Parameter(Position = 1)] [String]$Recipient ) $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" if ($Sender) { $MessageTraceFile = $Sender + "_Last7Days_MessageTrace_Sender_Search_" + $DateFull + ".csv" } if ($Recipient) { $MessageTraceFile = $Recipient + "_Last7Days_MessageTrace_Recipient_Search_" + $DateFull + ".csv" } $Table = $Null $Table = @() $StartDate = (Get-Date).AddDays(-7) $EndDate = Get-Date $Messages = $null $Messages = @() [Int]$i = 1 [Int]$MessageCount = 1 Do { If ($Sender) { $AllMessages = Get-MessageTrace -SenderAddress $Sender -EndDate $EndDate -StartDate $StartDate -PageSize 5000 -Page $i } If ($Recipient) { $AllMessages = Get-MessageTrace -RecipientAddress $Recipient -EndDate $EndDate -StartDate $StartDate -PageSize 5000 -Page $i } $MessageCount = ($AllMessages | Measure).count $Messages += $AllMessages $i++ } While ($MessageCount -ne 0) foreach ($Message in $Messages) { $MessageTraceID = $Null $MessageTraceID = $Message.MessageTraceId.Guid $SenderAddress = $Null $SenderAddress = $Message.SenderAddress $Received = $Null $Received = $Message.Received $RecipientAddress = $Null $RecipientAddress = $Message.RecipientAddress $Subject = $Null $Subject = $Message.Subject $Status = $Null $Status = $Message.Status $Table += New-object PSobject -Property ([Ordered] @{ SenderAddress = $SenderAddress; RecipientAddress = $RecipientAddress; Subject = $Subject; ReceivedDate = $Received; Status = $Status; MessageTraceID = $MessageTraceID; }) } $Table | Export-Csv $MessageTraceFile -NoTypeInformation -Encoding UTF8 Write-Host "The following CSV File was generated:" -NoNewline; Write-Host -ForegroundColor Green "$MessageTraceFile" # Open File $Openfile = Read-Host "Do you want to open the file? Y for Yes and N for No" If ($Openfile -eq "Y") { Invoke-Item $MessageTraceFile } Else { Write-Log -Level Warning -Message "End of the script" } } Function Run-EXOMessageTraceLast10Days { [CmdletBinding()] param ( [Parameter(Mandatory = $false, Position = 1)] [String]$Sender, [Parameter(Position = 1)] [String]$Recipient ) $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" if ($Sender) { $MessageTraceFile = $Sender + "_Last10Days_MessageTrace_Sender_Search_" + $DateFull + ".csv" } if ($Recipient) { $MessageTraceFile = $Recipient + "_Last10Days_MessageTrace_Recipient_Search_" + $DateFull + ".csv" } $Table = $Null $Table = @() $StartDate = (Get-Date).AddDays(-10) $EndDate = Get-Date $Messages = $null $Messages = @() [Int]$i = 1 [Int]$MessageCount = 1 Do { If ($Sender) { $AllMessages = Get-MessageTrace -SenderAddress $Sender -EndDate $EndDate -StartDate $StartDate -PageSize 5000 -Page $i } If ($Recipient) { $AllMessages = Get-MessageTrace -RecipientAddress $Recipient -EndDate $EndDate -StartDate $StartDate -PageSize 5000 -Page $i } $MessageCount = ($AllMessages | Measure).count $Messages += $AllMessages $i++ } While ($MessageCount -ne 0) foreach ($Message in $Messages) { $MessageTraceID = $Null $MessageTraceID = $Message.MessageTraceId.Guid $SenderAddress = $Null $SenderAddress = $Message.SenderAddress $Received = $Null $Received = $Message.Received $RecipientAddress = $Null $RecipientAddress = $Message.RecipientAddress $Subject = $Null $Subject = $Message.Subject $Status = $Null $Status = $Message.Status $Table += New-object PSobject -Property ([Ordered] @{ SenderAddress = $SenderAddress; RecipientAddress = $RecipientAddress; Subject = $Subject; ReceivedDate = $Received; Status = $Status; MessageTraceID = $MessageTraceID; }) } $Table | Export-Csv $MessageTraceFile -NoTypeInformation -Encoding UTF8 Write-Host "The following CSV File was generated:" -NoNewline; Write-Host -ForegroundColor Green "$MessageTraceFile" # Open File $Openfile = Read-Host "Do you want to open the file? Y for Yes and N for No" If ($Openfile -eq "Y") { Invoke-Item $MessageTraceFile } Else { Write-Log -Level Warning -Message "End of the script" } } function Run-EXOMessageTraceLast90Days { [CmdletBinding()] param ( [Parameter(Mandatory = $false, Position = 1)] [String]$Recipient, [Parameter(Mandatory = $false, Position = 2)] [String]$SenderAddress ) $EndDate = (Get-Date).AddDays(+ 1) $StartDate = (Get-Date).AddDays(-90) Read-Host "Are you connected to Exchange Online? - Enter to Continue or CTRL+C to Cancel" If ($SenderAddress -and $Recipient) { $SearchName = "MessageTrace_90days_Sender_" + $SenderAddress + "_Recipient_" + $Recipient Start-HistoricalSearch -ReportTitle $SearchName -RecipientAddress $Recipient -SenderAddress $SenderAddress -StartDate $StartDate -EndDate $EndDate -ReportType MessageTraceDetail Write-Host "Generating a Report for Recipient : $Recipient --- Sender: $SenderAddress --- From : $StartDate To: $EndDate ...." } Elseif ($SenderAddress -and !($Recipient)) { $SearchName = "MessageTrace_90days_Sender_" + $SenderAddress Start-HistoricalSearch -ReportTitle $SearchName -SenderAddress $SenderAddress -StartDate $StartDate -EndDate $EndDate -ReportType MessageTraceDetail Write-Host "Generating a Report for Sender : $SenderAddress From : $StartDate To: $EndDate ...." } Elseif ($Recipient -and !($SenderAddress)) { $SearchName = "MessageTrace_90days_Recipient_" + $Recipient Start-HistoricalSearch -ReportTitle $SearchName -RecipientAddress $Recipient -StartDate $StartDate -EndDate $EndDate -ReportType MessageTraceDetail Write-Host "Generating a Report for Recipient : $Recipient From : $StartDate To: $EndDate ...." } Write-Host "The Report $SearchName request is generated" Get-HistoricalSearch | where { $_.ReportTitle -eq $SearchName } | fl } Function Investigate-EXOUserInboxRules { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$EmailAddress, [Parameter(Mandatory = $true, Position = 2)] [datetime]$StartDate, [Parameter(Mandatory = $true, Position = 3)] [datetime]$EndDate ) # Inbox Rules $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $InboxRulesFile = $EmailAddress + "_InboxRules_" + $DateFull + ".csv" Write-host 'Searching Inbox Rules...' -ForegroundColor Yellow $InboxRules = Get-InboxRule -Mailbox $EmailAddress | Select Name, Description, Enabled, Identity, From, ForwardTo, ForwardAsAttachmentTo, SentTo, MoveToFolder | Export-csv $InboxRulesFile -NoTypeInformation -Encoding UTF8 $InboxRulesCount = ($InboxRules | Measure).Count Write-Host "Found" -NoNewline; Write-Host -ForegroundColor Green "$InboxRulesCount" -NoNewline; Write-Host "Outlook Rules - Export the report to:" -NoNewline; Write-Host -ForegroundColor Green "$InboxRulesFile" # Mailbox Audit Log Search $MailboxAuditLogSearch = Run-MailboxAuditLogSearch -Mailbox $EmailAddress -StartDate $StartDate -EndDate $EndDate # Unified Log Check for Outlook Rules History $UnifiedAuditLogsFile = $EmailAddress + "_UnifiedAuditLogs_InboxRules_" + $DateFull + ".csv" Write-Host -ForegroundColor Yellow "Analyzing Unified Audit Logs for Inbox Rules changes...." $UnifiedAuditLogs = Search-UnifiedAuditLog -StartDate $StartDate -EndDate $EndDate -Operations New-InboxRule, Set-InboxRule, UpdateInboxRules -UserIds $EmailAddress | Select Userids, RecordType, CreationDate, OPerations, AuditData | Export-csv $UnifiedAuditLogsFile -NoTypeInformation -Encoding UTF8 Write-Host "The script export Unified Audit Logs to:" -NoNewline; Write-Host -ForegroundColor Green "$UnifiedAuditLogsFile" # Open File $Openfile = Read-Host "Do you want to open the file? Y for Yes and N for No" If ($Openfile -eq "Y") { Invoke-Item $UnifiedAuditLogsFile Invoke-Item $InboxRulesFile } Else { Write-Log -Level Warning -Message "End of the script" } } Function Investigate-EXOBlockedMailbox { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$Sender ) $StartDate = (Get-Date).AddDays(-30) $EndDate = (Get-Date).AddDays(+ 1) Try { Write-Host "Script is checking if the user is Restricted from sending message (Sender: $Sender)...." $BlockSender = Get-BlockedSenderAddress -SenderAddress $Sender $Reason = $Null $Reason = $BlockSender.Reason # Convert Variable to Table $ReasonTable = $Reason.split("{;}") $OutboundSpamLast24Hours = $ReasonTable[0] $OutboundSpamLast24HoursValue = $OutboundSpamLast24Hours.Substring($OutboundSpamLast24Hours.IndexOf("=")) $OutboundSpamLast24HoursValue = $OutboundSpamLast24HoursValue.Substring(1) $OutboundMailLast24Hours = $ReasonTable[1] $OutboundMailLast24HoursValue = $OutboundMailLast24Hours.Substring($OutboundMailLast24Hours.IndexOf("=")) $OutboundMailLast24HoursValue = $OutboundMailLast24HoursValue.Substring(1) $OutboundSpamPercent = $ReasonTable[2] $OutboundSpamPercentValue = $OutboundSpamPercent.Substring($OutboundSpamPercent.IndexOf("=")) $OutboundSpamPercentValue = $OutboundSpamPercentValue.Substring(1) $LastMessageSent_MessageTraceID = $ReasonTable[3] $LastMessageSent_MessageTraceIDValue = $LastMessageSent_MessageTraceID.Substring($LastMessageSent_MessageTraceID.IndexOf(":")) $LastMessageSent_MessageTraceIDValue = $LastMessageSent_MessageTraceIDValue.Substring(1) $CreatedDateTime = $Null $CreatedDateTime = $BlockSender.CreatedDateTime $ChangedDateTime = $Null $ChangedDateTime = $BlockSender.ChangedDateTime #Searching Messages using MessageTraceID Try { $Messages = Get-MessageTrace -MessageTraceID $LastMessageSent_MessageTraceIDValue $MessageSubject = $Messages[0].Subject $MessageDate = $Messages[0].Received $MessagesFound = "Yes" } Catch { $MessagesFound = "No" } Write-Host "The script found $Sender was blocked" -ForegroundColor Red Write-Host "Please run the following CMDLet to remove the blocked:" -NoNewline; Write-Host -ForegroundColor Green "Remove-BlockedSenderAddress -SenderAddress $Sender" Write-Host "--- When: Created Date: $CreatedDateTime - Change Date:$ChangedDateTime" Write-Host "--- Reason: " -ForegroundColor Yellow Write-Host "------ Outbound Spam Last 24 Hours (Sent):" -NoNewline; Write-Host -ForegroundColor Green "$OutboundSpamLast24HoursValue " Write-Host "------ Outbound Mail Last 24 Hours(Sent):" -NoNewline; Write-Host -ForegroundColor Green " $OutboundMailLast24HoursValue" Write-Host "------ Outbound Spam Percent:" -NoNewline; Write-Host -ForegroundColor Green " $OutboundSpamPercentValue" If ($MessagesFound -ne "No") { Write-Host "------ Last Message Sent was (older than 10 days):" Write-Host "--------- Message Trace ID (Network MessageID):" -NoNewline; Write-Host -ForegroundColor Green " $LastMessageSent_MessageTraceIDValue" Write-Host "--------- Message Subject:" -NoNewline; Write-Host -ForegroundColor Green " $MessageSubject" Write-Host "--------- Message Sent Date:" -NoNewline; Write-Host -ForegroundColor Green " $MessageDate" } Else { Write-Host "------ Last Message Sent (Message Trace ID/Network MessageID) =" -NoNewline; Write-Host -ForegroundColor Green " $LastMessageSent_MessageTraceIDValue" } } Catch { Write-Host "Failed to find the user as restricted user" -ForegroundColor Green } # Check for mailbox forwarding option $Mailbox = $Null $Mailbox = Get-Mailbox $Sender $ForwardingAddress = $Null $ForwardingAddress = $Mailbox.ForwardingAddress If ($ForwardingAddress -eq $Null) { $ForwardingAddress = "Not Set" } $ForwardingSmtpAddress = $Null $ForwardingSmtpAddress = $Mailbox.ForwardingSmtpAddress If ($ForwardingSmtpAddress -eq $Null) { $ForwardingSmtpAddress = "Not Set" } Write-Host "The script is checking for Forwarding enable on $Sender :" -ForegroundColor Yellow Write-Host "------ ForwardingAddress (User):" -NoNewline; Write-Host -ForegroundColor Green "$ForwardingAddress" Write-Host "------ ForwardingSMTPAddress (Admin):" -NoNewline; Write-Host -ForegroundColor Green "$ForwardingSmtpAddress" # Check Delegate $DelegateInbox = $Sender + ":\Inbox" $Delegate = Get-MailboxFolderPermission $DelegateInbox | select Identity, FolderName, User, AccessRights Write-Host "The script is checking for delegate access on $Sender :" -ForegroundColor Yellow $Delegate | ft # Inbox Rules Write-Host "The script is checking for Inbox Rules for: $Sender :" -ForegroundColor Yellow $InboxRules = Get-InboxRule -Mailbox $Sender | Select Name, Description, Enabled, Identity, From, ForwardTo, ForwardAsAttachmentTo, SentTo, MoveToFolder $InboxRulesCount = ($InboxRules | measure).count if ($InboxRulesCount -gt 1) { $InboxRules | ft } Else { Write-Host "The script did NOT found any Inbox Rules for: $Sender" -ForegroundColor Green } # Unified Log Check for Outlook Rules History Write-Host 'The script is checking the Unified Logs for Inbox Rules changes (30 days)' -ForegroundColor Yellow $UnifiedAuditLogs = Search-UnifiedAuditLog -StartDate $StartDate -EndDate $EndDate -Operations New-InboxRule, Set-InboxRule, UpdateInboxRules -UserIds $Sender | Select Userids, RecordType, CreationDate, OPerations, AuditData $UnifiedAuditLogsCount = ($UnifiedAuditLogs | measure).count if ($UnifiedAuditLogsCount -gt 1) { $UnifiedAuditLogs | ft } Else { Write-Host "The script did NOT found any Inbox Rules changes (unified Audit Logs) for (last 30 days)" -ForegroundColor Green } #Mailbox Audit Logs $MailboxAuditLogs = $Null Write-Host "The script is checking Mailbox Audit Log for:" -ForegroundColor Yellow $MailboxAuditLogs = Run-MailboxAuditLogSearch -Mailbox $Sender -StartDate $StartDate -EndDate $EndDate } Function Run-EXOMailboxAuditLogSearch { param ( [Parameter(Mandatory = $true, Position = 1)] [string]$Mailbox, [Parameter(Mandatory = $true, Position = 2)] [string]$StartDate, [Parameter(Mandatory = $true, Position = 3)] [string]$EndDate, [Parameter(Mandatory = $false, Position = 4)] [string]$Subject, [Parameter(Mandatory = $false, Position = 5)] [switch]$IncludeFolderBind ) $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFile = $Mailbox + "_Report_MailboxAuditLog_" + $DateFull + ".csv" $Table = $Null $Table = @() $SearchResults = $Null $SearchResults = @() Try { Write-Log -Level Warning -Message 'Searching Mailbox Audit Logs...' $SearchResults = Search-MailboxAuditLog $Mailbox -StartDate $StartDate -EndDate $EndDate -LogonTypes Owner, Admin, Delegate -ShowDetails -resultsize 50000 if (-not $IncludeFolderBind) { Write-Log -Level Warning -Message 'Removing FolderBind operations.' $SearchResults = $SearchResults | Where { $_.Operation -notlike 'FolderBind' } $SearchResultsCount = ($SearchResults | measure).count Write-Log -Level -Level INFO -Message "The script found $SearchResultsCount entries Found" } Else { $SearchResultsCount = ($SearchResults | measure).count Write-Log -Level -Level INFO -Message "The script found $SearchResultsCount entries Found" } } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level -Level Error -Message "Failed to Retreive Mailbox Audit Log for $Mailbox" Write-Log -Level -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level -Level Error -Message "Failed with Error:$ErrorMessage" Write-Log -Level Error -Message "The Script will stop" # Exit the script Exit } foreach ($SearchResult in $SearchResults) { $Operation = $Null $Operation = $SearchResult.Operation $LogonUserDisplayName = $Null $LogonUserDisplayName = $SearchResult.LogonUserDisplayName $LastAccessed = $Null $LastAccessed = $SearchResult.LastAccessed $DestFolderPathName = $Null $DestFolderPathName = $SearchResult.DestFolderPathName $FolderPathName = $Null $FolderPathName = $SearchResult.FolderPathName $ClientInfoString = $Null $ClientInfoString = $SearchResult.ClientInfoString $ClientIPAddress = $Null $ClientIPAddress = $SearchResult.ClientIPAddress $ClientMachineName = $Null $ClientMachineName = $SearchResult.ClientMachineName $ClientProcessName = $Null $ClientProcessName = $SearchResult.ClientProcessName $ClientVersion = $Null $ClientVersion = $SearchResult.ClientVersion $LogonType = $Null $LogonType = $SearchResult.LogonType $MailboxResolvedOwnerName = $Null $MailboxResolvedOwnerName = $SearchResult.MailboxResolvedOwnerName $OperationResult = $Null $OperationResult = $SearchResult.OperationResult $Operation = $Null $Operation = $SearchResult.Operation $CrossMailboxOperation = $Null $CrossMailboxOperation = $SearchResult.CrossMailboxOperation $SourceItems = $Null $SourceItems = $SearchResult.SourceItems $SubjectItems = $Null if (($SourceItems.Count -eq 0) -or ($SourceItems.Count -eq $null)) { $SubjectItems = $SearchResult.ItemSubject } else { $SubjectItems = $SearchResult.SourceItemSubjectsList } if ($Operation -contains 'SendAs' -or $Operation -contains 'Create' -or $Operation -contains 'Update') { $CrossMailboxOperation = 'N/A' } if ($Subject) { if ($SubjectItems -match $Subject) { $Table += New-object PSobject -Property ([Ordered] @{ Subject = $SubjectItems; Operation = $Operation; LogonUserDisplayName = $LogonUserDisplayName; LastAccessed = $LastAccessed; DestFolderPathName = $DestFolderPathName; FolderPathName = $FolderPathName; ClientInfoString = $ClientInfoString; ClientIPAddress = $ClientIPAddress; ClientMachineName = $ClientMachineName; ClientProcessName = $ClientProcessName; ClientVersion = $ClientVersion; LogonType = $LogonType; MailboxResolvedOwnerName = $MailboxResolvedOwnerName; OperationResult = $OperationResult; CrossMailboxOperation = $CrossMailboxOperation; }) } } Else { $Table += New-object PSobject -Property ([Ordered] @{ Subject = $SubjectItems; Operation = $Operation; LogonUserDisplayName = $LogonUserDisplayName; LastAccessed = $LastAccessed; DestFolderPathName = $DestFolderPathName; FolderPathName = $FolderPathName; ClientInfoString = $ClientInfoString; ClientIPAddress = $ClientIPAddress; ClientMachineName = $ClientMachineName; ClientProcessName = $ClientProcessName; ClientVersion = $ClientVersion; LogonType = $LogonType; MailboxResolvedOwnerName = $MailboxResolvedOwnerName; OperationResult = $OperationResult; CrossMailboxOperation = $CrossMailboxOperation; }) } } # Export Report $Table | export-csv $ReportFile -NoTypeInformation -Encoding UTF8 Write-Log -Level Warning -Message "The Script has generate the following Report: $ReportFile" } Function Duplicate-EXODistributionGroupMembers { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$SourceDG, [Parameter(Mandatory = $true, Position = 2)] [String]$DestinationDG ) $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" #Backup Distribution Groups $SourceDGMembers = Get-DistributionGroupMember $SourceDG $SourceDGXMLFile = "Backup_DG_Members_Of_" + $SourceDG + "_" + $DateFull + ".xml" $SourceDGMembers | Export-Clixml $SourceDGXMLFile Write-Host "a backup of Distribution Group $SourceDG was created : $SourceDGXMLFile" $BeforeDestinationDGMembers = Get-DistributionGroupMember $DestinationDG $DestinationDGXMLFile = "Backup_DG_Members_Of_" + $DestinationDG + "_" + $DateFull + ".xml" $BeforeDestinationDGMembers | Export-Clixml $DestinationDGXMLFile Write-Host "a backup of Distribution Group $DestinationDG was created : $DestinationDGXMLFile" # Update Distribution Group $SourceDGMembers | foreach{ Add-DistributionGroupMember $DestinationDG -Member $_.WindowsLiveID } $SourceDGMembersCount = ($SourceDGMembers | measure).count Write-Host "Member of Source Distribution Group has $SourceDGMembersCount members" -ForegroundColor Yellow $DestinationDGMembers = Get-DistributionGroupMember $DestinationDG $DestinationDGMembersCount = ($DestinationDGMembers | measure).count Write-Host "Member of Destination Distribution Group has $DestinationDGMembersCount members" -ForegroundColor Green } Function Search-EXOAdminRolebyCMDlet { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$CMDLet ) $TableRole = $Null $TableRole = @() $ManagementRoles = Get-ManagementRole -Cmdlet $CMDLet $ManagementRolesCount = ($ManagementRoles | Measure).count Foreach ($ManagementRole in $ManagementRoles) { $ManagementRoleName = $ManagementRole.Name $ManagementRoleAssignment = Get-ManagementRoleAssignment -Role $ManagementRoleName $RoleAssigneeName = $Null $RoleAssigneeName = $ManagementRoleAssignment.RoleAssigneeName $TableRole += New-object PSobject -Property ([Ordered] @{ CMDLet = $CMDLet; ManagementRoleName = $ManagementRoleName; AdminRoles = $RoleAssigneeName; }) } $TableRole | ft } Function Add-EXOMailboxPermissionSendAs { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$SharedMailbox, [Parameter(Mandatory = $true, Position = 2)] [String]$User, [Parameter(Mandatory = $false, Position = 3)] [String]$LogFolder ) $DateSendAs = Get-Date -Format "ddMMyyyy_HH-mm-ss" If ($LogFolder) { Create-Folder $LogFolder } Else { $LogFolder = (get-location).path } $SendAsLog = $LogFolder + "\Assign_SendAs_Permission_" + $SharedMailbox + "_" + $DateSendAs + ".log" Try { #Assign Send As Permission Write-Log -Level Warning $SendAsLog "Attempt to assign Send As Permission - Mailbox : $SharedMailbox - Trustee: $User" Add-RecipientPermission $SharedMailbox -AccessRights SendAs -Trustee $User -Confirm:$False Write-Log -Level Warning $SendAsLog "Successfully Assign Send As Permission - Mailbox : $SharedMailbox - Trustee: $User" # Check Send As Permission Write-Log -Level Warning $SendAsLog "Attempt to check Send As Permission - Mailbox : $SharedMailbox - Trustee: $User" $SendAsPermissionData = Get-RecipientPermission $SharedMailbox -AccessRights SendAs | where { $_.Trustee -ne "NT AUTHORITY\SELF" } | select Identity, Trustee, AccessRights, AccessControlType Write-Log -Level Warning $SendAsLog "SendAs Permission assign to $SharedMailbox is: " $SendAsPermissionData | Out-File $SendAsLog -Append $SendAsPermissionData | ft } Catch { Write-Log -Level Error $SendAsLog "Failed to assign Send As Permission - Mailbox : $SharedMailbox - Trustee: $User" } } Function Remove-EXOMailboxPermissionSendAs { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$SharedMailbox, [Parameter(Mandatory = $true, Position = 2)] [String]$User, [Parameter(Mandatory = $false, Position = 3)] [String]$LogFolder ) $DateRemoveSendAs = Get-Date -Format "ddMMyyyy_HH-mm-ss" If ($LogFolder) { Create-Folder $LogFolder } Else { $LogFolder = (get-location).path } $RemoveSendAsLog = $LogFolder + "\Remove_SendAs_Permission_" + $SharedMailbox + "_" + $DateRemoveSendAs + ".log" Try { #Remove Send As Permission Write-Log -Level Warning $RemoveSendAsLog "Attempt to Remove Send As Permission - Mailbox : $SharedMailbox - Trustee: $User" Remove-RecipientPermission $SharedMailbox -AccessRights SendAs -Trustee $User -Confirm:$False Write-Log -Level Warning $RemoveSendAsLog "Successfully Remove Send As Permission - Mailbox : $SharedMailbox - Trustee: $User" # Check Send As Permission Write-Log -Level Warning $RemoveSendAsLog "Attempt to check Send As Permission - Mailbox : $SharedMailbox - Trustee: $User" $SendAsPermissionData = Get-RecipientPermission $SharedMailbox -AccessRights SendAs | where { $_.Trustee -ne "NT AUTHORITY\SELF" } | select Identity, Trustee, AccessRights, AccessControlType Write-Log -Level Warning $RemoveSendAsLog "SendAs Permission assign to $SharedMailbox is: " $SendAsPermissionData | Out-File $RemoveSendAsLog -Append $SendAsPermissionData | ft } Catch { Write-Log -Level Error $RemoveSendAsLog "Failed to Remove Send As Permission - Mailbox : $SharedMailbox - Trustee: $User" } } Function Add-EXOMailboxPermissionFullAccess { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$SharedMailbox, [Parameter(Mandatory = $true, Position = 2)] [String]$User, [Parameter(Mandatory = $false, Position = 3)] [String]$LogFolder ) $DateFullAccess = Get-Date -Format "ddMMyyyy_HH-mm-ss" If ($LogFolder) { Create-Folder $LogFolder } Else { $LogFolder = (get-location).path } $FolderFullAccessLog = $LogFolder + "\Assign_FullAccess_Permission_" + $SharedMailbox + "_" + $DateFullAccess + ".log" Try { #Assign Full Access Permission Write-Log -Level Warning $FolderFullAccessLog "Attempt to assign Full Access Permission - Mailbox : $SharedMailbox - User : $User" Add-MailboxPermission -Identity $SharedMailbox -User $User -AccessRights FullAccess -InheritanceType All -AutoMapping $false Write-Log -Level Warning $FolderFullAccessLog "Successfully Assign Full Access Permission - Mailbox : $SharedMailbox - User: $User" # Check Full Access Permission Write-Log -Level Warning $FolderFullAccessLog "Attempt to check Full Access Permission - Mailbox : $SharedMailbox - User: $User" $FullAccessPermissionData = Get-MailboxPermission $SharedMailbox | where { ($_.AccessRights -like "*FullAccess*") -and ($_.User -notlike "NT *") -and ($_.User -notlike "*Admin*") -and ($_.User -notlike "*Exchange*") -and ($_.User -notlike "*Organization Management") } | select Identity, User, AccessRights, Deny Write-Log -Level Warning $FolderFullAccessLog "Full Access Permission assign to $SharedMailbox is: " $FullAccessPermissionData | Out-File $FolderFullAccessLog -Append $FullAccessPermissionData | ft } Catch { Write-Log -Level Error $FolderFullAccessLog "Failed to assign Full Access Permission - Mailbox : $SharedMailbox - User: $User" } } Function Remove-EXOMailboxPermissionFullAccess { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$SharedMailbox, [Parameter(Mandatory = $true, Position = 2)] [String]$User, [Parameter(Mandatory = $false, Position = 3)] [String]$LogFolder ) $DateRemoveFullAccess = Get-Date -Format "ddMMyyyy_HH-mm-ss" If ($LogFolder) { Create-Folder $LogFolder } Else { $LogFolder = (get-location).path } $FolderRemoveFullAccessLog = $LogFolder + "\Remove_FullAccess_Permission_" + $SharedMailbox + "_" + $DateRemoveFullAccess + ".log" Try { # Remove Full Access Permission Write-Log -Level Warning $FolderRemoveFullAccessLog "Remove to assign Full Access Permission - Mailbox : $SharedMailbox - User : $User" Remove-MailboxPermission -Identity $SharedMailbox -User $User -AccessRights FullAccess -InheritanceType All -confirm:$False Write-Log -Level Warning $FolderRemoveFullAccessLog "Successfully Remove Full Access Permission - Mailbox : $SharedMailbox - User: $User" # Check Full Access Permission Write-Log -Level Warning $FolderRemoveFullAccessLog "Attempt to check Full Access Permission - Mailbox : $SharedMailbox - User: $User" $RemoveFullAccessPermissionData = Get-MailboxPermission $SharedMailbox | where { ($_.AccessRights -like "*FullAccess*") -and ($_.User -notlike "NT *") -and ($_.User -notlike "*Admin*") -and ($_.User -notlike "*Exchange*") -and ($_.User -notlike "*Organization Management") } | select Identity, User, AccessRights, Deny Write-Log -Level Warning $FolderRemoveFullAccessLog "Full Access Permission assign to $SharedMailbox is: " $RemoveFullAccessPermissionData | Out-File $FolderRemoveFullAccessLog -Append $RemoveFullAccessPermissionData | ft } Catch { Write-Log -Level Error $FolderRemoveFullAccessLog "Failed to assign Full Access Permission - Mailbox : $SharedMailbox - User: $User" } } Function Add-EXOMailboxPermissionSendOnBehalf { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$SharedMailbox, [Parameter(Mandatory = $true, Position = 2)] [String]$User, [Parameter(Mandatory = $false, Position = 3)] [String]$LogFolder ) $DateSendOnBehalf = Get-Date -Format "ddMMyyyy_HH-mm-ss" If ($LogFolder) { Create-Folder $LogFolder } Else { $LogFolder = (get-location).path } $FolderSendOnBehalfLog = $LogFolder + "\Assign_SendOnBehalf_Permission_" + $SharedMailbox + "_" + $DateSendOnBehalf + ".log" Try { #Assign Send On Behalf Permission Write-Log -Level Warning $FolderSendOnBehalfLog "Attempt to assign Send On Behalf Permission - Mailbox : $SharedMailbox - User : $User" Set-Mailbox -Identity $SharedMailbox -GrantSendOnBehalfTo @{ Add = $User } Write-Log -Level Warning $FolderSendOnBehalfLog "Successfully Assign Send On Behalf Permission - Mailbox : $SharedMailbox - User: $User" # Check Send On Behalf Permission Write-Log -Level Warning $FolderSendOnBehalfLog "Attempt to check Send On Behalf Permission - Mailbox : $SharedMailbox - User: $User" $SendOnBehalfPermissionData = Get-Mailbox $SharedMailbox | Select -ExpandProperty GrantSendOnBehalfTo Write-Log -Level Warning $FolderSendOnBehalfLog "Send On Behalf Permission assign to $SharedMailbox is: " $SendOnBehalfPermissionData | Out-File $FolderSendOnBehalfLog -Append $SendOnBehalfPermissionData | ft } Catch { Write-Log -Level Error $FolderSendOnBehalfLog "Failed to assign Full Access Permission - Mailbox : $SharedMailbox - User: $User" } } Function Remove-EXOMailboxPermissionSendOnBehalf { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$SharedMailbox, [Parameter(Mandatory = $true, Position = 2)] [String]$User, [Parameter(Mandatory = $false, Position = 3)] [String]$LogFolder ) $DateRemoveSendOnBehalf = Get-Date -Format "ddMMyyyy_HH-mm-ss" If ($LogFolder) { Create-Folder $LogFolder } Else { $LogFolder = (get-location).path } $FolderRemoveSendOnBehalfLog = $LogFolder + "\Assign_SendOnBehalf_Permission_" + $SharedMailbox + "_" + $DateRemoveSendOnBehalf + ".log" Try { #Remove Send On Behalf Permission Write-Log -Level Warning $FolderRemoveSendOnBehalfLog "Attempt to Remove Send On Behalf Permission - Mailbox : $SharedMailbox - User : $User" Set-Mailbox -Identity $SharedMailbox -GrantSendOnBehalfTo @{ Remove = $User } Write-Log -Level Warning $FolderRemoveSendOnBehalfLog "Successfully Remove Send On Behalf Permission - Mailbox : $SharedMailbox - User: $User" # Check Send On Behalf Permission Write-Log -Level Warning $FolderRemoveSendOnBehalfLog "Attempt to check Send On Behalf Permission - Mailbox : $SharedMailbox - User: $User" $SendOnBehalfPermissionData = Get-Mailbox $SharedMailbox | Select -ExpandProperty GrantSendOnBehalfTo Write-Log -Level Warning $FolderRemoveSendOnBehalfLog "Send On Behalf Permission assign to $SharedMailbox is: " $SendOnBehalfPermissionData | Out-File $FolderRemoveSendOnBehalfLog -Append $SendOnBehalfPermissionData | ft } Catch { Write-Log -Level Error $FolderRemoveSendOnBehalfLog "Failed to Remove Full Access Permission - Mailbox : $SharedMailbox - User: $User" } } Function Search-EXOMailEnabledPublicFolder { param ( [Parameter(Mandatory = $true, Position = 1)] [String]$Search ) $PublicFolders = Get-PublicFolder -Recurse | where { $_.Identity -like "*$Search*" } $Table = $null $Table = @() ForEach ($PublicFolder in $PublicFolders) { $Identity = $PublicFolder.Identity $MailEnabledPublicFolder = Get-MailPublicFolder $Identity $PublicFolderClientPermissions = Get-PublicFolderClientPermission $Identity -User Anonymous $AnonymousPermission = $PublicFolderClientPermissions.AccessRights $Name = $MailEnabledPublicFolder.Name $MailEnabled = $PublicFolder.MailEnabled $Alias = $MailEnabledPublicFolder.Alias $PrimarySmtpAddress = $MailEnabledPublicFolder.PrimarySmtpAddress $EmailAddressPolicyEnabled = $MailEnabledPublicFolder.EmailAddressPolicyEnabled $Table += New-object PSobject -Property ([Ordered] @{ Name = $Name; Identity = $Identity; Alias = $Alias; MailEnabled = $MailEnabled; PrimarySmtpAddress = $PrimarySmtpAddress; EmailAddressPolicyEnabled = $EmailAddressPolicyEnabled; AnonymousPermission = $AnonymousPermission; }) } $Table | ft } Function Fix-EXOAutoMappingMailbox { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$SharedMailbox, [Parameter(Mandatory = $true, Position = 2)] [String]$Delegate ) Write-Host "The Script will remove FullAccess permission - From: " -NoNewline; Write-Host "$SharedMailbox" -NoNewline -ForegroundColor Yellow; Write-Host " - For: " -NoNewline; Write-Host "$Delegate" -ForegroundColor Red Remove-MailboxPermission -Identity $SharedMailbox -User $Delegate -AccessRights FullAccess -confirm:$False Write-Host "The Script will add the FullAccess permission back - From: " -NoNewline; Write-Host "$SharedMailbox" -NoNewline -ForegroundColor Yellow; Write-Host " - For: " -NoNewline; Write-Host "$Delegate" -ForegroundColor Green Add-MailboxPermission -Identity $SharedMailbox -User $Delegate -AccessRights FullAccess -AutoMapping:$false } Function Fix-EXORecipientDisplayType { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$Mailbox, [Parameter(Mandatory = $true, Position = 2)] [String]$DC ) Write-Host "The Script will Check msExchRecipientDisplayType (Before Change) for: " -NoNewline; Write-Host "$Mailbox" -NoNewline -ForegroundColor Yellow; $ADUser = Get-ADUser -Filter { UserPrincipalName -eq $Mailbox } -Server $DC -properties * $msExchRecipientDisplayType = $ADUser.msExchRecipientDisplayType $UPN = $ADUser.UserPrincipalName $DisplayName = $ADUser.DisplayName $SAM = $ADUser.SamAccountName Write-Host "The Script find the following information: " Write-Host " --- DisplayName: $DisplayName" Write-Host " --- SamAccountName $SAM" Write-Host " --- UPN: $UPN" Write-Host " --- msExchRecipientDisplayType: " -NowNewline; Write-Host "$msExchRecipientDisplayType" -ForegroundColor Red Write-Host "The Script will update msExchRecipientDisplayType for: " -NoNewline; Write-Host "$Mailbox" -ForegroundColor Yellow; Get-ADUser -Filter { UserPrincipalName -eq $Mailbox } -Server $DC | Set-AdObject -Replace @{ msExchRecipientDisplayType = -1073741818 } -Server $DC Write-Host "The Script will Check msExchRecipientDisplayType (After Change) for: " -NoNewline; Write-Host "$Mailbox" -ForegroundColor Yellow; $ADUser1 = Get-ADUser -Filter { UserPrincipalName -eq $Mailbox } -Server $DC -properties * $msExchRecipientDisplayType1 = $ADUser1.msExchRecipientDisplayType $UPN1 = $ADUser1.UserPrincipalName $DisplayName1 = $ADUser1.DisplayName $SAM1 = $ADUser1.SamAccountName Write-Host "The Script find the following information: " Write-Host " --- DisplayName: $DisplayName1" Write-Host " --- SamAccountName $SAM1" Write-Host " --- UPN: $UPN1" Write-Host " --- msExchRecipientDisplayType: " -NowNewline; Write-Host "$msExchRecipientDisplayType1" -ForegroundColor Green } Function Convert-EXOUserMailboxToSharedMailbox { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$Mailbox, [Parameter(Mandatory = $False, Position = 2)] [String]$DC ) $Recipient = Get-Recipient $Mailbox -DomainController $DC $RecipientTypeDetails = $Null $RecipientTypeDetails = $Recipient.RecipientTypeDetails If ($RecipientTypeDetails -eq "UserMailbox") { Write-Host "$Mailbox is a " -NoNewline; Write-Host "$RecipientTypeDetails" -ForegroundColor Red Write-Host "The script will convert the mailbox to Shared Mailbox" Read-Host "Press Enter to continue or CTRL+C to Cancel" Set-Mailbox $Mailbox -Type Shared -DomainController $DC $Mailbox = Get-Mailbox $Mailbox -DomainController $DC $RecipientTypeDetails1 = $Mailbox.RecipientTypeDetails Write-Host "$Mailbox has been converted to: " -NoNewline; Write-Host "$RecipientTypeDetails1" -ForegroundColor Green } Else { Write-Host "$Mailbox is a " -NoNewline; Write-Host "$RecipientTypeDetails" -ForegroundColor Red Write-Host "The script will not apply any change" -ForegroundColor Yellow } } Function Fix-EXOMissingOnMicrosoft { param ( [Parameter(Mandatory = $true, Position = 1)] [string]$UPN, [Parameter(Mandatory = $true, Position = 2)] [string]$TenantName ) $Mailbox = Get-Mailbox $UPN -DomainController $DC Write-host "Proxy Email Addresses are (Before): " $EmailAddresses = $Mailbox | select -ExpandProperty EmailAddresses $EmailAddresses | ft | Out-String | Write-Host -ForegroundColor Green $Alias = $Mailbox.Alias $OnMicrosoftAddress = $Alias + '@' + $TenantName + '.mail.onmicrosoft.com' Write-host "will try to add the following Address: $OnMicrosoftAddress" Read-host "Pause before change" Set-Mailbox $UPN -EmailAddresses @{ add = $OnMicrosoftAddress } -DomainController $DC Write-Host "Update User Mailbox $UPN with $OnMicrosoftAddress" $Mailbox1 = Get-Mailbox $UPN -DomainController $DC Write-host "Proxy Email Addresses are (After): " $EmailAddresses1 = $Mailbox1 | select -ExpandProperty EmailAddresses $EmailAddresses1 | ft | Out-String | Write-Host -ForegroundColor Yellow } Function Enable-EXOMaibloxOOFMessage { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$EmailAddress, [Parameter(Mandatory = $true, Position = 2)] [String]$Message ) # message Should be in HTML with single quote Get-MailboxAutoReplyConfiguration $EmailAddress | fl MailboxOwnerID, AutoReplyState, ExternalMessage, InternalMessage Set-MailboxAutoReplyConfiguration -Identity $EmailAddress -AutoReplyState Enabled -InternalMessage $Message -ExternalMessage $Message Get-MailboxAutoReplyConfiguration $EmailAddress | fl MailboxOwnerID, AutoReplyState, ExternalMessage, InternalMessage } Function Get-EXORecipientStatistics { param ( [Parameter(Mandatory = $true, Position = 1)] [string]$Name ) $Recipient = Get-Recipient $Name $PrimarySmtpAddress = $Recipient.PrimarySmtpAddress Write-host "Primary SMTP address is:$PrimarySmtpAddress" Get-MailboxStatistics $PrimarySmtpAddress | ft DisplayName, ItemCount, TotalItemSize } Function Check-EXOLastMailboxAccess { param ( [Parameter(Mandatory = $true, Position = 1)] [string]$Identity ) Get-MailboxPermission $Identity | where { ($_.User -notlike "*PRD*") -and ($_.User -notlike "NT*") } | ft User, AccessRights Get-MailboxStatistics $Identity | fl LastInteractionTime, LastLogonTime, LastUserActionTime } Function Add-EXOTransportRuleSubjectOrBodyContainsWords { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$Identity, [Parameter(Mandatory = $true, Position = 2)] [String]$CSVFile ) Read-Host "Expected CSV Column:Name" $AddSpecificWordOrPhrases = Import-CSV $CSVFile $AddSpecificWordOrPhrasesCount = ($AddSpecificWordOrPhrases | Measure).count $TransportRule = Get-TransportRule $Identity $SubjectOrBodyContainsWords = $Null $SubjectOrBodyContainsWords = @() $SubjectOrBodyContainsWords = $TransportRule.SubjectOrBodyContainsWords [int]$i = 1 Foreach ($AddSpecificWordOrPhrase in $AddSpecificWordOrPhrases) { $Name = $Null $Name = $AddSpecificWordOrPhrase.Name Write-Host "The script will add the following SubjectOrBodyContainsWords: $Name - $i / $AddSpecificWordOrPhrasesCount" $SubjectOrBodyContainsWords += $Name $i++ } Set-TransportRule $Identity -SubjectOrBodyContainsWords $SubjectOrBodyContainsWords } Function Add-EXOTransportRuleSubjectContainsWords { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$Identity, [Parameter(Mandatory = $true, Position = 2)] [String]$CSVFile ) Read-Host "Expected CSV Column: Name" $AddSpecificWordOrPhrases = Import-CSV $CSVFile $AddSpecificWordOrPhrasesCount = ($AddSpecificWordOrPhrases | Measure).count $TransportRule = Get-TransportRule $Identity $SubjectContainsWords = $Null $SubjectContainsWords = @() $SubjectContainsWords = $TransportRule.SubjectContainsWords [int]$i = 1 Foreach ($AddSpecificWordOrPhrase in $AddSpecificWordOrPhrases) { $Name = $Null $Name = $AddSpecificWordOrPhrase.Name Write-Host "The script will add the following SubjectOrBodyContainsWords: $Name - $i / $AddSpecificWordOrPhrasesCount" $SubjectContainsWords += $Name $i++ } Set-TransportRule $Identity -SubjectContainsWords $SubjectContainsWords } Function Test-EXOSendO365Mail { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$Sender, [Parameter(Mandatory = $true, Position = 2)] [String]$Recipient ) $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ServerName = [Environment]::MachineName $Subject = "Test Message from :" + $ServerName + " --- " + $DateFull $Body = "Hi,`r`n" $Body += "This is a test Message at $DateFull`r`n" $Body += "Thank you`r`n" $Body += "Regards`r`n" Send-MailMessage -SmtpServer $Office365MXRecord -Subject $Subject -From $Sender -To $Recipient -Body $Body -UseSsl -Port 25 } Function Test-EXOSendMail { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$Sender, [Parameter(Mandatory = $true, Position = 2)] [String]$Recipient, [Parameter(Mandatory = $true, Position = 3)] [String]$SMTPServer, [Parameter(Position = 4)] [switch]$UseSSL ) $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $Subject = "Test Message from :$Sender - To: $Recipient - Server(From): $SMTPServer --- $DateFull" $Body = "Hi,`r`n" $Body += "This is a test Message at $DateFull`r`n" $Body += "Thank you`r`n" $Body += "Regards`r`n" If ($UseSSL) { Send-MailMessage -SmtpServer $SMTPServer -Subject $Subject -From $Sender -To $Recipient -Body $Body -UseSsl -port 25 } else { Send-MailMessage -SmtpServer $SMTPServer -Subject $Subject -From $Sender -To $Recipient -Body $Body -Port 25 } } Function Allow-EXOQuarantineMobileDevices { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$Mailbox ) # Check mobile quarantine status: Get-MobileDevice -Mailbox $Mailbox | ft FriendlyName, DeviceOS, DeviceUserAgent, DeviceAccessState, DeviceId, Identity # Search for quarantine Device $MobileDevice = Get-MobileDevice -Mailbox $Mailbox -Filter { DeviceAccessState -eq 'Quarantined' } # Retreive the list of Allows Devices $CASMailbox = Get-CasMailbox $Mailbox $AllowedDeviceIDs = $CASMailbox.ActiveSyncAllowedDeviceIDs # Allow the device $AllowedDevicesToAdd = $MobileDevice.DeviceId If (!($AllowedDevicesToAdd)) { $AllowedDeviceIDs } Else { $AllowedDeviceIDs += $AllowedDevicesToAdd } Set-CASMailbox -Identity $Mailbox -ActiveSyncAllowedDeviceIDs $AllowedDeviceIDs # Check mobile quarantine status: Get-MobileDevice -Mailbox $Mailbox | ft FriendlyName, DeviceOS, DeviceUserAgent, DeviceAccessState, DeviceId, Identity } Function Allow-EXOQuarantineIphone { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$Mailbox ) # Check mobile quarantine status: Get-MobileDevice -Mailbox $Mailbox | ft FriendlyName, DeviceOS, DeviceUserAgent, DeviceAccessState, DeviceId, Identity # Search for quarantine Device $MobileDevice = Get-MobileDevice -Mailbox $Mailbox -Filter "DeviceType -eq 'iPhone' -and DeviceAccessState -eq 'Quarantined'" # Retreive the list of Allows Devices $CASMailbox = Get-CasMailbox $Mailbox $AllowedDeviceIDs = $CASMailbox.ActiveSyncAllowedDeviceIDs # Allow the device $AllowedDevicesToAdd = $MobileDevice.DeviceId If (!($AllowedDevicesToAdd)) { $AllowedDeviceIDs } Else { $AllowedDeviceIDs += $AllowedDevicesToAdd } Set-CASMailbox -Identity $Mailbox -ActiveSyncAllowedDeviceIDs $AllowedDeviceIDs # Check mobile quarantine status: Get-MobileDevice -Mailbox $Mailbox | ft FriendlyName, DeviceOS, DeviceUserAgent, DeviceAccessState, DeviceId, Identity } Function Show-EXOQuarantineIphones { [CmdletBinding()] param () Get-MobileDevice -Filter "DeviceType -eq 'iPhone' -and DeviceAccessState -eq 'Quarantined'" | ft FriendlyName, DeviceOS, DeviceUserAgent, DeviceAccessState, DeviceId, Identity } Function Show-EXOQuarantineDevices { [CmdletBinding()] param () Get-MobileDevice -Filter "DeviceAccessState -eq 'Quarantined'" | ft FriendlyName, DeviceOS, DeviceUserAgent, DeviceAccessState, DeviceId, Identity } Function Block-EXOMobileDevice { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$Mailbox ) # Check mobiles Device for $Mailbox $MobilesDevices = $Null $MobilesDevices = @() $MobilesDevices = Get-MobileDevice -Mailbox $Mailbox | Select FriendlyName, DeviceOS, DeviceUserAgent, DeviceAccessState, DeviceId, Identity $MobilesDevices | ft [Int]$Number = Read-Host "Select the device you want to block, using 1 for first line and 2 for second line and so on" Try { [int]$i = $Number - 1 $MobileDeviceIdentity = $null $MobileDeviceIdentity = $MobilesDevices.Identity[$i] $MobileDeviceUserAgent = $null $MobileDeviceUserAgent = $MobilesDevices.DeviceUserAgent[$i] Write-Host "[$(Get-Date -Format "yyyy-MM-dd HH:mm:ss")]" -nonewline; Write-host " WARNING: " -ForegroundColor Yellow -NoNewline; Write-Host "Blocking the Device with the following Identity:" -NoNewline; Write-Host "$MobileDeviceUserAgent - $MobileDeviceIdentity" -ForegroundColor Yellow Read-Host "Press Enter to continue" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line Write-Host "The script failed to block the mobile device with Identity $MobileDeviceIdentity" Write-Host "Failed to run the following CMDLet: $CMDLet" Write-host "Failed with Error:$ErrorMessage" Exit } # Retreive the list of Allows Devices $CASMailbox = Get-CasMailbox $Mailbox $BlockedDeviceIDs = $Null $BlockedDeviceIDs = @() $BlockedDeviceIDs = $CASMailbox.ActiveSyncBlockedDeviceIDs $BlockedDeviceIDs | ft # Allow the device If (!($MobileDeviceIdentity)) { $BlockedDeviceIDs } Else { $BlockedDeviceIDs += $MobileDeviceIdentity } $BlockedDeviceIDs | ft Set-CASMailbox -Identity $Mailbox -ActiveSyncBlockedDeviceIDs $BlockedDeviceIDs # Check mobile quarantine status: Get-MobileDevice -Mailbox $Mailbox | ft FriendlyName, DeviceOS, DeviceUserAgent, DeviceAccessState, DeviceId, Identity } Function Clear-EXOCASMobileDevicesList { param ( [Parameter(Mandatory = $true, Position = 1)] [String]$Mailbox, [Parameter(Mandatory = $False, Position = 2)] [Switch]$Allowed, [Parameter(Mandatory = $False, Position = 3)] [Switch]$Blocked ) If ($Allowed) { Set-CASMailbox $Mailbox -ActiveSyncAllowedDeviceIDs $Null Write-Host "The ActiveSyncAllowedDeviceID list was cleared" } If ($Blocked) { Set-CASMailbox $Mailbox -ActiveSyncBlockedDeviceIDs $Null Write-Host "The ActiveSyncBlockedDeviceID list was cleared" } } Function Check-EXOMobileDevices { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$Mailbox ) Get-MobileDevice -Mailbox $Mailbox | ft FriendlyName, DeviceOS, DeviceUserAgent, DeviceAccessState, DeviceId, Identity } Function Check-EXOMobileDeviceByState { [CmdletBinding()] param ( [switch]$Quarantined, [switch]$Allowed, [switch]$Blocked ) If ($Quarantined) { Get-MobileDevice -Filter { DeviceAccessState -eq "quarantined" } | ft UserDisplayName, Deviceid, DeviceOS, DeviceType, DeviceModel, FriendlyName, DeviceAccessState, DeviceAccessStateReason } If ($Allowed) { Get-MobileDevice -Filter { DeviceAccessState -eq "Allowed" } | ft UserDisplayName, Deviceid, DeviceOS, DeviceType, DeviceModel, FriendlyName, DeviceAccessState, DeviceAccessStateReason } If ($Blocked) { Get-MobileDevice -Filter { DeviceAccessState -eq "Blocked" } | ft UserDisplayName, Deviceid, DeviceOS, DeviceType, DeviceModel, FriendlyName, DeviceAccessState, DeviceAccessStateReason } } Function Release-EXOMyQuarantineMessageDomain { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$Domain ) $DomainFilter = "*@" + $Domain $QuarantineMessagesFound = Get-QuarantineMessage | ? { $_.Senderaddress -like $DomainFilter } Write-Host "Script Found the following messages in quarantine with the following domain :$Domain" $QuarantineMessagesFound | ft SenderAddress, RecipientAddress, Subject, ReceivedTime, Direction, Type, PolicyName, ReleaseStatus, RecipientCount, Expires Read-Host 'Please Press <Enter> to release all messages or <CTRL+C to Cancel>' $QuarantineMessagesFound | Release-QuarantineMessage -ReleaseToAll } Function Generate-EXOSafeLinkReport { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$UrlOrDomain ) $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $StartDate = (Get-Date).AddDays(-7) $EndDate = Get-Date $ReportURLTrace = Get-UrlTrace -UrlOrDomain $UrlOrDomain -StartDate $StartDate -EndDate $EndDate $Location = (Get-Location).path $ReportCSVFile = $Location + "\Report_URLTrace_" + $DateFull + ".csv" $ReportURLTrace | Export-Csv $ReportCSVFile -NoTypeInformation -Encoding UTF8 Write-Host "The Script has Generate the following Report:" -NoNewline; Write-Host "$ReportCSVFile" -ForegroundColor Green } Function Generate-EXOAllSafeLinkReport { $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $StartDate = (Get-Date).AddDays(-7) $EndDate = Get-Date $ReportURLTrace = Get-UrlTrace -StartDate $StartDate -EndDate $EndDate $Location = (Get-Location).path $ReportCSVFile = $Location + "\Report_AllURLTrace_" + $DateFull + ".csv" $ReportURLTrace | Export-Csv $ReportCSVFile -NoTypeInformation -Encoding UTF8 Write-Host "The Script has Generate the following Report:" -NoNewline; Write-Host "$ReportCSVFile" -ForegroundColor Green } Function Search-EXOMessageBySubject { param ( [Parameter(Mandatory = $true, Position = 1)] [String]$Subject ) # $Subject = "RE: Reporte de Reprocesos de Teñido Mayan Agosto Semana 3" $Now = (Get-Date) $Yesterday = (Get-Date).AddDays(-1) $MessagesFound = $Null $MessagesFound = @() [Int]$i = 1 [Int]$MessageCount = 1 Do { $AllMessages = Get-MessageTrace -EndDate $Now -StartDate $Yesterday -PageSize 5000 -Page $i $MessageCount = ($AllMessages | Measure).count $MessagesFound += $AllMessages | where { $_.Subject -eq $Subject } $i++ } While ($MessageCount -ne 0) $MessagesFound | Out-GridView } Function Display-EXORecoverableItems { param ( [Parameter(Mandatory = $true, Position = 1)] [string]$Mailbox ) $RecoverableItems = $Null $RecoverableItems = Get-RecoverableItems -Identity $Mailbox -Resultsize unlimited | select LastParentPath, ItemClass, Subject, SourceFolder, LastModifiedTime Write-Host "using Get-RecoverableItems CMDLet: " -ForegroundColor Yellow $RecoverableItems | Group SourceFolder | ft Count, name Write-Host "Using Mailbox Statistics CMDLet:" -ForegroundColor Yellow $RecoverableItemsMailboxStatistics = $Null $RecoverableItemsMailboxStatistics = Get-MailboxFolderStatistics -Identity $Mailbox -FolderScope recoverableItems | Select Identity, ItemsInFolderAndSubfolders, FolderAndSubfolderSize $RecoverableItemsMailboxStatistics | Ft } Function Find-EXODeletedItems { param ( [Parameter(Mandatory = $true, Position = 1)] [string]$Mailbox ) $RecoverableItems = $Null $RecoverableItems = Get-RecoverableItems -Identity $Mailbox | select LastParentPath, ItemClass, Subject, SourceFolder, LastModifiedTime $RecoverableItems | Group SourceFolder | ft Count, name $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $Location = (Get-Location).path $CSVFile = $Location + "\Report_" + $Mailbox + "_" + $DateFull + ".csv" $RecoverableItems | Export-Csv $CSVFile -NoTypeInformation -Encoding UTF8 Write-Host "The Script has Generate the following Report:" -NoNewline; Write-Host "$CSVFile" -ForegroundColor Green } Function Find-EXODeletedItemsTime { param ( [Parameter(Mandatory = $true, Position = 1)] [string]$Mailbox, [Parameter(Mandatory = $true, Position = 2)] [string]$StartTime, [Parameter(Mandatory = $true, Position = 3)] [string]$EndTime ) $RecoverableItems = $Null $RecoverableItems = Get-RecoverableItems -Identity $Mailbox -FilterStartTime $StartTime -FilterEndTime $EndTime $RecoverableItems | ft LastParentPath, ItemClass, Subject, SourceFolder, LastModifiedTime $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $Location = (Get-Location).path $CSVFile = $Location + "\Report_" + $Mailbox + "_" + $DateFull + ".csv" $RecoverableItems | Export-Csv $CSVFile -NoTypeInformation -Encoding UTF8 Write-Host "The Script has Generate the following Report:" -NoNewline; Write-Host "$CSVFile" -ForegroundColor Green } Function Recover-EXORecoverableItems { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$PrimarySMTPAddress, [Parameter(Mandatory = $true, Position = 2)] [String]$AdminUserName ) Connect-EXO -AlternateID $AdminUserName $Items = $Null $Items = Get-RecoverableItems $PrimarySMTPAddress -ResultSize 500 -SourceFolder PurgedItems $ItemsCount = $Null $ItemsCount = ($Items | measure).count Write-Host "The script found for $PrimarySMTPAddress : $itemsCount Items to recover from Purges Folders" -ForegroundColor Red while ($ItemsCount -ge 1) { Write-Host "The function found: $ItemsCount for $PrimarySMTPAddress" $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $LocalPart = $PrimarySMTPAddress.Substring(0, $PrimarySMTPAddress.LastIndexOf("@")) if (!$LocalPart) { $LocalPart = $PrimarySMTPAddress } $500PurgedItems_XMLFile = $LocalPart + "_500_PurgedItems_" + $DateFull + ".xml" $Items | Export-Clixml $500PurgedItems_XMLFile $Items | -RecoverableItems $Items = $Null Connect-EXO -AlternateID $AdminUserName $Items = Get-RecoverableItems $PrimarySMTPAddress -ResultSize 500 -SourceFolder PurgedItems $ItemsCount = $Null $ItemsCount = ($Items | measure).count } } Function Restore-EXOInactiveMailbox { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$InactiveMailboxPrimaryAddress, [Parameter(Mandatory = $true, Position = 2)] [String]$TargetMailbox, [Parameter(Position = 3)] [String]$TargetRootFolderName ) Try { #Retreive Active mailbox Data $ActiveMailbox = Get-Mailbox -Identity $TargetMailbox $ActiveMailboxExchangeGUID = $ActiveMailbox.ExchangeGuid $ActiveMailboxGUID = $ActiveMailbox.Guid $ActiveMailboxDistinguishedName = $ActiveMailbox.DistinguishedName #Retreive Inactive mailbox Data $InactiveMailbox = Get-Mailbox -InactiveMailboxOnly -Identity $InactiveMailboxPrimaryAddress $Identity = $InactiveMailbox.Identity $PrimarySMTPAddress = $InactiveMailbox.PrimarySMTPAddress $ExchangeGuid = $InactiveMailbox.ExchangeGuid $Guid = $InactiveMailbox.Guid $DistinguishedName = $InactiveMailbox.DistinguishedName $LegacyExchangeDN = $InactiveMailbox.LegacyExchangeDN $AccountDisabled = $InactiveMailbox.AccountDisabled $WhenSoftDeleted = $InactiveMailbox.WhenSoftDeleted $WhenMailboxCreated = $InactiveMailbox.WhenMailboxCreated $LitigationHoldDate = $InactiveMailbox.LitigationHoldDate Write-Log -Level Warning -Message "The inactive mailbox was found" Write-Log -Level INFO -Message "--- Identity: $Identity" Write-Log -Level INFO -Message "--- PrimarySMTPAddress: $PrimarySMTPAddress" Write-Log -Level INFO -Message "--- Guid: $ExchangeGuid" Write-Log -Level INFO -Message "--- Guid: $Guid" Write-Log -Level INFO -Message "--- DistinguishedName: $DistinguishedName" Write-Log -Level INFO -Message "--- LegacyExchangeDN: $LegacyExchangeDN" Write-Log -Level INFO -Message "--- AccountDisabled: $AccountDisabled" Write-Log -Level INFO -Message "--- WhenSoftDeleted: $WhenSoftDeleted" Write-Log -Level INFO -Message "--- WhenMailboxCreated: $WhenMailboxCreated" Write-Log -Level INFO -Message "--- LitigationHoldDate: $LitigationHoldDate" # Set-Mailbox $ActiveMailboxDistinguishedName -EmailAddresses @{Add="X500:$LegacyExchangeDN"} } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to retreive inactive mailbox:$InactiveMailboxPrimaryAddress" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" Exit } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" If ($DistinguishedName) { $SourceMailbox = $DistinguishedName } Else { $SourceMailbox = $Guid } If ($ActiveMailboxDistinguishedName) { $LocalPart = $TargetMailbox.Substring(0, $TargetMailbox.LastIndexOf("@")) If ($TargetRootFolderName) { #Restore the inactive mailbox content to TargetFolder $MailboxRestoreRequestName = "Restore Inactive Mailbox - " + $LocalPart + "_" + $DateFull Read-Host "Are sure you want to restore the content of inactive mailbox $InactiveMailboxPrimaryAddress into $TargetMailbox (Folder: $TargetRootFolderName)? Press <Enter> to contine or <CTRL+C> to Cancel" $New_MailboxRestoreRequest = New-MailboxRestoreRequest -SourceMailbox $SourceMailbox -TargetMailbox $ActiveMailboxDistinguishedName -TargetRootFolder $TargetRootFolderName -AllowLegacyDNMismatch -Name $MailboxRestoreRequestName $RequestGuid = $New_MailboxRestoreRequest.RequestGuid } Else { #Restore inactive mailbox to existing mailbox $MailboxRestoreRequestName = "Merge Inactive Mailbox - " + $LocalPart + "_" + $DateFull Read-Host "Are sure you want to restore (Merge) the content of inactive mailbox $InactiveMailboxPrimaryAddress into $TargetMailbox? Press <Enter> to contine or <CTRL+C> to Cancel" $New_MailboxRestoreRequest = New-MailboxRestoreRequest -SourceMailbox $SourceMailbox -TargetMailbox $ActiveMailboxDistinguishedName -AllowLegacyDNMismatch -Name $MailboxRestoreRequestName $RequestGuid = $New_MailboxRestoreRequest.RequestGuid } sleep 10 Get-MailboxRestoreRequest -Name $MailboxRestoreRequestName Write-Log -Level Warning -Message "Please find the Command to check the status: Get-MailboxRestoreRequest -Name $MailboxRestoreRequestName" Write-Log -Level Warning -Message "Please find the Command to check the status: Get-MailboxRestoreRequestStatistics -identity $RequestGuid | fl Name,StatusDetail,PercentComplete,BytesTransferred,SyncedItemCount,EstimatedTransferSize" } Else { Write-Log -Level Error -Message "Failed to retreive Active mailbox ($TargetMailbox) GUID" } } Function Restore-EXOInactiveOnlineArchiveMailbox { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$InactiveMailboxPrimaryAddress, [Parameter(Mandatory = $true, Position = 2)] [String]$TargetMailbox, [Parameter(Mandatory = $true, Position = 3)] [String]$TargetRootFolderName ) Try { #Retreive Active mailbox Data $ActiveMailbox = Get-Mailbox -Identity $TargetMailbox $ActiveMailboxExchangeGUID = $ActiveMailbox.ExchangeGuid $ActiveMailboxGUID = $ActiveMailbox.Guid $ActiveMailboxDistinguishedName = $ActiveMailbox.DistinguishedName #Retreive Inactive mailbox Data $InactiveMailbox = Get-Mailbox -InactiveMailboxOnly -Identity $InactiveMailboxPrimaryAddress $Identity = $InactiveMailbox.Identity $PrimarySMTPAddress = $InactiveMailbox.PrimarySMTPAddress $ExchangeGuid = $InactiveMailbox.ExchangeGuid $Guid = $InactiveMailbox.Guid $DistinguishedName = $InactiveMailbox.DistinguishedName $LegacyExchangeDN = $InactiveMailbox.LegacyExchangeDN $AccountDisabled = $InactiveMailbox.AccountDisabled $WhenSoftDeleted = $InactiveMailbox.WhenSoftDeleted $WhenMailboxCreated = $InactiveMailbox.WhenMailboxCreated $LitigationHoldDate = $InactiveMailbox.LitigationHoldDate Write-Log -Level Warning -Message "The inactive mailbox was found" Write-Log -Level INFO -Message "--- Identity: $Identity" Write-Log -Level INFO -Message "--- PrimarySMTPAddress: $PrimarySMTPAddress" Write-Log -Level INFO -Message "--- Guid: $ExchangeGuid" Write-Log -Level INFO -Message "--- Guid: $Guid" Write-Log -Level INFO -Message "--- DistinguishedName: $DistinguishedName" Write-Log -Level INFO -Message "--- LegacyExchangeDN: $LegacyExchangeDN" Write-Log -Level INFO -Message "--- AccountDisabled: $AccountDisabled" Write-Log -Level INFO -Message "--- WhenSoftDeleted: $WhenSoftDeleted" Write-Log -Level INFO -Message "--- WhenMailboxCreated: $WhenMailboxCreated" Write-Log -Level INFO -Message "--- LitigationHoldDate: $LitigationHoldDate" # Set-Mailbox $ActiveMailboxDistinguishedName -EmailAddresses @{Add="X500:$LegacyExchangeDN"} } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to retreive inactive mailbox:$InactiveMailboxPrimaryAddress" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" Exit } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" If ($DistinguishedName) { $SourceMailbox = $DistinguishedName } Else { $SourceMailbox = $Guid } If ($ActiveMailboxDistinguishedName) { $LocalPart = $TargetMailbox.Substring(0, $TargetMailbox.LastIndexOf("@")) #Restore the inactive mailbox content to TargetFolder $MailboxRestoreRequestName = "Restore Inactive Online Archive Mailbox - " + $LocalPart + "_" + $DateFull Read-Host "Are sure you want to restore the content of inactive mailbox $InactiveMailboxPrimaryAddress into $TargetMailbox (Folder: $TargetRootFolderName)? Press <Enter> to contine or <CTRL+C> to Cancel" $New_MailboxRestoreRequest = New-MailboxRestoreRequest -SourceMailbox $SourceMailbox -TargetMailbox $ActiveMailboxDistinguishedName -TargetRootFolder $TargetRootFolderName -AllowLegacyDNMismatch -Name $MailboxRestoreRequestName -SourceIsArchive -TargetIsArchive $RequestGuid = $New_MailboxRestoreRequest.RequestGuid sleep 10 Get-MailboxRestoreRequest -Name $MailboxRestoreRequestName Write-Log -Level Warning -Message "Please find the Command to check the status: Get-MailboxRestoreRequest -Name $MailboxRestoreRequestName" Write-Log -Level Warning -Message "Please find the Command to check the status: Get-MailboxRestoreRequestStatistics -identity $RequestGuid | fl Name,StatusDetail,PercentComplete,BytesTransferred,SyncedItemCount,EstimatedTransferSize" } Else { Write-Log -Level Error -Message "Failed to retreive Active mailbox ($TargetMailbox) GUID" } } Function Restore-EXOSoftDeletedMailbox { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$SoftDeletedMailboxPrimaryAddress, [Parameter(Mandatory = $true, Position = 2)] [String]$TargetMailbox, [Parameter(Position = 3)] [String]$TargetRootFolderName ) Try { #Retreive Active mailbox Data $ActiveMailbox = Get-Mailbox -Identity $TargetMailbox $ActiveMailboxExchangeGUID = $ActiveMailbox.ExchangeGuid $ActiveMailboxGUID = $ActiveMailbox.Guid $ActiveMailboxDistinguishedName = $ActiveMailbox.DistinguishedName #Retreive Inactive mailbox Data $SoftDeletedMailbox = Get-Mailbox -SoftDeletedMailbox -Identity $SoftDeletedMailboxPrimaryAddress $Identity = $SoftDeletedMailbox.Identity $PrimarySMTPAddress = $SoftDeletedMailbox.PrimarySMTPAddress $ExchangeGuid = $SoftDeletedMailbox.ExchangeGuid $Guid = $SoftDeletedMailbox.Guid $DistinguishedName = $SoftDeletedMailbox.DistinguishedName $AccountDisabled = $SoftDeletedMailbox.AccountDisabled $WhenSoftDeleted = $SoftDeletedMailbox.WhenSoftDeleted $WhenMailboxCreated = $SoftDeletedMailbox.WhenMailboxCreated $LitigationHoldDate = $SoftDeletedMailbox.LitigationHoldDate Write-Log -Level Warning -Message "The inactive mailbox was found" Write-Log -Level INFO -Message "--- Identity: $Identity" Write-Log -Level INFO -Message "--- PrimarySMTPAddress: $PrimarySMTPAddress" Write-Log -Level INFO -Message "--- Guid: $ExchangeGuid" Write-Log -Level INFO -Message "--- Guid: $Guid" Write-Log -Level INFO -Message "--- DistinguishedName: $DistinguishedName" Write-Log -Level INFO -Message "--- AccountDisabled: $AccountDisabled" Write-Log -Level INFO -Message "--- WhenSoftDeleted: $WhenSoftDeleted" Write-Log -Level INFO -Message "--- WhenMailboxCreated: $WhenMailboxCreated" Write-Log -Level INFO -Message "--- LitigationHoldDate: $LitigationHoldDate" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to retreive inactive mailbox:$SoftDeletedMailboxPrimaryAddress" Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" Exit } If ($DistinguishedName) { $SourceMailbox = $DistinguishedName } Else { $SourceMailbox = $Guid } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" If ($ActiveMailboxDistinguishedName) { $LocalPart = $SoftDeletedMailboxPrimaryAddress.Substring(0, $SoftDeletedMailboxPrimaryAddress.LastIndexOf("@")) If ($TargetRootFolderName) { #Restore the inactive mailbox content to TargetFolder $MailboxRestoreRequestName = "Restore Soft Deleted Mailbox - " + $LocalPart + "_" + $DateFull Read-Host "Are sure you want to restore the content of Soft Deleted mailbox $SoftDeletedMailboxPrimaryAddress into $TargetMailbox (Folder: $TargetRootFolderName)? Press <Enter> to contine or <CTRL+C> to Cancel" New-MailboxRestoreRequest -SourceMailbox $SourceMailbox -TargetMailbox $ActiveMailboxDistinguishedName -TargetRootFolder $TargetRootFolderName -AllowLegacyDNMismatch -Name $MailboxRestoreRequestName } Else { #Restore inactive mailbox to existing mailbox $MailboxRestoreRequestName = "Merge Soft Deleted Mailbox - " + $LocalPart + "_" + $DateFull Read-Host "Are sure you want to restore (Merge) the content of Soft Deleted mailbox $SoftDeletedMailboxPrimaryAddress into $TargetMailbox? Press <Enter> to contine or <CTRL+C> to Cancel" New-MailboxRestoreRequest -SourceMailbox $SourceMailbox -TargetMailbox $ActiveMailboxDistinguishedName -AllowLegacyDNMismatch -Name $MailboxRestoreRequestName } sleep 10 Get-MailboxRestoreRequest -Name $MailboxRestoreRequestName } Else { Write-Log -Level Error -Message "Failed to retreive Active mailbox ($TargetMailbox) GUID" } } Function Recover-EXOInactiveMailbox { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$EmailAddress ) # Retreive User Information $InactiveMailbox = Get-Mailbox $EmailAddress -IncludeInactiveMailbox | sort -Descending WhenSoftDeleted | Select -first 1 $OnMicrosoft = $InactiveMailbox.EmailAddresses | where { ($_ -like "*.onmicrosoft.com") -and ($_ -notlike "*mail.onmicrosoft.com") } | select -First 1 Write-Log -Level Warning -Message "The script found the following onMicrosoft: $OnMicrosoft" $MicrosoftOnlineServicesID = $OnMicrosoft.Substring(5) Read-Host "Are you sure you want to recovery the Inactive mailbox with the following $MicrosoftOnlineServicesID - Press Enter to Continue or Ctrl+C to Cancel" New-Mailbox -InactiveMailbox $InactiveMailbox.DistinguishedName -Name $InactiveMailbox.Name -DisplayName $InactiveMailbox.DisplayName -MicrosoftOnlineServicesID $MicrosoftOnlineServicesID -Password (ConvertTo-SecureString -String '!!P@ssw0rd##' -AsPlainText -Force) -ResetPasswordOnNextLogon $true sleep 5 Write-Log -Level Warning -Message "The script recover the mailbox to $MicrosoftOnlineServicesID" sleep 5 Write-Log -Level INFO -Message "waiting for the Mailbox creation to complete" sleep 5 Write-Log -Level Warning -Message "The script is search for $MicrosoftOnlineServicesID" Get-mailbox $MicrosoftOnlineServicesID Write-Log -Level Warning -Message "Assign location + License" } Function Add-EXOX500EmailAddress { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$EmailAddress ) # Display Current Email Addresses of the mailbox $Mailbox = $Null $Mailbox = Get-Mailbox $EmailAddress $EmailAddresses = $Null $EmailAddresses = $Mailbox.emailaddresses $DisplayName = $Null $DisplayName = $Mailbox.DisplayName $LegacyExchangeDN = $Null $LegacyExchangeDN = $Mailbox.LegacyExchangeDN $X500 = 'X500:' + $LegacyExchangeDN Write-Log -Level INFO -message "The mailbox ($DisplayName) Email Addresses are:" $EmailAddresses | ft Write-Log -Level INFO -message "The mailbox ($DisplayName) LegacyExchangeDN is: $LegacyExchangeDN" Write-Log -Level INFO -message "The mailbox ($DisplayName) Calculated X500 is: $X500" # Add the X500 Email address Read-Host "Pause" Set-Mailbox -Identity $EmailAddress -EmailAddresses @{ Add = $X500 } # Review $Mailbox2 = Get-Mailbox $EmailAddress $EmailAddresses2 = $Null $EmailAddresses2 = $Mailbox2.emailaddresses Write-Log -Level INFO -message "The mailbox ($DisplayName) Email Addresses (After adding X500) are:" $EmailAddresses2 | ft } Function Check-EXOPhishingComplianceSearchActionToday { $DateFilter = Get-Date -Format "ddMMyyyy" $Filter = "*_PhishingMessage_Investigation_" + $DateFilter + "*" Get-ComplianceSearchAction | Where { $_.Name -like $Filter } | sort Name | ft } Function Check-EXOPhishingComplianceSearchActionDate { param ( [Parameter(Mandatory = $true, Position = 1)] [datetime]$Date ) $DateFilter = Get-Date $Date -Format "ddMMyyyy" $Filter = "*_PhishingMessage_Investigation_" + $DateFilter + "*" Get-ComplianceSearchAction | Where { $_.Name -like $Filter } | sort Name | ft } Function Check-EXOPhishingComplianceSearchToday { $DateFilter = Get-Date -Format "ddMMyyyy" $Filter = "*_PhishingMessage_Investigation_" + $DateFilter + "*" Get-ComplianceSearch | Where { $_.Name -like $Filter } | sort Name | ft } Function Check-EXOPhishingComplianceSearchDate { param ( [Parameter(Mandatory = $true, Position = 1)] [datetime]$Date ) $DateFilter = Get-Date $Date -Format "ddMMyyyy" $Filter = "*_PhishingMessage_Investigation_" + $DateFilter + "*" Get-ComplianceSearch | Where { $_.Name -like $Filter } | sort Name | ft } Function Check-EXOPhishingContentSearch { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$ContentSearchName ) Get-ComplianceSearch -Identity $ContentSearchName | ft Name, Runby, JobEndTime, Status, Items Try { # Search for Compliance Search Action Purge $ComplianceSearchActionName = $ContentSearchName + "_Purge" $ComplianceAction = Get-ComplianceSearchAction $ComplianceSearchActionName -ErrorAction Stop | fl Name, SearchName, Action, Status, ExchangeLocation, RunBy, CreateBy } Catch [System.Management.Automation.RemoteException] { Write-Log -Level Warning -message "No compliance Search action was created to purge" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -Message "Failed to Check Status of Compliance Search " Write-Log -Level Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -Message "Failed with Error:$ErrorMessage" } } Function New-EXOPhishingContentSearch { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$Sender, [Parameter(Position = 2)] [String]$Subject ) $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $Name = $Sender + "_PhishingMessage_Investigation_" + $DateFull If ($Subject) { $ContentMatchQuery = "(from:" + $Sender + ") and (Subject:" + $Subject + ")" New-ComplianceSearch -Name $Name -ExchangeLocation All -ContentMatchQuery $ContentMatchQuery } Else { $ContentMatchQuery = "(from:" + $Sender + ")" New-ComplianceSearch -Name $Name -ExchangeLocation All -ContentMatchQuery $ContentMatchQuery } Sleep 10 Start-ComplianceSearch -Identity $Name Sleep 10 Get-ComplianceSearch -Identity $Name | ft Name, RunBy, Status, ContentMatchQuery } Function Purge-EXOPhishingContentSearch { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$ContentSearchName ) New-ComplianceSearchAction -SearchName $ContentSearchName -Purge -PurgeType HardDelete $ComplianceSearchActionName = $ContentSearchName + "_Purge" Get-ComplianceSearchAction $ComplianceSearchActionName | fl Name, SearchName, Results, Action, Status, ExchangeLocation, RunBy, CreateBy } Function Update-EXOPhishingTransportRule { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$Sender ) #Add Phishing Email Address to Transport Rule: Phishing_Blocked_Senders $TransportRule = Get-TransportRule -identity Phishing_Blocked_Senders_7 $From = $Null $From = $TransportRule.From $From += $Sender Set-TransportRule -identity Phishing_Blocked_Senders_7 -From $From Write-Log -Level Warning -Message "The Transport Rule Phishing_Blocked_Senders: was updated with $Sender" Write-Log -Level warning -Message "The update list is:" Get-TransportRule -identity Phishing_Blocked_Senders_7 | select -ExpandProperty From } Function Check-EXORetentionExclusion { param ( [Parameter(Mandatory = $False, Position = 1)] [String]$InputFile ) Read-Host "Expected CSV Column: UserPrincipalName" $Table = $Null $Table = @() [int]$i = 1 $Date = get-date -UFormat %d%m%Y $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ServerName = [Environment]::MachineName ###### Create Root Folder $Location = $Null $Location = (Get-Location).Path $RootFolder = $Location + "\Check_RetentionExclusion\" ###### Create folder Variable $LogPathFolder = $RootFolder + "\Log\" $LogFile = $LogPathFolder + "Progress_" + $Date + ".log" $ReportPathFolder = $RootFolder + "\Reports\" ###### Create Folder Create-Folder $RootFolder Create-Folder $LogPathFolder Create-Folder $ReportPathFolder ########### Initiate the Process log file when the script started ############ $Initiat_LogA = "#################### starting the Script #####################" $Startat = "### The Script has been launch at $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")" $Startwith = "The Script has been start with the following Account:" + [Environment]::UserName $Starton = "The Script has been start on the following Computer:" + [Environment]::MachineName $Initiat_LogB = "##############################################################" $Initiat_LogB | Out-File -FilePath $LogFile -Append $Initiat_LogB | Out-File -FilePath $LogFile -Append $Initiat_LogA | Out-File -FilePath $LogFile -Append $Startat | Out-File -FilePath $LogFile -Append $Startwith | Out-File -FilePath $LogFile -Append $Starton | Out-File -FilePath $LogFile -Append $Initiat_LogB | Out-File -FilePath $LogFile -Append $Initiat_LogB | Out-File -FilePath $LogFile -Append ########### Main Script ########### Try { $ExceptionMailboxes = Import-Csv $InputFile Write-Host "CSV File Imported $InputFile" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error $LogFile -Message "Failed to Import CSV File : $InputFile" Write-Log -Level Error $LogFile-Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error $LogFile -Message "Failed with Error:$ErrorMessage" Write-Log -Level Error $LogFile -Message "The Script will stop" # Exit the script Exit } $ExceptionMailboxesCount = ($ExceptionMailboxes | Measure).Count forEach ($ExceptionMailbox in $ExceptionMailboxes) { $UPN = $Null $UPN = $ExceptionMailbox.UserPrincipalName $Mailbox = $Null $Recipient = $Null $Recipient = Get-Recipient $UPN $DisplayName = $Null $DisplayName = $Recipient.DisplayName $RecipientType = $Null $RecipientType = $Recipient.RecipientType Write-Log -Level INFO $LogFile -Message "Checking User: $DisplayName - $UPN - $RecipientType" If ($RecipientType -eq "UserMailbox") { Try { $Mailbox = Get-Mailbox $UPN $Retention = $Null $RetentionPolicy = $Mailbox.RetentionPolicy Write-Log -Level Warning $LogFile -Message 'Is Mailbox: $DisplayName - $UPN - $RecipientType' $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; UPN = $UPN; RetentionPolicy = $RetentionPolicy; }) } Catch { Write-Log -Level Error $LogFile -Message "Not a Mailbox" $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; UPN = $UPN; RetentionPolicy = "Not Migrated"; }) } } Else { Write-Log -Level Error $LogFile -Message '$UPN is Not a Mailbox - $RecipientType' $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; UPN = $UPN; RetentionPolicy = "Not Migrated"; }) } $i++ } $ExportCSVFile = $ReportPathFolder + "RetentionExclusion_" + $DateFull + ".csv" $Table | Export-csv $ExportCSVFile -NoTypeInformation -Encoding UTF8 Write-Log -Level Error $LogFile -Message 'the Data has been exported to $ExportCSVFile' } Function Get-EXOBookingMailboxOwner { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$BookingEmailAddress ) $MailboxPermission = Get-MailboxPermission $BookingEmailAddress | where { $_.User -ne "NT AUTHORITY\SELF" } return $MailboxPermission } Function Check-EXOBookingMailboxSettings { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$EmailAddress ) $BookingMailboxSettingsTable = $Null $BookingMailboxSettingsTable = @() $Owners = Get-BookingMailboxOwner $EmailAddress $Owners = $Owners.user -join ";" $Calendar = $Null $Calendar = Get-Mailbox $EmailAddress | Get-MailboxFolderStatistics -FolderScope calendar | select Name $CalendarName = $Null $CalendarName = $Calendar.Name $BookingURL = $Null $BookingURL = "https://outlook.office365.com/owa/" + $CalendarName + "/" + $EmailAddress + "/bookings/" $Response = $Null Try { $Response = Invoke-WebRequest -URI $BookingURL $SuccessfullConnection = "Yes" } Catch { $ErrorMessage = $Error[0].Exception.Message $SuccessfullConnection = $ErrorMessage } $SigninRedirection = $Null If ($Response | where { $_.Content -like '*<title>Sign in to Outlook</title>*' }) { $SigninRedirection = "Yes" } Else { $SigninRedirection = "No" } $BookingMailboxSettingsTable += New-object PSobject -Property ([Ordered] @{ EmailAddress = $EmailAddress; Owners = $Owners; CalendarName = $CalendarName; SigninRedirection = $SigninRedirection; BookingURL = $BookingURL; SuccessfullConnection = $SuccessfullConnection; }) return $BookingMailboxSettingsTable } Function Create-EXOSharedMailboxWithSG { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$LocalPart, [Parameter(Mandatory = $true, Position = 2)] [String]$Domain ) #Variable $SecurityGroupName = "MBX_" + $LocalPart + "_FP" $SecurityGroupEmailAddress = $SecurityGroupName + "@" + $Domain $PrimaryEmailAddress = $LocalPart + "@" + $Domain $CreateSharedMBXStatus = "Failed" $CreateSGStatus = "Failed" $GrantSendAsStatus = "Failed" # Create Security Group Try { Write-Log Info -Message "The script will try to create the Mail-Enabled Security Group $SecurityGroupName ($SecurityGroupEmailAddress)" New-DistributionGroup -Name $SecurityGroupName -Alias $SecurityGroupName -Type security -PrimarySmtpAddress $SecurityGroupEmailAddress Write-Log warning -Message "The script successfully created the Mail-Enabled Security Group $SecurityGroupName ($SecurityGroupEmailAddress)" $CreateSGStatus = "Success" # Create Shared Mailbox Try { Write-Log Info -Message "The script will try to create the Shared Mailbox $LocalPart ($PrimaryEmailAddress)" New-Mailbox -Shared -Name $LocalPart -DisplayName $LocalPart -Alias $LocalPart -PrimarySmtpAddress $PrimaryEmailAddress Write-Log warning -Message "The script successfully created the Shared Mailbox $LocalPart ($PrimaryEmailAddress)" $CreateSharedMBXStatus = "Success" #Assign SendAs Permission to Security Group Try { Write-Log Info -Message "The script will try to grant SendAs Permission $PrimaryEmailAddress to $SecurityGroupEmailAddress" Add-RecipientPermission -Identity $PrimaryEmailAddress -Trustee $SecurityGroupEmailAddress -AccessRights SendAs -confirm:$false Write-Log warning -Message "The script successfully grant SendAs Permission $PrimaryEmailAddress to $SecurityGroupEmailAddress" $GrantSendAsStatus = "Success" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to grant SendAs Permission $PrimaryEmailAddress to $SecurityGroupEmailAddress" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" } #Assign FullAccess Permission to Security Group Try { Write-Log Info -Message "The script will try to grant FullAccess $PrimaryEmailAddress to $SecurityGroupEmailAddress" Add-MailboxPermission -Identity $PrimaryEmailAddress -User $SecurityGroupEmailAddress -AccessRights FullAccess -InheritanceType All Write-Log warning -Message "The script successfully grant FullAccess $PrimaryEmailAddress to $SecurityGroupEmailAddress" $GrantFullAccessStatus = "Success" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to grant FullAccess $PrimaryEmailAddress to $SecurityGroupEmailAddress" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $GrantFullAccessStatus = "Failed" } } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to create the Shared Mailbox $LocalPart ($PrimaryEmailAddress)" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" } } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to create the Mail-Enabled Security Group $SecurityGroupName ($SecurityGroupEmailAddress)" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" } # Output $OutPut = $null $OutPut = @() $OutPut += New-object PSobject -Property ([Ordered] @{ SharedMailboxPrimaryEmailAddress = $PrimaryEmailAddress; SecurityGroupName = $SecurityGroupName; CreateSharedMBXStatus = $CreateSharedMBXStatus; GrantSendAsStatus = $GrantSendAsStatus; GrantFullAccessStatus = $GrantFullAccessStatus; }) Return $OutPut } Function Generate-EXOInactiveMailboxPermissionXML { [CmdletBinding()] param () $InactiveMailboxes = Get-Mailbox -InactiveMailboxOnly -resultsize unlimited $Table = $Null $Table = @() Foreach ($InactiveMailbox in $InactiveMailboxes) { $PrimarySmtpAddress = $Null $PrimarySmtpAddress = $InactiveMailbox.PrimarySmtpAddress $Permissions = $Null $Permissions = @() $Permissions = Get-MailboxPermission -identity $PrimarySmtpAddress -SoftDeletedMailbox $Permissions | Add-Member -NotePropertyName Email -NotePropertyValue $PrimarySmtpAddress $Table += $Permissions } $Table | Out-GridView $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFile = "Report_ExportAllInactiveMailboxesPermission_" + $DateFull + ".xml" $Table | Export-clixml $ReportFile Write-Log Warning -Message "The script generated the following $ReportFile" } Function Replace-EXOSMTPDomain { param ( [Parameter(Mandatory = $true, Position = 1)] [String]$DomainToRemoved, [Parameter(Position = 2)] [string]$ReplaceDomain, [Parameter(Position = 3)] [switch]$Cloud, [Parameter(Position = 4)] [switch]$Onpremise ) If (!$ReplaceDomain) { $ReplaceDomain = (Get-AcceptedDomain | where { ($_.DomainName -like "*.onmicrosoft.com") -and ($_.DomainName -notlike "*.mail.onmicrosoft.com") } | select -First 1).DomainName } If ($Onpremise) { # Backup Try { Write-Log Info -Message "The script will try to backupt all Recipients" $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $AllRecipients = Get-Recipient -ResultSize unlimited -DomainController $DC -ErrorAction Silentlycontinue -ErrorVariable CMDLetFailed $AllRecipientFile = "All_recipients_" + $DateFull + ".xml" $AllRecipients | Export-Clixml $AllRecipientFile $Recipients = $AllRecipients | where { $_.IsDirsynced -eq $False } If ($CMDLetFailed) { $ErrorMessage = $CMDLetFailed.Exception.Message $CMDLet = $CMDLetFailed.InvocationInfo.Line Write-Log Error -Message "Failed to backup all recipients" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $Status = "Failed" $CMDLetFailed.clear() } Else { $Status = "Success" Write-Log Info -Message "The script successfully backup all recipients" } } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to " Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $Status = "Failed" } If ($Status -eq "Failed") { Write-Log Error -Message "Failed to backup all Recipients - The script will stop" Exit } # Processing #Initiate the Hash Table [Int]$i = 1 $Table = $Null $Table = @() $RecipientsToUpdates = $Recipients | where { $_.EmailAddresses -match $DomainToRemoved } $RecipientsToUpdateFile = ".\RecipientsToUpdate_" + $DateFull + ".xml" $RecipientsToUpdates | select Alias, DisplayName, CustomAttribute12, PrimarySMTPAddress, EmailAddresses | Export-Clixml $RecipientsToUpdateFile $Count = ($RecipientsToUpdates | Measure).count foreach ($RecipientsToUpdate in $RecipientsToUpdates) { $RecipientTypeDetails = $Null $RecipientTypeDetails = $RecipientsToUpdate.RecipientTypeDetails $Alias = $Null $Alias = $RecipientsToUpdate.Alias $Identity = $Null $Identity = $RecipientsToUpdate.Identity $DisplayName = $Null $DisplayName = $RecipientsToUpdate.DisplayName $CustomAttribute12 = $Null $CustomAttribute12 = $RecipientsToUpdate.CustomAttribute12 $EmailAddresses = $Null $EmailAddresses = $RecipientsToUpdate.EmailAddresses $PrimarySMTPAddress = $Null $PrimarySMTPAddress = $RecipientsToUpdate.PrimarySMTPAddress $Localpart = $Null $LocalPart = $PrimarySMTPAddress.Substring(0, $PrimarySMTPAddress.LastIndexOf("@")) $NewPrimarySMTPAddress = $Null $NewPrimarySMTPAddress = $LocalPart + "@" + $ReplaceDomain # Search for onMicrosoft email Address $OnMicrosoft = $Null $Onmicrosoft = $Emailaddresses | where { $_ -match ".onmicrosoft.com" } | select -First 1 $Onmicrosoft = $Onmicrosoft.Substring(5) switch ($RecipientTypeDetails) { RemoteUserMailbox { Write-Log warning -Message "The script will analyze the following Remote User Mailbox (Alias:$Alias - Primary : $PrimarySMTPAddress - Onmicrosoft: $Onmicrosoft - RecipientTypeDetails: $RecipientTypeDetails)" $User = $Null $User = Get-User $PrimarySMTPAddress -DomainController $DC $UPN = $Null $UPN = $User.UserPrincipalName if ($UPN -match $DomainToRemoved) { Set-User $PrimarySMTPAddress -UserPrincipalName $NewPrimarySMTPAddress Write-Log info -Message "The script will update the UPN from $UPN to $NewPrimarySMTPAddress" $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; PrimarySMTPAddress = $PrimarySMTPAddress; UPN = $UPN; Onmicrosoft = $Onmicrosoft; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; CustomAttribute12 = $CustomAttribute12; Identity = $Identity; Action = "Upate UPN $PrimarySMTPAddress to $NewPrimarySMTPAddress"; }) } # Update Primary SMTP Addresss If ($PrimarySMTPAddress -match $DomainToRemoved) { Write-Log info -Message "The script will update the PrimarySMTPAddress from $PrimarySMTPAddress to $NewPrimarySMTPAddress" Set-RemoteMailbox -identity $PrimarySMTPAddress -PrimarySmtpAddress $NewPrimarySMTPAddress -DomainController $DC $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; PrimarySMTPAddress = $PrimarySMTPAddress; UPN = $UPN; Onmicrosoft = $Onmicrosoft; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; CustomAttribute12 = $CustomAttribute12; Identity = $Identity; Action = "Upate Primary $PrimarySMTPAddress to $NewPrimarySMTPAddress"; }) } # Search for Email Addresses to remove foreach ($EmailAddress in $EmailAddresses) { $EmailAddressToRemove = $Null $EmailAddressToRemove = $EmailAddress $EmailAddressToRemove = $EmailAddressToRemove.Substring(5) if ($EmailAddress -match $DomainToRemoved) { Write-Log warning -Message "The script will remove the email addresse $EmailAddressToRemove" Set-RemoteMailbox -Identity $NewPrimarySMTPAddress -EmailAddresses @{ Remove = $EmailAddressToRemove } -DomainController $DC Write-Log Info -Message "The script removed the email addresse $EmailAddressToRemove" $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; PrimarySMTPAddress = $PrimarySMTPAddress; UPN = $UPN; Onmicrosoft = $Onmicrosoft; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; CustomAttribute12 = $CustomAttribute12; Identity = $Identity; Action = "Remove $EmailAddressToRemove"; }) } Else { Write-Log Info -Message "The script will NOT remove the email addresse $EmailAddressToRemove" } } $i++ } RemoteSharedMailbox { Write-Log warning -Message "The script will analyze the following Remote Shared Mailbox (Alias:$Alias - Primary : $PrimarySMTPAddress - Onmicrosoft: $Onmicrosoft - RecipientTypeDetails: $RecipientTypeDetails)" $User = $Null $User = Get-User $PrimarySMTPAddress -DomainController $DC $UPN = $Null $UPN = $User.UserPrincipalName if ($UPN -match $DomainToRemoved) { Set-User $PrimarySMTPAddress -UserPrincipalName $NewPrimarySMTPAddress Write-Log info -Message "The script will update the UPN from $UPN to $NewPrimarySMTPAddress" $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; PrimarySMTPAddress = $PrimarySMTPAddress; UPN = $UPN; Onmicrosoft = $Onmicrosoft; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; CustomAttribute12 = $CustomAttribute12; Identity = $Identity; Action = "Upate UPN $PrimarySMTPAddress to $NewPrimarySMTPAddress"; }) } # Update Primary SMTP Addresss If ($PrimarySMTPAddress -match $DomainToRemoved) { Write-Log info -Message "The script will update the PrimarySMTPAddress from $PrimarySMTPAddress to $NewPrimarySMTPAddress" Set-RemoteMailbox -identity $PrimarySMTPAddress -PrimarySmtpAddress $NewPrimarySMTPAddress -DomainController $DC $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; PrimarySMTPAddress = $PrimarySMTPAddress; UPN = $UPN; Onmicrosoft = $Onmicrosoft; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; CustomAttribute12 = $CustomAttribute12; Identity = $Identity; Action = "Upate Primary $PrimarySMTPAddress to $NewPrimarySMTPAddress"; }) } # Search for Email Addresses to remove foreach ($EmailAddress in $EmailAddresses) { $EmailAddressToRemove = $Null $EmailAddressToRemove = $EmailAddress $EmailAddressToRemove = $EmailAddressToRemove.Substring(5) if ($EmailAddress -match $DomainToRemoved) { Write-Log warning -Message "The script will remove the email addresse $EmailAddressToRemove" Set-RemoteMailbox -Identity $NewPrimarySMTPAddress -EmailAddresses @{ Remove = $EmailAddressToRemove } -DomainController $DC Write-Log Info -Message "The script removed the email addresse $EmailAddressToRemove" $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; PrimarySMTPAddress = $PrimarySMTPAddress; UPN = $UPN; Onmicrosoft = $Onmicrosoft; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; CustomAttribute12 = $CustomAttribute12; Identity = $Identity; Action = "Remove $EmailAddressToRemove"; }) } Else { Write-Log Info -Message "The script will NOT remove the email addresse $EmailAddressToRemove" } } $i++ } RemoteRoomMailbox { Write-Log warning -Message "The script will analyze the following Remote Room Mailbox (Alias:$Alias - Primary : $PrimarySMTPAddress - Onmicrosoft: $Onmicrosoft - RecipientTypeDetails: $RecipientTypeDetails)" $User = $Null $User = Get-User $PrimarySMTPAddress -DomainController $DC $UPN = $Null $UPN = $User.UserPrincipalName if ($UPN -match $DomainToRemoved) { Set-User $PrimarySMTPAddress -UserPrincipalName $NewPrimarySMTPAddress Write-Log info -Message "The script will update the UPN from $UPN to $NewPrimarySMTPAddress" $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; PrimarySMTPAddress = $PrimarySMTPAddress; UPN = $UPN; Onmicrosoft = $Onmicrosoft; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; CustomAttribute12 = $CustomAttribute12; Identity = $Identity; Action = "Upate UPN $PrimarySMTPAddress to $NewPrimarySMTPAddress"; }) } # Update Primary SMTP Addresss If ($PrimarySMTPAddress -match $DomainToRemoved) { Write-Log info -Message "The script will update the PrimarySMTPAddress from $PrimarySMTPAddress to $NewPrimarySMTPAddress" Set-RemoteMailbox -identity $PrimarySMTPAddress -PrimarySmtpAddress $NewPrimarySMTPAddress -DomainController $DC $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; PrimarySMTPAddress = $PrimarySMTPAddress; UPN = $UPN; Onmicrosoft = $Onmicrosoft; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; CustomAttribute12 = $CustomAttribute12; Identity = $Identity; Action = "Upate Primary $PrimarySMTPAddress to $NewPrimarySMTPAddress"; }) } # Search for Email Addresses to remove foreach ($EmailAddress in $EmailAddresses) { $EmailAddressToRemove = $Null $EmailAddressToRemove = $EmailAddress $EmailAddressToRemove = $EmailAddressToRemove.Substring(5) if ($EmailAddress -match $DomainToRemoved) { Write-Log warning -Message "The script will remove the email addresse $EmailAddressToRemove" Set-RemoteMailbox -Identity $NewPrimarySMTPAddress -EmailAddresses @{ Remove = $EmailAddressToRemove } -DomainController $DC Write-Log Info -Message "The script removed the email addresse $EmailAddressToRemove" $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; PrimarySMTPAddress = $PrimarySMTPAddress; UPN = $UPN; Onmicrosoft = $Onmicrosoft; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; CustomAttribute12 = $CustomAttribute12; Identity = $Identity; Action = "Remove $EmailAddressToRemove"; }) } Else { Write-Log Info -Message "The script will NOT remove the email addresse $EmailAddressToRemove" } } $i++ } MailUser { Write-Log warning -Message "The script will analyze the following MailUser (Alias:$Alias - Primary : $PrimarySMTPAddress - Onmicrosoft: $Onmicrosoft - RecipientTypeDetails: $RecipientTypeDetails)" $User = $Null $User = Get-User $PrimarySMTPAddress -DomainController $DC $UPN = $Null $UPN = $User.UserPrincipalName if ($UPN -match $DomainToRemoved) { Set-User $PrimarySMTPAddress -UserPrincipalName $NewPrimarySMTPAddress Write-Log info -Message "The script will update the UPN from $UPN to $NewPrimarySMTPAddress" $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; PrimarySMTPAddress = $PrimarySMTPAddress; UPN = $UPN; Onmicrosoft = $Onmicrosoft; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; CustomAttribute12 = $CustomAttribute12; Identity = $Identity; Action = "Upate UPN $PrimarySMTPAddress to $NewPrimarySMTPAddress"; }) } # Update Primary SMTP Addresss If ($PrimarySMTPAddress -match $DomainToRemoved) { Write-Log info -Message "The script will update the PrimarySMTPAddress from $PrimarySMTPAddress to $NewPrimarySMTPAddress" Set-MailUser -identity $PrimarySMTPAddress -PrimarySmtpAddress $NewPrimarySMTPAddress -DomainController $DC $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; PrimarySMTPAddress = $PrimarySMTPAddress; UPN = $UPN; Onmicrosoft = $Onmicrosoft; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; CustomAttribute12 = $CustomAttribute12; Identity = $Identity; Action = "Upate Primary $PrimarySMTPAddress to $NewPrimarySMTPAddress"; }) } # Search for Email Addresses to remove foreach ($EmailAddress in $EmailAddresses) { $EmailAddressToRemove = $Null $EmailAddressToRemove = $EmailAddress $EmailAddressToRemove = $EmailAddressToRemove.Substring(5) if ($EmailAddress -match $DomainToRemoved) { Write-Log warning -Message "The script will remove the email addresse $EmailAddressToRemove" Set-MailUser -Identity $NewPrimarySMTPAddress -EmailAddresses @{ Remove = $EmailAddressToRemove } -DomainController $DC Write-Log Info -Message "The script removed the email addresse $EmailAddressToRemove" $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; PrimarySMTPAddress = $PrimarySMTPAddress; UPN = $UPN; Onmicrosoft = $Onmicrosoft; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; CustomAttribute12 = $CustomAttribute12; Identity = $Identity; Action = "Remove $EmailAddressToRemove"; }) } Else { Write-Log Info -Message "The script will NOT remove the email addresse $EmailAddressToRemove" } } $i++ } Default { Write-Log warning -Message "The script will Not take any action against this object (Alias:$Alias - Primary : $PrimarySMTPAddress - Onmicrosoft: $Onmicrosoft - RecipientTypeDetails: $RecipientTypeDetails)" } } $i++ } } If ($Cloud) { # Backup Try { Write-Log Info -Message "The script will try to backupt all Recipients" $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $AllRecipients = Get-Recipient -ResultSize unlimited -ErrorAction Silentlycontinue -ErrorVariable CMDLetFailed $AllRecipientFile = "All_recipients_" + $DateFull + ".xml" $AllRecipients | Export-Clixml $AllRecipientFile $Recipients = $AllRecipients | where { $_.IsDirsynced -eq $False } If ($CMDLetFailed) { $ErrorMessage = $CMDLetFailed.Exception.Message $CMDLet = $CMDLetFailed.InvocationInfo.Line Write-Log Error -Message "Failed to backup all recipients" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $Status = "Failed" $CMDLetFailed.clear() } Else { $Status = "Success" Write-Log Info -Message "The script successfully backup all recipients" } } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to " Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $Status = "Failed" } If ($Status -eq "Failed") { Write-Log Error -Message "Failed to backup all Recipients - The script will stop" Exit } # Processing #Initiate the Hash Table [Int]$i = 1 $Table = $Null $Table = @() $RecipientsToUpdates = $Recipients | where { $_.EmailAddresses -match $DomainToRemoved } $RecipientsToUpdateFile = ".\RecipientsToUpdate_" + $DateFull + ".xml" $RecipientsToUpdates | select Alias, DisplayName, CustomAttribute12, PrimarySMTPAddress, EmailAddresses | Export-Clixml $RecipientsToUpdateFile $Count = ($RecipientsToUpdates | Measure).count foreach ($RecipientsToUpdate in $RecipientsToUpdates) { $RecipientTypeDetails = $Null $RecipientTypeDetails = $RecipientsToUpdate.RecipientTypeDetails $Alias = $Null $Alias = $RecipientsToUpdate.Alias $DisplayName = $Null $DisplayName = $RecipientsToUpdate.DisplayName $CustomAttribute12 = $Null $CustomAttribute12 = $RecipientsToUpdate.CustomAttribute12 $EmailAddresses = $Null $EmailAddresses = $RecipientsToUpdate.EmailAddresses $PrimarySMTPAddress = $Null $PrimarySMTPAddress = $RecipientsToUpdate.PrimarySMTPAddress $Localpart = $Null $LocalPart = $PrimarySMTPAddress.Substring(0, $PrimarySMTPAddress.LastIndexOf("@")) $NewPrimarySMTPAddress = $Null $NewPrimarySMTPAddress = $LocalPart + "@" + $ReplaceDomain # Search for onMicrosoft email Address $OnMicrosoft = $Null $Onmicrosoft = $Emailaddresses | where { $_ -match "onmicrosoft.com" } | select -First 1 $Onmicrosoft = $Onmicrosoft.Substring(5) switch ($RecipientTypeDetails) { UserMailbox { # Update Primary SMTP Addresss Set-Mailbox -identity $PrimarySMTPAddress -WindowsEmailAddress $NewPrimarySMTPAddress $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; PrimarySMTPAddress = $PrimarySMTPAddress; Onmicrosoft = $Onmicrosoft; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; CustomAttribute12 = $CustomAttribute12; Action = "Upate Primary $PrimarySMTPAddress to $NewPrimarySMTPAddress"; }) Write-Log warning -Message "The script will analyze the following user (Alias:$Alias - Primary : $PrimarySMTPAddress - Onmicrosoft: $Onmicrosoft - RecipientTypeDetails: $RecipientTypeDetails)" # Search for Email Addresses to remove foreach ($EmailAddress in $EmailAddresses) { $EmailAddressToRemove = $Null $EmailAddressToRemove = $EmailAddress $EmailAddressToRemove = $EmailAddressToRemove.Substring(5) if ($EmailAddress -match $DomainToRemoved) { Write-Log warning -Message "The script will remove the email addresse $EmailAddressToRemove" Set-Mailbox -Identity $Onmicrosoft -EmailAddresses @{ Remove = $EmailAddressToRemove } Write-Log Info -Message "The script removed the email addresse $EmailAddressToRemove" $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; PrimarySMTPAddress = $PrimarySMTPAddress; Onmicrosoft = $Onmicrosoft; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; CustomAttribute12 = $CustomAttribute12; Action = "Remove $EmailAddressToRemove"; }) } Else { Write-Log Info -Message "The script will NOT remove the email addresse $EmailAddressToRemove" } } $i++ } SharedMailbox { # Update Primary SMTP Addresss Set-Mailbox -identity $PrimarySMTPAddress -WindowsEmailAddress $NewPrimarySMTPAddress $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; PrimarySMTPAddress = $PrimarySMTPAddress; Onmicrosoft = $Onmicrosoft; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; CustomAttribute12 = $CustomAttribute12; Action = "Upate Primary $PrimarySMTPAddress to $NewPrimarySMTPAddress"; }) Write-Log warning -Message "The script will analyze the following shared (Alias:$Alias - Primary : $PrimarySMTPAddress - Onmicrosoft: $Onmicrosoft - RecipientTypeDetails: $RecipientTypeDetails)" # Search for Email Addresses to remove foreach ($EmailAddress in $EmailAddresses) { $EmailAddressToRemove = $Null $EmailAddressToRemove = $EmailAddress $EmailAddressToRemove = $EmailAddressToRemove.Substring(5) if ($EmailAddress -match $DomainToRemoved) { Write-Log warning -Message "The script will remove the email addresse $EmailAddressToRemove" Set-Mailbox -Identity $Onmicrosoft -EmailAddresses @{ Remove = $EmailAddressToRemove } Write-Log Info -Message "The script removed the email addresse $EmailAddressToRemove" $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; PrimarySMTPAddress = $PrimarySMTPAddress; Onmicrosoft = $Onmicrosoft; Alias = $Alias; RecipientTypeDetails = $RecipientTypeDetails; Action = "Remove $EmailAddressToRemove"; }) } Else { Write-Log Info -Message "The script will NOT remove the email addresse $EmailAddressToRemove" } } $i++ } MailUser { } MailUniversalDistributionGroup { } GroupMailbox { } Default { } } $i++ } } } Function Add-EXOUsersToOneDGCSV { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$GroupEmailAddress, [Parameter(Mandatory = $true, Position = 2)] [String]$CSVFile ) Read-Host "Expected CSV Column:EmailAddress" $Users = Import-Csv $CSVFile $Count = ($Users | Measure).count [Int]$i = 1 $Table = $Null $Table = @() Foreach ($User in $Users) { $UserEmailAddress = $Null $UserEmailAddress = $User.EmailAddress Write-Host "User $UserEmailAddress will be added to Group $GroupEmailAddress --- $i/$Count" Try { Add-DistributionGroupMember -Identity $GroupEmailAddress -Member $UserEmailAddress -ErrorAction Stop $Status = "Success" } Catch { $ErrorMessage = $Error[0].Exception.Message If ($ErrorMessage -like "*member*") { $Status = "Failed - already members" } Else { $Status = "Failed - $ErrorMessage" } } $Table += New-object PSobject -Property ([Ordered] @{ GroupEmailAddress = $GroupEmailAddress; UserName = $UserEmailAddress; Action = "Add"; Status = $Status; }) $i++ } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFile = ".\Report_Users_Added_To_" + $GroupEmailAddress + "_" + $DateFull + ".csv" $Table | Export-Csv $ReportFile -NoTypeInformation -Encoding UTF8 Write-Host "Generate the following Report: $ReportFile " } Function Add-EXOUserToSDG { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$GroupEmailAddress, [Parameter(Mandatory = $true, Position = 2)] [String]$UserEmailAddress ) Try { Write-log info -Message "The script will try to add $UserEmailAddress to $GroupEmailAddress" Add-DistributionGroupMember -Identity $GroupEmailAddress -Member $UserEmailAddress -ErrorAction Stop $Status = "Success" Write-log warning -Message "The script Status of the change: $Status" } Catch { $ErrorMessage = $Error[0].Exception.Message If ($ErrorMessage -like "*member*") { $Status = "Failed - already members" } Else { $Status = "Failed - $ErrorMessage" } Write-log Error -Message "The script Status of the change: $Status" } } #endregion #region ExchangeOnpremise #################################################### ################# Exchange OnPremise #################### ################################################### Function Clear-msExchRemoteRecipientType { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$SamAccountName ) # Source: https://learn.microsoft.com/en-us/exchange/troubleshoot/administration/mail-user-who-has-proxy-addresses-that-use-non-verified-domains-not-synced Get-ADUser -Identity $SamAccountName -Properties * | ft UserprincipalName, msExchRemoteRecipientType Read-Host "Press Enter to Clear msExchRemoteRecipientType Attribute" Set-ADUser -Identity $SamAccountName -Clear msExchRemoteRecipientType Get-ADUser -Identity $SamAccountName -Properties * | ft UserprincipalName, msExchRemoteRecipientType } Function Fix-EXOArchiveMailboxGUID { [CmdletBinding()] param ( [Parameter(Position = 1)] [string]$DC, [Parameter(Mandatory = $true, Position = 2)] [String]$UPN ) #Backup $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $UPNName = $UPN.replace('@', '_').replace('.', '_') $ADUserXMLFile = ".\Backup_ADUser_" + $UPNName + "_" + $DateFull + ".xml" $RemoteMailboxXMLFile = ".\Backup_RemoteMailbox_" + $UPNName + "_" + $DateFull + ".xml" $OnlineMailboxXMLFile = ".\Backup_OnlineMailbox_" + $UPNName + "_" + $DateFull + ".xml" $Table = @() $FoundADUserStatus = "No" $FoundRemoteMailboxStatus = "No" $FoundOnlineMailboxStatus = "No" $DisableArchiveStatus = "No" $ManualADConnectDeltaSyncStatus = "No" $EnableArchiveStatus = "No" Try { Write-log warning -Message "Searching for ADUser $UPN" $ADUser = Get-ADUser -Filter { UserPrincipalName -eq $UPN } -Properties * -Server $DC $ADUser | Export-Clixml $ADUserXMLFile Write-log INFO -Message "Generate the following backup File for $UPN: $ADUserXMLFile" $msExchDisabledArchiveGUID = $ADUser.msExchDisabledArchiveGUID $msExchArchiveGUID = $ADUser.msExchArchiveGUID $SamAccountName = $ADUser.SamAccountName $FoundADUserStatus = "Yes" # Backup RemoteMailbox Try { Write-log warning -Message "Searching for RemoteMailbox: $UPN" $RemoteMailbox = Get-RemoteMailbox $UPN -DomainController $DC $RemoteMailboxDisabledArchiveGuid = $RemoteMailbox.DisabledArchiveGuid $RemoteMailbox | Export-Clixml $RemoteMailboxXMLFile Write-log INFO -Message "Generate the following backup File for RemoteMailbox $UPN: $RemoteMailboxXMLFile" $FoundRemoteMailboxStatus = "Yes" # Backup RemoteMailbox Try { Write-log warning -Message "Searching for Online Mailbox: $UPN" Connect-exchangeonline -Prefix OL $OnlineMailbox = Get-OLMailbox $UPN $OnlineMailboxArchiveGuid = $OnlineMailbox.ArchiveGuid $OnlineMailbox | Export-Clixml $OnlineMailboxXMLFile Write-log INFO -Message "Generate the following backup File for Online Mailbox $UPN : $OnlineMailboxXMLFile" $FoundOnlineMailboxStatus = "Yes" # Disable Archive for Remote Mailbox Try { Write-log warning -Message "Disabling Archive and clear msExchDisabledArchiveGUID Attribute for RemoteMailbox: $UPN" Disable-RemoteMailbox -Identity $UPN -Archive -DomainController $DC Set-ADUser -Identity $SamAccountName -Clear msExchDisabledArchiveGUID -Server $DC Write-log INFO -Message "Disabled Archive and clear msExchDisabledArchiveGUID Attribute for RemoteMailbox: $UPN" $DisableArchiveStatus = "Yes" # Pause for AD Connect Sync Write-Log warning -Message "Please run a delta sync on you AD Connect Server using the following CMDLet: Start-ADSyncSyncCycle -PolicyType Delta" Read-Host "Please press <Enter> to continue" $ManualADConnectDeltaSyncStatus = "Yes" # Enable Archive for Remote Mailbox Try { Write-log warning -Message "Enable Archive and clear msExchDisabledArchiveGUID Attribute for RemoteMailbox: $UPN" Enable-Remotemailbox -Identity $UPN -Archive -DomainController $DC Set-RemoteMailbox -Identity $UPN -ArchiveGUID $OnlineMailboxArchiveGuid -DomainController $DC Write-log INFO -Message "Disabled Archive and clear msExchDisabledArchiveGUID Attribute for RemoteMailbox: $UPN" $EnableArchiveStatus = "Yes" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to Disable Archive and clear msExchDisabledArchiveGUID Attribute for RemoteMailbox: $UPN" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $EnableArchiveStatus = "Failed with Error:$ErrorMessage" } } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to Disable Archive and clear msExchDisabledArchiveGUID Attribute for RemoteMailbox: $UPN" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $DisableArchiveStatus = "Failed with Error:$ErrorMessage" } } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to Backup RemoteMailbox: $UPN" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundOnlineMailboxStatus = "Failed with Error:$ErrorMessage" } } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to Backup RemoteMailbox: $UPN" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundRemoteMailboxStatus = "Failed with Error:$ErrorMessage" } } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to Backup ADUser: $UPN" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundADUserStatus = "Failed with Error:$ErrorMessage" } $Table += New-object PSobject -Property ([Ordered] @{ UPN = $UPN; FoundADUser = $FoundADUserStatus; msExchDisabledArchiveGUID = $msExchDisabledArchiveGUID; msExchArchiveGUID = $msExchArchiveGUID; SamAccountName = $SamAccountName; ADUserXMLFile = $ADUserXMLFile; FoundRemoteMailbox = $FoundRemoteMailboxStatus; RemoteMailboxDisabledArchiveGuid = $RemoteMailboxDisabledArchiveGuid; FoundOnlineMailbox = $FoundOnlineMailboxStatus; OnlineMailboxArchiveGuid = $OnlineMailboxArchiveGuid; DisableArchive = $DisableArchiveStatus; ManualADConnectDeltaSync = $ManualADConnectDeltaSyncStatus; EnableArchive = $EnableArchiveStatus; }) Return $Table } Function Fix-EXOArchiveMailboxGUIDv1 { [CmdletBinding()] param ( [Parameter(Position = 1)] [string]$DC, [Parameter(Mandatory = $true, Position = 2)] [String]$UPN ) #Backup $ADUser = Get-ADUser -Filter { UserPrincipalName -eq $UPN } -Properties * $msExchDisabledArchiveGUID = $ADUser.msExchDisabledArchiveGUID $msExchArchiveGUID = $ADUser.msExchArchiveGUID $SamAccountName = $ADUser.SamAccountName $RemoteMailbox = Get-RemoteMailbox $UPN -DomainController $DC $RemoteMailboxDisabledArchiveGuid = $RemoteMailbox.DisabledArchiveGuid Connect-exchangeonline -Prefix OL $OnlineMailbox = Get-OLMailbox $UPN $OnlineMailboxArchiveGuid = $OnlineMailbox.ArchiveGuid If ($msExchArchiveGUID -ne $OnlineMailboxArchiveGuid) { Write-Log Warning -Message "Onpremise Archive GUID: $msExchArchiveGUID is NOT equal to Online Archive GUID:$OnlineMailboxArchiveGuid" Disable-RemoteMailbox -Identity $UPN -Archive -DomainController $DC Set-ADUser -Identity $SamAccountName -Clear msExchDisabledArchiveGUID -Server $DC Enable-Remotemailbox -Identity $UPN -Archive -DomainController $DC Set-RemoteMailbox -Identity $UPN -ArchiveGUID $OnlineMailboxArchiveGuid -DomainController $DC Write-Log Info -Message "Please run a Delta Sync (AD Connect)" } Else { Write-Log Warning -Message "The Onpremise Archive GUID $msExchArchiveGUID is equal to Online Archive GUID: $OnlineMailboxArchiveGuid" } } Function Update-EXORemoteMailboxPrimary { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$EmailAddress, [Parameter(Mandatory = $true, Position = 2)] [string]$NewPrimaryEmailAddress, [Parameter(Mandatory = $false, Position = 3)] [switch]$Confirm ) # Update Primary $RemoteMailbox = Get-RemoteMailbox $EmailAddress -DomainController $DC $DisplayName = $RemoteMailbox.DisplayName $PrimarySmtpAddress = $RemoteMailbox.PrimarySmtpAddress $UserPrincipalName = $RemoteMailbox.UserPrincipalName Write-host "RemoteMailbox info - $DisplayName (UPN: $UserPrincipalName - Primary : $PrimarySmtpAddress)" $RemoteMailbox | select -ExpandProperty EmailAddresses If (!$Confirm) { Read-Host "Are you sure you want to update the Primary Email Address from $PrimarySmtpAddress to $NewPrimaryEmailAddress" } Set-RemoteMailbox -Identity $PrimarySmtpAddress -EmailAddressPolicyEnabled $False -PrimarySmtpAddress $NewPrimaryEmailAddress -DomainController $DC $RemoteMailbox1 = Get-RemoteMailbox $EmailAddress -DomainController $DC $DisplayName1 = $RemoteMailbox1.DisplayName $PrimarySmtpAddress1 = $RemoteMailbox1.PrimarySmtpAddress $UserPrincipalName1 = $RemoteMailbox1.UserPrincipalName Write-host "RemoteMailbox info - $DisplayName1 (UPN: $UserPrincipalName1 - Primary : $PrimarySmtpAddress1)" } Function Add-EXORemoteMailboxSecondary { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$EmailAddress, [Parameter(Mandatory = $true, Position = 2)] [string]$NewSecondaryEmailAddress, [Parameter(Mandatory = $false, Position = 3)] [switch]$Confirm ) # Update Primary $RemoteMailbox = Get-RemoteMailbox $EmailAddress -DomainController $DC $DisplayName = $RemoteMailbox.DisplayName $PrimarySmtpAddress = $RemoteMailbox.PrimarySmtpAddress $UserPrincipalName = $RemoteMailbox.UserPrincipalName Write-host "RemoteMailbox info - $DisplayName (UPN: $UserPrincipalName - Primary : $PrimarySmtpAddress)" $RemoteMailbox | select -ExpandProperty EmailAddresses If (!$Confirm) { Read-Host "Are you sure you want to add $NewSecondaryEmailAddress" } Get-RemoteMailbox $PrimarySmtpAddress -DomainController $DC | Set-RemoteMailbox -EmailAddresses @{ Add = "$NewSecondaryEmailAddress" } -EmailAddressPolicyEnabled $False -DomainController $DC $RemoteMailbox1 = Get-RemoteMailbox $EmailAddress -DomainController $DC $DisplayName1 = $RemoteMailbox1.DisplayName $PrimarySmtpAddress1 = $RemoteMailbox1.PrimarySmtpAddress $UserPrincipalName1 = $RemoteMailbox1.UserPrincipalName Write-host "RemoteMailbox info - $DisplayName1 (UPN: $UserPrincipalName1 - Primary : $PrimarySmtpAddress1)" $RemoteMailbox1 | select -ExpandProperty EmailAddresses } Function Update-EXOPrimaryRemoteMailboxusingCSV { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$CSVFile, [Parameter(Mandatory = $false, Position = 2)] [switch]$Check ) Read-Host "Expected CSV Column: Email,NewEmail" $RemoteMailboxes = Import-Csv $CSVFile [Int]$i = 1 $Table = $Null $Table = @() $Count = ($RemoteMailboxes | Measure).count foreach ($RemoteMailbox in $RemoteMailboxes) { $Email = $Null $Email = $RemoteMailbox.Email $NewEmail = $Null $NewEmail = $RemoteMailbox.NewEmail Write-Log warning -Message "The script will try update the RemoteMailbox $Email with New primary Email Address: $NewEmail .... --- $i/$Count" $RemoteMailbox = $Null Try { $RemoteMailbox = Get-RemoteMailbox -identity $Email -DomainController $DC -ErrorAction Stop $CurrentPrimaryRemoteMailbox = $Null $CurrentPrimaryRemoteMailbox = $RemoteMailbox.PrimarySmtpAddress $FoundRemoteMailbox = "Yes" } Catch { $ErrorMessage = $Error[0].Exception.Message If ($ErrorMessage -like "*couldn't be found*") { $FoundRemoteMailbox = "No - Not a RemoteMailbox" } Else { $FoundRemoteMailbox = "No - $ErrorMessage" } } If (!($Check)) { Update-EXORemoteMailboxPrimary -EmailAddress $Email -NewPrimaryEmailAddress $NewEmail -confirm } $NewRemoteMailbox = $Null $NewRemoteMailbox = Get-RemoteMailbox -identity $Email -DomainController $DC $NewRemoteMailboxPrimary = $Null $NewRemoteMailboxPrimary = $NewRemoteMailbox.PrimarySmtpAddress $Table += New-object PSobject -Property ([Ordered] @{ Email = $Email; NewEmail = $NewEmail; FoundRemoteMailbox = $FoundRemoteMailbox; CurrentPrimaryRemoteMailbox = $CurrentPrimaryRemoteMailbox; NewRemoteMailboxPrimary = $NewRemoteMailboxPrimary; }) $i++ } $Table | Out-GridView $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = "UpdatePrimaryEmailAddress_RemoteMailboxes_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx -TableName "UpdatePrimary" -Title "Update Primary Remote Mailbox" -TitleBold -WorksheetName "UpdatePrimary" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } Function Add-EXOSendAsOnPremiseMailbox { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$SharedMailbox, [Parameter(Mandatory = $true, Position = 2)] [String]$User ) Try { #Assign Send As Permission Write-Host "INFO:Attempt to assign Send As Permission to On-premise Recipient Object: $SharedMailbox - Trustee: $User" -ForegroundColor White Get-Mailbox $SharedMailbox | Add-ADPermission -User $User -ExtendedRights "Send As" -Confirm:$False Write-host "Warning: Successfully to assign Send As Permission to On-premise Recipient Object: $SharedMailbox - Trustee: $User" -ForegroundColor Yellow } Catch { Write-host "Error: Failed to assign Send As Permission to On-premise Recipient Object : $SharedMailbox - Trustee: $User" -ForegroundColor Red } } Function Convert-EXORemoteUserToSharedMailbox { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$UPN, [Parameter(Mandatory = $true, Position = 2)] [String]$DC ) # Connect-ExchangeOnPremise $Recipient = $Null $Recipient = Get-Recipient $UPN $Name = $Null $Name = $Recipient.Name $Alias = $Null $Alias = $Recipient.Alias $SamAccountName = $Null $SamAccountName = $Recipient.SamAccountName $RecipientTypeDetails = $Null $RecipientTypeDetails = $Recipient.RecipientTypeDetails Write-host "The user:" -NoNewline; Write-host "$Name (Alias:$Alias) " -NoNewline -ForegroundColor Red; Write-Host "RecipientTypeDetails is: $RecipientTypeDetails" $ADUser = $Null $ADUser = Get-ADUser -Filter { UserPrincipalName -eq $UPN } -Properties * -Server $DC $msExchRemoteRecipientType = $Null $msExchRemoteRecipientType = $ADUser.msExchRemoteRecipientType Write-host "Before - msExchRemoteRecipientType value is :" -NoNewline; Write-Host "$msExchRemoteRecipientType" -ForegroundColor Yellow Set-ADUser -Identity $SamAccountName -Replace @{ msExchRemoteRecipientType = "100" } #Sleep 5 $ADUser2 = $Null $ADUser2 = Get-ADUser -Filter { UserPrincipalName -eq $UPN } -Properties * -Server $DC $msExchRemoteRecipientType2 = $Null $msExchRemoteRecipientType2 = $ADUser2.msExchRemoteRecipientType Write-host "After - msExchRemoteRecipientType value is :" -NoNewline; Write-Host "$msExchRemoteRecipientType2" -ForegroundColor Green } Function Enable-EXORemoteMailbox { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$TenantName, [Parameter(Mandatory = $true, Position = 2)] [String]$Domain, [Parameter(Mandatory = $true, Position = 3)] [String]$DC, [Parameter(Mandatory = $true, Position = 4)] [String]$SamAccountName ) $ADUser = $Null $ADUser = Get-ADUser -Identity $SamAccountName -properties * -server $DC $mail = $Null $mail = $ADUser.mail $UserPrincipalName = $Null $UserPrincipalName = $ADUser.UserPrincipalName $RemoteRoutingAddress = $Null $RemoteRoutingAddress = $SamAccountName + "@" + $TenantName + ".mail.onmicrosoft.com" Enable-Remotemailbox -Identity $UserPrincipalName -RemoteRoutingAddress $RemoteRoutingAddress -PrimarySmtpAddress $UserPrincipalName -DomainController $DC Sleep 2 Set-RemoteMailbox -Identity $UserPrincipalName -EmailAddressPolicyEnabled $True -DomainController $DC Sleep 2 $RemoteMailbox = Get-RemoteMailbox -Identity $UserPrincipalName -DomainController $DC $Primary = $RemoteMailbox.PrimarySmtpAddress $LocalPart = $Primary.Substring(0, $Primary.LastIndexOf("@")) $NewPrimary = $LocalPart + "@" + $Domain Set-RemoteMailbox -Identity $UserPrincipalName -RemoteRoutingAddress $RemoteRoutingAddress -PrimarySmtpAddress $NewPrimary -EmailAddressPolicyEnabled $False -DomainController $DC } #endregion |