【Azure 应用服务】Azure Function 中运行Powershell 脚本,定位 -DefaultProfile 引发的错误
问题描述
突然之间,使用PowerShell脚本 Get-AzVirtualNetwork 获取虚拟网络信息时,如果带上 -DefaultProfile $sub 参数,就出现 Azure credentials 错误。
代码:
Connect-AzAccount -ServicePrincipal -Credential $pscredential -Tenant $cloudroomTenantId -Environment $region $sub = Set-AzContext -SubscriptionId $cloudroomId -Tenant $cloudroomTenantId Get-AzVirtualNetwork -Name $VNetName -ResourceGroupName $ResourceGroupName -DefaultProfile $sub -ErrorAction "SilentlyContinue"
错误消息:
ERROR: Your Azure credentials have not been set up or have expired, please run Connect-AzAccount to set up your Azure credentials.No certificate thumbprint or secret provided for the given service principal
这是为什么呢?
问题分析
根据错误消息,是Connect-AzAccount中获取的Credentials信息不对导致的。但是当 Get-AzVirtualNetwork 不使用 -DefaultProfile参数时,命令确认成功执行。那么可以定位到问题是 -DefaultProfile $sub 引发。
在代码不变动的情况下,是什么原因导致DefaultProfile信息不对呢? 所以就深入查看了Azure Function中所依赖的模块('Az.Accounts')的版本情况,发现当使用 version '2.7.0'时,就会遇见这样的错误,在本地也能复现问题。当修改为version '2.6.2' 后,脚本能正常运行。
如何修改Azure Function中 Powershell脚本的依赖版本呢?
第一步:进入高级管理工具(Kudu:)
第二步:点击DebugConsole,并进入到wwwroot文件夹
第三步:找到requirements.psd1,首先点击edit图标修改requirements.psd1,安装Az.Accountsde 2.6.2依赖
# This file enables modules to be automatically managed by the Functions service. # See https://aka.ms/functionsmanageddependency for additional information. # @{ # 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' = '6.5.0' 'Az.Accounts' = '2.6.2' }
第四步:然后找到 profile.ps1文件,修改profile.ps1文件,在第一行添加: Import-Module Az.Accounts -RequiredVersion '2.6.2'
第五步:修改完成后,回到Function App界面点击重启按钮,重启会重新安装这些依赖(重装依赖包耗时在20分钟左右)。
附录一:Function Script
using namespace System.Net # Input Parameter param($Request, $TriggerMetadata) $username = $env:ClientID $password = $env:Password # Login to Azure $password = ConvertTo-SecureString -String $password -AsPlainText -Force $pscredential = New-Object System.Management.Automation.PSCredential($username, $password) # Write to the Azure Functions log stream. Write-Host "PowerShell HTTP trigger function processed a request." $VNetName = "XXXXXXXXXXXX" $ResourceGroupName = "XXXXXXXXXXXX" $cloudroomTenantId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" $cloudroomId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" Connect-AzAccount -ServicePrincipal -Credential $pscredential -Tenant $cloudroomTenantId -Environment "China East" $sub = Set-AzContext -SubscriptionId $cloudroomId -Tenant $cloudroomTenantId # SELECT-AzSubscription -SubscriptionId $cloudroomId $vnetResult = Get-AzVirtualNetwork -Name $VNetName -ResourceGroupName $ResourceGroupName -DefaultProfile $sub -ErrorAction "SilentlyContinue" if ($vnetResult -and $vnetResult -ne "") { Write-Host "OK" } else { Write-Host "Fail" }
参考资料
Function Dependency management :https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-powershell?tabs=portal#dependency-management
当在复杂的环境中面临问题,格物之道需:浊而静之徐清,安以动之徐生。 云中,恰是如此!