You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Function调用Start-AzContainerGroup时出现InvokeMethodOnNull错误

问题描述

我基于PowerShell创建了一个基础Azure Function,参考微软Learn教程修改代码,用来启停Azure租户里已有的容器实例。但本地调试时触发了InvokeMethodOnNull错误,推测是AzurePS模块里的$Host变量为空;在Azure云端运行该函数时请求超时,不过本地PowerShell直接执行Start-AzContainerGroup命令却能正常工作。

相关代码及错误信息

函数代码

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.
$command = $Request.Query.Command
if (-not $command) {
    $command = $Request.Body.Command
}

$body = "This HTTP triggered function executed successfully. Either pass 'start' or 'stop' as the 'command' parameter for the appropriate action to be executed on the acme-dns container."

if ($command) {
    $body = "Command received: $command"         
    if ($command = "start") {
        Start-AzContainerGroup -ResourceGroupName test -Name dev
    }
    elseif ($command = "stop") {
        Stop-AzContainerGroup -ResourceGroupName test -Name dev
    }

    if ($?) {
        $body = "This HTTP triggered function executed successfully. Started container group $name"
    }
    else  {
        $body = "There was a problem starting the container group."
    }
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body = $body
})

requirements.psd1

@{
    # For latest supported version, go to 'https://www.powershellgallery.com/packages/Az'.
    # To use the Az module in your function app, please uncomment the line below.
    'Az' = '9.*'
}

本地调试错误信息

Azure Functions Core Tools
Core Tools Version:       4.0.4915 Commit hash: N/A  (64-bit)
Function Runtime Version: 4.14.0.19631


Functions:

        HttpExample: [GET,POST] http://localhost:7071/api/HttpExample

