在本地调试 PowerShell Azure Functions

Azure Functions 允许将函数开发为 PowerShell 脚本。

可以使用以下标准开发工具在本地调试 PowerShell 函数:

  • Visual Studio Code:使用 PowerShell 扩展Microsoft的免费、轻型和开源文本编辑器,提供完整的 PowerShell 开发体验。
  • PowerShell 控制台:使用用于调试任何其他 PowerShell 进程的相同命令进行调试。

Azure Functions Core Tools 支持本地调试 Azure Functions,包括 PowerShell 函数。

示例函数应用

本文中使用的函数应用具有单个 HTTP 触发的函数,并具有以下文件:

PSFunctionApp
 | - HttpTriggerFunction
 | | - run.ps1
 | | - function.json
 | - local.settings.json
 | - host.json
 | - profile.ps1

此函数应用类似于完成 PowerShell 快速入门时获取的函数应用。

中的函数代码 run.ps1 类似于以下脚本:

param($Request)

$name = $Request.Query.Name

if($name) {
    $status = 200
    $body = "Hello $name"
}
else {
    $status = 400
    $body = "Please pass a name on the query string or in the request body."
}

Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = $status
    Body = $body
})

设置附加点

若要调试任何 PowerShell 函数,需要停止该函数才能附加调试器。 该 Wait-Debugger cmdlet 停止执行并等待调试器。

备注

使用 PowerShell 7 时,无需在代码中添加 Wait-Debugger 调用。

您只需在Wait-Debugger语句上方添加对if cmdlet 的调用,如下所示:

param($Request)

$name = $Request.Query.Name

# This is where we will wait for the debugger to attach
Wait-Debugger

if($name) {
    $status = 200
    $body = "Hello $name"
}
# ...

if语句开始调试。

设置好 Wait-Debugger 后,可以使用 Visual Studio Code 或 PowerShell 控制台来调试函数。

在 Visual Studio Code 中进行调试

若要在 Visual Studio Code 中调试 PowerShell 函数,必须安装以下各项:

安装这些依赖项后,加载现有的 PowerShell Functions 项目,或 创建第一个 PowerShell Functions 项目

备注

如果项目没有所需的配置文件,系统会提示你添加这些文件。

设置 PowerShell 版本

PowerShell Core 与 Windows PowerShell 并排安装。 将 PowerShell Core 设置为用于 Visual Studio Code 的 PowerShell 扩展的 PowerShell 版本。

  1. 按 F1 显示命令托盘,然后搜索 Session

  2. 选择 PowerShell:显示会话菜单

  3. 如果 当前会话 不是 PowerShell Core 6,请选择 “切换到:PowerShell Core 6”。

打开 PowerShell 文件时,窗口右下角会显示绿色的版本。 选择此文本还会显示会话菜单。 若要了解详细信息,请参阅 选择要用于扩展的 PowerShell 版本

启动函数应用

请确认在您要附加调试器的函数中是否设置了Wait-Debugger。 添加 Wait-Debugger 后,您可以使用 Visual Studio Code 调试函数应用程序。

选择“调试”窗格,然后选择“附加到 PowerShell 函数”

调试器

还可以按 F5 键开始调试。

启动调试操作执行以下任务:

  • 在终端中运行 func extensions install ,以安装函数应用所需的任何 Azure Functions 扩展。
  • 在终端中运行 func host start 以启动 Functions 主机中的函数应用。
  • 将 PowerShell 调试器附加到 Functions 运行时中的 PowerShell 运行空间。

备注

需要确保 PSWorkerInProcConcurrencyUpperBound 设置为 1,以确保 Visual Studio Code 中的正确调试体验。 这是默认值。

运行函数应用后,需要单独的 PowerShell 控制台来调用 HTTP 触发的函数。

在这种情况下,PowerShell 控制台是客户端。 是 Invoke-RestMethod 用于触发函数的。

在 PowerShell 控制台中运行以下命令:

Invoke-RestMethod "http://localhost:7071/api/HttpTrigger?Name=Functions"

你会注意到不会立即收到反馈。 这是因为 Wait-Debugger 已附加调试器,PowerShell 执行在一有可能时便进入中断模式。 这是因为 BreakAll 概念,稍后将对此进行说明。 按下 continue 按钮后,调试程序现在会在行上的 Wait-Debugger 后立即中断。

此时,调试器已附加,你可以进行所有常规的调试操作。 有关在 Visual Studio Code 中使用调试器的详细信息,请参阅 官方文档

继续并完全调用脚本后,你会注意到:

  • 执行 Invoke-RestMethod 的 PowerShell 控制台返回了结果
  • Visual Studio Code 中的 PowerShell 集成控制台正在等待脚本执行

稍后调用同一函数时,PowerShell 扩展中的调试器会在Wait-Debugger处中断。

在 PowerShell 控制台中进行调试

备注

本部分假定你已阅读 Azure Functions Core Tools 文档 ,并了解如何使用 func host start 命令启动函数应用。

打开控制台, cd 进入函数应用的目录,并运行以下命令:

func host start

当函数应用运行起来且 Wait-Debugger 就位后,你可以附加到进程。 你确实需要另外两个 PowerShell 控制台。

其中一个控制台充当客户端。 从中,调用 Invoke-RestMethod 以触发函数。 例如,你可以运行以下命令:

Invoke-RestMethod "http://localhost:7071/api/HttpTrigger?Name=Functions"

您会注意到它没有返回响应,这是由于Wait-Debugger造成的。 PowerShell 运行空间现在正在等待调试程序附加到其中。 把它附上。

在其他 PowerShell 控制台中运行以下命令:

Get-PSHostProcessInfo

此 cmdlet 返回类似于以下输出的表:

ProcessName ProcessId AppDomainName
----------- --------- -------------
dotnet          49988 None
pwsh            43796 None
pwsh            49970 None
pwsh             3533 None
pwsh            79544 None
pwsh            34881 None
pwsh            32071 None
pwsh            88785 None

记下表中 ProcessIdProcessName 的项的 dotnet。 此进程是你的函数应用。

接下来,运行以下代码片段:

# This enters into the Azure Functions PowerShell process.
# Put your value of `ProcessId` here.
Enter-PSHostProcess -Id $ProcessId

# This triggers the debugger.
Debug-Runspace 1

启动后,调试器会中断并显示类似于以下输出的内容:

Debugging Runspace: Runspace1

To end the debugging session type the 'Detach' command at the debugger prompt, or type 'Ctrl+C' otherwise.

At /Path/To/PSFunctionApp/HttpTriggerFunction/run.ps1:13 char:1
+ if($name) { ...
+ ~~~~~~~~~~~
[DBG]: [Process:49988]: [Runspace1]: PS /Path/To/PSFunctionApp>>

此时会在 PowerShell 调试程序中的断点处停止。 在这里,你可以执行所有常用的调试操作:单步跳过、单步执行、继续、退出以及其他操作。 若要查看控制台中可用的调试命令的完整集,请运行 h? 命令。

还可以使用 Set-PSBreakpoint cmdlet 在此级别设置断点。

继续并完全调用脚本后,你会注意到:

  • 你在其中执行的 Invoke-RestMethod PowerShell 控制台现在已返回结果。
  • 您执行 Debug-Runspace 的 PowerShell 控制台正在等待执行脚本。

可以再次调用同一函数( Invoke-RestMethod 例如),调试器会在 Wait-Debugger 命令后中断。

调试注意事项

在调试 Functions 代码时,请记住以下问题。

BreakAll 可能会导致调试器在意外位置中断

PowerShell 扩展使用 Debug-Runspace,而后者又依赖于 PowerShell BreakAll 的功能。 此功能告知 PowerShell 停止执行的第一个命令。 此行为使你有机会在调试的运行空间中设置断点。

Azure Functions 运行时在实际调用run.ps1脚本之前会运行几个命令,因此调试器最终可能在Microsoft.Azure.Functions.PowerShellWorker.psm1Microsoft.Azure.Functions.PowerShellWorker.psd1中断。

如果发生此中断,请运行 continuec 命令跳过此断点。 然后,在预期的断点处停止。

故障排除

如果在调试过程中遇到困难,应检查以下内容:

检查 行动
从终端运行 func --version 。 如果出现“找不到 func”错误,则可能是因为本地 path 变量缺少 Core Tools (func.exe)。 重新安装核心工具
在 Visual Studio Code 中,默认终端需要有权访问 func.exe。 请确保未使用未安装 Core Tools 的默认终端,例如适用于 Linux 的 Windows 子系统(WSL)。 将 Visual Studio Code 中的默认 shell 设置为 PowerShell 7(建议)或 Windows PowerShell 5.1。

后续步骤

若要详细了解如何使用 PowerShell 开发 Functions,请参阅 Azure Functions PowerShell 开发人员指南