This document details the programming model for developing Azure Functions using PowerShell. Learn how to structure your functions, handle triggers and bindings, and manage dependencies.
Azure Functions provides a serverless compute experience that allows you to run small pieces of code, called "functions," without explicitly provisioning or managing infrastructure. The PowerShell programming model enables you to leverage your existing PowerShell scripting skills within the Azure Functions environment.
Key benefits include:
A typical PowerShell Azure Function consists of a script file (e.g., run.ps1) and a function.json file that defines the function's triggers and bindings.
run.ps1This script file contains the core logic of your function. It receives input data and returns output based on the configured triggers and bindings.
param($MyTimer, $MyQueueItem)
# Check if trigger data is available
if ($MyQueueItem) {
Write-Host "PowerShell queue trigger function processed work item: $MyQueueItem"
# Process the queue item...
} elseif ($MyTimer) {
Write-Host "PowerShell timer trigger function executed at: $(Get-Date)"
# Perform scheduled tasks...
} else {
Write-Host "No trigger data received."
}
# Return output if applicable (e.g., to an output binding)
# Example: return "Processed: $MyQueueItem"
function.jsonThis JSON file defines the metadata for your function, including its entry point, trigger type, and input/output bindings. The file is located in a folder named after your function.
{
"scriptFile": "run.ps1",
"bindings": [
{
"name": "MyTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 */5 * * * *"
},
{
"name": "MyQueueItem",
"type": "queueTrigger",
"direction": "in",
"queueName": "myqueue-items",
"connection": "AzureWebJobsStorage"
},
{
"name": "outputBlob",
"type": "blob",
"direction": "out",
"path": "output-container/{queueTrigger}",
"connection": "AzureWebJobsStorage"
}
]
}
In this example:
scriptFile specifies the PowerShell script to execute.run.ps1 is MyTimer.myqueue-items queue. The input parameter name is MyQueueItem.output-container, with the blob name derived from the queue trigger content. The parameter name for this output is implicitly handled by Azure Functions when using output bindings.Triggers define how your function is invoked, while bindings simplify the integration with other services by providing declarative ways to connect to data and services.
You can find a comprehensive list of triggers and bindings in the Azure Functions triggers and bindings documentation.
For PowerShell functions, you can manage external modules and dependencies using the requirements.psd1 file.
requirements.psd1Place this file in the root of your function app project. It follows the standard PowerShell module manifest format.
#
# This file is used to install PowerShell modules for your Azure Functions.
# For more information, see: https://go.microsoft.com/fwlink/?LinkID=532799
#
# Specify module versions by listing them in the following format:
# Module = @{ ModuleName = 'RequiredVersion' }
# Example:
# Az = @{ Az = '2.0.0' }
# Pester = @{ Pester = '4.0.0' }
# Add your required modules here.
# For example, to include the Az module:
# Az = @{ Az = '5.0.0' }
# For a specific version:
# Az.Accounts = @{ Az.Accounts = '2.2.0' }
# If you don't need a specific version, just list the module name:
# SomeModule = 'SomeModule'
When your function app starts, Azure Functions will automatically install the modules listed in requirements.psd1.
The param() block in your run.ps1 script is crucial for receiving input from triggers and bindings. The parameter names must match the name property defined in your function.json bindings.
Trigger data is passed as parameters to your script. For example, a queue trigger item is often passed as a string or a JSON object.
param($MyQueueItem)
if ($MyQueueItem) {
$data = ConvertFrom-Json $MyQueueItem -ErrorAction SilentlyContinue
if ($data) {
Write-Host "Processing data: $($data.id)"
} else {
Write-Host "Received raw queue item: $MyQueueItem"
}
}
To write data to an output binding, you typically assign values to a special object that represents the output binding. This is often done implicitly by returning a value from the script if the output binding is the primary return value, or by using specific cmdlets provided by the Azure Functions host.
In many cases, you can simply return a value from your script:
param($MyQueueItem, $MyOutputBlob)
# ... process MyQueueItem ...
# If you have an output binding named 'MyOutputBlob' in function.json
# and it's configured to accept a string or JSON:
return "Successfully processed item: $MyQueueItem"
For more complex output scenarios, or when dealing with multiple output bindings, you might use dedicated output binding objects or cmdlets provided by the Azure Functions runtime.
Effective logging and error handling are vital for debugging and monitoring your functions.
Use standard PowerShell cmdlets like Write-Host, Write-Verbose, Write-Warning, and Write-Error. These outputs are captured by the Azure Functions runtime and are visible in Application Insights and the Kudu console.
Write-Host "Starting function execution."
Write-Verbose "Detailed information about the process."
Write-Warning "A potential issue was detected."
Write-Error "An unrecoverable error occurred."
Use try...catch blocks to gracefully handle exceptions.
try {
# Code that might throw an error
$result = Invoke-RestMethod -Uri "http://invalid.url"
Write-Host "Successfully called external service."
} catch {
Write-Error "An error occurred during external service call: $($_.Exception.Message)"
# You can re-throw the exception if you want the function to fail
# throw $_
}