Ócáid
Mar 17, 9 PM - Mar 21, 10 AM
Bí ar an tsraith meetup chun réitigh AI inscálaithe a thógáil bunaithe ar chásanna úsáide fíor-dhomhanda le forbróirí agus saineolaithe eile.
Cláraigh anoisNí thacaítear leis an mbrabhsálaí seo a thuilleadh.
Uasghrádú go Microsoft Edge chun leas a bhaint as na gnéithe is déanaí, nuashonruithe slándála, agus tacaíocht theicniúil.
This article provides details about how you write Azure Functions using PowerShell.
A PowerShell Azure function (function) is represented as a PowerShell script that executes when triggered. Each function script has a related function.json
file that defines how the function behaves, such as how it is triggered and its input and output parameters. To learn more, see the Triggers and binding article.
Like other kinds of functions, PowerShell script functions take in parameters that match the names of all the input bindings defined in the function.json
file. A TriggerMetadata
parameter is also passed that contains additional information on the trigger that started the function.
This article assumes that you have already read the Azure Functions developer reference. It also assumes you have completed the Functions quickstart for PowerShell to create your first PowerShell function.
The required folder structure for a PowerShell project looks like the following. This default can be changed. For more information, see the scriptFile section.
PSFunctionApp
| - MyFirstFunction
| | - run.ps1
| | - function.json
| - MySecondFunction
| | - run.ps1
| | - function.json
| - Modules
| | - myFirstHelperModule
| | | - myFirstHelperModule.psd1
| | | - myFirstHelperModule.psm1
| | - mySecondHelperModule
| | | - mySecondHelperModule.psd1
| | | - mySecondHelperModule.psm1
| - local.settings.json
| - host.json
| - requirements.psd1
| - profile.ps1
| - extensions.csproj
| - bin
At the root of the project, there's a shared host.json
file that can be used to configure the function app. Each function has a folder with its own code file (.ps1) and binding configuration file (function.json
). The name of the function.json file's parent directory is always the name of your function.
Certain bindings require the presence of an extensions.csproj
file. Binding extensions, required in version 2.x and later versions of the Functions runtime, are defined in the extensions.csproj
file, with the actual library files in the bin
folder. When developing locally, you must register binding extensions. When you are developing functions in the Azure portal, this registration is done for you.
In PowerShell Function Apps, you may optionally have a profile.ps1
which runs when a function app starts to run (otherwise know as a cold start). For more information, see PowerShell profile.
By default, the Functions runtime looks for your function in run.ps1
, where run.ps1
shares the same parent directory as its corresponding function.json
.
Your script is passed several arguments on execution. To handle these parameters, add a param
block to the top of your script as in the following example:
# $TriggerMetadata is optional here. If you don't need it, you can safely remove it from the param block
param($MyFirstInputBinding, $MySecondInputBinding, $TriggerMetadata)
The TriggerMetadata
parameter is used to supply additional information about the trigger. This metadata varies from binding to binding but they all contain a sys
property that contains the following data:
$TriggerMetadata.sys
Property | Description | Type |
---|---|---|
UtcNow | When, in UTC, the function was triggered | DateTime |
MethodName | The name of the Function that was triggered | string |
RandGuid | a unique guid to this execution of the function | string |
Every trigger type has a different set of metadata. For example, the $TriggerMetadata
for QueueTrigger
contains the InsertionTime
, Id
, DequeueCount
, among other things. For more information on the queue trigger's metadata, go to the official documentation for queue triggers. Check the documentation on the triggers you're working with to see what comes inside the trigger metadata.
In PowerShell, bindings are configured and defined in a function's function.json. Functions interact with bindings in a number of ways.
Trigger and input bindings are read as parameters passed to your function. Input bindings have a direction
set to in
in function.json. The name
property defined in function.json
is the name of the parameter, in the param
block. Since PowerShell uses named parameters for binding, the order of the parameters doesn't matter. However, it's a best practice to follow the order of the bindings defined in the function.json
.
param($MyFirstInputBinding, $MySecondInputBinding)
In Functions, an output binding has a direction
set to out
in the function.json. You can write to an output binding by using the Push-OutputBinding
cmdlet, which is available to the Functions runtime. In all cases, the name
property of the binding as defined in function.json
corresponds to the Name
parameter of the Push-OutputBinding
cmdlet.
The following example shows how to call Push-OutputBinding
in your function script:
param($MyFirstInputBinding, $MySecondInputBinding)
Push-OutputBinding -Name myQueue -Value $myValue
You can also pass in a value for a specific binding through the pipeline.
param($MyFirstInputBinding, $MySecondInputBinding)
Produce-MyOutputValue | Push-OutputBinding -Name myQueue
Push-OutputBinding
behaves differently based on the value specified for -Name
:
When the specified name can't be resolved to a valid output binding, then an error is thrown.
When the output binding accepts a collection of values, you can call Push-OutputBinding
repeatedly to push multiple values.
When the output binding only accepts a singleton value, calling Push-OutputBinding
a second time raises an error.
The following are valid parameters for calling Push-OutputBinding
:
Name | Type | Position | Description |
---|---|---|---|
-Name |
String | 1 | The name of the output binding you want to set. |
-Value |
Object | 2 | The value of the output binding you want to set, which is accepted from the pipeline ByValue. |
-Clobber |
SwitchParameter | Named | (Optional) When specified, forces the value to be set for a specified output binding. |
The following common parameters are also supported:
Verbose
Debug
ErrorAction
ErrorVariable
WarningAction
WarningVariable
OutBuffer
PipelineVariable
OutVariable
For more information, see About CommonParameters.
An HTTP trigger returns a response using an output binding named response
. In the following example, the output binding of response
has the value of "output #1":
PS >Push-OutputBinding -Name response -Value ([HttpResponseContext]@{
StatusCode = [System.Net.HttpStatusCode]::OK
Body = "output #1"
})
Because the output is to HTTP, which accepts a singleton value only, an error is thrown when Push-OutputBinding
is called a second time.
PS >Push-OutputBinding -Name response -Value ([HttpResponseContext]@{
StatusCode = [System.Net.HttpStatusCode]::OK
Body = "output #2"
})
For outputs that only accept singleton values, you can use the -Clobber
parameter to override the old value instead of trying to add to a collection. The following example assumes that you have already added a value. By using -Clobber
, the response from the following example overrides the existing value to return a value of "output #3":
PS >Push-OutputBinding -Name response -Value ([HttpResponseContext]@{
StatusCode = [System.Net.HttpStatusCode]::OK
Body = "output #3"
}) -Clobber
Push-OutputBinding
is used to send data to output bindings, such as an Azure Queue storage output binding. In the following example, the message written to the queue has a value of "output #1":
PS >Push-OutputBinding -Name outQueue -Value "output #1"
The output binding for a Storage queue accepts multiple output values. In this case, calling the following example after the first writes to the queue a list with two items: "output #1" and "output #2".
PS >Push-OutputBinding -Name outQueue -Value "output #2"
The following example, when called after the previous two, adds two more values to the output collection:
PS >Push-OutputBinding -Name outQueue -Value @("output #3", "output #4")
When written to the queue, the message contains these four values: "output #1", "output #2", "output #3", and "output #4".
You can use the Get-OutputBinding
cmdlet to retrieve the values currently set for your output bindings. This cmdlet retrieves a hashtable that contains the names of the output bindings with their respective values.
The following is an example of using Get-OutputBinding
to return current binding values:
Get-OutputBinding
Name Value
---- -----
MyQueue myData
MyOtherQueue myData
Get-OutputBinding
also contains a parameter called -Name
, which can be used to filter the returned binding, as in the following example:
Get-OutputBinding -Name MyQ*
Name Value
---- -----
MyQueue myData
Wildcards (*) are supported in Get-OutputBinding
.
Logging in PowerShell functions works like regular PowerShell logging. You can use the logging cmdlets to write to each output stream. Each cmdlet maps to a log level used by Functions.
Functions logging level | Logging cmdlet |
---|---|
Error | Write-Error |
Warning | Write-Warning |
Information | Write-Information Write-Host Write-Output Writes to the Information log level. |
Debug | Write-Debug |
Trace | Write-Progress Write-Verbose |
In addition to these cmdlets, anything written to the pipeline is redirected to the Information
log level and displayed with the default PowerShell formatting.
Tábhachtach
Using the Write-Verbose
or Write-Debug
cmdlets is not enough to see verbose and debug level logging. You must also configure the log level threshold, which declares what level of logs you actually care about. To learn more, see Configure the function app log level.
Azure Functions lets you define the threshold level to make it easy to control the way Functions writes to the logs. To set the threshold for all traces written to the console, use the logging.logLevel.default
property in the host.json
file. This setting applies to all functions in your function app.
The following example sets the threshold to enable verbose logging for all functions, but sets the threshold to enable debug logging for a function named MyFunction
:
{
"logging": {
"logLevel": {
"Function.MyFunction": "Debug",
"default": "Trace"
}
}
}
For more information, see host.json reference.
If your Function App is running in Azure, you can use Application Insights to monitor it. Read monitoring Azure Functions to learn more about viewing and querying function logs.
If you're running your Function App locally for development, logs default to the file system. To see the logs in the console, set the AZURE_FUNCTIONS_ENVIRONMENT
environment variable to Development
before starting the Function App.
There are many triggers and bindings available to you to use with your function app. The full list of triggers and bindings can be found here.
All triggers and bindings are represented in code as a few real data types:
The first five types in this list are standard .NET types. The last two are used only by the HttpTrigger trigger.
Each binding parameter in your functions must be one of these types.
HTTP and webhook triggers and HTTP output bindings use request and response objects to represent the HTTP messaging.
The request object that is passed into the script is of the type HttpRequestContext
, which has the following properties:
Property | Description | Type |
---|---|---|
Body |
An object that contains the body of the request. Body is serialized into the best type based on the data. For example, if the data is JSON, it is passed in as a hashtable. If the data is a string, it's passed in as a string. |
object |
Headers |
A dictionary that contains the request headers. | Dictionary<string,string>* |
Method |
The HTTP method of the request. | string |
Params |
An object that contains the routing parameters of the request. | Dictionary<string,string>* |
Query |
An object that contains the query parameters. | Dictionary<string,string>* |
Url |
The URL of the request. | string |
* All Dictionary<string,string>
keys are case-insensitive.
The response object that you should send back is of the type HttpResponseContext
, which has the following properties:
Property | Description | Type |
---|---|---|
Body |
An object that contains the body of the response. | object |
ContentType |
A short hand for setting the content type for the response. | string |
Headers |
An object that contains the response headers. | Dictionary or Hashtable |
StatusCode |
The HTTP status code of the response. | string or int |
When you work with HTTP triggers, you can access the HTTP request the same way you would with any other input binding. It's in the param
block.
Use an HttpResponseContext
object to return a response, as shown in the following example:
function.json
{
"bindings": [
{
"type": "httpTrigger",
"direction": "in",
"authLevel": "anonymous"
},
{
"type": "http",
"direction": "out",
"name": "Response"
}
]
}
run.ps1
param($req, $TriggerMetadata)
$name = $req.Query.Name
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = [System.Net.HttpStatusCode]::OK
Body = "Hello $name!"
})
The result of invoking this function would be:
PS > irm http://localhost:5001?Name=Functions
Hello Functions!
For certain bindings like the blob binding, you're able to specify the type of the parameter.
For example, to have data from Blob storage supplied as a string, add the following type cast to my param
block:
param([string] $myBlob)
In PowerShell, there's the concept of a PowerShell profile. If you're not familiar with PowerShell profiles, see About profiles.
In PowerShell Functions, the profile script is executed once per PowerShell worker instance in the app when first deployed and after being idled (cold start. When concurrency is enabled by setting the PSWorkerInProcConcurrencyUpperBound value, the profile script is run for each runspace created.
When you create a function app using tools, such as Visual Studio Code and Azure Functions Core Tools, a default profile.ps1
is created for you. The default profile is maintained
on the Core Tools GitHub repository
and contains:
AzureRM
PowerShell aliases if you would like.The following table shows the PowerShell versions available to each major version of the Functions runtime, and the .NET version required:
Functions version | PowerShell version | .NET version |
---|---|---|
4.x | PowerShell 7.4 | .NET 8 |
4.x | PowerShell 7.2 (support ending) | .NET 6 |
You can see the current version by printing $PSVersionTable
from any function.
To learn more about Azure Functions runtime support policy, refer to this article
Nóta
Support for PowerShell 7.2 in Azure Functions ends on November 8, 2024. You might have to resolve some breaking changes when upgrading your PowerShell 7.2 functions to run on PowerShell 7.4. Follow this migration guide to upgrade to PowerShell 7.4.
When running your PowerShell functions locally, you need to add the setting "FUNCTIONS_WORKER_RUNTIME_VERSION" : "7.4"
to the Values
array in the local.setting.json file in the project root. When running locally on PowerShell 7.4, your local.settings.json file looks like the following example:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "",
"FUNCTIONS_WORKER_RUNTIME": "powershell",
"FUNCTIONS_WORKER_RUNTIME_VERSION" : "7.4"
}
}
Nóta
In PowerShell Functions, the value "~7" for FUNCTIONS_WORKER_RUNTIME_VERSION refers to "7.0.x". We do not automatically upgrade PowerShell Function apps that have "~7" to "7.4". Going forward, for PowerShell Function Apps, we will require that apps specify both the major and minor version they want to target. Hence, it is necessary to mention "7.4" if you want to target "7.4.x"
Take these considerations into account before you migrate your PowerShell function app to PowerShell 7.4:
Because the migration might introduce breaking changes in your app, review this migration guide before upgrading your app to PowerShell 7.4.
Make sure that your function app is running on the latest version of the Functions runtime in Azure, which is version 4.x. For more information, see View and update the current runtime version.
Use the following steps to change the PowerShell version used by your function app. You can perform this operation either in the Azure portal or by using PowerShell.
In the Azure portal, browse to your function app.
Under Settings, choose Configuration. In the General settings tab, locate the PowerShell version.
Choose your desired PowerShell Core version and select Save. When warned about the pending restart choose Continue. The function app restarts on the chosen PowerShell version.
Nóta
Azure Functions support for PowerShell 7.4 is generally available (GA). You may see PowerShell 7.4 still indicated as preview in the Azure portal, but this will be updated soon to reflect the GA status.
The function app restarts after the change is made to the configuration.
Managing modules in Azure Functions written in PowerShell can be approached in two ways: using the Managed Dependencies feature or including the modules directly in your app content. Each method has its own advantages, and choosing the right one depends on your specific needs.
Why use the Managed Dependencies feature?
requirements.psd1
file.Why include modules in app content?
The Managed Dependencies feature allows Azure Functions to automatically download and manage PowerShell modules specified in the requirements.psd1
file. This feature is enabled by default in new PowerShell function apps.
To use Managed Dependencies in Azure Functions with PowerShell, you need to configure a requirements.psd1
file. This file specifies the modules your function requires, and Azure Functions automatically downloads and updates these modules to ensure that your environment stays up-to-date.
Here's how to set up and configure the requirements.psd1
file:
requirements.psd1
file in the root directory of your Azure Function if one doesn't already exist.Example requirements.psd1
file:
@{
'Az' = '9.*' # Specifies the Az module and will use the latest version with major version 9
}
For more control over your module versions and to avoid dependencies on external resources, you can include modules directly in your function app’s content.
To include custom modules:
Create a Modules
folder at the root of your function app.
mkdir ./Modules
Copy modules to the Modules
folder using one of the following methods:
If modules are already available locally:
Copy-Item -Path /mymodules/mycustommodule -Destination ./Modules -Recurse
Using Save-Module
to retrieve from the PowerShell Gallery:
Save-Module -Name MyCustomModule -Path ./Modules
Using Save-PSResource
from the PSResourceGet
module:
Save-PSResource -Name MyCustomModule -Path ./Modules
Your function app should have the following structure:
PSFunctionApp
| - MyFunction
| | - run.ps1
| | - function.json
| - Modules
| | - MyCustomModule
| | - MyOtherCustomModule
| | - MySpecialModule.psm1
| - local.settings.json
| - host.json
| - requirements.psd1
When you start your function app, the PowerShell language worker adds this Modules
folder to the $env:PSModulePath
so that you can rely on module autoloading just as you would in a regular PowerShell script.
Nóta
If your function app is under source control, you should confirm that all the content in the Modules folder that you add is not excluded by .gitignore. For example, if one of your modules has a bin folder that is getting excluded, you would want to modify the .gitignore by replacing bin
with
**/bin/**
!Modules/**
In order for Managed Dependencies to function, the feature must be enabled in host.json:
{
"managedDependency": {
"enabled": true
}
}
When targeting specific module versions, it’s important to follow both of the following steps to ensure the correct module version is loaded:
Specify the module version in requirements.psd1
:
@{
'Az.Accounts' = '1.9.5'
}
Add an import statement to profile.ps1
:
Import-Module Az.Accounts -RequiredVersion '1.9.5'
Following these steps ensures the specified version is loaded when your function starts.
You can configure how Managed Dependencies are downloaded and installed using the following app settings:
Setting | Default Value | Description |
---|---|---|
MDMaxBackgroundUpgradePeriod | 7.00:00:00 (seven days) |
Controls the background update period for PowerShell function apps. |
MDNewSnapshotCheckPeriod | 01:00:00 (one hour) |
Specifies how often the PowerShell worker checks for updates. |
MDMinBackgroundUpgradePeriod | 1.00:00:00 (one day) |
Minimum time between upgrade checks. |
https://www.powershellgallery.com
to download modules. Ensure that your environment allows this access, including modifying firewall/VNet rules as needed.$env:PSModulePath
. When running in Azure, the $env:PSModulePath
for a PowerShell function app differs from $env:PSModulePath
in a regular PowerShell script and will contain both the Modules
folder uploaded with your app contents and a separate location managed by Managed Dependencies.In Functions, app settings, such as service connection strings, are exposed as environment variables during execution. You can access these settings using $env:NAME_OF_ENV_VAR
, as shown in the following example:
param($myTimer)
Write-Host "PowerShell timer trigger function ran! $(Get-Date)"
Write-Host $env:AzureWebJobsStorage
Write-Host $env:WEBSITE_SITE_NAME
There are several ways that you can add, update, and delete function app settings:
Changes to function app settings require your function app to be restarted.
When running locally, app settings are read from the local.settings.json project file.
By default, the Functions PowerShell runtime can only process one invocation of a function at a time. However, this concurrency level might not be sufficient in the following situations:
There are a few concurrency models that you could explore depending on the type of workload:
Increase FUNCTIONS_WORKER_PROCESS_COUNT
. Increasing this setting allows handling function invocations in multiple processes within the same instance, which introduces certain CPU and memory overhead. In general, I/O-bound functions don't suffer from this overhead. For CPU-bound functions, the impact may be significant.
Increase the PSWorkerInProcConcurrencyUpperBound
app setting value. Increasing this setting allows creating multiple runspaces within the same process, which significantly reduces CPU and memory overhead.
You set these environment variables in the app settings of your function app.
Depending on your use case, Durable Functions may significantly improve scalability. To learn more, see Durable Functions application patterns.
Nóta
You might get "requests are being queued due to no available runspaces" warnings, please note that this is not an error. The message is telling you that requests are being queued and they will be handled when the previous requests are completed.
PowerShell is a single_threaded scripting language by default. However, concurrency can be added by using multiple PowerShell runspaces in the same process. The number of runspaces created, and therefore the number of concurrent threads per worker, is limited by the PSWorkerInProcConcurrencyUpperBound
application setting. By default, the number of runspaces is set to 1,000 in version 4.x of the Functions runtime. In versions 3.x and below, the maximum number of runspaces is set to 1. The throughput of your function app is impacted by the amount of CPU and memory available in the selected plan.
Azure PowerShell uses some process-level contexts and state to help save you from excess typing. However, if you turn on concurrency in your function app and invoke actions that change state, you could end up with race conditions. These race conditions are difficult to debug because one invocation relies on a certain state and the other invocation changed the state.
There's immense value in concurrency with Azure PowerShell, since some operations can take a considerable amount of time. However, you must proceed with caution. If you suspect that you're experiencing a race condition, set the PSWorkerInProcConcurrencyUpperBound app setting to 1
and instead use language worker process level isolation for concurrency.
By default, a PowerShell function is executed from run.ps1
, a file that shares the same parent directory as its corresponding function.json
.
The scriptFile
property in the function.json
can be used to get a folder structure that looks like the following example:
FunctionApp
| - host.json
| - myFunction
| | - function.json
| - lib
| | - PSFunction.ps1
In this case, the function.json
for myFunction
includes a scriptFile
property referencing the file with the exported function to run.
{
"scriptFile": "../lib/PSFunction.ps1",
"bindings": [
// ...
]
}
PowerShell functions in this article are shown with the default run.ps1
script file generated by the templates.
However, you can also include your functions in PowerShell modules. You can reference your specific function code in the module by using the scriptFile
and entryPoint
fields in the function.json` configuration file.
In this case, entryPoint
is the name of a function or cmdlet in the PowerShell module referenced in scriptFile
.
Consider the following folder structure:
FunctionApp
| - host.json
| - myFunction
| | - function.json
| - lib
| | - PSFunction.psm1
Where PSFunction.psm1
contains:
function Invoke-PSTestFunc {
param($InputBinding, $TriggerMetadata)
Push-OutputBinding -Name OutputBinding -Value "output"
}
Export-ModuleMember -Function "Invoke-PSTestFunc"
In this example, the configuration for myFunction
includes a scriptFile
property that references PSFunction.psm1
, which is a PowerShell module in another folder. The entryPoint
property references the Invoke-PSTestFunc
function, which is the entry point in the module.
{
"scriptFile": "../lib/PSFunction.psm1",
"entryPoint": "Invoke-PSTestFunc",
"bindings": [
// ...
]
}
With this configuration, the Invoke-PSTestFunc
gets executed exactly as a run.ps1
would.
When you work with PowerShell functions, be aware of the considerations in the following sections.
When developing Azure Functions in the serverless hosting model, cold starts are a reality. Cold start refers to period of time it takes for your function app to start running to process a request. Cold start happens more frequently in the Consumption plan because your function app gets shut down during periods of inactivity.
Running Install-Module
in your function script on each invocation can cause performance issues. Instead, use Save-Module
or Save-PSResource
before publishing your function app to bundle the necessary modules.
For more information, see the Dependency Management section.
For more information, see the following resources:
Ócáid
Mar 17, 9 PM - Mar 21, 10 AM
Bí ar an tsraith meetup chun réitigh AI inscálaithe a thógáil bunaithe ar chásanna úsáide fíor-dhomhanda le forbróirí agus saineolaithe eile.
Cláraigh anoisOiliúint
Cosán foghlama
Use advance techniques in canvas apps to perform custom updates and optimization - Training
Use advance techniques in canvas apps to perform custom updates and optimization