Last active
February 9, 2018 18:00
-
-
Save joerodgers/e0518ee519b44fdc23b56b7e6f0ace3a to your computer and use it in GitHub Desktop.
Create a new client context with logic to handle service throttling.
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
function New-ClientContextWithRetry | |
{ | |
[cmdletbinding()] | |
param | |
( | |
[Parameter(Mandatory=$true, ParameterSetName = "CredentialComponents")] | |
[Parameter(Mandatory=$true, ParameterSetName = "SharePointOnlineCredential")] | |
[string]$ContextUrl, | |
[Parameter(Mandatory=$true, ParameterSetName = "CredentialComponents")] | |
[string]$UserName, | |
[Parameter(Mandatory=$true, ParameterSetName = "CredentialComponents")] | |
[System.Security.SecureString]$SecurePassword, | |
[Parameter(Mandatory=$true, ParameterSetName = "SharePointOnlineCredential")] | |
[Microsoft.SharePoint.Client.SharePointOnlineCredentials]$SharePointOnlineCredential, | |
[Parameter(Mandatory=$false, ParameterSetName = "CredentialComponents")] | |
[Parameter(Mandatory=$false, ParameterSetName = "SharePointOnlineCredential")] | |
[int]$Delay = 10, | |
[Parameter(Mandatory=$false, ParameterSetName = "CredentialComponents")] | |
[Parameter(Mandatory=$false, ParameterSetName = "SharePointOnlineCredential")] | |
[int]$RetryAttempts = 5 | |
) | |
begin | |
{ | |
$executions = 1 | |
$clientContext = $null | |
} | |
process | |
{ | |
do | |
{ | |
try | |
{ | |
$clientContext = New-Object Microsoft.SharePoint.Client.ClientContext($ContextUrl) | |
if( $PSCmdlet.ParameterSetName -eq "CredentialComponents" ) | |
{ | |
$clientContext.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $SecurePassword) | |
} | |
else | |
{ | |
$clientContext.Credentials = $SharePointOnlineCredential | |
} | |
$clientContext.Load($clientContext.Web) | |
$clientContext.Load($clientContext.Site) | |
$clientContext.ExecuteQuery() | |
return $clientContext | |
} | |
catch [System.Net.WebException] | |
{ | |
$response = $_.Exception.Response -as [System.Net.HttpWebResponse] | |
$statusCode = [int]$response.StatusCode | |
Write-Verbose "Full Exception Details: $($_.Exception)" | |
Write-Verbose "Status Code: $statusCode" | |
# 429 and 503 are throttling exceptions. | |
if( $response -and ($statusCode -eq 429 -or $statusCode -eq 503) ) | |
{ | |
Write-Warning -Message "Execution attempt $executions was throttled, trying again in $Delay seconds." | |
$executions++ | |
Start-Sleep -Seconds $Delay | |
} | |
# seeing erroneous 403 exceptions that require a retry | |
elseif( $response -and $statusCode -eq 403 ) | |
{ | |
Write-Warning -Message "Execution attempt $executions was forbidden, trying again in $Delay seconds." | |
$executions++ | |
Start-Sleep -Seconds $Delay | |
} | |
elseif( $response -and $statusCode -eq 404 ) | |
{ | |
Write-Warning -Message "A site with the URL $($ContextUrl) was not found in the tenant." | |
return $null | |
} | |
else | |
{ | |
Write-Error -Message "An error occurred connecting to $($ContextUrl). Exception: $($_.Exception.Message)" | |
return $null | |
} | |
} | |
catch | |
{ | |
Write-Verbose "Full Exception Details: $($_.Exception)" | |
if( $_.Exception.Message -match "Access to this Web site has been blocked") | |
{ | |
Write-Warning -Message "Cannot contact site at the specified URL $ContextUrl. Access to this Web site has been blocked." | |
return $null | |
} | |
Write-Error -Message "$($MyInvocation.MyCommand.Name) - Unexpected execution exception: $($_.Exception.Message)" | |
return $null | |
} | |
} | |
while( $executions -le $RetryAttempts ) | |
} | |
end | |
{ | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment