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