Public/Test-AzRegionLatency.ps1
function Test-AzRegionLatency { <# .SYNOPSIS Tests network latency to one or more Azure regions. .DESCRIPTION Tests network latency to one or more Azure regions. .PARAMETER Iterations The number of test iterations to run in each region. .PARAMETER DelaySeconds An optional number of seconds to wait between each iteration. .PARAMETER DelayMilliseconds An optional number of milliseconds to wait between each iteration. .EXAMPLE PS C:\> Test-AzRegionLatency -Region westus RawResults : {@{Time=4/18/18 8:54:46 PM; Timespan=00:00:00.0350430; LatencyMS=35}, @{Time=4/18/18 8:54:46 PM; Timespan=00:00:00.0339910; LatencyMS=33}, @{Time=4/18/18 8:54:46 PM; Timespan=00:00:00.0336530; LatencyMS=33}, @{Time=4/18/18 8:54:46 PM; Timespan=00:00:00.0349360; LatencyMS=34}...} ComputerName : HDK3948GKLD TotalTime : 00:00:03.8771200 Region : westus Maximum : 52 Average : 35.02 Minimum : 32 Test the network latency from the local computer to the West US Azure region. .EXAMPLE PS C:\> $results = Test-AzRegionLatency -Region eastus -Iterations 300 -DelaySeconds 1 Test the network latency from the local comptuer to the East US Azure region. Run this test for 5 minutes and delay each iteration by 1 second. #> [OutputType([PSCustomObject])] [cmdletbinding()] param( [int]$Iterations = 100, [int]$DelaySeconds, [int]$DelayMilliseconds ) # Region dynamic parameter DynamicParam { # Create attribute $regionAttribute = [System.Management.Automation.ParameterAttribute]::new() $regionAttribute.Mandatory = $false $regionAttribute.ValueFromPipeline = $true $regionAttribute.Position = 0 $regionAttribute.ParameterSetName = '__AllParameterSets' $regionAttribute.HelpMessage = 'The region(s) to test. By default ALL available Azure regions will be tested.' $attributeCollection = New-Object -TypeName System.Collections.ObjectModel.Collection[System.Attribute] $attributeCollection.Add($regionAttribute) # Create ValidateSet $regions = $script:storageLocations | Select-Object -ExpandProperty Location $regionValidateSet = New-Object -TypeName System.Management.Automation.ValidateSetAttribute($regions) $attributeCollection.Add($regionValidateSet) # Create parameter $regionParam = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter('Region', [string[]], $attributeCollection) $regionParam.Value = $regions $PSBoundParameters['Region'] = $regions $paramDictionary = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('Region', $regionParam) return $paramDictionary } begin { # Bind the dynamic parameter to a friendly variable $Region = $PSBoundParameters['Region'] $computer = hostname $origProgressPref = $ProgressPreference } process { $regionsTested = 0 foreach ($testRegion in $Region) { $testUri = ($script:storageLocations | Where-Object {$_.Location -eq $testRegion}).TestUri $regionProgressParams = @{ Id = 1 Activity = 'Testing latency to Azure regions' Status = "Region: $testRegion" CurrentOperation = "Region: $regionsTested of $($Region.Count)" PercentComplete = [int]$regionsTested / $Region.Count * 100 } Write-Progress @regionProgressParams Write-Verbose -Message "Testing region [$testRegion]" $regionResult = @{ PSTypeName = 'AzSpeedTestResult' Region = $testRegion ComputerName = $computer } try { $stopwatch = [System.Diagnostics.Stopwatch]::new() $iwrParams = @{ Uri = $testUri Verbose = $false Debug = $false UseBasicParsing = $true } $interationTimes = [System.Collections.ArrayList]::new() $regionStartTime = Get-Date for ($i = 0; $i -lt $Iterations; $i++) { $interationProgressParams = @{ Id = 2 ParentId = 1 Activity = "Testing latency to region: $testRegion" CurrentOperation = "Iteration: $i of $Iterations" PercentComplete = [int]$i / $Iterations * 100 } Write-Progress @interationProgressParams $stopwatch.Start() $ProgressPreference = 'SilentlyContinue' Invoke-WebRequest @iwrParams > $null $ProgressPreference = $origProgressPref $stopwatch.Stop() if ($DelaySeconds) { Start-Sleep -Seconds $DelaySeconds } if ($DelayMilliseconds) { Start-Sleep -Milliseconds $DelayMilliseconds } $iterationResult = [PSCustomObject]@{ PSTypeName = 'AzSpeedTestIterationResult' Time = [DateTime]::Now Timespan = $stopwatch.Elapsed LatencyMS = $stopwatch.ElapsedMilliseconds } $interationTimes.Add($iterationResult) > $null $stopwatch.Reset() } $regionStopTime = [DateTime]::Now $totalRegionTestTime = $regionStopTime - $regionStartTime $regionResult.Maximum = ($interationTimes | Measure-Object -Property LatencyMS -Maximum).Maximum $regionResult.Minimum = ($interationTimes | Measure-Object -Property LatencyMS -Minimum).Minimum $regionResult.Average = ($interationTimes | Measure-Object -Property LatencyMS -Average).Average $regionResult.TotalTime = $totalRegionTestTime $regionResult.RawResults = $interationTimes [PSCustomObject]$regionResult } catch { Write-Error -Message "Failed to test region [$testRegion]" Write-Error $_ } finally { $regionsTested++ } } } } |