Azure Durable PowerShell Function -Automatic Retry Sample

Azure Functions offers a cost-effective solution for developing provisioning code, including managing SharePoint with PnP. By leveraging Azure Functions, applications can execute actions securely using managed identities and Entra ID authentication. However, as my workflows increase in complexity, the need for a more stateful approach becomes apparent. Initially, my project started with a simple one-method function, but it evolved into complex provisioning, leading me to adopt durable functions instead of having to manage state and queues myself. Let’s take a quick look at the automatic retry functionality and how to get it to work using PowerShell.

Consider the following example where I provision a SharePoint site and check its readiness:

$siteUrl = Invoke-DurableActivity -FunctionName 'CreateSite' -Input $Context



$retryOptionsSiteStatus = New-DurableRetryOptions `
        -FirstRetryInterval (New-TimeSpan -Seconds 15) `
        -MaxNumberOfAttempts 5

Invoke-DurableActivity -FunctionName 'CheckSiteReady' -Input $siteUrl -RetryOptions $retryOptionsSiteStatus

The CheckSiteReady activity:


param($siteUrl)
try {
    
    Connect-PnPOnline ...
    $site = Get-PnPTenantSite | Where { $_.Url -eq $siteUrl }
    If ($Site -eq $null) {  
        throw
    }  
    Else {  
        Write-host "Site $siteUrl exists" 
    }  
}
catch {
    Write-host "Site $siteUrl doesn't exist!"  
} 

I create the site then verify the site exists. When executing it, it threw an exception in the orchestrator if the site did not exist, but it did not automatically retry.

[Error] EXCEPTION: Orchestrator: Could not validate Input. Unexpected error Value cannot be null. (Parameter 'input')

Exception :
Type : Microsoft.PowerShell.Commands.WriteErrorException
Message : Orchestrator: Could not validate Input. Unexpected error Value cannot be null. (Parameter 'input')

The documentation https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-error-handling?tabs=powershell just shows the invoke-durableactivity from the orchestrator level and not the activity. I created a CSS ticket to see if they had some more info on how to actually use this cmdlet.

While I wait to hear back from CSS, I thought at this point the exception is being handled in the activity and not being returned to the orchestrator to handle it. Sure enough, I removed the try/catch in the activity and it worked! CSS came back and originally said it might be a bug and to use the preview SDK. Well, I did try out the new SDK and it did change the behavior up a little.

[Information]   282f4e67-4de6-4807-a785-389a030c2c79: Function 'Orchestrator (Orchestrator)' completed. ContinuedAsNew: False. IsReplay: False. Output: (null). State: Completed. RuntimeStatus: Completed. HubName: functest1. AppName: functest1. SlotName: Production. ExtensionVersion: 2.12.0. SequenceNumber: 9. TaskEventId: -1

I believe the preview SDK does fix the behavior around the input being null, but at the end of the day, I still needed to remove the try/catch within the activity in order for the automatic retry to work.