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.
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.
My PowerShell Function
Below is the PowerShell based function I used in this example.
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
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.
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
######################################################### | |
####### 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" –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" –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" –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" –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.
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!