-
Notifications
You must be signed in to change notification settings - Fork 390
Expand file tree
/
Copy pathFreeBusyChecker.ps1
More file actions
305 lines (270 loc) · 13.3 KB
/
FreeBusyChecker.ps1
File metadata and controls
305 lines (270 loc) · 13.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
<#
.SYNOPSIS
.\FreeBusyChecker.ps1
.DESCRIPTION
This script can be used to validate the Availability configuration of the following Exchange Server Versions:
- Exchange Server
- Exchange Online
Required Permissions:
- Organization Management
- Domain Admin
Please make sure that the account used is a member of the Local Administrator group. This should be fulfilled on Exchange Servers by being a member of the Organization Management group. However, if the group membership was adjusted, or in case the script is executed on a non-Exchange system like a management Server, you need to add your account to the Local Administrator group.
How To Run:
This script must be run as Administrator in Exchange Management Shell on an Exchange Server. You can provide no parameters, and the script will just run against Exchange On-Premises and Exchange Online to query for OAuth and DAuth configuration settings. It will compare existing values with standard values and provide details of what may not be correct.
Please take note that though this script may output that a specific setting is not a standard setting, it does not mean that your configurations are incorrect. For example, DNS may be configured with specific mappings that this script cannot evaluate.
To collect information for Exchange Online a connection to Exchange Online must be established before running the script using Connection Prefix "EO".
Example:
PS C:\scripts\FreeBusyChecker> Connect-ExchangeOnline -Prefix EO
.PARAMETER Auth
Allows you to choose the authentication type to validate.
.PARAMETER Org
Allows you to choose the organization type to validate.
.PARAMETER OnPremUser
Specifies the Exchange On Premise User that will be used to test Free Busy Settings.
.PARAMETER OnlineUser
Specifies the Exchange Online User that will be used to test Free Busy Settings.
.PARAMETER OnPremDomain
Specifies the domain for on-premises Organization.
.PARAMETER OnPremEWSUrl
Specifies the EWS (Exchange Web Services) URL for on-premises Exchange Server.
.PARAMETER OnPremLocalDomain
Specifies the local AD domain for the on-premises Organization.
.PARAMETER Help
Show help for this script.
.EXAMPLE
.\FreeBusyChecker.ps1
This cmdlet will run the Free Busy Checker script and Check Availability OAuth and DAuth Configurations both for Exchange On-Premises and Exchange Online.
.EXAMPLE
.\FreeBusyChecker.ps1 -Auth OAuth
This cmdlet will run the Free Busy Checker Script against OAuth Availability Configurations.
.EXAMPLE
.\FreeBusyChecker.ps1 -Auth DAuth
This cmdlet will run the Free Busy Checker Script against DAuth Availability Configurations.
.EXAMPLE
.\FreeBusyChecker.ps1 -Org ExchangeOnline
This cmdlet will run the Free Busy Checker Script for Exchange Online Availability Configurations.
.EXAMPLE
.\FreeBusyChecker.ps1 -Org ExchangeOnPremise
This cmdlet will run the Free Busy Checker Script for Exchange On-Premises OAuth or DAuth Availability Configurations.
.EXAMPLE
.\FreeBusyChecker.ps1 -Org All
This cmdlet will run the Free Busy Checker Script for Exchange On-Premises and Exchange Online OAuth or DAuth Availability Configurations.
.EXAMPLE
.\FreeBusyChecker.ps1 -Org ExchangeOnPremise -Auth OAuth
This cmdlet will run the Free Busy Checker Script for Exchange On-Premises Availability OAuth Configurations
#>
# Exchange On-Premises
#>
#region Properties and Parameters
#Requires -Module ActiveDirectory
[CmdletBinding(DefaultParameterSetName = "FreeBusyInfo_OP", SupportsShouldProcess)]
param(
[Parameter(Mandatory = $false, ParameterSetName = "Test")]
[ValidateSet('DAuth', 'OAuth', 'All', '')]
[string[]]$Auth,
[Parameter(Mandatory = $false, ParameterSetName = "Test")]
[ValidateSet('ExchangeOnPremise', 'ExchangeOnline')]
[string[]]$Org,
[Parameter(Mandatory = $true, ParameterSetName = "Help")]
[switch]$Help,
[Parameter(Mandatory = $false, ParameterSetName = "Test")]
[string]$OnPremisesUser,
[Parameter(Mandatory = $false, ParameterSetName = "Test")]
[string]$OnlineUser,
[Parameter(Mandatory = $false, ParameterSetName = "Test")]
[string]$OnPremDomain,
[Parameter(Mandatory = $false, ParameterSetName = "Test")]
[string]$OnPremEWSUrl,
[Parameter(Mandatory = $false, ParameterSetName = "Test")]
[string]$OnPremLocalDomain,
[Parameter(Mandatory = $true, ParameterSetName = "ScriptUpdateOnly", HelpMessage = "Update only script.")]
[switch]$ScriptUpdateOnly,
[Parameter(Mandatory = $false, ParameterSetName = "SkipVersionCheck", HelpMessage = "Skip version check.")]
[switch]$SkipVersionCheck
)
begin {
. $PSScriptRoot\Functions\OnPremDAuthFunctions.ps1
. $PSScriptRoot\Functions\OnPremOAuthFunctions.ps1
. $PSScriptRoot\Functions\ExoDAuthFunctions.ps1
. $PSScriptRoot\Functions\ExoOAuthFunctions.ps1
. $PSScriptRoot\Functions\htmlContent.ps1
. $PSScriptRoot\Functions\hostOutput.ps1
. $PSScriptRoot\Functions\CommonFunctions.ps1
. $PSScriptRoot\..\..\Shared\Confirm-ExchangeShell.ps1
. $PSScriptRoot\..\..\Shared\ScriptUpdateFunctions\GenericScriptUpdate.ps1
} end {
$Script:countOrgRelIssues = (0)
$Script:WebServicesVirtualDirectory = $null
$Script:Server = hostname
$Script:startingDate = (Get-Date -Format yyyyMMdd_HHmmss)
$Script:htmlFile = "$PSScriptRoot\FBCheckerOutput_$($Script:startingDate).html"
#Check if EXO module is required and available, if so, import it.
if (-not $Org -or ($Org -eq 'ExchangeOnline')) {
if (-not (Get-Module -ListAvailable -Name ExchangeOnlineManagement)) {
Write-Error "The ExchangeOnlineManagement module is required but not installed.
Install it with: Install-Module ExchangeOnlineManagement"
return
}
Import-Module ExchangeOnlineManagement -ErrorAction Stop}
loadingParameters
#Parameter input
if (-not $OnlineUser) {
$Script:UserOnline = Get-RemoteMailbox -ResultSize 1 -WarningAction SilentlyContinue
$Script:UserOnline = $Script:UserOnline.RemoteRoutingAddress.SmtpAddress
} else {
$Script:UserOnline = Get-RemoteMailbox $OnlineUser -ResultSize 1 -WarningAction SilentlyContinue -ErrorAction SilentlyContinue
$Script:UserOnline = $Script:UserOnline.RemoteRoutingAddress.SmtpAddress
}
$Script:ExchangeOnlineDomain = ($Script:UserOnline -split "@")[1]
if ($Script:ExchangeOnlineDomain -like "*.mail.onmicrosoft.com") {
$Script:ExchangeOnlineAltDomain = (($Script:ExchangeOnlineDomain.Split(".")))[0] + ".onmicrosoft.com"
} else {
$Script:ExchangeOnlineAltDomain = (($Script:ExchangeOnlineDomain.Split(".")))[0] + ".mail.onmicrosoft.com"
}
$Script:temp = "*" + $Script:ExchangeOnlineDomain
$Script:UserOnPrem = ""
if (-not $OnPremisesUser) {
$Script:UserOnPrem = Get-mailbox -ResultSize 2 -WarningAction SilentlyContinue -Filter 'EmailAddresses -like $temp -and HiddenFromAddressListsEnabled -eq $false' -ErrorAction SilentlyContinue
if ($Script:UserOnPrem) {
$Script:UserOnPrem = $Script:UserOnPrem[1].PrimarySmtpAddress.Address
}
} else {
$Script:UserOnPrem = Get-mailbox $OnPremisesUser -WarningAction SilentlyContinue -Filter 'EmailAddresses -like $temp -and HiddenFromAddressListsEnabled -eq $false' -ErrorAction SilentlyContinue
$Script:UserOnPrem = $Script:UserOnPrem.PrimarySmtpAddress.Address
}
$Script:ExchangeOnPremDomain = ($Script:UserOnPrem -split "@")[1]
if (-not $OnPremEWSUrl) {
FetchEWSInformation
} else {
FetchEWSInformation
$Script:ExchangeOnPremEWS = ($OnPremEWSUrl)
}
if (-not $OnPremDomain) {
$ADDomain = Get-ADDomain
$Script:ExchangeOnPremLocalDomain = $ADDomain.forest
} else {
$Script:ExchangeOnPremLocalDomain = $OnPremDomain
}
$Script:ExchangeOnPremLocalDomain = $ADDomain.forest
if ([string]::IsNullOrWhitespace($ADDomain)) {
$Script:ExchangeOnPremLocalDomain = $exchangeOnPremDomain
}
if ($ExchangeOnPremDomain) {
$Script:FedInfoEOP = Get-federationInformation -DomainName $ExchangeOnPremDomain -BypassAdditionalDomainValidation -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Select-Object *
}
#endregion
if ($Help) {
PrintDynamicWidthLine
ShowHelp
PrintDynamicWidthLine
exit
}
#region Show Parameters
$Script:IntraOrgCon = Get-IntraOrganizationConnector -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Where-Object { $_.TargetAddressDomains -contains $Script:ExchangeOnlineDomain } | Select-Object Name, TarGetAddressDomains, DiscoveryEndpoint, Enabled
ShowParameters
CheckParameters
if ($Script:IntraOrgCon.enabled -eq $true) {
$Auth = hostOutputIntraOrgConEnabled($Auth)
}
if ($Script:IntraOrgCon.enabled -eq $false) {
hostOutputIntraOrgConNotEnabled
}
# Free busy Lookup methods
PrintDynamicWidthLine
$Script:OrgRel = Get-OrganizationRelationship | Where-Object { ($_.DomainNames -like $Script:ExchangeOnlineDomain) } -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Select-Object Enabled, Identity, DomainNames, FreeBusy*, TarGet*
$Script:EDiscoveryEndpoint = Get-IntraOrganizationConfiguration -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Select-Object OnPremiseDiscoveryEndpoint
$Script:SPDomainsOnprem = Get-SharingPolicy -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Format-List Domains
$Script:SPOnprem = Get-SharingPolicy -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Select-Object *
if ($Org -contains 'ExchangeOnPremise' -or -not $Org) {
#region DAuth Checks
if ($Auth -like "DAuth" -or -not $Auth -or $Auth -like "All") {
Write-Host " Testing DAuth Configuration"
OrgRelCheck -OrgRelParameter $Script:OrgRel
PrintDynamicWidthLine
FedInfoCheck
FedTrustCheck
AutoDVirtualDCheck
PrintDynamicWidthLine
EWSVirtualDirectoryCheck
AvailabilityAddressSpaceCheck
TestFedTrust
TestOrgRel
}
#endregion
#region OAuth Check
if ($Auth -like "OAuth" -or -not $Auth -or $Auth -like "All") {
Write-Host " Testing OAuth Configuration"
IntraOrgConCheck
PrintDynamicWidthLine
AuthServerCheck
PrintDynamicWidthLine
PartnerApplicationCheck
PrintDynamicWidthLine
ApplicationAccountCheck
PrintDynamicWidthLine
ManagementRoleAssignmentCheck
PrintDynamicWidthLine
AuthConfigCheck
PrintDynamicWidthLine
CurrentCertificateThumbprintCheck
PrintDynamicWidthLine
AutoDVirtualDCheckOAuth
PrintDynamicWidthLine
EWSVirtualDirectoryCheckOAuth
PrintDynamicWidthLine
AvailabilityAddressSpaceCheckOAuth
PrintDynamicWidthLine
OAuthConnectivityCheck
PrintDynamicWidthLine
}
#endregion
}
# EXO Part
if ($Org -contains 'ExchangeOnline' -or -not $Org) {
#region ConnectExo
$Exo = Test-ExchangeOnlineConnection
if (-not ($Exo)) {
Write-Host -ForegroundColor Red "`n Please connect to Exchange Online Using the EXO V3 module using EO as connection Prefix to collect Exchange OnLine Free Busy configuration Information."
Write-Host -ForegroundColor Cyan "`n`n Example: PS C:\Connect-ExchangeOnline -Prefix EO"
Write-Host -ForegroundColor Yellow "`n More Info at:https://learn.microsoft.com/en-us/powershell/exchange/exchange-online-powershell-v2?view=exchange-ps"
exit
}
Write-Host " Connected to Exchange Online."
$Script:ExoOrgRel = Get-EOOrganizationRelationship | Where-Object { ($_.DomainNames -like $ExchangeOnPremDomain ) } | Select-Object Enabled, Identity, DomainNames, FreeBusy*, TarGet*
$Script:ExoIntraOrgCon = Get-EOIntraOrganizationConnector | Select-Object Name, TarGetAddressDomains, DiscoveryEndpoint, Enabled
$Script:tarGetAddressPr1 = ("https://AutoDiscover." + $ExchangeOnPremDomain + "/AutoDiscover/AutoDiscover.svc/WSSecurity")
$Script:tarGetAddressPr2 = ("https://" + $ExchangeOnPremDomain + "/AutoDiscover/AutoDiscover.svc/WSSecurity")
exoHeaderHtml
#endregion
#region ExoDAuthCheck
if ($Auth -like "DAuth" -or -not $Auth -or $Auth -like "All") {
PrintDynamicWidthLine
Write-Host $TestingExoDAuthConfiguration
ExoOrgRelCheck
PrintDynamicWidthLine
ExoFedOrgIdCheck
PrintDynamicWidthLine
ExoTestOrgRelCheck
SharingPolicyCheck
}
#endregion
#region ExoOauthCheck
if ($Auth -like "OAuth" -or -not $Auth -or $Auth -like "All") {
Write-Host $TestingExoOAuthConfiguration
ExoIntraOrgConCheck
PrintDynamicWidthLine
EXOIntraOrgConfigCheck
PrintDynamicWidthLine
EXOAuthServerCheck
PrintDynamicWidthLine
ExoTestOAuthCheck
PrintDynamicWidthLine
}
#endregion
Write-Host -ForegroundColor Green $ThatIsAllForTheExchangeOnlineSide
PrintDynamicWidthLine
}
Stop-Transcript
}