Azure Functions PowerShell 开发人员指南Azure Functions PowerShell developer guide

本文详细介绍了如何使用 PowerShell 编写 Azure Functions。This article provides details about how you write Azure Functions using PowerShell.

PowerShell Azure 函数(简称函数)表示为在触发时执行的 PowerShell 脚本。A PowerShell Azure function (function) is represented as a PowerShell script that executes when triggered. 每个函数脚本都有一个相关的 function.json 文件,用于定义该函数的行为方式,例如其触发方式及其输入和输出参数。Each function script has a related function.json file that defines how the function behaves, such as how it's triggered and its input and output parameters. 若要了解详细信息,请参阅触发器和绑定一文。To learn more, see the Triggers and binding article.

与其他类型的函数一样,PowerShell 脚本函数采用与 function.json 文件中定义的所有输入绑定的名称相匹配的参数。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. 此外还传递了一个 TriggerMetadata 参数,该参数包含启动了该函数的触发器的附加信息。A TriggerMetadata parameter is also passed that contains additional information on the trigger that started the function.

本文假定你已阅读 Azure Functions 开发人员参考This article assumes that you have already read the Azure Functions developer reference. 你应当也已完成创建第一个 PowerShell 函数所需的 PowerShell 函数快速入门You should have also completed the Functions quickstart for PowerShell to create your first PowerShell function.

文件夹结构Folder structure

PowerShell 项目所需的文件夹结构如下所示。The required folder structure for a PowerShell project looks like the following. 可更改此默认值。This default can be changed. 有关详细信息,请参阅下面的 scriptFile 部分。For more information, see the scriptFile section below.

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

项目的根目录中有共享的 host.json 文件,可用于配置函数应用。At the root of the project, there's a shared host.json file that can be used to configure the function app. 每个函数都有一个文件夹,其中包含它自己的代码文件 (.ps1) 和绑定配置文件 (function.json)。Each function has a folder with its own code file (.ps1) and binding configuration file (function.json). function.json 文件的父目录的名称始终是函数的名称。The name of the function.json file's parent directory is always the name of your function.

某些绑定要求存在 extensions.csproj 文件。Certain bindings require the presence of an extensions.csproj file. 2.x 及更高版本的 Functions 运行时中所需的绑定扩展在 extensions.csproj 文件中定义,实际库文件位于 bin 文件夹中。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. 在 Azure 门户中开发函数时,系统将为你完成此注册。When developing functions in the Azure portal, this registration is done for you.

在 PowerShell 函数应用中,你可以选择创建一个在函数应用开始运行(也称为冷启动)时运行的 profile.ps1In 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. 有关详细信息,请参阅 PowerShell 配置文件For more information, see PowerShell profile.

将 PowerShell 脚本定义为函数Defining a PowerShell script as a function

默认情况下,Functions 运行时会在 run.ps1 中查找你的函数,其中,run.ps1 与其相应的 function.json 共享同一个父目录。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 a number of arguments on execution. 若要处理这些参数,请将 param 块添加到脚本顶部,如以下示例所示: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)

TriggerMetadata 参数TriggerMetadata parameter

TriggerMetadata 参数用于提供有关触发器的附加信息。The TriggerMetadata parameter is used to supply additional information about the trigger. 附加元数据因绑定而异,但是它们都包含一个 sys 属性,该属性包含以下数据:The additional metadata varies from binding to binding but they all contain a sys property that contains the following data:

$TriggerMetadata.sys
PropertyProperty 说明Description 类型Type
UtcNowUtcNow 函数的触发时间(采用 UTC 格式)When, in UTC, the function was triggered DateTimeDateTime
MethodNameMethodName 已触发的函数的名称The name of the Function that was triggered 字符串string
RandGuidRandGuid 针对函数的此执行操作的唯一 GUIDa unique guid to this execution of the function 字符串string

每个触发器类型都有一组不同的元数据。Every trigger type has a different set of metadata. 例如,QueueTrigger$TriggerMetadata 包含 InsertionTimeIdDequeueCount 等内容。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.

绑定Bindings

在 PowerShell 中,需在函数的 function.json 中配置和定义绑定In PowerShell, bindings are configured and defined in a function's function.json. 函数通过多种方式来与绑定交互。Functions interact with bindings a number of ways.

读取触发器和输入数据Reading trigger and input data

触发器和输入绑定被读取为传递给函数的参数。Trigger and input bindings are read as parameters passed to your function. 输入绑定在 function.json 中有一个设置为 indirectionInput bindings have a direction set to in in function.json. function.json 中定义的 name 属性是 param 块中参数的名称。The name property defined in function.json is the name of the parameter, in the param block. 由于 PowerShell 使用已命名参数进行绑定,因此参数的顺序并不重要。Since PowerShell uses named parameters for binding, the order of the parameters doesn't matter. 不过,最佳做法是遵循 function.json 中定义的绑定的顺序。However, it's a best practice to follow the order of the bindings defined in the function.json.

param($MyFirstInputBinding, $MySecondInputBinding)

写入输出数据Writing output data

在 Functions 中,输出绑定在 function.json 中有一个设置为 outdirectionIn Functions, an output binding has a direction set to out in the function.json. 你可以使用 Push-OutputBinding cmdlet(可用于 Functions 运行时)将数据写入到输出绑定。You can write to an output binding by using the Push-OutputBinding cmdlet, which is available to the Functions runtime. 在所有情况下,function.json 中定义的绑定的 name 属性都对应于 Push-OutputBinding cmdlet 的 Name 参数。In all cases, the name property of the binding as defined in function.json corresponds to the Name parameter of the Push-OutputBinding cmdlet.

下面展示了如何在函数脚本中调用 Push-OutputBindingThe following 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 的行为因为 -Name 指定的值而异:Push-OutputBinding behaves differently based on the value specified for -Name:

  • 当指定的名称无法解析为有效的输出绑定时,会引发错误。When the specified name cannot be resolved to a valid output binding, then an error is thrown.

  • 当输出绑定接受值的集合时,可以重复调用 Push-OutputBinding 来推送多个值。When the output binding accepts a collection of values, you can call Push-OutputBinding repeatedly to push multiple values.

  • 当输出绑定只接受单一实例值时,第二次调用 Push-OutputBinding 会引发错误。When the output binding only accepts a singleton value, calling Push-OutputBinding a second time raises an error.

Push-OutputBinding 语法Push-OutputBinding syntax

下面是用于调用 Push-OutputBinding 的有效参数:The following are valid parameters for calling Push-OutputBinding:

名称Name 类型Type 位置Position 说明Description
-Name 字符串String 11 你要设置的输出绑定的名称。The name of the output binding you want to set.
-Value ObjectObject 22 你要设置的输出绑定的值,它是从管道 ByValue 接受的。The value of the output binding you want to set, which is accepted from the pipeline ByValue.
-Clobber SwitchParameterSwitchParameter 名为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

有关详细信息,请参阅关于 CommonParametersFor more information, see About CommonParameters.

Push-OutputBinding 示例:HTTP 响应Push-OutputBinding example: HTTP responses

HTTP 触发器使用名为 response 的输出绑定返回响应。An HTTP trigger returns a response using an output binding named response. 在下面的示例中,response 的输出绑定具有“output #1”值: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"
})

由于输出是针对 HTTP(仅接受单一实例值),因此在第二次调用 Push-OutputBinding 时会引发错误。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"
})

对于仅接受单一实例值的输出,可以使用 -Clobber 参数替代旧值,而不要尝试将内容添加到集合。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. 通过使用 -Clobber,以下示例中的响应会替代现有值以返回“output #3”值: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 示例:队列输出绑定Push-OutputBinding example: Queue output binding

Push-OutputBinding 用于将数据发送到输出绑定,例如 Azure 队列存储输出绑定Push-OutputBinding is used to send data to output bindings, such as an Azure Queue storage output binding. 在下面的示例中,写入到队列的消息具有值“output #1”: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. 在本例中,在第一个示例之后调用以下示例会向队列中写入具有以下两个项的列表:“output #1”和“output #2”。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")

写入到队列时,消息包含这四个值:“output #1”、“output #2”、“output #3”和“output #4”。When written to the queue, the message contains these four values: "output #1", "output #2", "output #3", and "output #4".

Get-OutputBinding cmdletGet-OutputBinding cmdlet

可以使用 Get-OutputBinding cmdlet 来检索当前为你的输出绑定设置的值。You can use the Get-OutputBinding cmdlet to retrieve the values currently set for your output bindings. 此 cmdlet 会检索一个包含输出绑定名称及其各自值的哈希表。This cmdlet retrieves a hashtable that contains the names of the output bindings with their respective values.

下面是使用 Get-OutputBinding 返回当前绑定值的示例:The following is an example of using Get-OutputBinding to return current binding values:

Get-OutputBinding
Name                           Value
----                           -----
MyQueue                        myData
MyOtherQueue                   myData

Get-OutputBinding 还包含一个名为 -Name 的参数,该参数可用于筛选返回的绑定,如以下示例所示: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

Get-OutputBinding 支持通配符 (*)。Wildcards (*) are supported in Get-OutputBinding.

LoggingLogging

PowerShell 函数中的日志记录的工作方式类似于常规的 PowerShell 日志记录。Logging in PowerShell functions works like regular PowerShell logging. 你可以使用日志记录 cmdlet 将内容写入到每个输出流。You can use the logging cmdlets to write to each output stream. 每个 cmdlet 都映射到 Functions 使用的一个日志级别。Each cmdlet maps to a log level used by Functions.

Functions 日志记录级别Functions logging level 日志记录 cmdletLogging cmdlet
错误Error Write-Error
警告Warning Write-Warning
信息Information Write-Information
Write-Host
Write-Output
信息Information 写入到信息级别的日志记录。Writes to Information level logging.
调试Debug Write-Debug
跟踪Trace Write-Progress
Write-Verbose

除了这些 cmdlet 外,写入到管道的任何内容都会重定向到 Information 日志级别,并以默认的 PowerShell 格式设置进行显示。In addition to these cmdlets, anything written to the pipeline is redirected to the Information log level and displayed with the default PowerShell formatting.

重要

并非仅使用 Write-VerboseWrite-Debug cmdlet 就可以查看详细级别和调试级别的日志记录。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.

配置函数应用日志级别Configure the function app log level

可以使用 Azure Functions 来定义阈值级别,以便轻松控制 Functions 向日志写入内容的方式。Azure Functions lets you define the threshold level to make it easy to control the way Functions writes to the logs. 若要针对写入到控制台的所有跟踪设置阈值,请在 [host.json 文件][host.json 参考]中使用 logging.logLevel.default 属性。To set the threshold for all traces written to the console, use the logging.logLevel.default property in the host.json file. 此设置应用于 Function App 中的所有函数。This setting applies to all functions in your function app.

以下示例将阈值设置为对所有函数启用详细日志记录,但将阈值设置为对名为 MyFunction 的函数启用调试日志记录: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"
        }
    }
}  

有关详细信息,请参阅 [host.json 参考]。For more information, see host.json reference.

查看日志Viewing the logs

如果你的函数应用在 Azure 中运行,则可以使用 Application Insights 监视它。If your Function App is running in Azure, you can use Application Insights to monitor it. 若要了解有关查看和查询函数日志的详细信息,请阅读监视 Azure FunctionsRead 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. 若要在控制台中查看日志,请在启动函数应用之前将 AZURE_FUNCTIONS_ENVIRONMENT 环境变量设置为 DevelopmentTo see the logs in the console, set the AZURE_FUNCTIONS_ENVIRONMENT environment variable to Development before starting the Function App.

触发器和绑定类型Triggers and bindings types

你可以将许多触发器和绑定用于你的函数应用。There are a number of 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:

  • HashtableHashtable
  • 字符串string
  • byte[]byte[]
  • intint
  • Doubledouble
  • HttpRequestContextHttpRequestContext
  • HttpResponseContextHttpResponseContext

此列表中的前五个类型是标准 .NET 类型。The first five types in this list are standard .NET types. 最后两个类型仅由 HttpTrigger 触发器使用。The last two are used only by the HttpTrigger trigger.

函数中的每个绑定参数都必须是这些类型之一。Each binding parameter in your functions must be one of these types.

HTTP 触发器和绑定HTTP triggers and bindings

HTTP 和 webhook 触发器以及 HTTP 输出绑定使用请求和响应对象来表示 HTTP 消息。HTTP and webhook triggers and HTTP output bindings use request and response objects to represent the HTTP messaging.

请求对象Request object

传递给脚本的请求对象是 HttpRequestContext 类型的,它具有以下属性:The request object that's passed into the script is of the type HttpRequestContext, which has the following properties:

PropertyProperty 说明Description 类型Type
Body 一个包含请求正文的对象。An object that contains the body of the request. Body 基于数据序列化为最佳类型。Body is serialized into the best type based on the data. 例如,如果数据是 JSON,则它将作为哈希表传入。For example, if the data is JSON, it's 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>*Dictionary<string,string>*
Method 请求的 HTTP 方法。The HTTP method of the request. 字符串string
Params 一个包含请求的路由参数的对象。An object that contains the routing parameters of the request. Dictionary<string,string>*Dictionary<string,string>*
Query 一个包含查询参数的对象。An object that contains the query parameters. Dictionary<string,string>*Dictionary<string,string>*
Url 请求的 URL。The URL of the request. 字符串string

* 所有 Dictionary<string,string> 键都不区分大小写。* All Dictionary<string,string> keys are case-insensitive.

响应对象Response object

应当发送回的响应对象的类型为 HttpResponseContext,该类型具有以下属性:The response object that you should send back is of the type HttpResponseContext, which has the following properties:

PropertyProperty 说明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 响应的 HTTP 状态代码。The HTTP status code of the response. 字符串或整数string or int

访问请求和响应Accessing the request and response

使用 HTTP 触发器时,可以使用与任何其他输入绑定相同的方式访问 HTTP 请求。When you work with HTTP triggers, you can access the HTTP request the same way you would with any other input binding. 它位于 param 块中。It's in the param block.

使用 HttpResponseContext 对象返回一个响应,如下所示:Use an HttpResponseContext object to return a response, as shown in the following:

function.json

{
  "bindings": [
    {
      "type": "httpTrigger",
      "direction": "in",
      "authLevel": "anonymous"
    },
    {
      "type": "http",
      "direction": "out"
    }
  ]
}

run.ps1

param($req, $TriggerMetadata)

$name = $req.Query.Name

Push-OutputBinding -Name res -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!

触发器和绑定的类型强制转换Type-casting for triggers and bindings

对于某些绑定(例如 blob 绑定),你可以指定参数的类型。For certain bindings like the blob binding, you're able to specify the type of the parameter.

例如,若要将 Blob 存储中的数据作为字符串提供,请将以下类型强制转换添加到 param 块:For example, to have data from Blob storage supplied as a string, add the following type cast to my param block:

param([string] $myBlob)

PowerShell 配置文件PowerShell profile

在 PowerShell 中存在 PowerShell 配置文件的概念。In PowerShell, there's the concept of a PowerShell profile. 如果你不熟悉 PowerShell 配置文件,请参阅关于配置文件If you're not familiar with PowerShell profiles, see About profiles.

在 PowerShell 函数中,在首次部署并闲置后,会在应用中为每个 PowerShell 工作进程实例执行一次配置文件脚本(冷启动)。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. 如果通过设置 PSWorkerInProcConcurrencyUpperBound 值启用了并发,则会为所创建的每个运行空间运行配置文件脚本。When concurrency is enabled by setting the PSWorkerInProcConcurrencyUpperBound value, the profile script is run for each runspace created.

当你使用工具(例如 Visual Studio Code 和 Azure Functions Core Tools)创建函数应用时,系统会为你创建一个默认的 profile.ps1When 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. 默认配置文件在 Core Tools GitHub 存储库中维护,其中包含:The default profile is maintained on the Core Tools GitHub repository and contains:

  • 自动向 Azure 进行 MSI 身份验证的功能。Automatic MSI authentication to Azure.
  • 根据需要启用 Azure PowerShell AzureRM PowerShell 别名的功能。The ability to turn on the Azure PowerShell AzureRM PowerShell aliases if you would like.

PowerShell 版本PowerShell versions

下表显示了适用于 Functions 运行时的每个主要版本的 PowerShell 版本,以及所需的 .NET 版本:The following table shows the PowerShell versions available to each major version of the Functions runtime, and the .NET version required:

Functions 版本Functions version PowerShell 版本PowerShell version .NET 版本.NET version
3.x(建议)3.x (recommended) PowerShell 7(建议)PowerShell 7 (recommended)
PowerShell Core 6PowerShell Core 6
.NET Core 3.1.NET Core 3.1
.NET Core 2.1.NET Core 2.1
2.x2.x PowerShell Core 6PowerShell Core 6 .NET Core 2.2.NET Core 2.2

可以通过输出任何函数的 $PSVersionTable 来查看当前版本。You can see the current version by printing $PSVersionTable from any function.

在特定版本上以本地方式运行Running local on a specific version

以本地方式运行时,Azure Functions 运行时默认为使用 PowerShell Core 6。When running locally the Azure Functions runtime defaults to using PowerShell Core 6. 若要在以本地方式运行时改用 PowerShell 7,则需要在项目根目录的 local.setting.json 文件的 Values 数组中添加设置 "FUNCTIONS_WORKER_RUNTIME_VERSION" : "~7"To instead use PowerShell 7 when running locally, you need to add the setting "FUNCTIONS_WORKER_RUNTIME_VERSION" : "~7" to the Values array in the local.setting.json file in the project root. 在 PowerShell 7 上以本地方式运行时,你的 local.settings.json 文件类似于以下示例:When running locally on PowerShell 7, your local.settings.json file looks like the following example:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "FUNCTIONS_WORKER_RUNTIME": "powershell",
    "FUNCTIONS_WORKER_RUNTIME_VERSION" : "~7"
  }
}

更改 PowerShell 版本Changing the PowerShell version

函数应用必须在版本 3.x 上运行才能从 PowerShell Core 6 升级到 PowerShell 7。Your function app must be running on version 3.x to be able to upgrade from PowerShell Core 6 to PowerShell 7. 若要了解如何执行此操作,请参阅查看和更新当前运行时版本To learn how to do this, see View and update the current runtime version.

请使用以下步骤更改函数应用使用的 PowerShell 版本。Use the following steps to change the PowerShell version used by your function app. 可以通过 Azure 门户或 PowerShell 执行此操作。You can do this either in the Azure portal or by using PowerShell.

  1. Azure 门户中,浏览到你的函数应用。In the Azure portal, browse to your function app.

  2. 在“设置”下,选择“配置” 。Under Settings, choose Configuration. 在“常规设置”选项卡中,找到“PowerShell 版本”。In the General settings tab, locate the PowerShell version.

    选择函数应用使用的 PowerShell 版本

  3. 选择所需的 PowerShell Core 版本 并选择“保存”。Choose your desired PowerShell Core version and select Save. 收到等待重启的警告时,请选择“继续”。When warned about the pending restart choose Continue. 函数应用会在所选的 PowerShell 版本上重启。The function app restarts on the chosen PowerShell version.

在对配置进行更改后,函数应用会重启。The function app restarts after the change is made to the configuration.

依赖项管理Dependency management

Functions 允许你利用 PowerShell 库来管理依赖项。Functions lets you leverage PowerShell gallery for managing dependencies. 启用依赖项管理后,使用 requirements.psd1 文件来自动下载所需的模块。With dependency management enabled, the requirements.psd1 file is used to automatically download required modules. 启用此行为的方法是:在 host.json 文件的根目录中,将 managedDependency 属性设置为 true,如以下示例所示:You enable this behavior by setting the managedDependency property to true in the root of the host.json file, as in the following example:

{
  "managedDependency": {
          "enabled": true
       }
}

创建新的 PowerShell 函数项目时,默认情况下会启用依赖项管理,并且会包括 Azure Az 模块When you create a new PowerShell functions project, dependency management is enabled by default, with the Azure Az module included. 当前支持的最大模块数为 10。The maximum number of modules currently supported is 10. 支持的语法为 MajorNumber .* 或确切的模块版本,如以下 requirements.psd1 示例所示:The supported syntax is MajorNumber.* or exact module version as shown in the following requirements.psd1 example:

@{
    Az = '1.*'
    SqlServer = '21.1.18147'
}

更新 requirements.psd1 文件时,会在重启后安装更新的模块。When you update the requirements.psd1 file, updated modules are installed after a restart.

备注

托管依赖项需要访问 www.powershellgallery.com 来下载模块。Managed dependencies requires access to www.powershellgallery.com to download modules. 在本地运行时,请通过添加任何所需的防火墙规则来确保运行时可以访问此 URL。When running locally, make sure that the runtime can access this URL by adding any required firewall rules.

备注

托管依赖项当前不支持要求用户接受许可证的模块,无论是通过交互方式接受许可证,还是通过在调用 Install-Module 时提供 -AcceptLicense 开关。Managed dependencies currently don't support modules that require the user to accept a license, either by accepting the license interactively, or by providing -AcceptLicense switch when invoking Install-Module.

可以使用以下应用程序设置来更改下载和安装托管依赖项的方式。The following application settings can be used to change how the managed dependencies are downloaded and installed. 你的应用升级在 MDMaxBackgroundUpgradePeriod 内启动,升级过程在大约 MDNewSnapshotCheckPeriod 内完成。Your app upgrade starts within MDMaxBackgroundUpgradePeriod, and the upgrade process completes within approximately the MDNewSnapshotCheckPeriod.

函数应用设置Function App setting 默认值Default value 说明Description
MDMaxBackgroundUpgradePeriod 7.00:00:00(7 天)7.00:00:00 (7 days) 每个 PowerShell 工作进程都会在进程启动时检查 PowerShell 库上的模块升级,并在之后每 MDMaxBackgroundUpgradePeriod 检查一次。Each PowerShell worker process initiates checking for module upgrades on the PowerShell Gallery on process start and every MDMaxBackgroundUpgradePeriod after that. 当 PowerShell 库中有新的模块版本时,该版本会被安装到文件系统,并提供给 PowerShell 工作进程。When a new module version is available in the PowerShell Gallery, it's installed to the file system and made available to PowerShell workers. 减小此值后,函数应用不但可以更快地获取较新的模块版本,而且可以增加应用资源使用率(网络 I/O、CPU、存储)。Decreasing this value lets your function app get newer module versions sooner, but it also increases the app resource usage (network I/O, CPU, storage). 增大此值会减少应用的资源使用率,但也可能会延迟将新的模块版本传递给你的应用。Increasing this value decreases the app's resource usage, but it may also delay delivering new module versions to your app.
MDNewSnapshotCheckPeriod 01:00:00(1 小时)01:00:00 (1 hour) 将新的模块版本安装到文件系统后,必须重启每个 PowerShell 工作进程。After new module versions are installed to the file system, every PowerShell worker process must be restarted. 重启 PowerShell 工作进程会影响应用可用性,因为它可能会中断当前的函数执行操作。Restarting PowerShell workers affects your app availability as it can interrupt current function execution. 在所有 PowerShell 工作进程都重启之前,函数调用可能使用旧的模块版本,也可能使用新的模块版本。Until all PowerShell worker processes are restarted, function invocations may use either the old or the new module versions. 重启所有 PowerShell 工作进程的操作会在 MDNewSnapshotCheckPeriod 内完成。Restarting all PowerShell workers complete within MDNewSnapshotCheckPeriod. 增大此值可降低中断频率,但也可能会延长不确定(即,不确定函数调用是使用旧模块版本还是使用新模块版本)的时段。Increasing this value decreases the frequency of interruptions, but may also increase the period of time when function invocations use either the old or the new module versions non-deterministically.
MDMinBackgroundUpgradePeriod 1.00:00:00(1 天)1.00:00:00 (1 day) 为了避免在频繁重启工作进程时进行过多的模块升级,当任何工作进程在上一个 MDMinBackgroundUpgradePeriod 中启动了模块升级检查时,系统不会执行该检查。To avoid excessive module upgrades on frequent Worker restarts, checking for module upgrades isn't performed when any worker has already initiated that check in the last MDMinBackgroundUpgradePeriod.

利用你自己的自定义模块的方式与通常的方式稍有不同。Leveraging your own custom modules is a little different than how you would do it normally.

在本地计算机上,该模块安装在 $env:PSModulePath 的全局可用文件夹之一中。On your local computer, the module gets installed in one of the globally available folders in your $env:PSModulePath. 在 Azure 中运行时,你无法访问计算机上安装的模块。When running in Azure, you don't have access to the modules installed on your machine. 这意味着 PowerShell 函数应用的 $env:PSModulePath 与常规 PowerShell 脚本中的 $env:PSModulePath 不同。This means that the $env:PSModulePath for a PowerShell function app differs from $env:PSModulePath in a regular PowerShell script.

在 Functions 中,PSModulePath 包含两个路径:In Functions, PSModulePath contains two paths:

  • 位于你的函数应用根目录中的 Modules 文件夹。A Modules folder that exists at the root of your function app.
  • 由 PowerShell 语言工作进程控制的 Modules 文件夹的路径。A path to a Modules folder that is controlled by the PowerShell language worker.

函数应用级 Modules 文件夹Function app-level Modules folder

若要使用自定义模块,可以将你的函数依赖的模块放置在 Modules 文件夹中。To use custom modules, you can place modules on which your functions depend in a Modules folder. 在此文件夹中,模块可以自动用于函数运行时。From this folder, modules are automatically available to the functions runtime. 函数应用中的任何函数都可以使用这些模块。Any function in the function app can use these modules.

备注

