Skip to content

Commit b54bf8d

Browse files
authored
Merge branch 'main' into FreeBusyChecker
2 parents 93f4d6b + c8e54dd commit b54bf8d

8 files changed

+129
-55
lines changed

Admin/CrossTenantMailboxMigrationValidation.ps1

+14-15
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,8 @@ function CheckObjects {
193193
#Check for the T2T license on any of the objects (either source or target) as long as the source mailbox is a regular mailbox
194194
Write-Verbose -Message "Informational: Source mailbox is regular, checking if either SOURCE mailbox or TARGET MailUser has the T2T license assigned"
195195
if ($SourceObject.RecipientTypeDetails -eq 'UserMailbox') {
196-
if ($SourceObject.PersistedCapabilities -notmatch 'ExchangeT2TMbxMove') {
197-
if ($TargetObject.PersistedCapabilities -notmatch 'ExchangeT2TMbxMove') {
196+
if ($SourceObject.PersistedCapabilities -notcontains 'ExchangeT2TMbxMove') {
197+
if ($TargetObject.PersistedCapabilities -notcontains 'ExchangeT2TMbxMove') {
198198
Write-Host ">> Error: Neither SOURCE mailbox or TARGET MailUser have a valid T2T migration license. This is a pre-requisite, and if the license is not assigned by the time the migration is injected, it will fail to complete" -ForegroundColor Red
199199
} else {
200200
Write-Verbose -Message "TARGET MailUser has a valid T2T migration license"
@@ -273,8 +273,8 @@ function CheckObjects {
273273

274274
#Verify if SOURCE mailbox is part of the Mail-Enabled Security Group defined on the SOURCE organization relationship
275275
Write-Verbose -Message "Informational: Checking if the SOURCE mailbox is a member of the SOURCE organization relationship Mail-Enabled Security Group defined on the MailboxMovePublishedScopes"
276-
$SourceTenantOrgRelationship = Get-SourceOrganizationRelationship | Where-Object { ($_.MailboxMoveCapability -eq "RemoteOutbound") -and ($null -ne $_.OauthApplicationId) }
277-
if ((Get-SourceDistributionGroupMember $SourceTenantOrgRelationship.MailboxMovePublishedScopes[0]).Name -contains $SourceObject.Name) {
276+
$SourceTenantOrgRelationship = Get-SourceOrganizationRelationship | Where-Object { ($_.MailboxMoveCapability -like "*RemoteOutbound*") -and ($null -ne $_.OauthApplicationId) }
277+
if ((Get-SourceDistributionGroupMember $SourceTenantOrgRelationship.MailboxMovePublishedScopes[0] -ResultSize unlimited).Name -contains $SourceObject.Name) {
278278
Write-Host ">> SOURCE mailbox is within the MailboxMovePublishedScopes" -ForegroundColor Green
279279
} else {
280280
Write-Host ">> Error: SOURCE mailbox is NOT within the MailboxMovePublishedScopes. The migration will fail if you don't correct this" -ForegroundColor Red
@@ -416,7 +416,7 @@ function CheckObjects {
416416
Write-Verbose -Message "Informational: The X500 address $($Address) from SOURCE object is present on TARGET object"
417417
} else {
418418
if (!$TargetObject.IsDirSynced) {
419-
Write-Host ">> Error: $($Address) is not present on the TARGET MailUser, would you like to add it? (Y/N): " -ForegroundColor Red -NoNewline
419+
Write-Host ">> Warning: $($Address) is not present on the TARGET MailUser. All of the X500 addresses of the source mailbox object, as a best practice, should be present on the target MailUser object. Would you like to add it? (Y/N): " -ForegroundColor Yellow -NoNewline
420420
$AddX500 = Read-Host
421421
Write-Host " Your input: $($AddX500)"
422422
if ($AddX500.ToLower() -eq "y") {
@@ -426,7 +426,7 @@ function CheckObjects {
426426
$TargetObject = Get-TargetMailUser $TargetIdentity
427427
}
428428
} else {
429-
Write-Host ">> Error: $($Address) is not present on the TARGET MailUser and the object is DirSynced. This is not a change that can be done directly on EXO, please add the X500 address from on-premises and perform an AADConnect delta sync" -ForegroundColor Red
429+
Write-Host ">> Warning: $($Address) is not present on the TARGET MailUser and the object is DirSynced. All of the X500 addresses of the source mailbox object, as a best practice, should be present on the target MailUser object. This is not a change that can be done directly on EXO, please add the X500 address from on-premises and perform an AADConnect delta sync" -ForegroundColor Yellow
430430
}
431431
}
432432
}
@@ -489,8 +489,8 @@ function CheckObjectsSourceOffline {
489489
#Check for the T2T license on any of the objects (either source or target) as long as the source mailbox is a regular mailbox
490490
Write-Verbose -Message "Informational: Source mailbox is regular, checking if either SOURCE mailbox or TARGET MailUser has the T2T license assigned"
491491
if ($SourceObject.RecipientTypeDetails -eq 'UserMailbox') {
492-
if ($SourceObject.PersistedCapabilities -notmatch 'ExchangeT2TMbxMove') {
493-
if ($TargetObject.PersistedCapabilities -notmatch 'ExchangeT2TMbxMove') {
492+
if ($SourceObject.PersistedCapabilities -notcontains 'ExchangeT2TMbxMove') {
493+
if ($TargetObject.PersistedCapabilities -notcontains 'ExchangeT2TMbxMove') {
494494
Write-Host ">> Error: Neither SOURCE mailbox or TARGET MailUser have a valid T2T migration license. This is a pre-requisite, and if the license is not assigned by the time the migration is injected, it will fail to complete" -ForegroundColor Red
495495
} else {
496496
Write-Verbose -Message "TARGET MailUser has a valid T2T migration license"
@@ -559,7 +559,7 @@ function CheckObjectsSourceOffline {
559559
#Verify if SOURCE mailbox is part of the Mail-Enabled Security Group defined on the SOURCE organization relationship
560560
Write-Verbose -Message "Informational: Checking if the SOURCE mailbox is a member of the SOURCE organization relationship Mail-Enabled Security Group defined on the MailboxMovePublishedScopes"
561561
$SourceTenantOrgRelationship = (Import-Clixml $OutputPath\SourceOrgRelationship.xml)
562-
$SourceTenantOrgRelationship = $SourceTenantOrgRelationship | Where-Object { ($_.MailboxMoveCapability -eq "RemoteOutbound") -and ($null -ne $_.OauthApplicationId) }
562+
$SourceTenantOrgRelationship = $SourceTenantOrgRelationship | Where-Object { ($_.MailboxMoveCapability -like "*RemoteOutbound*") -and ($null -ne $_.OauthApplicationId) }
563563
$SourceTenantMailboxMovePublishedScopesSGMembers = Import-Clixml $OutputPath\MailboxMovePublishedScopesSGMembers.xml
564564
if ($SourceTenantMailboxMovePublishedScopesSGMembers.Name -contains $SourceObject.Name) {
565565
Write-Host ">> SOURCE mailbox is within the MailboxMovePublishedScopes" -ForegroundColor Green
@@ -704,7 +704,7 @@ function CheckObjectsSourceOffline {
704704
Write-Verbose -Message "Informational: The X500 address $($Address) from SOURCE object is present on TARGET object"
705705
} else {
706706
if (!$TargetObject.IsDirSynced) {
707-
Write-Host ">> Error: $($Address) is not present on the TARGET MailUser, would you like to add it? (Y/N): " -ForegroundColor Red -NoNewline
707+
Write-Host ">> Error: $($Address) is not present on the TARGET MailUser. All of the X500 addresses of the source mailbox object, as a best practice, should be present on the target MailUser object. Would you like to add it? (Y/N): " -ForegroundColor Red -NoNewline
708708
$AddX500 = Read-Host
709709
Write-Host " Your input: $($AddX500)"
710710
if ($AddX500.ToLower() -eq "y") {
@@ -714,7 +714,7 @@ function CheckObjectsSourceOffline {
714714
$TargetObject = Get-TargetMailUser $TargetIdentity
715715
}
716716
} else {
717-
Write-Host ">> Error: $($Address) is not present on the TARGET MailUser and the object is DirSynced. This is not a change that can be done directly on EXO, please add the X500 address from on-premises and perform an AADConnect delta sync" -ForegroundColor Red
717+
Write-Host ">> Error: $($Address) is not present on the TARGET MailUser and the object is DirSynced. All of the X500 addresses of the source mailbox object, as a best practice, should be present on the target MailUser object. This is not a change that can be done directly on EXO, please add the X500 address from on-premises and perform an AADConnect delta sync" -ForegroundColor Red
718718
}
719719
}
720720
}
@@ -811,7 +811,7 @@ function CheckOrgs {
811811
Write-Verbose -Message "Informational: Checking SOURCE tenant organization relationship"
812812
if ($SourceTenantOrgRelationship.MailboxMoveEnabled) {
813813
Write-Host "Organization relationship on SOURCE tenant is enabled for moves" -ForegroundColor Green
814-
if ($SourceTenantOrgRelationship.MailboxMoveCapability -eq "RemoteOutbound") {
814+
if ($SourceTenantOrgRelationship.MailboxMoveCapability -like "*RemoteOutbound*") {
815815
Write-Host "Organization relationship on SOURCE tenant MailboxMove is correctly set" -ForegroundColor Green
816816
if ($SourceTenantOrgRelationship.DomainNames -contains $TargetTenantId) {
817817
Write-Host "Organization relationship on SOURCE tenant DomainNames is correctly pointing to TargetTenantId" -ForegroundColor Green
@@ -879,7 +879,7 @@ function CheckOrgsSourceOffline {
879879
Write-Verbose -Message "Informational: Checking SOURCE tenant organization relationship"
880880
if ($SourceTenantOrgRelationship.MailboxMoveEnabled) {
881881
Write-Host "Organization relationship on SOURCE tenant is enabled for moves" -ForegroundColor Green
882-
if ($SourceTenantOrgRelationship.MailboxMoveCapability -eq "RemoteOutbound") {
882+
if ($SourceTenantOrgRelationship.MailboxMoveCapability -like "*RemoteOutbound*") {
883883
Write-Host "Organization relationship on SOURCE tenant MailboxMove is correctly set" -ForegroundColor Green
884884
if ($SourceTenantOrgRelationship.DomainNames -contains $TargetTenantId) {
885885
Write-Host "Organization relationship on SOURCE tenant DomainNames is correctly pointing to TargetTenantId" -ForegroundColor Green
@@ -1112,7 +1112,7 @@ if ($CollectSourceOnly -and $CSV) {
11121112
$SourceTenantOrganizationRelationship | ForEach-Object {
11131113
if (($_.MailboxMoveEnabled) -and ($_.MailboxMoveCapability -eq "RemoteOutbound") -and ($_.MailboxMovePublishedScopes)) {
11141114
Write-Host "Informational: $($_.Identity) organization relationship meets the conditions for a cross tenant mailbox migration scenario, exporting members of the security group defined on the MailboxMovePublishedScopes" -ForegroundColor Yellow
1115-
Get-SourceDistributionGroupMember $_.MailboxMovePublishedScopes[0] | Export-Clixml $OutputPath\MailboxMovePublishedScopesSGMembers.xml
1115+
Get-SourceDistributionGroupMember $_.MailboxMovePublishedScopes[0] -ResultSize Unlimited | Export-Clixml $OutputPath\MailboxMovePublishedScopesSGMembers.xml
11161116
} else {
11171117
Write-Host "Informational: $($_.Identity) organization relationship doesn't match for a cross tenant mailbox migration scenario" -ForegroundColor Yellow
11181118
}
@@ -1192,4 +1192,3 @@ if ($SourceIsOffline -and $PathForCollectedData -and $CheckOrgs) {
11921192
LoggingOff
11931193
KillSessions
11941194
}
1195-

Diagnostics/HealthChecker/DataCollection/ExchangeInformation/Get-ExchangeServerMaintenanceState.ps1

+2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ function Get-ExchangeServerMaintenanceState {
2121

2222
try {
2323
$errorCount = $Error.Count
24+
Write-Verbose "Trying to run Get-ClusterNode"
2425
$getClusterNode = Get-ClusterNode -Name $Server -ErrorAction Stop
26+
Invoke-ErrorCatchActionLoopFromIndex $errorCount
2527
} catch {
2628
Write-Verbose "Failed to run Get-ClusterNode"
2729
Invoke-ErrorCatchActionLoopFromIndex $errorCount

M365/Remove-MailboxExtendedProperty.ps1

+34-15
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# Copyright (c) Microsoft Corporation.
22
# Licensed under the MIT License.
33

4-
#Requires -Modules @{ ModuleName="ExchangeOnlineManagement"; ModuleVersion="3.4.0" }
5-
#Requires -Modules @{ ModuleName="Microsoft.Graph.Users"; ModuleVersion="2.24.0" }
6-
#Requires -Modules @{ ModuleName="Microsoft.Graph.Mail"; ModuleVersion="2.24.0" }
4+
#Requires -Modules @{ ModuleName="ExchangeOnlineManagement"; ModuleVersion="3.7.0" }
5+
#Requires -Modules @{ ModuleName="Microsoft.Graph.Users"; ModuleVersion="2.25.0" }
6+
#Requires -Modules @{ ModuleName="Microsoft.Graph.Mail"; ModuleVersion="2.25.0" }
77

88
<#
99
.SYNOPSIS
@@ -17,9 +17,17 @@
1717
1818
.EXAMPLE
1919
$mailboxExtendedProperty = Get-MailboxExtendedProperty -Identity [email protected] | Where-Object { $_.PropertyName -like '*Some Pattern*' }
20+
21+
Delegated permissions:
22+
2023
$messagesWithExtendedProperty = .\Search-MailboxExtendedProperty.ps1 -MailboxExtendedProperty $mailboxExtendedProperty
2124
.\Remove-MailboxExtendedProperty.ps1 -MessagesWithExtendedProperty $messagesWithExtendedProperty
2225
26+
Application permissions:
27+
28+
$messagesWithExtendedProperty = .\Search-MailboxExtendedProperty.ps1 -MailboxExtendedProperty $mailboxExtendedProperty -UserPrincipalName [email protected]
29+
.\Remove-MailboxExtendedProperty.ps1 -MessagesWithExtendedProperty $messagesWithExtendedProperty -UserPrincipalName [email protected]
30+
2331
#>
2432
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
2533
param(
@@ -31,22 +39,33 @@ param(
3139
throw "The parameter MailboxExtendedProperty doesn't appear to be the result from running 'Search-MailboxExtendedProperty'."
3240
}
3341
})]
34-
$MessagesWithExtendedProperty
42+
$MessagesWithExtendedProperty,
43+
[Parameter(Mandatory = $false, Position = 1)]
44+
$UserPrincipalName
3545
)
3646

3747
process {
38-
# Get the current Microsoft Graph context
39-
$context = Get-MgContext
40-
if ($null -eq $context) {
41-
Write-Host -ForegroundColor Red "No valid context. Please connect to Microsoft Graph first."
42-
return
43-
}
48+
if ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('UserPrincipalName')) {
49+
# Get the user information for the supplied user principal name
50+
$user = Get-MgUser -UserId $UserPrincipalName -Select 'displayName, id, mail, userPrincipalName'
51+
if ($null -eq $user) {
52+
Write-Host -ForegroundColor Red "No valid user. Please check the name and retry."
53+
return
54+
}
55+
} else {
56+
# Get the current Microsoft Graph context
57+
$context = Get-MgContext
58+
if ($null -eq $context) {
59+
Write-Host -ForegroundColor Red "No valid context. Please connect to Microsoft Graph first."
60+
return
61+
}
4462

45-
# Get the user information for the context
46-
$user = Get-MgUser -UserId $context.Account -Select 'displayName, id, mail, userPrincipalName'
47-
if ($null -eq $user) {
48-
Write-Host -ForegroundColor Red "No valid user. Please check the Microsoft Graph connection."
49-
return
63+
# Get the user information for the context
64+
$user = Get-MgUser -UserId $context.Account -Select 'displayName, id, mail, userPrincipalName'
65+
if ($null -eq $user) {
66+
Write-Host -ForegroundColor Red "No valid user. Please check the Microsoft Graph connection."
67+
return
68+
}
5069
}
5170

5271
Write-Host "Attempting to remove $($MessagesWithExtendedProperty.Count) extended properties from the mailbox of $($user.UserPrincipalName)."

M365/Search-MailboxExtendedProperty.ps1

+33-15
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# Copyright (c) Microsoft Corporation.
22
# Licensed under the MIT License.
33

4-
#Requires -Modules @{ ModuleName="ExchangeOnlineManagement"; ModuleVersion="3.4.0" }
5-
#Requires -Modules @{ ModuleName="Microsoft.Graph.Users"; ModuleVersion="2.24.0" }
6-
#Requires -Modules @{ ModuleName="Microsoft.Graph.Mail"; ModuleVersion="2.24.0" }
4+
#Requires -Modules @{ ModuleName="ExchangeOnlineManagement"; ModuleVersion="3.7.0" }
5+
#Requires -Modules @{ ModuleName="Microsoft.Graph.Users"; ModuleVersion="2.25.0" }
6+
#Requires -Modules @{ ModuleName="Microsoft.Graph.Mail"; ModuleVersion="2.25.0" }
77

88
<#
99
.SYNOPSIS
@@ -20,7 +20,14 @@
2020
2121
.EXAMPLE
2222
$mailboxExtendedProperty = Get-MailboxExtendedProperty -Identity [email protected] | Where-Object { $_.PropertyName -like '*Some Pattern*' }
23+
24+
Delegated permissions:
25+
2326
$messagesWithExtendedProperty = .\Search-MailboxExtendedProperty.ps1 -MailboxExtendedProperty $mailboxExtendedProperty
27+
28+
Application permissions:
29+
30+
$messagesWithExtendedProperty = .\Search-MailboxExtendedProperty.ps1 -MailboxExtendedProperty $mailboxExtendedProperty -UserPrincipalName [email protected]
2431
#>
2532
param(
2633
[Parameter(Mandatory = $true, Position = 0)]
@@ -31,7 +38,9 @@ param(
3138
throw "The parameter MailboxExtendedProperty doesn't appear to be the result from running 'Get-MailboxExtendedProperty'."
3239
}
3340
})]
34-
$MailboxExtendedProperty
41+
$MailboxExtendedProperty,
42+
[Parameter(Mandatory = $false, Position = 1)]
43+
$UserPrincipalName
3544
)
3645

3746
process {
@@ -69,18 +78,27 @@ process {
6978
# Messages found with the extended property
7079
$message = @()
7180

72-
# Get the current Microsoft Graph context
73-
$context = Get-MgContext
74-
if ($null -eq $context) {
75-
Write-Host -ForegroundColor Red "No valid context. Please connect to Microsoft Graph first."
76-
return
77-
}
81+
if ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('UserPrincipalName')) {
82+
# Get the user information for the supplied user principal name
83+
$user = Get-MgUser -UserId $UserPrincipalName -Select 'displayName, id, mail, userPrincipalName'
84+
if ($null -eq $user) {
85+
Write-Host -ForegroundColor Red "No valid user. Please check the name and retry."
86+
return
87+
}
88+
} else {
89+
# Get the current Microsoft Graph context
90+
$context = Get-MgContext
91+
if ($null -eq $context) {
92+
Write-Host -ForegroundColor Red "No valid context. Please connect to Microsoft Graph first."
93+
return
94+
}
7895

79-
# Get the user information for the context
80-
$user = Get-MgUser -UserId $context.Account -Select 'displayName, id, mail, userPrincipalName'
81-
if ($null -eq $user) {
82-
Write-Host -ForegroundColor Red "No valid user. Please check the Microsoft Graph connection."
83-
return
96+
# Get the user information for the context
97+
$user = Get-MgUser -UserId $context.Account -Select 'displayName, id, mail, userPrincipalName'
98+
if ($null -eq $user) {
99+
Write-Host -ForegroundColor Red "No valid user. Please check the Microsoft Graph connection."
100+
return
101+
}
84102
}
85103

86104
Write-Host "Searching for mailbox items with the specified $($MailboxExtendedProperty.Count) extended properties in the mailbox of $($user.UserPrincipalName)."

M365/Test-MailboxExtendedProperty.ps1

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copyright (c) Microsoft Corporation.
22
# Licensed under the MIT License.
33

4-
#Requires -Modules @{ ModuleName="ExchangeOnlineManagement"; ModuleVersion="3.4.0" }
4+
#Requires -Modules @{ ModuleName="ExchangeOnlineManagement"; ModuleVersion="3.7.0" }
55

66
<#
77
.SYNOPSIS
@@ -14,7 +14,7 @@
1414
The identity of the user whose mailbox extended properties are to be retrieved.
1515
1616
.PARAMETER Threshold
17-
The quota threshold to check for having exceeded. Default is 0.9, which is 90% of the allowed quota.
17+
The quota threshold to check for having exceeded. Default is 1.0, which is 100% of the allowed quota.
1818
1919
.PARAMETER SelectFirst
2020
The number of sorted descending results to select, when checking any namespace or same name prefix quota. Default is 10.
@@ -30,7 +30,7 @@ param(
3030
$Identity,
3131
[Parameter(Mandatory = $false, Position = 1)]
3232
[ValidateRange(0.0, 1.0)]
33-
[double]$Threshold = 0.9,
33+
[double]$Threshold = 1.0,
3434
[Parameter(Mandatory = $false, Position = 2)]
3535
$SelectFirst = 10
3636
)

0 commit comments

Comments
 (0)