For detailed output, run func with --verbose flag.
[2022-12-13T14:27:14.456Z] Worker process started and initialized.
[2022-12-13T14:27:18.512Z] Host lock lease acquired by instance ID '0000000000000000000000000713F6BA'.
[2022-12-13T14:27:38.039Z] Executing 'Functions.HttpExample' (Reason='This function was programmatically called via the host APIs.', Id=5b3c9e21-290f-4ff4-ac49-21f362414926)
[2022-12-13T14:27:38.238Z] INFORMATION: PowerShell HTTP trigger function processed a request.
[2022-12-13T14:27:56.862Z] EXCEPTION: You cannot call a method on a null-valued expression.
[2022-12-13T14:27:56.863Z]
[2022-12-13T14:27:56.863Z] Exception             :
[2022-12-13T14:27:56.864Z]     Type    : System.Management.Automation.ParentContainsErrorRecordException
[2022-12-13T14:27:56.865Z]     Message : You cannot call a method on a null-valued expression.
[2022-12-13T14:27:56.866Z]     HResult : -2146233087
[2022-12-13T14:27:56.867Z] CategoryInfo          : InvalidOperation: (:) [], ParentContainsErrorRecordException
[2022-12-13T14:27:56.868Z] FullyQualifiedErrorId : InvokeMethodOnNull
[2022-12-13T14:27:56.869Z] InvocationInfo        :
[2022-12-13T14:27:56.870Z]     ScriptLineNumber : 1777
[2022-12-13T14:27:56.871Z]     OffsetInLine     : 13
[2022-12-13T14:27:56.872Z]     HistoryId        : -1
[2022-12-13T14:27:56.873Z]     ScriptName       : C:\Users\{USER}\Documents\PowerShell\Modules\Az.ContainerInstance\3.1.0\exports\ProxyCmdletDefinitions.ps1
[2022-12-13T14:27:56.874Z]     Line             : [Microsoft.WindowsAzure.Commands.Utilities.Common.AzurePSCmdlet]::PowerShellVersion = $Host.Runspace.Version.ToString()
[2022-12-13T14:27:56.875Z]
[2022-12-13T14:27:56.876Z]     PositionMessage  : At C:\Users\{USER}\Documents\PowerShell\Modules\Az.ContainerInstance\3.1.0\exports\ProxyCmdletDefinitions.ps1:1777 char:13
[2022-12-13T14:27:56.877Z]                        +             [Microsoft.WindowsAzure.Commands.Utilities.Common.AzurePS .
[2022-12-13T14:27:56.878Z]                        +             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[2022-12-13T14:27:56.879Z]     PSScriptRoot     : C:\Users\{USER}\Documents\PowerShell\Modules\Az.ContainerInstance\3.1.0\exports
[2022-12-13T14:27:56.880Z]     PSCommandPath    : C:\Users\{USER}\Documents\PowerShell\Modules\Az.ContainerInstance\3.1.0\exports\ProxyCmdletDefinitions.ps1
[2022-12-13T14:27:56.881Z]     CommandOrigin    : Internal
[2022-12-13T14:27:56.882Z] ScriptStackTrace      : at Start-AzContainerGroup<Begin>, C:\Users\{USER}\Documents\PowerShell\Modules\Az.ContainerInstance\3.1.0\exports\ProxyCmdletDefinitions.ps1: line 1777
[2022-12-13T14:27:56.883Z]                         at <ScriptBlock>, C:\Coding\AzFunctions\PsHttpTrigger\HttpExample\run.ps1: line 20
[2022-12-13T14:27:56.884Z]
[2022-12-13T14:27:56.884Z]
[2022-12-13T14:27:56.913Z] Executed 'Functions.HttpExample' (Failed, Id=5b3c9e21-290f-4ff4-ac49-21f362414926, Duration=18894ms)
[2022-12-13T14:27:56.914Z] System.Private.CoreLib: Exception while executing function: Functions.HttpExample. System.Private.CoreLib: Result: Failure
Exception: You cannot call a method on a null-valued expression.
Stack:    at System.Management.Automation.Runspaces.PipelineBase.Invoke(IEnumerable input)
[2022-12-13T14:27:56.914Z]    at System.Management.Automation.Runspaces.Pipeline.Invoke()
[2022-12-13T14:27:56.915Z]    at System.Management.Automation.PowerShell.Worker.ConstructPipelineAndDoWork(Runspace rs, Boolean performSyncInvoke)
[2022-12-13T14:27:56.916Z]    at System.Management.Automation.PowerShell.Worker.CreateRunspaceIfNeededAndDoWork(Runspace rsToUse, Boolean isSync)
[2022-12-13T14:27:56.917Z]    at System.Management.Automation.PowerShell.CoreInvokeHelper[TInput,TOutput](PSDataCollection`1 input, PSDataCollection`1 output, PSInvocationSettings settings)       
[2022-12-13T14:27:56.917Z]    at System.Management.Automation.PowerShell.CoreInvoke[TInput,TOutput](PSDataCollection`1 input, PSDataCollection`1 output, PSInvocationSettings settings)
[2022-12-13T14:27:56.918Z]    at System.Management.Automation.PowerShell.Invoke[T](IEnumerable input, IList`1 output, PSInvocationSettings settings)
[2022-12-13T14:27:56.919Z]    at System.Management.Automation.PowerShell.Invoke[T]()
[2022-12-13T14:27:56.919Z]    at Microsoft.Azure.Functions.PowerShellWorker.PowerShell.PowerShellExtensions.InvokeAndClearCommands[T](PowerShell pwsh) in /mnt/vss/_work/1/s/src/PowerShell/PowerShellExtensions.cs:line 45
[2022-12-13T14:27:56.920Z]    at Microsoft.Azure.Functions.PowerShellWorker.PowerShell.PowerShellManager.InvokeNonOrchestrationFunction(DurableController durableController, IDictionary outputBindings) in /mnt/vss/_work/1/s/src/PowerShell/PowerShellManager.cs:line 301
[2022-12-13T14:27:56.921Z]    at Microsoft.Azure.Functions.PowerShellWorker.PowerShell.PowerShellManager.InvokeFunction(AzFunctionInfo functionInfo, Hashtable triggerMetadata, TraceContext traceContext, RetryContext retryContext, IList`1 inputData, FunctionInvocationPerformanceStopwatch stopwatch) in /mnt/vss/_work/1/s/src/PowerShell/PowerShellManager.cs:line 230
[2022-12-13T14:27:56.922Z]    at Microsoft.Azure.Functions.PowerShellWorker.RequestProcessor.InvokeFunction(AzFunctionInfo functionInfo, PowerShellManager psManager, FunctionInvocationPerformanceStopwatch stopwatch, InvocationRequest invocationRequest) in /mnt/vss/_work/1/s/src/RequestProcessor.cs:line 336
[2022-12-13T14:27:56.923Z]    at Microsoft.Azure.Functions.PowerShellWorker.RequestProcessor.ProcessInvocationRequestImpl(StreamingMessage request, AzFunctionInfo functionInfo, PowerShellManager psManager, FunctionInvocationPerformanceStopwatch stopwatch) in /mnt/vss/_work/1/s/src/RequestProcessor.cs:line 308.

解决方案

1. 修复$Host变量为空问题

Azure Functions的PowerShell环境中,$Host.Runspace可能未初始化,导致Az模块调用报错。在函数开头添加以下代码手动补齐必要属性:

# 手动初始化$Host.Runspace.Version以避免Az模块报错
if (-not $Host.Runspace) {
    $Host | Add-Member -MemberType NoteProperty -Name Runspace -Value ([PSCustomObject]@{
        Version = [Version]$PSVersionTable.PSVersion.ToString()
    }) -Force
}

2. 修正代码逻辑错误

原代码存在两处关键问题:

  • 条件判断使用赋值运算符=而非比较运算符-eq,导致所有请求都会走start分支
  • 成功消息中的$name变量未定义,需替换为实际容器组名称

修正后的完整函数代码:

using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# 手动初始化$Host.Runspace.Version以避免Az模块报错
if (-not $Host.Runspace) {
    $Host | Add-Member -MemberType NoteProperty -Name Runspace -Value ([PSCustomObject]@{
        Version = [Version]$PSVersionTable.PSVersion.ToString()
    }) -Force
}

# 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.
$command = $Request.Query.Command
if (-not $command) {
    $command = $Request.Body.Command
}

$containerGroupName = "dev"
$resourceGroupName = "test"
$body = "This HTTP triggered function executed successfully. Either pass 'start' or 'stop' as the 'command' parameter for the appropriate action to be executed on the acme-dns container."

if ($command) {
    $body = "Command received: $command"         
    $operationSuccess = $false
    if ($command -eq "start") {
        Start-AzContainerGroup -ResourceGroupName $resourceGroupName -Name $containerGroupName
        $operationSuccess = $?
    }
    elseif ($command -eq "stop") {
        Stop-AzContainerGroup -ResourceGroupName $resourceGroupName -Name $containerGroupName
        $operationSuccess = $?
    }
    else {
        $body = "Invalid command. Please pass 'start' or 'stop'."
    }

    if ($operationSuccess) {
        $body = "This HTTP triggered function executed successfully. $command container group $containerGroupName"
    }
    elseif ($command -in "start", "stop") {
        $body = "There was a problem $command the container group $containerGroupName."
    }
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body = $body
})

3. 解决云端请求超时问题

  • 延长函数超时时间:在函数项目的host.json中配置超时时间(消耗计划最大为10分钟,高级/专用计划可更长):
{
  "version": "2.0",
  "functionTimeout": "00:10:00"
}
  • 异步处理优化:若容器启停耗时超过10分钟,建议改用Durable Functions或Azure Queue Storage实现异步处理,函数立即返回响应,后台执行容器操作。

4. 确认云端权限配置

确保函数应用的托管身份拥有目标资源组的Container Instance Contributor角色,避免因权限不足导致隐性超时或执行失败。

内容的提问来源于stack exchange,提问作者Albie Janse van Rensburg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 22:20:21