requirements.psd1 文件中指定的模块会自动下载并包含在路径中,因此不需要将它们包含在 modules 文件夹中。Modules specified in the requirements.psd1 file are automatically downloaded and included in the path so you don't need to include them in the modules folder. 它们存储在本地的 $env:LOCALAPPDATA/AzureFunctions 文件夹中;在云中运行时,它们存储在 /data/ManagedDependencies 文件夹中。These are stored locally in the $env:LOCALAPPDATA/AzureFunctions folder and in the /data/ManagedDependencies folder when run in the cloud.

若要利用自定义模块功能,请在你的函数应用的根目录中创建一个 Modules 文件夹。To take advantage of the custom module feature, create a Modules folder in the root of your function app. 将需要在函数中使用的模块复制到此位置。Copy the modules you want to use in your functions to this location.

mkdir ./Modules
Copy-Item -Path /mymodules/mycustommodule -Destination ./Modules -Recurse

对于 Modules 文件夹,函数应用应具有以下文件夹结构:With a Modules folder, your function app should have the following folder structure:

PSFunctionApp
 | - MyFunction
 | | - run.ps1
 | | - function.json
 | - Modules
 | | - MyCustomModule
 | | - MyOtherCustomModule
 | | - MySpecialModule.psm1
 | - local.settings.json
 | - host.json
 | - requirements.psd1

当你启动函数应用时,PowerShell 语言工作进程会将此 Modules 文件夹添加到 $env:PSModulePath 中,以便你可以像在常规 PowerShell 脚本中那样依赖于模块自动加载。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.

语言工作进程级 Modules 文件夹Language worker level Modules folder

PowerShell 语言工作进程通常使用几个模块。Several modules are commonly used by the PowerShell language worker. 这些模块在 PSModulePath 的最后一个位置中定义。These modules are defined in the last position of PSModulePath.

模块的当前列表如下所示:The current list of modules is as follows:

  • Microsoft.PowerShell.Archive:用于处理存档(例如 .zip.nupkg 和其他存档)的模块。Microsoft.PowerShell.Archive: module used for working with archives, like .zip, .nupkg, and others.
  • ThreadJob:PowerShell 作业 API 的基于线程的实现。ThreadJob: A thread-based implementation of the PowerShell job APIs.

默认情况下,函数使用这些模块的最新版本。By default, Functions uses the most recent version of these modules. 若要使用特定的模块版本,请将该特定版本放置在你的函数应用的 Modules 文件夹中。To use a specific module version, put that specific version in the Modules folder of your function app.

环境变量Environment variables

在 Functions 中,服务连接字符串等应用设置在执行过程中将公开为环境变量。In Functions, app settings, such as service connection strings, are exposed as environment variables during execution. 可以使用 $env:NAME_OF_ENV_VAR 访问这些设置,如以下示例所示: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.

在本地运行时,可从 local.settings.json 项目文件读取应用设置。When running locally, app settings are read from the local.settings.json project file.

并发Concurrency

默认情况下,Functions PowerShell 运行时一次只能处理一个函数调用。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:

  • 当你尝试同时处理大量调用时。When you're trying to handle a large number of invocations at the same time.
  • 当函数调用同一函数应用内的其他函数时。When you have functions that invoke other functions inside the same function app.

你可以根据工作负荷的类型来探索几个并发模型:There are a few concurrency models that you could explore depending on the type of workload:

  • 增大 FUNCTIONS_WORKER_PROCESS_COUNTIncrease FUNCTIONS_WORKER_PROCESS_COUNT. 这样就可以在同一实例的多个进程中处理函数调用,这会带来一定的 CPU 和内存开销。This allows handling function invocations in multiple processes within the same instance, which introduces certain CPU and memory overhead. 通常,I/O 绑定函数不受此开销影响。In general, I/O-bound functions will not suffer from this overhead. 对于 CPU 绑定函数,影响可能会很大。For CPU-bound functions, the impact may be significant.

  • 增大 PSWorkerInProcConcurrencyUpperBound 应用设置值。Increase the PSWorkerInProcConcurrencyUpperBound app setting value. 这样就可以在同一进程中创建多个运行空间,从而大大降低 CPU 和内存开销。This 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.

Durable Functions 可能会显著提高可伸缩性,具体取决于你的用例。Depending on your use case, Durable Functions may significantly improve scalability. 若要了解详细信息,请参阅 Durable Functions 应用程序模式To learn more, see Durable Functions application patterns.

备注

你可能会收到“请求正在排队,因为没有可用的运行空间”警告,请注意这不是错误。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.

