PowerShell Azure Functions dependency on PowerShell Gallery

I started writing a blog post today about hooking PowerShell Azure Functions into PowerApps.

But I couldn’t get even the simplest function to work – every query resulted in 500 (Internal Server Error).

Of course, I spent ages looking for a stupid mistake that I’d made. (And I found one: my code containted Wait-Debugger – this is still my biggest Azure Functions gotcha.)

Then I put two and two together. The PowerShell Gallery is down today, and this has broken a bunch of people’s CI/CD pipelines.

This is the error that I see in the Azure Functions portal:

Result: Failure
Exception: Fail to install function app dependencies.
Restarting the app may resolve the error.
Error: 'A connection attempt failed because the 
connected party did not properly respond after a period 
of time, or established connection failed because 
connected host has failed to respond A connection attempt
failed because the connected party did not properly respond 
after a period of time, or established connection failed 
because connected host has failed to respond'
Stack:
at Microsoft.Azure.Functions.PowerShellWorker.
DependencyManagement.DependencyManager.Initialize
(FunctionLoadRequest request) 
in C:\projects\azure-functions-powershell-worker\src\
DependencyManagement\DependencyManager.cs:line 179
at Microsoft.Azure.Functions.PowerShellWorker.
RequestProcessor.ProcessFunctionLoadRequest
(StreamingMessage request)
in C:\projects\azure-functions-powershell-worker\src\
RequestProcessor.cs:line 169

And I was able to fix my Function by commenting out the Az line in my local project’s requirements.psd1 and pushing the changes to Azure:

# This file enables modules to be automatically managed by the Functions service.
# Only the Azure Az module is supported in preview.
# See https://aka.ms/functionsmanageddependency for additional information.
#
@{
    #'Az' = '1.*'
}

Needless to say, PowerShell Azure Functions is in Public Preview, and it’s expected that things will sometimes not work.

But I expect dependencies on PowerShell Gallery in the wider ecosystem will get a lot of attention after today!

Demo: Debug PowerShell Azure Functions locally

Over the past couple weeks I’ve started making a PowerApp called Boop for my wife.

But I’m a PowerShell guy at heart, and I’ve also been exploring preview support for PowerShell in Azure Functions, Microsoft’s serverless “run code on-demand” service.

I plan to stitch Azure Functions into Boop – and step one is to set up a local development environment for Azure Functions.

Here’s a demo of me debugging a local Azure Function, followed by some notes, and the code for my tweaked run.ps1.

All I’m doing is following Microsoft’s instructions, but hopefully seeing them in video form helps someone out there!

  • If you want to play along, first go to the Create your first PowerShell function in Azure (preview) quickstart guide, and run through Prerequisites, Install the Azure Function extension, and Create a function app project.
  • I’m using the default run.ps1 file that you get when creating a HttpTrigger Function, with a couple of tweaks:
    • Rather than just returning a string, I’ve created a hashtable and converted it to JSON. This gives us a head start when it comes to tying into PowerApps.
    • And I’m writing $body to the log stream so it’s easier to see what’s going on.
  • You can see that this method of debugging works great with PowerShell 7.0.0-preview.1.
  • But I could only get debugging with Visual Studio code to work with PowerShell 6.x, and even then, I couldn’t explore variables like $TriggerMetadata with the Debug panel – they just appear as flat objects.
  • The biggest gotcha so far is that it’s very easy to forget to remove Wait-Debugger from your script when you publish to Azure. This has already caught me out. Has anyone got a clever solution? Perhaps we can put Wait-Debugger in an if statement that only runs locally?

Here’s my version of run.ps1:

using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters or the body of the request.
$name = $Request.Query.Name
if (-not $name) {
    $name = $Request.Body.Name
}

if ($name) {
    $status = [HttpStatusCode]::OK
    # Create a hashtable and convert to JSON
    $body = @{
        greeting = "Hello $name"
    } | ConvertTo-Json
}
else {
    $status = [HttpStatusCode]::BadRequest
    $body = "Please pass a name on the query string or in the request body."
}

Write-Information 'Write $body to log stream'
$body

Wait-Debugger

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = $status
    Body = $body
})