PowerShell based Azure Functions v2

I am writing this for all PowerShell people, it’s not easy for non-developers or IT Pros who can use PowerShell only to grasp things like HTTP methods for example. Running PowerShell based Azure Functions allows you to do any type of function based stuff you would normally do with a PowerShell function, feeding it parameter values and getting output. Plus it makes you feel like a developer, where you can sort of create your own APIs!

Using parameters and feeding parameter values to PowerShell functions Vs using PowerShell Azure Functions works slightly different.

There are 3 ways to send parameter values to Azure Functions – PARAMS, BODY, QUERY.

  • PARAMS this is used when using a route template. Parameter values are passed along with the URL the order of the route template using the HTTP GET method.
https://ejuke2.azurewebsites.net/api/RouteName/{param1}/{param2}/{param3}
  • BODY this is used without using a route template (can’t be called from a browser), this uses the HTTP POST method.
  • QUERY this is used without using a route template using using the HTTP GET method
https://ejuke2.azurewebsites.net/api/function_name/?<ParameterName1>=<Parameter1_Value>&<ParameterName2>=<Parameter2_Value>

This blog will cover the two HTTP methods, GET & POST

Without using a Route Template

Your options here are passing parameter values in the BODY using the http POST method, or passing parameter values using QUERY using the http GET method.

Annotation 2019-05-02 112034

Using a Route Template

Using the route template then only allows you to use the PARAMS way of sending parameter values to the Azure Function.

Annotation 2019-05-02 111635

My PowerShell Function

Below is the PowerShell based function I used in this example.


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.
$FirstName = $Request.Query.FirstName # Query based parameters
if (-not $FirstName) {$FirstName = $Request.Body.FirstName} # JSON Body (POST)
if (-not $FirstName) {$FirstName = $Request.Params.FirstName} # Route Template
$Surname = $Request.Query.Surname # Query based parameters
if (-not $Surname) {$Surname = $Request.Body.Surname} # JSON Body (POST)
if (-not $Surname) {$Surname = $Request.Params.Surname} # Route Template
if ($FirstName -and $Surname) {
$status = [HttpStatusCode]::OK
$body = "Hello $FirstName" + " $Surname"
}
else {
$status = [HttpStatusCode]::BadRequest
$body = "Please pass a name on the query string or in the request body."
}
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = $status
Body = $body
})

Calling the Azure Function

Calling the Azure Function can be done in the browser using a GET request, or programmably using something like PowerShell for both GET & POST.

Below there’s two options, not using a route template, and using a route template.


#########################################################
####### only works if the Route template is blank #######
#########################################################
# QUERY based parameter values – GET method
$firstName = 'Marc'
$surName = 'Kean'
$iwr = Invoke-WebRequest -Uri "https://ejuke2.azurewebsites.net/api/blog?firstname=$firstName&surname=$surName&quot; -Method Get
$iwr.content
# BODY based parameter values – POST method
$firstName = 'Marc'
$surName = 'Kean'
$postParams = @{"firstname" = $firstName;"surName" = $surName} | ConvertTo-Json
$iwr = Invoke-WebRequest -Uri "https://ejuke2.azurewebsites.net/api/blog&quot; -Method POST -Body $postParams
$iwr.content
#########################################################
##### only works if the Route template is NOT blank #####
#########################################################
# Route Template: RouteName/{firstname}/{surname}
# PARAMS path based parameter values – GET method
$firstName = 'Marc'
$surName = 'Kean'
$iwr = Invoke-WebRequest -Uri "https://ejuke2.azurewebsites.net/api/RouteName/$firstName/$surName&quot; -Method Get
$iwr.content
# PARAMS path based parameter values – POST method
$firstName = 'Marc'
$surName = 'Kean'
$iwr = Invoke-WebRequest -Uri "https://ejuke2.azurewebsites.net/api/RouteName/$firstName/$surName&quot; -Method POST
$iwr.content

Output to HTML

Of you want to output to HTML, change the last section of your function to something like this:

$html = @"
<html>
<p>$body</p>
</html>
"@

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value (@{
headers = @{"content-type" = "text/html"}
Body = $html
})

Then you can run this in a browser and bring back something more human readable.

One Comment

  1. This is extremely useful, I tried to do some decoding between the .NET docs and this and got partially there, but things like the route based params are great. Now that Functions is PSv5.1 if your instances have been upgraded to 2016, it’s becoming a fully functional item!

Leave a comment