使用并发时的注意事项Considerations for using concurrency

默认情况下,PowerShell 是单线程脚本语言。PowerShell is a single threaded scripting language by default. 但是,可以通过在同一进程中使用多个 PowerShell 运行空间来添加并发。However, concurrency can be added by using multiple PowerShell runspaces in the same process. 创建的运行空间数量将与 PSWorkerInProcConcurrencyUpperBound 应用程序设置匹配。The amount of runspaces created will match the PSWorkerInProcConcurrencyUpperBound application setting. 吞吐量会受选定计划中可用的 CPU 和内存量影响。The throughput will be impacted by the amount of CPU and memory available in the selected plan.

Azure PowerShell 使用某些进程级上下文和状态,避免你进行过多的键入。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.

Azure PowerShell 提供的并发性具有巨大的价值,因为某些操作可能需要相当长的时间。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. 如果怀疑出现争用情况,请将 PSWorkerInProcConcurrencyUpperBound 应用设置设为 1,并且为并发改用语言工作进程级隔离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.

配置函数 scriptFileConfigure function scriptFile

默认情况下通过 run.ps1(一个文件,与对应的 function.json 共享相同父目录)执行 PowerShell 函数。By default, a PowerShell function is executed from run.ps1, a file that shares the same parent directory as its corresponding function.json.

可以使用 function.json 中的 scriptFile 属性来获取以下示例所示的文件夹结构: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

在本例中,myFunctionfunction.json 包括一个 scriptFile 属性,该属性引用要运行的已导出函数所在的文件。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": [
    // ...
  ]
}

通过配置 entryPoint 来使用 PowerShell 模块Use PowerShell modules by configuring an entryPoint

本文展示了模板生成的默认 run.ps1 脚本文件中的 PowerShell 函数。This article has shown PowerShell functions in the default run.ps1 script file generated by the templates. 但是,你还可以在 PowerShell 模块中包含你的函数。However, you can also include your functions in PowerShell modules. 你可以通过在 function.json 配置文件中使用 scriptFileentryPoint 字段来引用模块中的特定函数代码。You can reference your specific function code in the module by using the scriptFile and entryPoint fields in the function.json` configuration file.

在本例中,entryPointscriptFile 中引用的 PowerShell 模块中的函数或 cmdlet 的名称。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

其中,PSFunction.psm1 包含:Where PSFunction.psm1 contains:

function Invoke-PSTestFunc {
    param($InputBinding, $TriggerMetadata)

    Push-OutputBinding -Name OutputBinding -Value "output"
}

Export-ModuleMember -Function "Invoke-PSTestFunc"

在此示例中,myFunction 的配置包含 scriptFile 属性,该属性引用 PSFunction.psm1,这是另一文件夹中的 PowerShell 模块。In this example, the configuration for myFunction includes a scriptFile property that references PSFunction.psm1, which is a PowerShell module in another folder. entryPoint 属性引用 Invoke-PSTestFunc 函数,该函数是模块中的入口点。The entryPoint property references the Invoke-PSTestFunc function, which is the entry point in the module.

{
  "scriptFile": "../lib/PSFunction.psm1",
  "entryPoint": "Invoke-PSTestFunc",
  "bindings": [
    // ...
  ]
}

使用此配置,Invoke-PSTestFunc 会完全像 run.ps1 那样执行。With this configuration, the Invoke-PSTestFunc gets executed exactly as a run.ps1 would.

PowerShell 函数的注意事项Considerations for PowerShell functions

使用 PowerShell 函数时,请注意以下各部分中的注意事项。When you work with PowerShell functions, be aware of the considerations in the following sections.

冷启动Cold Start

当在无服务器托管模型中开发 Azure Functions 时,冷启动是存在的现实情况。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.

绑定模块,而不是使用 Install-ModuleBundle modules instead of using Install-Module

脚本在每次调用时运行。Your script is run on every invocation. 避免在脚本中使用 Install-ModuleAvoid using Install-Module in your script. 在发布前改用 Save-Module,以便你的函数无需浪费时间来下载模块。Instead use Save-Module before publishing so that your function doesn't have to waste time downloading the module. 如果冷启动会影响你的函数,请考虑将函数应用部署到设置为“始终可用”或设置为高级计划应用服务计划If cold starts are impacting your functions, consider deploying your function app to an App Service plan set to always on or to a Premium plan.

后续步骤Next steps

有关详细信息,请参阅以下资源:For more information, see the following resources: