1212 Specifies the file that contains a set of links to ignore when verifying.
1313
1414 . PARAMETER devOpsLogging
15- Switch that will enable devops specific logging for warnings
15+ Switch that will enable devops specific logging for warnings.
1616
1717 . PARAMETER recursive
18- Check the links recurisvely based on recursivePattern .
18+ Check the links recurisvely. Applies to links starting with 'baseUrl' parameter. Defaults to true .
1919
2020 . PARAMETER baseUrl
2121 Recursively check links for all links verified that begin with this baseUrl, defaults to the folder the url is contained in.
22+ If 'recursive' parameter is set to false, this parameter has no effect.
2223
2324 . PARAMETER rootUrl
2425 Path to the root of the site for resolving rooted relative links, defaults to host root for http and file directory for local files.
@@ -74,6 +75,8 @@ param (
7475 [string ] $requestTimeoutSec = 15
7576)
7677
78+ Set-StrictMode - Version 3.0
79+
7780$ProgressPreference = " SilentlyContinue" ; # Disable invoke-webrequest progress dialog
7881# Regex of the locale keywords.
7982$locale = " /en-us/"
@@ -184,11 +187,15 @@ function ParseLinks([string]$baseUri, [string]$htmlContent)
184187 # $hrefs | Foreach-Object { Write-Host $_ }
185188
186189 Write-Verbose " Found $ ( $hrefs.Count ) raw href's in page $baseUri " ;
187- $links = $hrefs | ForEach-Object { ResolveUri $baseUri $_.Groups [" href" ].Value }
190+ [ string []] $links = $hrefs | ForEach-Object { ResolveUri $baseUri $_.Groups [" href" ].Value }
188191
189192 # $links | Foreach-Object { Write-Host $_ }
190193
191- return $links
194+ if ($null -eq $links ) {
195+ $links = @ ()
196+ }
197+
198+ return , $links
192199}
193200
194201function CheckLink ([System.Uri ]$linkUri , $allowRetry = $true )
@@ -239,11 +246,27 @@ function CheckLink ([System.Uri]$linkUri, $allowRetry=$true)
239246 }
240247 }
241248 catch {
242- $statusCode = $_.Exception.Response.StatusCode.value__
249+
250+ $responsePresent = $_.Exception.psobject.Properties.name -contains " Response"
251+ if ($responsePresent ) {
252+ $statusCode = $_.Exception.Response.StatusCode.value__
253+ } else {
254+ $statusCode = $null
255+ }
243256
244- if (! $statusCode ) {
257+ if (! $statusCode ) {
245258 # Try to pull the error code from any inner SocketException we might hit
246- $statusCode = $_.Exception.InnerException.ErrorCode
259+
260+ $innerExceptionPresent = $_.Exception.psobject.Properties.name -contains " InnerException"
261+
262+ $errorCodePresent = $false
263+ if ($innerExceptionPresent ) {
264+ $errorCodePresent = $_.Exception.InnerException.psobject.Properties.name -contains " ErrorCode"
265+ }
266+
267+ if ($errorCodePresent ) {
268+ $statusCode = $_.Exception.InnerException.ErrorCode
269+ }
247270 }
248271
249272 if ($statusCode -in $errorStatusCodes ) {
@@ -257,13 +280,30 @@ function CheckLink ([System.Uri]$linkUri, $allowRetry=$true)
257280 $linkValid = $false
258281 }
259282 else {
283+
260284 if ($null -ne $statusCode ) {
285+
261286 # For 429 rate-limiting try to pause if possible
262- if ($allowRetry -and $_.Exception.Response -and $statusCode -eq 429 ) {
263- $retryAfter = $_.Exception.Response.Headers.RetryAfter.Delta.TotalSeconds
287+ if ($allowRetry -and $responsePresent -and $statusCode -eq 429 ) {
288+
289+ $headersPresent = $_.Exception.psobject.Properties.name -contains " Headers"
290+
291+ $retryAfterPresent = $false
292+ if ($headersPresent ) {
293+ $retryAfterPresent = $_.Exception.Headers.psobject.Properties.name -contains " RetryAfter"
294+ }
295+
296+ $retryAfterDeltaPresent = $false
297+ if ($retryAfterPresent ) {
298+ $retryAfterDeltaPresent = $_.Exception.Headers.RetryAfter.psobject.Properties.name -contains " Delta"
299+ }
300+
301+ if ($retryAfterDeltaPresent ) {
302+ $retryAfter = $_.Exception.Response.Headers.RetryAfter.Delta.TotalSeconds
303+ }
264304
265305 # Default retry after 60 (arbitrary) seconds if no header given
266- if (! $retryAfter -or $retryAfter -gt 60 ) { $retryAfter = 60 }
306+ if (! $retryAfterDeltaPresent -or $retryAfter -gt 60 ) { $retryAfter = 60 }
267307 Write-Host " Rate-Limited for $retryAfter seconds while requesting $linkUri "
268308
269309 Start-Sleep - Seconds $retryAfter
@@ -366,9 +406,9 @@ function GetLinks([System.Uri]$pageUri)
366406 LogError " Don't know how to process uri $pageUri "
367407 }
368408
369- $links = ParseLinks $pageUri $content
409+ [ string []] $links = ParseLinks $pageUri $content
370410
371- return $links ;
411+ return , $links ;
372412}
373413
374414if ($urls ) {
@@ -433,59 +473,71 @@ if ($devOpsLogging) {
433473while ($pageUrisToCheck.Count -ne 0 )
434474{
435475 $pageUri = $pageUrisToCheck.Dequeue ();
436- if ($checkedPages.ContainsKey ($pageUri )) { continue }
437- $checkedPages [$pageUri ] = $true ;
438-
439- $linkUris = GetLinks $pageUri
440- Write-Host " Checking $ ( $linkUris.Count ) links found on page $pageUri " ;
441- $badLinksPerPage = @ ();
442- foreach ($linkUri in $linkUris ) {
443- $isLinkValid = CheckLink $linkUri
444- if (! $isLinkValid -and ! $badLinksPerPage.Contains ($linkUri )) {
445- if (! $linkUri.ToString ().Trim()) {
446- $linkUri = $emptyLinkMessage
476+ Write-Verbose " Processing pageUri $pageUri "
477+ try {
478+ if ($checkedPages.ContainsKey ($pageUri )) { continue }
479+ $checkedPages [$pageUri ] = $true ;
480+
481+ [string []] $linkUris = GetLinks $pageUri
482+ Write-Host " Checking $ ( $linkUris.Count ) links found on page $pageUri " ;
483+ $badLinksPerPage = @ ();
484+ foreach ($linkUri in $linkUris ) {
485+ $isLinkValid = CheckLink $linkUri
486+ if (! $isLinkValid -and ! $badLinksPerPage.Contains ($linkUri )) {
487+ if (! $linkUri.ToString ().Trim()) {
488+ $linkUri = $emptyLinkMessage
489+ }
490+ $badLinksPerPage += $linkUri
447491 }
448- $badLinksPerPage += $linkUri
449- }
450- if ($recursive -and $isLinkValid ) {
451- if ($linkUri.ToString ().StartsWith($baseUrl ) -and ! $checkedPages.ContainsKey ($linkUri )) {
452- $pageUrisToCheck.Enqueue ($linkUri );
492+ if ($recursive -and $isLinkValid ) {
493+ if ($linkUri.ToString ().StartsWith($baseUrl ) -and ! $checkedPages.ContainsKey ($linkUri )) {
494+ $pageUrisToCheck.Enqueue ($linkUri );
495+ }
453496 }
454497 }
498+ if ($badLinksPerPage.Count -gt 0 ) {
499+ $badLinks [$pageUri ] = $badLinksPerPage
500+ }
501+ } catch {
502+ Write-Host " Exception encountered while processing pageUri $pageUri : $ ( $_.Exception ) "
503+ throw
455504 }
456- if ($badLinksPerPage.Count -gt 0 ) {
457- $badLinks [$pageUri ] = $badLinksPerPage
458- }
459- }
460- if ($devOpsLogging ) {
461- Write-Host " ##[endgroup]"
462505}
463506
464- if ($badLinks.Count -gt 0 ) {
465- Write-Host " Summary of broken links:"
466- }
467- foreach ($pageLink in $badLinks.Keys ) {
468- Write-Host " '$pageLink ' has $ ( $badLinks [$pageLink ].Count) broken link(s):"
469- foreach ($brokenLink in $badLinks [$pageLink ]) {
470- Write-Host " $brokenLink "
507+ try {
508+ if ($devOpsLogging ) {
509+ Write-Host " ##[endgroup]"
471510 }
472- }
473511
474- $linksChecked = $checkedLinks.Count - $cachedLinksCount
512+ if ($badLinks.Count -gt 0 ) {
513+ Write-Host " Summary of broken links:"
514+ }
515+ foreach ($pageLink in $badLinks.Keys ) {
516+ Write-Host " '$pageLink ' has $ ( $badLinks [$pageLink ].Count) broken link(s):"
517+ foreach ($brokenLink in $badLinks [$pageLink ]) {
518+ Write-Host " $brokenLink "
519+ }
520+ }
475521
476- if ($badLinks.Count -gt 0 ) {
477- Write-Host " Checked $linksChecked links with $ ( $badLinks.Count ) broken link(s) found."
478- }
479- else {
480- Write-Host " Checked $linksChecked links. No broken links found."
481- }
522+ $linksChecked = $checkedLinks.Count - $cachedLinksCount
482523
483- if ($outputCacheFile )
484- {
485- $goodLinks = $checkedLinks.Keys.Where ({ " True" -eq $checkedLinks [$_ ].ToString() }) | Sort-Object
524+ if ($badLinks.Count -gt 0 ) {
525+ Write-Host " Checked $linksChecked links with $ ( $badLinks.Count ) broken link(s) found."
526+ }
527+ else {
528+ Write-Host " Checked $linksChecked links. No broken links found."
529+ }
530+
531+ if ($outputCacheFile )
532+ {
533+ $goodLinks = $checkedLinks.Keys.Where ({ " True" -eq $checkedLinks [$_ ].ToString() }) | Sort-Object
486534
487- Write-Host " Writing the list of validated links to $outputCacheFile "
488- $goodLinks | Set-Content $outputCacheFile
535+ Write-Host " Writing the list of validated links to $outputCacheFile "
536+ $goodLinks | Set-Content $outputCacheFile
537+ }
538+ } catch {
539+ Write-Host " Exception encountered after all pageUris have been processed : $ ( $_.Exception ) "
540+ throw
489541}
490542
491543exit $badLinks.Count
0 commit comments