-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Release 0.1.10 -- Added Azure Connectivity Tester
- Loading branch information
Showing
16 changed files
with
672 additions
and
16 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file added
BIN
+216 KB
PSModule/ModernWorkplaceClientCenter/Data/AzureEndpointExpectedResults.json
Binary file not shown.
Binary file not shown.
125 changes: 125 additions & 0 deletions
125
PSModule/ModernWorkplaceClientCenter/Functions/Invoke-AnalyzeAzureConnectivity.ps1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
function Invoke-AnalyzeAzureConnectivity { | ||
<# | ||
.Synopsis | ||
Analyzes the connectifity to O365 and Azure Endpoints. | ||
.Description | ||
Analyzes the connectifity to O365 and Azure Endpoints according to https://docs.microsoft.com/en-us/office365/enterprise/urls-and-ip-address-ranges. | ||
Returns array of Messages with four properties: | ||
- Testname: Name of the Tets | ||
- Type: Information, Warning or Error | ||
- Issue: Description of the issue | ||
- Possible Cause: Tips on how to solve the issue. | ||
.Example | ||
# Displays a deep analyisis of the currently found issues in the system. | ||
Invoke-AnalyzeAzureConnectivity | ||
#> | ||
[alias("Invoke-AnalyzeO365Connectivity")] | ||
[CmdletBinding()] | ||
param( | ||
[ValidateSet("Common","Exchange","Skype","SharePoint","All")] | ||
[String] | ||
$UrlSet = "Common", | ||
[Switch] | ||
$OnlyRequired | ||
) | ||
|
||
Write-Verbose "Conenctivity Tests to Azure Endpoints in $UrlSet category, which are Required=$OnlyRequired." | ||
$data = New-Object System.Collections.Generic.List[PSCustomObject] | ||
$possibleErrors = @() | ||
$results = New-Object System.Collections.Generic.List[pscustomobject] | ||
Write-Progress -Activity "Connectivity Tests" -status "Load TestUrls" -percentComplete 0 | ||
|
||
$EndpointsObjs = Get-AzureO365UrlEndpoint -Path ((Get-Item $PSScriptRoot).Parent.FullName) | ||
$EndpointsObjs = $EndpointsObjs | Where-Object { ($_.serviceArea -eq $UrlSet -or $UrlSet -eq "All") -and ($OnlyRequired -eq $false -or $_.required -eq $true)} | ||
Write-Progress -Activity "Connectivity Tests" -status "Load TestUrls finisehed" -percentComplete 100 | ||
Write-Verbose "Found $($EndpointsObjs.length) endpoints to check" | ||
$j = 0 | ||
foreach($EndpointsObj in $EndpointsObjs){ | ||
Write-Progress -Activity "Connectivity Tests" -status "Building urls for $($EndpointsObj.serviceArea) with id $($EndpointsObj.id)" -percentComplete ($j / $EndpointsObjs.length*100) | ||
if($null -ne $EndpointsObj.tcpPorts){ | ||
Add-Member -InputObject $EndpointsObj -MemberType NoteProperty -Name tcpPorts -Value "443" | ||
} | ||
foreach($Port in $EndpointsObj.tcpPorts.Split(',')){ | ||
switch ($Port) { | ||
80 {$Protocol = "http://"; $UsePort = "";$TestType="HTTP"; break} | ||
443 {$Protocol = "https://"; $UsePort = "";$TestType="HTTP"; break} | ||
default {$Protocol = ""; $UsePort = $Port;$TestType="TCP"; break} | ||
} | ||
if($EndpointsObj.PSObject.Properties.Name -match "notes"){ | ||
$Notes = " - " + $EndpointsObj.notes | ||
} else { | ||
$Notes = "" | ||
} | ||
foreach($url in $EndpointsObj.urls){ | ||
if($TestType -eq "HTTP"){ | ||
$ExpectedResult = Get-AzureEndpointExpectedResult -TestType $TestType -Url ($Protocol + $url) -Path ((Get-Item $PSScriptRoot).Parent.FullName) | ||
} else { | ||
$ExpectedResult = Get-AzureEndpointExpectedResult -TestType $TestType -Url ($url + ":" + $UsePort) -Path ((Get-Item $PSScriptRoot).Parent.FullName) | ||
} | ||
if($url -notmatch "\*"){ | ||
$data.Add([PSCustomObject]@{ TestType = $TestType; TestUrl = $url; UsePort = $UsePort; Protocol = $Protocol; UrlPattern = $url; ExpectedStatusCode = $ExpectedResult.ActualStatusCode; Description = "$($EndpointsObj.serviceAreaDisplayName)$Notes"; PerformBluecoatLookup=$false; IgnoreCertificateValidationErrors=$ExpectedResult.HasError; Blocked=$ExpectedResult.Blocked; Verbose=$false }) | ||
} else { | ||
$staticUrls = Get-UrlWildCardLookup -Url $url -Path ((Get-Item $PSScriptRoot).Parent.FullName) | ||
if($staticUrls){ | ||
foreach($staticUrl in $staticUrls){ | ||
$data.Add([PSCustomObject]@{ TestType = $TestType; TestUrl = $staticUrl; UsePort = $UsePort; Protocol = $Protocol; UrlPattern = $url; ExpectedStatusCode = $ExpectedResult.ActualStatusCode; Description = "$($EndpointsObj.serviceAreaDisplayName)$Notes"; PerformBluecoatLookup=$false; IgnoreCertificateValidationErrors=$ExpectedResult.HasError; Blocked=$ExpectedResult.Blocked; Verbose=$false }) | ||
} | ||
} else { | ||
|
||
$possibleErrors += New-AnalyzeResult -TestName "Connectivity" -Type "Warning" -Issue "Could not check connectivity to $url and Port $Port because no static url for this wildcard url was found." -PossibleCause $Cause | ||
} | ||
} | ||
} | ||
<#if($EndpointsObj.PSObject.Properties.Name -match "ips"){ | ||
foreach($ip in $EndpointsObj.ips){ | ||
$firstip = $ip.Split("/")[0] | ||
$data.Add(@{ TestUrl = ($Protocol + $firstip + $UsePort); UrlPattern = ($Protocol + $firstip + $UsePort); ExpectedStatusCode = 403; Description = "$($EndpointsObj.serviceAreaDisplayName) - $Notes - Need communication $Protocol to $ip"; PerformBluecoatLookup=$false; Verbose=$false }) | ||
} | ||
}#> | ||
} | ||
} | ||
|
||
$possibleErrors = $possibleErrors | Group-Object -Property @("Type", "Issue") | ForEach-Object{ $_.Group | Select-Object * -First 1} | ||
$i = 1 | ||
$dataObjs = $data | Group-Object -Property @("TestUrl","TestType","UsePort") | ForEach-Object{ $_.Group | Select-Object * -First 1} | ||
ForEach($dataObj in $dataObjs) { | ||
Write-Progress -Activity "Connectivity Tests" -status "Processing $($d.TestUrl)" -percentComplete ($i / $dataObjs.count*100) | ||
if($dataObj.TestType -eq "HTTP"){ | ||
$connectivity = Get-HttpConnectivity -TestUrl ($dataObj.Protocol + $dataObj.TestUrl) -Method "GET" -UrlPattern ($dataObj.Protocol + $dataObj.UrlPattern) -ExpectedStatusCode $dataObj.ExpectedStatusCode -Description $dataObj.Description -PerformBluecoatLookup $dataObj.PerformBluecoatLookup -IgnoreCertificateValidationErrors:$dataObj.IgnoreCertificateValidationErrors | ||
} else { | ||
$connectivity = Get-TcpConnectivity -TestHostname $dataObj.TestUrl -TestPort $dataObj.UsePort -HostnamePattern ($dataObj.UrlPattern + ":" + $dataObj.UsePort) -ExpectedStatusCode $dataObj.ExpectedStatusCode -Description $dataObj.Description | ||
} | ||
$results.Add($connectivity) | ||
if ($connectivity.Blocked -eq $true -and $dataObj.Blocked -eq $false) { | ||
$possibleErrors += New-AnalyzeResult -TestName "Connectivity" -Type "Error" -Issue "Connection blocked `n $($connectivity)" -PossibleCause "Firewall is blocking connection to '$($connectivity.UnblockUrl)'." | ||
} | ||
if ($connectivity.Resolved -eq $false) { | ||
$possibleErrors += New-AnalyzeResult -TestName "Connectivity" -Type "Error" -Issue "DNS name not resolved `n $($connectivity)" -PossibleCause "DNS server not correctly configured." | ||
} | ||
if ($connectivity.ActualStatusCode -ne $connectivity.ExpectedStatusCode) { | ||
if($connectivity.ActualStatusCode -eq 407){ | ||
$Cause = "Keep in mind that the proxy has to be set in WinHTTP.`nWindows 1709 and newer: Set the proxy by using netsh or WPAD. --> https://docs.microsoft.com/en-us/windows/desktop/WinHttp/winhttp-autoproxy-support `nWindows 1709 and older: Set the proxy by using 'netsh winhttp set proxy ?' --> https://blogs.technet.microsoft.com/netgeeks/2018/06/19/winhttp-proxy-settings-deployed-by-gpo/ " | ||
} else { | ||
$Cause = "Interfering Proxy server can change HTTP status codes." | ||
} | ||
$possibleErrors += New-AnalyzeResult -TestName "Connectivity" -Type "Error" -Issue "Returned Status code '$($connectivity.ActualStatusCode)' is not expected '$($connectivity.ExpectedStatusCode)'`n $($connectivity)" -PossibleCause $Cause | ||
} | ||
if ($null -ne $connectivity.ServerCertificate -and $connectivity.ServerCertificate.HasError -and -not $dataObj.IgnoreCertificateValidationErrors) { | ||
$possibleErrors += New-AnalyzeResult -TestName "Connectivity" -Type "Error" -Issue "Certificate Error when connecting to $($connectivity.TestUrl)`n $(($connectivity.ServerCertificate))" -PossibleCause "Interfering Proxy server can change Certificate or not the Root Certificate is not trusted." | ||
} | ||
$i += 1 | ||
} | ||
Write-Progress -Completed -Activity "Connectivity Tests" | ||
|
||
# No errors detected, return success message | ||
if ($possibleErrors.Count -eq 0) { | ||
$possibleErrors += New-AnalyzeResult -TestName "All" -Type Information -Issue "All tests went through successfully." -PossibleCause "" | ||
} | ||
|
||
return $possibleErrors | ||
} |
45 changes: 45 additions & 0 deletions
45
PSModule/ModernWorkplaceClientCenter/Internal/Get-AzureEndpointExpectedResult.ps1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
function Get-AzureEndpointExpectedResult{ | ||
<# | ||
.Synopsis | ||
Returns the expected result and SSL error for a specific endpoint. | ||
.Description | ||
Returns the expected result and SSL error for a specific endpoint. | ||
.Example | ||
Get-AzureEndpointExpectedResult -Url "http://*.contoso.com" -Path "PathToModule" | ||
#> | ||
[OutputType([PSCustomObject])] | ||
[CmdletBinding()] | ||
param( | ||
[String]$Url, | ||
[String]$Path, | ||
[String]$TestType | ||
) | ||
$returnValue = $null | ||
Write-Verbose "Try to get expected connectivity result for '$Url' from file '$Path\Data\AzureEndpointExpectedResults.json'." | ||
try{ | ||
$ExpectedResult = Get-Content -Path "$Path\Data\AzureEndpointExpectedResults.json" -ErrorAction Stop | ||
$ExpectedResultObjs = $ExpectedResult | ConvertFrom-Json | ||
foreach($ExpectedResultObj in $ExpectedResultObjs){ | ||
if($ExpectedResultObj.UnblockUrl -eq $Url){ | ||
$returnValue = $ExpectedResultObj | ||
break | ||
} | ||
} | ||
} catch { | ||
Write-Warning "Could not find '$Path\Data\AzureEndpointExpectedResults.json', failed to get expected connectifity results." | ||
} | ||
|
||
if($null -eq $returnValue){ | ||
if($TestType -eq "HTTP"){ | ||
Write-Warning "Using default Expected Result Http Status 200 without SSL validation for url $($url)." | ||
$returnValue = [PSCustomObject]@{ UnblockUrl = $Url;ActualStatusCode = 200; HasError = $true } | ||
} else { | ||
Write-Warning "Using default Expected Result Tcp Status 1 $($url)." | ||
$returnValue = [PSCustomObject]@{ UnblockUrl = $Url;ActualStatusCode = 1; HasError = $true } | ||
} | ||
} | ||
return $returnValue | ||
} |
39 changes: 39 additions & 0 deletions
39
PSModule/ModernWorkplaceClientCenter/Internal/Get-AzureO365UrlEndpoint.ps1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
function Get-AzureO365UrlEndpoint{ | ||
<# | ||
.Synopsis | ||
Returns list of Azure/O365 endpoints from the official Microsoft webservice. | ||
.Description | ||
Try loading the actual list of Azure/O365 endpoints from the official Microsoft webservice. If not possible it will used a cached version. If an online version can be retriefed and the script is executed with administrative permission it also updates the local cache. | ||
.Example | ||
Get-AzureO365UrlEndpoint | ||
#> | ||
[OutputType([PSCustomObject[]])] | ||
[CmdletBinding()] | ||
param( | ||
[String] | ||
$Path | ||
) | ||
$Endpoints = Invoke-WebRequest -Uri "https://endpoints.office.com/endpoints/worldwide?clientrequestid=$(New-Guid)" | ||
if($Endpoints.StatusCode -ne 200){ | ||
Write-Error "Error downloading the actual endpoint list ($($Endpoints.StatusDescription) - $($Endpoints.StatusCode)) `n https://endpoints.office.com" -ErrorAction Continue | ||
Write-Warning "Try using cached endpoint list" | ||
|
||
try{ | ||
$AzureEndpointCache = Get-Content -Path "$Path\Data\AzureEndpointCache.json" -ErrorAction Stop | ||
$EndpointsObjs = $AzureEndpointCache | ConvertFrom-Json | ||
} catch { | ||
throw "Could not find '$Path\Data\AzureEndpointCache.json, failed to load azure endpoints for connectivity tests." | ||
} | ||
} else { | ||
$EndpointsObjs = $Endpoints.Content | ConvertFrom-Json | ||
Write-Verbose "Successfully retrieved $($EndpointsObjs.Length) Endpoints from online source." | ||
if(Get-IsAdmin){ | ||
Write-Verbose "Function is executed as Administrator, therefore trying to update local cache file." | ||
Out-File -FilePath "$Path\Data\AzureEndpointCache.json" -InputObject $Endpoints.content -Force | ||
} | ||
} | ||
return $EndpointsObjs | ||
} |
52 changes: 52 additions & 0 deletions
52
PSModule/ModernWorkplaceClientCenter/Internal/Get-UrlWildCardLookup.ps1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
function Get-UrlWildCardLookup{ | ||
<# | ||
.Synopsis | ||
tryes to find a static URL for a Wildcard URL from the . | ||
.Description | ||
Returns $true if the script is executed with administrator priviledge, false if not. | ||
.Example | ||
Get-UrlWildCardLookup -Url "*.contoso.com" | ||
#> | ||
[OutputType([String[]])] | ||
[CmdletBinding()] | ||
param( | ||
[String]$Url, | ||
[String]$Path | ||
) | ||
|
||
|
||
[String[]]$StaticUrls = @() | ||
Write-Verbose "Try to resolve '$Url' Wildcard Url to an static url from file '$Path\Data\UrlWildcardLookup.json'." | ||
try{ | ||
$AddToCache = $true | ||
$WildCardJSON = Get-Content -Path "$Path\Data\UrlWildcardLookup.json" -ErrorAction Stop | ||
$WildCardJSONObjs = $WildCardJSON | ConvertFrom-Json | ||
foreach($WildCardJSONObj in $WildCardJSONObjs){ | ||
if($WildCardJSONObj.Wildcard -eq $Url){ | ||
if($null -ne $WildCardJSONObj.static){ | ||
foreach($UrlPart in $WildCardJSONObj.static.Split(",")){ | ||
if(-not [String]::IsNullOrWhiteSpace($UrlPart)){ | ||
$StaticUrls += $Url -replace "\*",$UrlPart | ||
Write-Verbose "Resolved URL $($Url -replace "\*",$UrlPart)" | ||
} | ||
} | ||
} else { | ||
$AddToCache = $false | ||
Write-Verbose "Found a matching URL, but there are no static entries for '$Url' Url. Please add them in the '$Path\Data\UrlWildcardLookup.json'." | ||
} | ||
} | ||
} | ||
if($StaticUrls.Length -eq 0 -and $AddToCache){ | ||
Write-Warning "Could not find a matching static URL for the suplied wildcard '$Url' Url." | ||
$WildCardJSONObjs += [PSCustomObject]@{ Wildcard = $Url; static = $null } | ||
Out-File -FilePath "$Path\Data\UrlWildcardLookup.json" -InputObject ($WildCardJSONObjs | ConvertTo-Json) -Force | ||
} | ||
} catch { | ||
Write-Warning "Could not find '$Path\Data\UrlWildcardLookup.json', failed to convert wildcard into static url. $($_.Exception.Message)" | ||
|
||
} | ||
return $StaticUrls | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file added
BIN
+8.96 KB
...odernWorkplaceClientCenter/NestedModules/TcpConnectivityTester/TcpConnectivityTester.psd1
Binary file not shown.
Oops, something went wrong.