DynamicsNetworkTest.ps1
<#PSScriptInfo
.VERSION 1.1 .GUID 3835ff6c-24eb-49b8-8a11-8b8350402fb5 .DESCRIPTION Use this script to test basic network connectivity to Dynamics 365 online endpoints. .AUTHOR Aaron Guilmette .COMPANYNAME Microsoft .COPYRIGHT 2021 .TAGS User hold policies .LICENSEURI .PROJECTURI https://www.undocumented-features.com/2018/04/20/dynamics-365-network-test-tool/ .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES #> <# .SYNOPSIS Test basic connectivity and name resolution for Dynamics 365. .PARAMETER DebugLogging Enable debug error logging to log file. .PARAMETER Logfile Self-explanatory. .PARAMETER OnlineEndPoints Use this parameter to conduct communication tests against online endpoints. .PARAMETER OnlineEndPointTarget Use this optional parameter to select region. Valid values: - NA (North America) - SA (South America) - EMEA (Europe, Middle East, Africa) - APAC (Asia-Pacific) - JP (Japan) - IN (India) - CA (Canada) - USGOV (United States Government) - UK (United Kingdom) - Oceania (Oceania-area) .PARAMETER SystemConfiguration Report on system configuration items, including TLS registry entries and proxy configurations. .EXAMPLE .\DynamicsNetworkTest.ps1 Runs all tests and writes to default log file location (YYYY-MM-DD_DynamicsConnectivity.txt) .EXAMPLE .\DynamicsNetworkTest.ps1 -SystemConfiguration Runs System Configuration test and writes to default log file location (YYYY-MM-DD_DynamicsConnectivity.txt). .EXAMPLE .\DynamicsNetworkTest.ps1 -OnlineEndPointTarget USGOV -DebugLogging Runs OnlineEndPoints test using the U.S. Government online endpoints list and writes to default log file location (YYYY-MM-DD_DynamicsConnectivity.txt) with debug logging enabled. .LINK https://www.undocumented-features.com/2018/04/20/dynamics-365-network-test-tool/ .NOTES - 2021-04-07 Updated endpoints with latest from https://support.microsoft.com/en-us/help/2655102/internet-accessible-urls-required-for-connectivity-to-microsoft-dynami Updated for PowerShell Gallery. - 2018-06-27 Updated endpoints for crmdynint.com and passport.net. Updated system configuration check. Added browser detection. - 2018-04-20 Updated system configuration check. - 2018-04-20 Updated online endpoint targets for additional regions. - 2018-04-20 Initial release. #> param ( [switch]$DebugLogging, [string]$Logfile = (Get-Date -Format yyyy-MM-dd) + "_DynamicsConnectivity.txt", [switch]$OnlineEndPoints, [ValidateSet("NA", "USGOV","SA","EMEA","APAC","JP","IN","CA","Oceania","UK")] [string]$OnlineEndPointTarget = "NA", [switch]$SystemConfiguration ) ## Functions # Logging function function Write-Log([string[]]$Message, [string]$LogFile = $Script:LogFile, [switch]$ConsoleOutput, [ValidateSet("SUCCESS", "INFO", "WARN", "ERROR", "DEBUG")][string]$LogLevel) { $Message = $Message + $Input If (!$LogLevel) { $LogLevel = "INFO" } switch ($LogLevel) { SUCCESS { $Color = "Green" } INFO { $Color = "White" } WARN { $Color = "Yellow" } ERROR { $Color = "Red" } DEBUG { $Color = "Gray" } } if ($Message -ne $null -and $Message.Length -gt 0) { $TimeStamp = [System.DateTime]::Now.ToString("yyyy-MM-dd HH:mm:ss") if ($LogFile -ne $null -and $LogFile -ne [System.String]::Empty) { Out-File -Append -FilePath $LogFile -InputObject "[$TimeStamp] [$LogLevel] $Message" } if ($ConsoleOutput -eq $true) { Write-Host "[$TimeStamp] [$LogLevel] :: $Message" -ForegroundColor $Color } } } # Test Online Networking Only function OnlineEndPoints { switch -regex ($OnlineEndPointTarget) { 'NA' { Write-Log -LogFile $Logfile -LogLevel INFO -Message "Starting Online Endpoints tests (North America)." Write-Log -LogFile $Logfile -LogLevel INFO -Message "See https://support.microsoft.com/en-us/help/2655102/internet-accessible-urls-required-for-connectivity-to-microsoft-dynami" Write-Log -LogFile $Logfile -LogLevel INFO -Message "for more details on endpoints." # Test on port 80 to retrieve CRL $CRL = @( "http://crl.microsoft.com/pki/crl/products/microsoftrootcert.crl", "http://mscrl.microsoft.com/pki/mscorp/crl/msitwww2.crl", "http://ocsp.verisign.com", "http://ocsp.entrust.net") # Resolve DNS name to IP and attempt TCP connection on 443 $RequiredResources = @( "login.microsoftonline-p.com", "login.live.com", "online.dynamics.com", "login.windows.net", "secure.aadcdn.microsoftonline-p.com", "mbs.microsoft.com", "go.microsoft.com", "urs.microsoft.com", "auth.gfx.ms", # "sc.imp.live.com", # URL does not have valid DNS "dynamicscrmna.accesscontrol.windows.net", "nexus.passport.com", # in place of passport.net, since can't find a valid endpoint "clientconfig.passport.net", "login.microsoftonline.com", "home.dynamics.com", "crmcdn.azureedge.net", # in place of *.azureedge.net "www.crmdynint.com", # "cloudredirectornamsec.cloudapp.net", # URL does not have valid DNS # "cloudredirectornam.cloudapp.net", # URL does not have valid DNS "mem.gfx.ms", "test.crm.dynamics.com" # used in place of *.crm2.dynamics.com "www.d365ccafpi.com" ) # Resolve DNS and attempt to retrieve data from endpoint $RequiredResourcesEndpoints = @( "http://clientconfig.passport.net/ppcrlconfig.bin", "https://disco.crm.dynamics.com/XRMServices/2011/Discovery.svc", "http://disco.crm.dynamics.com/XRMServices/2011/Discovery.svc", "https://disco.crm9.dynamics.com/XRMServices/2011/Discovery.svc" "https://login.windows.net", "https://secure.aadcdn.microsoftonline-p.com/ests/2.1.5975.9/content/cdnbundles/jquery.1.11.min.js") # Use Optional resources for addtional services. $OptionalResources = @() # Optional resources endpoints. Specify as exact URI to download/test, such as # https://endpoint.domain.com/uri.svc $OptionalResourcesEndpoints = @() # Use the AdditionalResources array to specify items that need a port test on a port other # than 80 or 443. Specify as endpoint:port $AdditionalResources = @() } 'USGOV' { Write-Log -LogFile $Logfile -LogLevel INFO -Message "Starting Online Endpoints tests (US Government)." Write-Log -LogFile $Logfile -LogLevel INFO -Message "See https://support.microsoft.com/en-us/help/2655102/internet-accessible-urls-required-for-connectivity-to-microsoft-dynami" Write-Log -LogFile $Logfile -LogLevel INFO -Message "for more details on endpoints." # Test on port 80 to retrieve CRL $CRL = @( "http://crl.microsoft.com/pki/crl/products/microsoftrootcert.crl", "http://mscrl.microsoft.com/pki/mscorp/crl/msitwww2.crl", "http://ocsp.verisign.com", "http://ocsp.entrust.net") # Resolve DNS name to IP and attempt TCP connection on 443 $RequiredResources = @( "login.microsoftonline-p.com", "login.live.com", "online.dynamics.com", "login.windows.net", "secure.aadcdn.microsoftonline-p.com", "mbs.microsoft.com", "go.microsoft.com", "urs.microsoft.com", "auth.gfx.ms", #"sc.imp.live.com", # url does not have valid DNS #"dynamicscrmgcc.accesscontrol.usgovcloudapi.net", # no valid DNS "nexus.passport.com", # in place of passport.net, since can't find a valid endpoint "clientconfig.passport.net", "login.microsoftonline.com", "home.dynamics.com", "crmcdn.azureedge.net", # in place of *.azureedge.net # "cloudredirectornamsec.cloudapp.net", # URL does not have valid DNS # "cloudredirectornam.cloudapp.net", # URL does not have valid DNS "mem.gfx.ms", "test.crm9.dynamics.com" # used in place of *.crm2.dynamics.com "www.d365ccafpi.com", "www.crmdynint-gcc.com") # Support site incorrectly lists this as www.www.crmdynint-gcc.com # Resolve DNS and attempt to retrieve data from endpoint $RequiredResourcesEndpoints = @( "http://clientconfig.passport.net/ppcrlconfig.bin", "https://disco.crm9.dynamics.com/XRMServices/2011/Discovery.svc" "https://login.windows.net", "https://secure.aadcdn.microsoftonline-p.com/ests/2.1.5975.9/content/cdnbundles/jquery.1.11.min.js") # Use Optional resources for addtional services. $OptionalResources = @() # Optional resources endpoints. Specify as exact URI to download/test, such as # https://endpoint.domain.com/uri.svc $OptionalResourcesEndpoints = @() # Use the AdditionalResources array to specify items that need a port test on a port other # than 80 or 443. Specify as endpoint:port $AdditionalResources = @() } 'SA' { Write-Log -LogFile $Logfile -LogLevel INFO -Message "Starting Online Endpoints tests (South America)." Write-Log -LogFile $Logfile -LogLevel INFO -Message "See https://support.microsoft.com/en-us/help/2655102/internet-accessible-urls-required-for-connectivity-to-microsoft-dynami" Write-Log -LogFile $Logfile -LogLevel INFO -Message "for more details on endpoints." # Test on port 80 to retrieve CRL $CRL = @( "http://crl.microsoft.com/pki/crl/products/microsoftrootcert.crl", "http://mscrl.microsoft.com/pki/mscorp/crl/msitwww2.crl", "http://ocsp.verisign.com", "http://ocsp.entrust.net") # Resolve DNS name to IP and attempt TCP connection on 443 $RequiredResources = @( "login.microsoftonline-p.com", "login.live.com", "online.dynamics.com", "login.windows.net", "secure.aadcdn.microsoftonline-p.com", "mbs.microsoft.com", "go.microsoft.com", "urs.microsoft.com", "auth.gfx.ms", # "sc.imp.live.com", # URL does not have valid DNS "dynamicscrmsam.accesscontrol.windows.net", "nexus.passport.com", # in place of passport.net, since can't find a valid endpoint "clientconfig.passport.net", "login.microsoftonline.com", "home.dynamics.com", "crmcdn.azureedge.net", # in place of *.azureedge.net "www.crmdynint.com", # parked domain # "cloudredirectorsamsec.cloudapp.net", # URL does not have valid DNS # "cloudredirectorsam.cloudapp.net", # URL does not have valid DNS "mem.gfx.ms", "test.crm2.dynamics.com" # used in place of *.crm2.dynamics.com "www.d365ccafpi.com" ) # Resolve DNS and attempt to retrieve data from endpoint $RequiredResourcesEndpoints = @( "http://clientconfig.passport.net/ppcrlconfig.bin", "http://disco.crm2.dynamics.com/XRMServices/2011/Discovery.svc", "https://disco.crm2.dynamics.com/XRMServices/2011/Discovery.svc" "https://login.windows.net", "https://secure.aadcdn.microsoftonline-p.com/ests/2.1.5975.9/content/cdnbundles/jquery.1.11.min.js") # Use Optional resources for addtional services. $OptionalResources = @() # Optional resources endpoints. Specify as exact URI to download/test, such as # https://endpoint.domain.com/uri.svc $OptionalResourcesEndpoints = @() # Use the AdditionalResources array to specify items that need a port test on a port other # than 80 or 443. Specify as endpoint:port $AdditionalResources = @() } 'EMEA' { Write-Log -LogFile $Logfile -LogLevel INFO -Message "Starting Online Endpoints tests (Europe, Middle East, and Africa)." Write-Log -LogFile $Logfile -LogLevel INFO -Message "See https://support.microsoft.com/en-us/help/2655102/internet-accessible-urls-required-for-connectivity-to-microsoft-dynami" Write-Log -LogFile $Logfile -LogLevel INFO -Message "for more details on endpoints." # Test on port 80 to retrieve CRL $CRL = @( "http://crl.microsoft.com/pki/crl/products/microsoftrootcert.crl", "http://mscrl.microsoft.com/pki/mscorp/crl/msitwww2.crl", "http://ocsp.verisign.com", "http://ocsp.entrust.net") # Resolve DNS name to IP and attempt TCP connection on 443 $RequiredResources = @( "login.microsoftonline-p.com", "login.live.com", "online.dynamics.com", "login.windows.net", "secure.aadcdn.microsoftonline-p.com", "mbs.microsoft.com", "go.microsoft.com", "urs.microsoft.com", "auth.gfx.ms", # "sc.imp.live.com", # URL does not have valid DNS "dynamicscrmemea.accesscontrol.windows.net", "nexus.passport.com", # in place of passport.net, since can't find a valid endpoint "clientconfig.passport.net", "login.microsoftonline.com", "home.dynamics.com", "crmcdn.azureedge.net", # in place of *.azureedge.net "www.crmdynint.com", # "cloudredirectoreursec.cloudapp.net", # URL does not have valid DNS # "cloudredirectoreur.cloudapp.net", # URL does not have valid DNS "mem.gfx.ms", "test.crm4.dynamics.com" # used in place of *.crm4.dynamics.com "www.d365ccafpi.com") # Resolve DNS and attempt to retrieve data from endpoint $RequiredResourcesEndpoints = @( "http://clientconfig.passport.net/ppcrlconfig.bin", "http://disco.crm4.dynamics.com/XRMServices/2011/Discovery.svc", "https://disco.crm4.dynamics.com/XRMServices/2011/Discovery.svc" "https://login.windows.net", "https://secure.aadcdn.microsoftonline-p.com/ests/2.1.5975.9/content/cdnbundles/jquery.1.11.min.js") # Use Optional resources for addtional services. $OptionalResources = @() # Optional resources endpoints. Specify as exact URI to download/test, such as # https://endpoint.domain.com/uri.svc $OptionalResourcesEndpoints = @() # Use the AdditionalResources array to specify items that need a port test on a port other # than 80 or 443. Specify as endpoint:port $AdditionalResources = @() } 'APAC' { Write-Log -LogFile $Logfile -LogLevel INFO -Message "Starting Online Endpoints tests (Europe, Middle East, and Africa)." Write-Log -LogFile $Logfile -LogLevel INFO -Message "See https://support.microsoft.com/en-us/help/2655102/internet-accessible-urls-required-for-connectivity-to-microsoft-dynami" Write-Log -LogFile $Logfile -LogLevel INFO -Message "for more details on endpoints." # Test on port 80 to retrieve CRL $CRL = @( "http://crl.microsoft.com/pki/crl/products/microsoftrootcert.crl", "http://mscrl.microsoft.com/pki/mscorp/crl/msitwww2.crl", "http://ocsp.verisign.com", "http://ocsp.entrust.net") # Resolve DNS name to IP and attempt TCP connection on 443 $RequiredResources = @( "login.microsoftonline-p.com", "login.live.com", "online.dynamics.com", "login.windows.net", "secure.aadcdn.microsoftonline-p.com", "mbs.microsoft.com", "go.microsoft.com", "urs.microsoft.com", "auth.gfx.ms", # "sc.imp.live.com", # URL does not have valid DNS "dynamicscrmapac.accesscontrol.windows.net", "nexus.passport.com", # in place of passport.net, since can't find a valid endpoint "clientconfig.passport.net", "login.microsoftonline.com", "home.dynamics.com", "crmcdn.azureedge.net", # in place of *.azureedge.net "www.crmdynint.com", # "cloudredirectorapjsec.cloudapp.net", # URL does not have valid DNS # "cloudredirectorapj.cloudapp.net", # URL does not have valid DNS "mem.gfx.ms", "test.crm5.dynamics.com" # used in place of *.crm2.dynamics.com "www.d365ccafpi.com") # Resolve DNS and attempt to retrieve data from endpoint $RequiredResourcesEndpoints = @( "http://clientconfig.passport.net/ppcrlconfig.bin", "http://disco.crm5.dynamics.com/XRMServices/2011/Discovery.svc", "https://disco.crm5.dynamics.com/XRMServices/2011/Discovery.svc" "https://login.windows.net", "https://secure.aadcdn.microsoftonline-p.com/ests/2.1.5975.9/content/cdnbundles/jquery.1.11.min.js") # Use Optional resources for addtional services. $OptionalResources = @() # Optional resources endpoints. Specify as exact URI to download/test, such as # https://endpoint.domain.com/uri.svc $OptionalResourcesEndpoints = @() # Use the AdditionalResources array to specify items that need a port test on a port other # than 80 or 443. Specify as endpoint:port $AdditionalResources = @() } 'JP' { Write-Log -LogFile $Logfile -LogLevel INFO -Message "Starting Online Endpoints tests (Europe, Middle East, and Africa)." Write-Log -LogFile $Logfile -LogLevel INFO -Message "See https://support.microsoft.com/en-us/help/2655102/internet-accessible-urls-required-for-connectivity-to-microsoft-dynami" Write-Log -LogFile $Logfile -LogLevel INFO -Message "for more details on endpoints." # Test on port 80 to retrieve CRL $CRL = @( "http://crl.microsoft.com/pki/crl/products/microsoftrootcert.crl", "http://mscrl.microsoft.com/pki/mscorp/crl/msitwww2.crl", "http://ocsp.verisign.com", "http://ocsp.entrust.net") # Resolve DNS name to IP and attempt TCP connection on 443 $RequiredResources = @( "login.microsoftonline-p.com", "login.live.com", "online.dynamics.com", "login.windows.net", "secure.aadcdn.microsoftonline-p.com", "mbs.microsoft.com", "go.microsoft.com", "urs.microsoft.com", "auth.gfx.ms", # "sc.imp.live.com", # URL does not have valid DNS "dynamicscrmjpn.accesscontrol.windows.net", "nexus.passport.com", # in place of passport.net, since can't find a valid endpoint "clientconfig.passport.net", "login.microsoftonline.com", "home.dynamics.com", "crmcdn.azureedge.net", # in place of *.azureedge.net "www.crmdynint.com", # "cloudredirectorjpnsec.cloudapp.net", # URL does not have valid DNS # "cloudredirectorjpn.cloudapp.net", # URL does not have valid DNS "mem.gfx.ms", "test.crm7.dynamics.com" # used in place of *.crm2.dynamics.com "www.d365ccafpi.com") # Resolve DNS and attempt to retrieve data from endpoint $RequiredResourcesEndpoints = @( "http://clientconfig.passport.net/ppcrlconfig.bin", "http://disco.crm7.dynamics.com/XRMServices/2011/Discovery.svc", "https://disco.crm7.dynamics.com/XRMServices/2011/Discovery.svc" "https://login.windows.net", "https://secure.aadcdn.microsoftonline-p.com/ests/2.1.5975.9/content/cdnbundles/jquery.1.11.min.js") # Use Optional resources for addtional services. $OptionalResources = @() # Optional resources endpoints. Specify as exact URI to download/test, such as # https://endpoint.domain.com/uri.svc $OptionalResourcesEndpoints = @() # Use the AdditionalResources array to specify items that need a port test on a port other # than 80 or 443. Specify as endpoint:port $AdditionalResources = @() } 'IN' { Write-Log -LogFile $Logfile -LogLevel INFO -Message "Starting Online Endpoints tests (Europe, Middle East, and Africa)." Write-Log -LogFile $Logfile -LogLevel INFO -Message "See https://support.microsoft.com/en-us/help/2655102/internet-accessible-urls-required-for-connectivity-to-microsoft-dynami" Write-Log -LogFile $Logfile -LogLevel INFO -Message "for more details on endpoints." # Test on port 80 to retrieve CRL $CRL = @( "http://crl.microsoft.com/pki/crl/products/microsoftrootcert.crl", "http://mscrl.microsoft.com/pki/mscorp/crl/msitwww2.crl", "http://ocsp.verisign.com", "http://ocsp.entrust.net") # Resolve DNS name to IP and attempt TCP connection on 443 $RequiredResources = @( "login.microsoftonline-p.com", "login.live.com", "online.dynamics.com", "login.windows.net", "secure.aadcdn.microsoftonline-p.com", "mbs.microsoft.com", "go.microsoft.com", "urs.microsoft.com", "auth.gfx.ms", # "sc.imp.live.com", # URL does not have valid DNS "dynamicscrmind.accesscontrol.windows.net", "nexus.passport.com", # in place of passport.net, since can't find a valid endpoint "clientconfig.passport.net", "login.microsoftonline.com", "home.dynamics.com", "crmcdn.azureedge.net", # in place of *.azureedge.net "www.crmdynint.com", # "cloudredirectorindsec.cloudapp.net", # URL does not have valid DNS # "cloudredirectorind.cloudapp.net", # URL does not have valid DNS "mem.gfx.ms", "test.crm8.dynamics.com" # used in place of *.crm2.dynamics.com "www.d365ccafpi.com") # Resolve DNS and attempt to retrieve data from endpoint $RequiredResourcesEndpoints = @( "http://clientconfig.passport.net/ppcrlconfig.bin", "http://disco.crm8.dynamics.com/XRMServices/2011/Discovery.svc", "https://disco.crm8.dynamics.com/XRMServices/2011/Discovery.svc" "https://login.windows.net", "https://secure.aadcdn.microsoftonline-p.com/ests/2.1.5975.9/content/cdnbundles/jquery.1.11.min.js") # Use Optional resources for addtional services. $OptionalResources = @() # Optional resources endpoints. Specify as exact URI to download/test, such as # https://endpoint.domain.com/uri.svc $OptionalResourcesEndpoints = @() # Use the AdditionalResources array to specify items that need a port test on a port other # than 80 or 443. Specify as endpoint:port $AdditionalResources = @() } 'CA' { Write-Log -LogFile $Logfile -LogLevel INFO -Message "Starting Online Endpoints tests (Europe, Middle East, and Africa)." Write-Log -LogFile $Logfile -LogLevel INFO -Message "See https://support.microsoft.com/en-us/help/2655102/internet-accessible-urls-required-for-connectivity-to-microsoft-dynami" Write-Log -LogFile $Logfile -LogLevel INFO -Message "for more details on endpoints." # Test on port 80 to retrieve CRL $CRL = @( "http://crl.microsoft.com/pki/crl/products/microsoftrootcert.crl", "http://mscrl.microsoft.com/pki/mscorp/crl/msitwww2.crl", "http://ocsp.verisign.com", "http://ocsp.entrust.net") # Resolve DNS name to IP and attempt TCP connection on 443 $RequiredResources = @( "login.microsoftonline-p.com", "login.live.com", "online.dynamics.com", "login.windows.net", "secure.aadcdn.microsoftonline-p.com", "mbs.microsoft.com", "go.microsoft.com", "urs.microsoft.com", "auth.gfx.ms", # "sc.imp.live.com", # URL does not have valid DNS "dynamicscrmcan.accesscontrol.windows.net", "nexus.passport.com", # in place of passport.net, since can't find a valid endpoint "clientconfig.passport.net", "login.microsoftonline.com", "home.dynamics.com", "crmcdn.azureedge.net", # in place of *.azureedge.net "www.crmdynint.com", # "cloudredirectorcansec.cloudapp.net", # URL does not have valid DNS # "cloudredirectorcan.cloudapp.net", # URL does not have valid DNS "mem.gfx.ms", "test.crm3.dynamics.com" # used in place of *.crm2.dynamics.com "www.d365ccafpi.com") # Resolve DNS and attempt to retrieve data from endpoint $RequiredResourcesEndpoints = @( "http://clientconfig.passport.net/ppcrlconfig.bin", "http://disco.crm3.dynamics.com/XRMServices/2011/Discovery.svc", "https://disco.crm3.dynamics.com/XRMServices/2011/Discovery.svc" "https://login.windows.net", "https://secure.aadcdn.microsoftonline-p.com/ests/2.1.5975.9/content/cdnbundles/jquery.1.11.min.js") # Use Optional resources for addtional services. $OptionalResources = @() # Optional resources endpoints. Specify as exact URI to download/test, such as # https://endpoint.domain.com/uri.svc $OptionalResourcesEndpoints = @() # Use the AdditionalResources array to specify items that need a port test on a port other # than 80 or 443. Specify as endpoint:port $AdditionalResources = @() } 'Oceania' { Write-Log -LogFile $Logfile -LogLevel INFO -Message "Starting Online Endpoints tests (Europe, Middle East, and Africa)." Write-Log -LogFile $Logfile -LogLevel INFO -Message "See https://support.microsoft.com/en-us/help/2655102/internet-accessible-urls-required-for-connectivity-to-microsoft-dynami" Write-Log -LogFile $Logfile -LogLevel INFO -Message "for more details on endpoints." # Test on port 80 to retrieve CRL $CRL = @( "http://crl.microsoft.com/pki/crl/products/microsoftrootcert.crl", "http://mscrl.microsoft.com/pki/mscorp/crl/msitwww2.crl", "http://ocsp.verisign.com", "http://ocsp.entrust.net") # Resolve DNS name to IP and attempt TCP connection on 443 $RequiredResources = @( "login.microsoftonline-p.com", "login.live.com", "online.dynamics.com", "login.windows.net", "secure.aadcdn.microsoftonline-p.com", "mbs.microsoft.com", "go.microsoft.com", "urs.microsoft.com", "auth.gfx.ms", # "sc.imp.live.com", # URL does not have valid DNS "dynamicscrmoce.accesscontrol.windows.net", "nexus.passport.com", # in place of passport.net, since can't find a valid endpoint "clientconfig.passport.net", "login.microsoftonline.com", "home.dynamics.com", "crmcdn.azureedge.net", # in place of *.azureedge.net "www.crmdynint.com", # "cloudredirectorocesec.cloudapp.net", # URL does not have valid DNS # "cloudredirectoroce.cloudapp.net", # URL does not have valid DNS "mem.gfx.ms", "test.crm6.dynamics.com" # used in place of *.crm2.dynamics.com "www.d365ccafpi.com") # Resolve DNS and attempt to retrieve data from endpoint $RequiredResourcesEndpoints = @( "http://clientconfig.passport.net/ppcrlconfig.bin", "http://disco.crm6.dynamics.com/XRMServices/2011/Discovery.svc", "https://disco.crm6.dynamics.com/XRMServices/2011/Discovery.svc" "https://login.windows.net", "https://secure.aadcdn.microsoftonline-p.com/ests/2.1.5975.9/content/cdnbundles/jquery.1.11.min.js") # Use Optional resources for addtional services. $OptionalResources = @() # Optional resources endpoints. Specify as exact URI to download/test, such as # https://endpoint.domain.com/uri.svc $OptionalResourcesEndpoints = @() # Use the AdditionalResources array to specify items that need a port test on a port other # than 80 or 443. Specify as endpoint:port $AdditionalResources = @() } 'UK' { Write-Log -LogFile $Logfile -LogLevel INFO -Message "Starting Online Endpoints tests (Europe, Middle East, and Africa)." Write-Log -LogFile $Logfile -LogLevel INFO -Message "See https://support.microsoft.com/en-us/help/2655102/internet-accessible-urls-required-for-connectivity-to-microsoft-dynami" Write-Log -LogFile $Logfile -LogLevel INFO -Message "for more details on endpoints." # Test on port 80 to retrieve CRL $CRL = @( "http://crl.microsoft.com/pki/crl/products/microsoftrootcert.crl", "http://mscrl.microsoft.com/pki/mscorp/crl/msitwww2.crl", "http://ocsp.verisign.com", "http://ocsp.entrust.net") # Resolve DNS name to IP and attempt TCP connection on 443 $RequiredResources = @( "login.microsoftonline-p.com", "login.live.com", "online.dynamics.com", "login.windows.net", "secure.aadcdn.microsoftonline-p.com", "mbs.microsoft.com", "go.microsoft.com", "urs.microsoft.com", "auth.gfx.ms", # "sc.imp.live.com", # URL does not have valid DNS "dynamicscrmoce.accesscontrol.windows.net", "nexus.passport.com", # in place of passport.net, since can't find a valid endpoint "clientconfig.passport.net", "login.microsoftonline.com", "home.dynamics.com", "crmcdn.azureedge.net", # in place of *.azureedge.net "www.crmdynint.com", # "cloudredirectorocesec.cloudapp.net", # URL does not have valid DNS # "cloudredirectoroce.cloudapp.net", # URL does not have valid DNS "mem.gfx.ms", "test.crm11.dynamics.com" # used in place of *.crm2.dynamics.com "www.d365ccafpi.com") # Resolve DNS and attempt to retrieve data from endpoint $RequiredResourcesEndpoints = @( "http://clientconfig.passport.net/ppcrlconfig.bin", "http://disco.crm11.dynamics.com/XRMServices/2011/Discovery.svc", "https://disco.crm11.dynamics.com/XRMServices/2011/Discovery.svc" "https://login.windows.net", "https://secure.aadcdn.microsoftonline-p.com/ests/2.1.5975.9/content/cdnbundles/jquery.1.11.min.js") # Use Optional resources for addtional services. $OptionalResources = @() # Optional resources endpoints. Specify as exact URI to download/test, such as # https://endpoint.domain.com/uri.svc $OptionalResourcesEndpoints = @() # Use the AdditionalResources array to specify items that need a port test on a port other # than 80 or 443. Specify as endpoint:port $AdditionalResources = @() } } # CRL Endpoint tests Write-Log -LogFile $Logfile -LogLevel INFO -Message "Testing CRL endpoint tests (Invoke-WebRequest)." -ConsoleOutput foreach ($url in $CRL) { try { $Result = Invoke-WebRequest -Uri $url -ea stop -wa silentlycontinue Switch ($Result.StatusCode) { 200 { Write-Log -LogFile $Logfile -LogLevel SUCCESS -Message "Successfully obtained CRL from $($url)." -ConsoleOutput } 400 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to obtain CRL from $($url): Bad request." -ConsoleOutput } 401 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to obtain CRL from $($url): Unauthorized." -ConsoleOutput } 403 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to obtain CRL from $($url): Forbidden." -ConsoleOutput } 404 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to obtain CRL from $($url): Not found." -ConsoleOutput } 407 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to obtain CRL from $($url): Proxy authentication required." -ConsoleOutput } 502 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to obtain CRL from $($url): Bad gateway (likely proxy)." -ConsoleOutput } 503 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to obtain CRL from $($url): Service unavailable (transient, try again)." -ConsoleOutput } 504 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to obtain CRL from $($url): Gateway timeout (likely proxy)." -ConsoleOutput } default { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Unable to obtain CRL from $($url)" -ConsoleOutput Write-Log -LogFile $Logfile -LogLevel ERROR -Message "$($Result)" } } } catch { $ErrorMessage = $_ Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Exception: Unable to obtain CRL from $($url)" -ConsoleOutput Write-Log -LogFile $Logfile -LogLevel ERROR -Message $($ErrorMessage) } finally { If ($DebugLogging) { Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Debug log entry for $($url)." Write-Log -LogFile $Logfile -LogLevel DEBUG -Message $Result.StatusCode Write-Log -LogFile $Logfile -LogLevel DEBUG -Message $Result.StatusDescription If ($Result.RawContent.Length -lt 400) { $DebugContent = $Result.RawContent -join ";" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message $DebugContent } Else { $DebugContent = $Result.RawContent.Substring(0, 400) -join ";" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message $DebugContent } } } } # End Foreach CRL # Required Resource tests Write-Log -LogFile $Logfile -LogLevel INFO -Message "Testing Required Resources (TCP:443)." -ConsoleOutput foreach ($url in $RequiredResources) { [array]$ResourceAddresses = (Resolve-DnsName $url).IP4Address foreach ($ip4 in $ResourceAddresses) { try { $Result = Test-NetConnection $ip4 -Port 443 -ea stop -wa silentlycontinue switch ($Result.TcpTestSucceeded) { true { Write-Log -LogFile $Logfile -LogLevel SUCCESS -Message "TCP connection to $($url) [$($ip4)]:443 successful." -ConsoleOutput } false { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "TCP connection to $($url) [$($ip4)]:443 failed." -ConsoleOutput } } } catch { $ErrorMessage = $_ Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Error resolving or connecting to $($url) [$($ip4)]:443" -ConsoleOutput Write-Log -LogFile $Logfile -LogLevel ERROR -Message $($Error) } finally { If ($DebugLogging) { Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Debug log entry for $($url) [$($Result.RemoteAddress)]:443." Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Remote endpoint: $($url)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Remote port: $($Result.RemotePort)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Interface Alias: $($Result.InterfaceAlias)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Source Interface Address: $($Result.SourceAddress.IPAddress)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Ping Succeeded: $($Result.PingSucceeded)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Ping Reply Time (RTT) Status: $($Result.PingReplyDetails.Status)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Ping Reply Time (RTT) RoundTripTime: $($Result.PingReplyDetails.RoundtripTime)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "TCPTestSucceeded: $($Result.TcpTestSucceeded)" } } } } # End Foreach Resources # Optional Resources tests If ($OptionalResources) { Write-Log -LogFile $Logfile -LogLevel INFO -Message "Testing Optional Resources (TCP:443)." -ConsoleOutput foreach ($url in $OptionalResources) { [array]$OptionalResourceAddresses = (Resolve-DnsName $url).IP4Address foreach ($ip4 in $OptionalResourceAddresses) { try { $Result = Test-NetConnection $ip4 -Port 443 -ea stop -wa silentlycontinue switch ($Result.TcpTestSucceeded) { true { Write-Log -LogFile $Logfile -LogLevel SUCCESS -Message "TCP connection to $($url) [$($ip4)]:443 successful." -ConsoleOutput } false { Write-Log -LogFile $Logfile -LogLevel WARN -Message "TCP connection to $($url) [$($ip4)]:443 failed." -ConsoleOutput If ($DebugLogging) { Write-Log -LogFile $Logfile -LogLevel DEBUG -Message $($Result) } } } } catch { $ErrorMessage = $_ Write-Log -LogFile $Logfile -LogLevel WARN -Message "Error resolving or connecting to $($url) [$($ip4)]:443" -ConsoleOutput Write-Log -LogFile $Logfile -LogLevel WARN -Message $($ErrorMessage) } finally { If ($DebugLogging) { Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Debug log entry for $($url) [$($Result.RemoteAddress)]:443." Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Remote endpoint: $($url)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Remote port: $($Result.RemotePort)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Interface Alias: $($Result.InterfaceAlias)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Source Interface Address: $($Result.SourceAddress.IPAddress)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Ping Succeeded: $($Result.PingSucceeded)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Ping Reply Time (RTT) Status: $($Result.PingReplyDetails.Status)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Ping Reply Time (RTT) RoundTripTime: $($Result.PingReplyDetails.RoundtripTime)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "TCPTestSucceeded: $($Result.TcpTestSucceeded)" } } } } # End Foreach OptionalResources } # Required Resources Endpoints tests Write-Log -LogFile $Logfile -LogLevel INFO -Message "Testing Required Resources Endpoints (Invoke-Webrequest)." -ConsoleOutput foreach ($url in $RequiredResourcesEndpoints) { try { $Result = Invoke-WebRequest -Uri $url -ea stop -wa silentlycontinue Switch ($Result.StatusCode) { 200 { Write-Log -LogFile $Logfile -LogLevel SUCCESS -Message "Successfully connected to $($url)." -ConsoleOutput } 400 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to contact $($url): Bad request." -ConsoleOutput } 401 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to contact $($url): Unauthorized." -ConsoleOutput } 403 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to contact $($url): Forbidden." -ConsoleOutput } 404 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to contact $($url): Not found." -ConsoleOutput } 407 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to contact $($url): Proxy authentication required." -ConsoleOutput } 502 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to contact $($url): Bad gateway (likely proxy)." -ConsoleOutput } 503 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to contact $($url): Service unavailable (transient, try again)." -ConsoleOutput } 504 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to contact $($url): Gateway timeout (likely proxy)." -ConsoleOutput } default { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "OTHER: Failed to contact $($url)" -ConsoleOutput Write-Log -LogFile $Logfile -LogLevel ERROR -Message "$($Result)" -ConsoleOutput } } } catch { $ErrorMessage = $_ Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Exception: Unable to contact $($url)" -ConsoleOutput Write-Log -LogFile $Logfile -LogLevel ERROR -Message $($ErrorMessage) } finally { If ($DebugLogging) { Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Debug log entry for $($url)." Write-Log -LogFile $Logfile -LogLevel DEBUG -Message $Result.StatusCode Write-Log -LogFile $Logfile -LogLevel DEBUG -Message $Result.StatusDescription If ($Result.RawContent.Length -lt 400) { $DebugContent = $Result.RawContent -join ";" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message $DebugContent } Else { $DebugContent = $Result.RawContent -join ";" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message $DebugContent.Substring(0, 400) } } } } # End Foreach RequiredResourcesEndpoints # Optional Resources Endpoints tests If ($OptionalResourcesEndpoints) { Write-Log -LogFile $Logfile -LogLevel INFO -Message "Testing Optional Resources Endpoints (Invoke-Webrequest)." -ConsoleOutput foreach ($url in $OptionalResourcesEndpoints) { try { $Result = Invoke-WebRequest -Uri $url -ea stop -wa silentlycontinue Switch ($Result.StatusCode) { 200 { Write-Log -LogFile $Logfile -LogLevel SUCCESS -Message "Successfully connected to $($url)." -ConsoleOutput } 400 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to contact $($url): Bad request." -ConsoleOutput } 401 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to contact $($url): Unauthorized." -ConsoleOutput } 403 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to contact $($url): Forbidden." -ConsoleOutput } 404 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to contact $($url): Not found." -ConsoleOutput } 407 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to contact $($url): Proxy authentication required." -ConsoleOutput } 502 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to contact $($url): Bad gateway (likely proxy)." -ConsoleOutput } 503 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to contact $($url): Service unavailable (transient, try again)." -ConsoleOutput } 504 { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Failed to contact $($url): Gateway timeout (likely proxy)." -ConsoleOutput } default { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "OTHER: Failed to contact $($url)" -ConsoleOutput Write-Log -LogFile $Logfile -LogLevel ERROR -Message "$($Result)" -ConsoleOutput } } } catch { $ErrorMessage = $_ Write-Log -LogFile $Logfile -LogLevel ERROR -Message "Exception: Unable to contact $($url)" -ConsoleOutput Write-Log -LogFile $Logfile -LogLevel ERROR -Message $($ErrorMessage) } finally { If ($DebugLogging) { Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Debug log entry for $($url)." Write-Log -LogFile $Logfile -LogLevel DEBUG -Message $Result.StatusCode Write-Log -LogFile $Logfile -LogLevel DEBUG -Message $Result.StatusDescription If ($Result.RawContent.Length -lt 400) { $DebugContent = $Result.RawContent -join ";" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message $DebugContent } Else { $DebugContent = $Result.RawContent -join ";" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message $DebugContent.Substring(0, 400) } } } } # End Foreach RequiredResourcesEndpoints } # Additional Resources tests If ($AdditionalResources) { Write-Log -LogFile $Logfile -LogLevel INFO -Message "Testing Additional Resources Endpoints (Invoke-Webrequest)." -ConsoleOutput foreach ($url in $AdditionalResources) { if ($url -match "\:") { $Name = $url.Split(":")[0] [array]$Resources = (Resolve-DnsName $Name).Ip4Address $ResourcesPort = $url.Split(":")[1] } Else { $Name = $url [array]$Resources = (Resolve-DnsName $Name).IP4Address $ResourcesPort = "443" } foreach ($ip4 in $Resources) { try { $Result = Test-NetConnection $ip4 -Port $ResourcesPort -ea stop -wa silentlycontinue switch ($Result.TcpTestSucceeded) { true { Write-Log -LogFile $Logfile -LogLevel SUCCESS -Message "TCP connection to $($Name) [$($ip4)]:$($ResourcesPort) successful." -ConsoleOutput } false { Write-Log -LogFile $Logfile -LogLevel WARN -Message "TCP connection to $($Name) [$($ip4)]:$($ResourcesPort) failed." -ConsoleOutput If ($DebugLogging) { Write-Log -LogFile $Logfile -LogLevel DEBUG -Message $($Result) } } } } catch { $ErrorMessage = $_ Write-Log -LogFile $Logfile -LogLevel WARN -Message "Error resolving or connecting to $($Name) [$($ip4)]:$($ResourcesPort)" -ConsoleOutput Write-Log -LogFile $Logfile -LogLevel WARN -Message $($ErrorMessage) } finally { If ($DebugLogging) { Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Debug log entry for $($Name) [$($Result.RemoteAddress)]:443." Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Remote endpoint: $($Name)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Remote port: $($Result.RemotePort)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Interface Alias: $($Result.InterfaceAlias)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Source Interface Address: $($Result.SourceAddress.IPAddress)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Ping Succeeded: $($Result.PingSucceeded)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Ping Reply Time (RTT) Status: $($Result.PingReplyDetails.Status)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Ping Reply Time (RTT) RoundTripTime: $($Result.PingReplyDetails.RoundtripTime)" Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "TCPTestSucceeded: $($Result.TcpTestSucceeded)" } } } } # End ForEach AdditionalResources } # End IF AdditionalResources Write-Log -LogFile $Logfile -LogLevel INFO -Message "Finished Online Endpoints tests." } # End Function OnlineEndPoints function SystemConfiguration { ## Show system configuration Write-Log -LogFile $Logfile -LogLevel INFO -Message "Starting system configuration gathering." [string]$OSVersion = ([System.Environment]::OSVersion.Version.Major.ToString() + "." + [System.Environment]::OSVersion.Version.Minor.ToString()) [string]$OperatingSystem = (Get-WmiObject -Class Win32_OperatingSystem -Namespace "root\cimv2").Caption [string]$OSBitness = [System.Environment]::Is64BitOperatingSystem [string]$OSMachineName = [System.Environment]::MachineName.ToString() $bytes = (Get-WmiObject -class "cim_physicalmemory" | Measure-Object -Property Capacity -Sum).Sum $gb = $bytes/1073741824 Write-Log -LogFile $Logfile -LogLevel INFO -Message "System name: $($OSMachineName)" Write-Log -LogFile $Logfile -LogLevel INFO -Message "64-bit operating system detected: $($OSBitness)" Write-Log -LogFile $Logfile -LogLevel INFO -Message "Operating System: $($OperatingSystem) $($OSVersion)" Write-Log -LogFile $Logfile -LogLevel INFO -Message "System memory: $($gb) GB" If ($bytes) { switch ($gb) { ({ $_ -lt 2 }) { Write-Log -ConsoleOutput -LogFile $Logfile -LogLevel ERROR -Message "This computer does not meet the minimum memory recommendation of 2GB." } ({ $_ -lt 4 }) { Write-Log -LogFile $Logfile -LogLevel INFO -Message "This computer meets the minimum memory recommendation of 2GB." } ({ $_ -ge 4 }) { Write-Log -LogFile $Logfile -LogLevel INFO -Message "This computer meets or exceeds recommended memory recommendation of 4GB." } } } ## Browser versions # Internet Explorer Write-Log -LogFile $Logfile -LogLevel INFO -Message "Checking browser versions." -ConsoleOutput If ((Get-ItemProperty -ea silentlycontinue 'HKLM:\SOFTWARE\Microsoft\Internet Explorer').svcVersion) { $IEVersion = (Get-ItemProperty -ea silentlycontinue 'HKLM:\SOFTWARE\Microsoft\Internet Explorer').svcVersion } Else { $IEVersion = (Get-ItemProperty -ea silentlycontinue 'HKLM:\SOFTWARE\Microsoft\Internet Explorer').Version } # Firefox If ((Get-ItemProperty -ea silentlycontinue 'HKLM:\SOFTWARE\Mozilla\Mozilla Firefox').'(Default)') { $FirefoxVersion = (Get-ItemProperty -ea silentlycontinue 'HKLM:\SOFTWARE\Mozilla\Mozilla Firefox').'(Default)' } # Chrome Try { If ((Get-Item -ea silentlycontinue (Get-ItemProperty -ea silentlycontinue 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe').'(Default)').VersionInfo.ProductVersion) { $ChromeVersion = (Get-Item -ea silentlycontinue (Get-ItemProperty -ea silentlycontinue 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe').'(Default)').VersionInfo.ProductVersion $ChromeVersion = $ChromeVersion.Split(".")[0] } } catch { # Chrome is not installed } # Edge If ($OSVersion -eq "10.0") { $EdgePath = (Get-AppxPackage Microsoft.MicrosoftEdge -ea silentlycontinue).InstallLocation + "\MicrosoftEdge.exe" $EdgeVersion = (Get-ItemProperty $EdgePath -ea silentlycontinue).VersionInfo.ProductVersion } If ($IEVersion) { Write-Log -LogFile $Logfile -LogLevel INFO -Message "Internet Explorer Version $($IEVersion) detected." If (($IEVersion.Split(".")[0]) -ge 10) { Write-Log -LogFile $Logfile -LogLevel SUCCESS -Message "This computer has a supported version of Internet Explorer." } Else { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "This computer does not have a supported version of Internet Explorer." } } If ($FirefoxVersion) { Write-Log -LogFile $Logfile -LogLevel INFO -Message "Mozilla Firefox Version $($FirefoxVersion) detected." If (($FirefoxVersion.Split(".")[0]) -ge 60) { Write-Log -LogFile $Logfile -LogLevel SUCCESS -Message "This computer has a supported version of Mozilla Firefox." } Else { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "This computer does not have a supported version of Mozilla Firefox." } } If ($ChromeVersion) { Write-Log -LogFile $Logfile -LogLevel INFO -Message "Google Chrome Version $($ChromeVersion) detected." If (($ChromeVersion.Split(".")[0]) -ge 67) { Write-Log -LogFile $Logfile -LogLevel SUCCESS -Message "This computer has a supported version of Google Chrome." } Else { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "This computer does not have a supported version of Google Chrome." } } If ($EdgeVersion) { Write-Log -LogFile $Logfile -LogLevel INFO -Message "Microsoft Edge $($EdgeVersion) detected." If (($EdgeVersion.Split(".")[0]) -ge 11) { Write-Log -LogFile $Logfile -LogLevel SUCCESS -Message "This computer has a supported version of Microsoft Edge." } Else { Write-Log -LogFile $Logfile -LogLevel ERROR -Message "This computer does not have a supported version of Microsoft Edge." } } # Netsh WinHTTP proxy Write-Log -LogFile $Logfile -LogLevel INFO -Message "WinHTTP proxy settings (netsh winhttp show proxy):" $WinHTTPProxy = (netsh winhttp show proxy) $WinHTTPProxy = ($WinHTTPProxy -join " ").Trim() Write-Log -LogFile $Logfile -LogLevel INFO -Message $WinHTTPProxy # .NET Proxy Write-Log -LogFile $Logfile -LogLevel INFO -Message ".NET proxy settings (machine.config/configuration/system.net/defaultproxy):" [xml]$machineconfig = gc $env:windir\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config if (!$machineconfig.configuration.'system.net'.defaultproxy) { Write-Log -LogFile $Logfile -LogLevel INFO -Message "No proxy configuration exists in $env:windir\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config." } else { Write-Log -LogFile $Logfile -LogLevel INFO -Message "The following proxy configuration exists in $env:windir\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config." $nodes = $machineconfig.ChildNodes.SelectNodes("/configuration/system.net/defaultproxy/proxy") | Sort -Unique Write-Log -Logfile $Logfile -LogLevel INFO -Message "UseSystemDefault: $($nodes.usesystemdefault)" Write-Log -LogFile $Logfile -LogLevel INFO -Message "ProxyAddress: $($nodes.proxyaddress)" Write-Log -LogFile $Logfile -LogLevel INFO -Message "BypassOnLocal $($nodes.bypassonlocal)" } Write-Log -LogFile $Logfile -LogLevel INFO -Message "For more .NET proxy configuration parameters, see https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/network/proxy-element-network-settings" # Check for TLS capabilities switch ($OSVersion) { "10.0" { Write-Log -Logfile $Logfile -ConsoleOutput -LogLevel INFO -Message "Checking TLS settings for Windows 10 or Windows Server 2016." $KeysArray = @( @{ Path = "HKLM:SOFTWARE\Microsoft\.NETFramework\v4.0.30319"; Item = "SchUseStrongCrypto"; type = "REG_DWORD"; Value = "1" }, @{ Path = "HKLM:SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319"; Item = "SchUseStrongCrypto"; type = "REG_DWORD"; Value = "1" } ) } # End 10.0 / Windows Server 2016 "6.3" { Write-Log -Logfile $Logfile -ConsoleOutput -LogLevel INFO -Message "Checking TLS settings for Windows 8.1 or Server 2012 R2." $KeysArray = @( @{ Path = "HKLM:SOFTWARE\Microsoft\.NETFramework\v4.0.30319"; Item = "SchUseStrongCrypto"; type = "REG_DWORD"; Value = "1" }, @{ Path = "HKLM:SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319"; Item = "SchUseStrongCrypto"; type = "REG_DWORD"; Value = "1" } ) } # End 6.3 / Windows Server 2012 R2 "6.2" { Write-Log -Logfile $Logfile -ConsoleOutput -LogLevel INFO -Message "Checking TLS settings for Windows 8 Server 2012." $KeysArray = @( @{ Path = "HKLM:SOFTWARE\Microsoft\.NETFramework\v4.0.30319"; Item = "SchUseStrongCrypto"; type = "REG_DWORD"; Value = "1" }, @{ Path = "HKLM:SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319"; Item = "SchUseStrongCrypto"; type = "REG_DWORD"; Value = "1" } ) } # End 6.2 / Windows Server 2012 "6.1" { Write-Log -Logfile $Logfile -ConsoleOutput -LogLevel INFO -Message "Checking TLS settings for Windows 7 or Windows Server Server 2008 R2." $KeysArray = @( @{ Path = "HKLM:SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client"; Item = "DisabledByDefault"; Type = "REG_DWORD"; Value = "0" }, @{ Path = "HKLM:SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client"; Item = "Enabled"; type = "REG_DWORD"; Value = "1" }, @{ Path = "HKLM:SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server"; Item = "DisabledByDefault"; type = "REG_DWORD"; Value = "0" }, @{ Path = "HKLM:SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server"; Item = "Enabled"; type = "REG_DWORD"; Value = "1" }, @{ Path = "HKLM:SOFTWARE\Microsoft\.NETFramework\v4.0.30319"; Item = "SchUseStrongCrypto"; type = "REG_DWORD"; Value = "1" }, @{ Path = "HKLM:SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319"; Item = "SchUseStrongCrypto"; type = "REG_DWORD"; Value = "1" } ) } # End 6.1 / Windows Server 2008 R2 "6.0" { Write-Log -Logfile $Logfile -ConsoleOutput -LogLevel INFO -Message "Checking TLS settings for Windows Vista or Windows Server 2008." Write-Log -LogFile $Logfile -ConsoleOutput -LogLevel WARN -Message "TLS 1.2 cannot be enabled on Windows Vista or Windows Server 2008." } # End 6.0 / Windows Vista or Windows Server 2008 default { Write-Log -LogFile $Logfile -ConsoleOutput -LogLevel WARN -Message "Unable to determine Windows Version. TLS checks will be skipped." } } If ($KeysArray) { foreach ($Key in $KeysArray) { try { $Result = (Get-ItemProperty -erroraction SilentlyContinue $Key.Path).$($Key.Item).ToString() If ($Result) { If ($Result -match $Key.Value) { Write-Log -LogFile $Logfile -LogLevel INFO -Message "Key $($Key.Path)\$($Key.Item) with a value of $($Key.Value) is set correctly for TLS 1.2 Configuration." } Else { $RegKeyPath = ($Key.Path).Replace(":", "\") Write-Log -LogFile $Logfile -LogLevel INFO -Message "Key $($Key.Path)\$($Key.Item) with a value of $($Key.Value) is not set correctly for TLS 1.2 Configuration." Write-Log -LogFile $LogFile -LogLevel INFO -Message "Key $($Key.Path)\$($Key.Item) must be set to $($Key.Value) for TLS 1.2 support." Write-Log -LogFile $Logfile -LogLevel INFO -Message "To configure, run: REG ADD ""$($RegKeyPath)"" /v $($Key.Item) /d $($Key.Value) /t REG_DWORD /f" } } Else { $RegKeyPath = ($Key.Path).Replace(":", "\") Write-Log -LogFile $Logfile -LogLevel INFO -Message "Key $($Key.Path)\$($Key.Item) not found." Write-Log -LogFile $LogFile -LogLevel INFO -Message "Key $($Key.Path)\$($Key.Item) must be set to $($Key.Value) for TLS 1.2 support." Write-Log -LogFile $Logfile -LogLevel INFO -Message "To configure, run: REG ADD ""$($RegKeyPath)"" /v $($Key.Item) /d $($Key.Value) /t REG_DWORD /f" } } Catch { $RegKeyPath = ($Key.Path).Replace(":", "\") Write-Log -LogFile $Logfile -LogLevel INFO -Message "Exception or $($Key.Path)\$($Key.Item) not found." Write-Log -LogFile $LogFile -LogLevel INFO -Message "Key $($Key.Path)\$($Key.Item) must be set to $($Key.Value) for TLS 1.2 support." Write-Log -LogFile $Logfile -LogLevel INFO -Message "To configure, run: REG ADD ""$($RegKeyPath)"" /v $($Key.Item) /d $($Key.Value) /t REG_DWORD /f" } } Write-Log -LogFile $Logfile -LogLevel INFO -Message "Finished checking for TLS 1.2 Configuration settings." } Write-Log -LogFile $Logfile -LogLevel INFO -Message "Finished gathering system configuration." } # End Function System Configuration ## Begin script Write-Log -LogFile $Logfile -LogLevel INFO -Message "=========================================================" Write-Log -LogFile $Logfile -LogLevel INFO -Message "Starting Dynamics 365 connectivity and resolution testing." # List modifier parameters to exclude from switch statement. These are the parameters that should not affect which tests are run. $Excluded = @( 'debuglogging', 'logfile', 'onlineendpointtarget') [regex]$ParametersToExclude = '(?i)^(\b' + (($Excluded | foreach { [regex]::escape($_) }) –join "\b|\b") + '\b)$' $Params = $PSBoundParameters.Keys | ? { $_ -notmatch $ParametersToExclude } If ($Params) { switch -regex ($Params) { '\bonlineendpoints\b' { OnlineEndPoints } '\bsystemconfiguration\b' { SystemConfiguration } } } else { "Running all tests." OnlineEndPoints; SystemConfiguration } Write-Log -LogFile $Logfile -LogLevel INFO -Message "Done! Logfile is $($Logfile)." -ConsoleOutput Write-Log -LogFile $Logfile -LogLevel INFO -Message "---------------------------------------------------------" |