Az Powershell 模块 - 显示“找不到名称为 xxx 的存储帐户”但它存在
我的 powershell 脚本构建了一个 azure 函数并遇到了问题。它的所有依赖项。
这就是正在发生的事情:(我在这里手动进行演示...)
我请求这样的存储帐户信息:
PS C:\Users\me\> Get-AzStorageAccount -ResourceGroupName widget-resource-group
StorageAccountName ResourceGroupName PrimaryLocation SkuName Kind AccessTier CreationTime ProvisioningState EnableHttpsTrafficOnly LargeFileShares
------------------ ----------------- --------------- ------- ---- ---------- ------------ ----------------- ---------------------- ---------------
widgetx4ge6v27rlgdk widget-resource-group eastus Standard_LRS StorageV2 Hot 2022-03-10 2:00:26 PM Succeeded True
它会返回正确的信息。然后我尝试获取这样的连接字符串:
PS C:\Users\me> func azure storage fetch-connection-string widgetx4ge6v27rlgdk
Cannot find storage account with name widgetx4ge6v27rlgdk
但它说找不到存储帐户。 实际代码如下所示:
# Look up function app name that was dynamically created by ARM template:
$AZ_FUNCTION_APP = Get-AzFunctionApp -ResourceGroupName $currentEnv.AZ_RESOURCE_GROUP_NAME
#look up the storage account name for this resource group.
$AZ_STORAGE_ACCOUNT = Get-AzStorageAccount -ResourceGroupName $currentEnv.AZ_RESOURCE_GROUP_NAME
Write-Output $AZ_STORAGE_ACCOUNT.StorageAccountName
# Get new connection string for the storage account.
func azure storage fetch-connection-string $AZ_STORAGE_ACCOUNT.StorageAccountName
当代码运行时,一切正常,直到调用“func azure storage fetch-connection-string”。
关于我所缺少的任何提示?
编辑 1
如果有帮助的话,当我针对租户 1、订阅 A 运行此逻辑时,此逻辑工作得很好。但对于租户 1、订阅 B,它会崩溃。 我已确保它运行的服务帐户原则是两个订阅的贡献者。 值得一提的是,该脚本能够创建资源组以及其中的许多资源。这只是当我尝试获取连接字符串时,它爆炸了。当它尝试在我的函数应用程序中部署函数时,它还会在脚本中进一步轰炸。但错误消息类似 - 它抱怨找不到我刚刚完成创建的函数应用程序。
编辑2
所以我找到了问题所在,但不知道如何以一种很好/简单的方式解决它。 对于 90% 的脚本(包括登录),我使用新的 Az Powershell 模块。但是,“func azure”工具依赖于 az cli 提供的登录信息。 (这似乎被缓存了?)
为了让您在同一页面上,这是脚本中代码的相关部分:
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $AZ_DEPLOYMENT_CLIENT_ID, $Secure2
#Connect
Connect-AzAccount -ServicePrincipal -TenantId $AZ_TENANT_ID -Credential $Credential
#OPTIONAL - List the subscriptions available to the current User
Get-Azcontext -ListAvailable
#Set the subscription context to subscription 2
Set-Azcontext -Subscription $AZ_SUBSCRIPTION_ID -Tenant $AZ_TENANT_ID
#Create a new resource group
New-AzResourceGroup -Name $AZ_RESOURCE_GROUP_NAME -Location $AZ_RESOURCE_LOCATION -Force
New-AzResourceGroupDeployment -ResourceGroupName $AZ_RESOURCE_GROUP_NAME -TemplateFile (Join-Path $PSScriptRoot "./artifacts/widget-resources.json")
# Look up function app name that was dynamically created by ARM template:
$AZ_FUNCTION_APP = Get-AzFunctionApp -ResourceGroupName $AZ_RESOURCE_GROUP_NAME
#look up the storage account name for this resource group.
$AZ_STORAGE_ACCOUNT = Get-AzStorageAccount -ResourceGroupName $AZ_RESOURCE_GROUP_NAME
Write-Output $AZ_STORAGE_ACCOUNT.StorageAccountName
# this is where it is failing because it is using a subscription that is visible to az cli.
func azure storage fetch-connection-string $AZ_STORAGE_ACCOUNT.StorageAccountName
这是我从 powershell cli 进行故障排除所做的操作:
az account list
返回此:
{
"cloudName": "AzureCloud",
"homeTenantId": "asdf-asdf-asdf-asdf-12312312313",
"id": "[guid]",
"isDefault": false,
"managedByTenants": [],
"name": "subscription-1",
"state": "Enabled",
"tenantId": "[our-tenant-id]",
"user": {
"name": "[another-guid]",
"type": "servicePrincipal"
}
}
当我运行上述命令时,出于讨论目的,它仅返回一个名为“subscription-1”的订阅。它不是/以前不是脚本其余部分正在使用的那个。脚本的其余部分正在处理订阅 2 在测试时,我在调用 func azure storage 之前添加了以下代码行:
az login --service-principal --username $AZ_APPLICATION_CLIENT_ID --password $AZ_SECRET --tenant $AZ_TENANT --allow-no-subscriptions
#set the subscription we want to use
az account set --subscription $subscription2
func azure storage fetch-connection-string $AZ_STORAGE_ACCOUNT.StorageAccountName
现在它找到了正确的订阅和资源组/存储帐户。现在,当我再次运行 az account list 时,它会显示两个订阅。
一项补充评论/观察。使用所需的订阅 ID 运行 az 登录 / az 帐户集后,我注意到我可以从脚本中删除 az 登录和帐户集逻辑,并且它只使用缓存的值。我并不是说这就是我想做的……因为我认为最好明确一点。但这只是一个观察,它解释了我最初被咬的原因。
所以我的问题是...是否有办法避免登录两次 - 一次使用 az cli,另一次使用 Az Powerhsell 模块? 我正在考虑放弃 Az Powershell 模块并在 az cli 中重写所有内容。
但请社区看看是否有更好的方法来做到这一点。
编辑3
基于azure核心功能工具的文档,从技术上讲,我应该能够使用powershell模块或cli:
“您必须有本地安装的 Azure CLI 或 Azure PowerShell 以便能够从 Core Tools 发布到 Azure。”
I've run into a snag with my powershell script that builds an azure function & all its dependencies.
This is what's happening: (i'm doing it manually here to demo...)
I request the storage account information like this:
PS C:\Users\me\> Get-AzStorageAccount -ResourceGroupName widget-resource-group
StorageAccountName ResourceGroupName PrimaryLocation SkuName Kind AccessTier CreationTime ProvisioningState EnableHttpsTrafficOnly LargeFileShares
------------------ ----------------- --------------- ------- ---- ---------- ------------ ----------------- ---------------------- ---------------
widgetx4ge6v27rlgdk widget-resource-group eastus Standard_LRS StorageV2 Hot 2022-03-10 2:00:26 PM Succeeded True
It comes back with the correct information. So then I try to get the connection string like this:
PS C:\Users\me> func azure storage fetch-connection-string widgetx4ge6v27rlgdk
Cannot find storage account with name widgetx4ge6v27rlgdk
But it says it can't find the storage account.
The actual code looks like this:
# Look up function app name that was dynamically created by ARM template:
$AZ_FUNCTION_APP = Get-AzFunctionApp -ResourceGroupName $currentEnv.AZ_RESOURCE_GROUP_NAME
#look up the storage account name for this resource group.
$AZ_STORAGE_ACCOUNT = Get-AzStorageAccount -ResourceGroupName $currentEnv.AZ_RESOURCE_GROUP_NAME
Write-Output $AZ_STORAGE_ACCOUNT.StorageAccountName
# Get new connection string for the storage account.
func azure storage fetch-connection-string $AZ_STORAGE_ACCOUNT.StorageAccountName
When the code runs, everything works until the call to "func azure storage fetch-connection-string".
Any tips on what I'm missing?
Edit 1
In case it helps, this logic works just fine when I run it against Tenant 1, Subscription A. But for Tenant 1, Subscription B it bombs.
I've made sure the service account principle it runs under is contributor on both subscriptions.
And for what it's worth, the script is able to create the resource group and many of the resources inside. It's just hat when I try to get the connection string, it bombs. It also bombs further down in the script when it tries to deploy the functions in my function app. The error message though is similar - it complains that it can't find the function app that I just finished creating.
Edit 2
So I figured out the problm but not sure how to fix it in a nice / simple way.
For 90% of the script, including login, i'm using the new Az Powershell modules. However, the "func azure" tool relies on login information provided by the az cli. (that seems to be cached??)
To get you on the same page, here's the relevant part of the code in the script:
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $AZ_DEPLOYMENT_CLIENT_ID, $Secure2
#Connect
Connect-AzAccount -ServicePrincipal -TenantId $AZ_TENANT_ID -Credential $Credential
#OPTIONAL - List the subscriptions available to the current User
Get-Azcontext -ListAvailable
#Set the subscription context to subscription 2
Set-Azcontext -Subscription $AZ_SUBSCRIPTION_ID -Tenant $AZ_TENANT_ID
#Create a new resource group
New-AzResourceGroup -Name $AZ_RESOURCE_GROUP_NAME -Location $AZ_RESOURCE_LOCATION -Force
New-AzResourceGroupDeployment -ResourceGroupName $AZ_RESOURCE_GROUP_NAME -TemplateFile (Join-Path $PSScriptRoot "./artifacts/widget-resources.json")
# Look up function app name that was dynamically created by ARM template:
$AZ_FUNCTION_APP = Get-AzFunctionApp -ResourceGroupName $AZ_RESOURCE_GROUP_NAME
#look up the storage account name for this resource group.
$AZ_STORAGE_ACCOUNT = Get-AzStorageAccount -ResourceGroupName $AZ_RESOURCE_GROUP_NAME
Write-Output $AZ_STORAGE_ACCOUNT.StorageAccountName
# this is where it is failing because it is using a subscription that is visible to az cli.
func azure storage fetch-connection-string $AZ_STORAGE_ACCOUNT.StorageAccountName
Here's what I did to troubleshoot from a powershell cli:
az account list
That returns this:
{
"cloudName": "AzureCloud",
"homeTenantId": "asdf-asdf-asdf-asdf-12312312313",
"id": "[guid]",
"isDefault": false,
"managedByTenants": [],
"name": "subscription-1",
"state": "Enabled",
"tenantId": "[our-tenant-id]",
"user": {
"name": "[another-guid]",
"type": "servicePrincipal"
}
}
When I ran the above command, it only returned one subscription called "subscription-1" for discussion purposes. It isn't/wasn't the one that the rest of the script was working with. The rest of script was dealing with subscription 2
As I test, I added the following lines of code just before call func azure storage:
az login --service-principal --username $AZ_APPLICATION_CLIENT_ID --password $AZ_SECRET --tenant $AZ_TENANT --allow-no-subscriptions
#set the subscription we want to use
az account set --subscription $subscription2
func azure storage fetch-connection-string $AZ_STORAGE_ACCOUNT.StorageAccountName
And now it finds the correct subscription and resource group / storage account. And now when I run az account list again, it shows me both subscriptions.
One addition comment / observation. Once the az login / az account set has been run with the desired subscription id, i've noticed that I can remove the az login and account set logic from the script and it just uses the cached values. I'm not saying this is what I want to do ... cuz I think it' best to be explicit. But just an observation which explains what bit me in the first place.
So my question is... is there anyway to avoid having to log in twice - once with az cli and another time with the Az Powerhsell modules?
I'm thinking of just abandoning the Az Powershell module and just rewriting everything in just az cli.
But asking the community to see if there's a better way to do this.
EDIT 3
Based on the docs for the azure core functions tools, technically I should be able to use the powershell modules or the cli:
"You must have the Azure CLI or Azure PowerShell installed locally to be able to publish to Azure from Core Tools."
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,混合使用 azcli 和 azure powershell,因为它们本身就是独立的实体,因此您需要单独登录每个实体。
是的,你是对的,最好放弃它们并选择其中之一!这样就干净多了
Yes, using a mix of azcli and azure powershell, as they are their seperate entities in their own right, you would need to login to each of them individually.
And yes, you are right its better to ditch of them and choose one or the other ! Just much cleaner that way
问题是 azure 核心功能工具正在使用缓存的 az 帐户列表来查找我的资源。
换句话说,我不知道的是,func 方法使用的是 az cli,而脚本的其余部分则使用新的 Az Powershell 模块。
目前,我刚刚用 az cli 语法重写了所有内容,对此感到很满意。但根据文档,Azure 核心功能工具似乎应该能够与 az cli 或 az powershell 一起使用。将提出一个单独的问题来解决这一点。现在,我的脚本又可以工作了。
The issue was that the azure core functions tool is using the cached az account list to find my resources.
So in other words, unbeknownst to me, the func method was using az cli, whereas the rest of the script is using the new Az Powershell modules.
For now, I've just rewritten everything in az cli syntax, and am happy with that. But per the docs it seems that the azure core functions tools should be able to work with either az cli or az powershell. Will open a separate question that addresses that point. For now, my script is working again.