Az Powershell 模块 - 说 "Cannot find storage account with name xxx" 但它存在

Az Powershell Module - says "Cannot find storage account with name xxx" but it exists

我的 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

当代码 运行s 时,一切正常,直到调用“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

那个returns这个:

  {
    "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”的订阅以供讨论。它不是't/wasn脚本其余部分使用的那个。脚本的其余部分处理订阅 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 时,它会显示两个订阅。

一个额外的评论/观察。一旦 az login / az account set 运行 具有所需的订阅 ID,我注意到我可以从脚本中删除 az login 和 account set 逻辑,它只使用缓存的值。我并不是说这是我想做的……因为我认为最好是明确的。但只是一个观察结果,它首先解释了我的感受。

所以我的问题是...有没有办法避免必须登录两次 - 一次使用 az cli,另一次使用 Az Powerhsell 模块? 我正在考虑放弃 Az Powershell 模块并在 az cli 中重写所有内容。

但是请社区看看是否有更好的方法来做到这一点。

编辑 3

根据 azure 核心功能工具的文档,技术上我应该能够使用 powershell 模块或 cli:

https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local?tabs=v4%2Cwindows%2Ccsharp%2Cportal%2Cbash#publish

“您必须在本地安装 Azure CLI 或 Azure PowerShell 才能从 Core Tools 发布到 Azure。”

是的,混合使用 azcli 和 azure powershell,因为它们本身就是独立的实体,您需要分别登录到它们中的每一个。 是的,您是对的,最好放弃它们并选择其中之一!这样就干净多了

问题是 azure 核心功能工具正在使用缓存的 az 帐户列表来查找我的资源。 所以换句话说,在我不知道的情况下,func 方法使用的是 az cli,而脚本的其余部分使用的是新的 Az Powershell 模块。

目前,我刚刚用 az cli 语法重写了所有内容,对此我很满意。但根据文档,似乎 azure 核心功能工具应该能够与 az cli 或 az powershell 一起使用。将打开一个单独的问题来解决这一点。现在,我的脚本又能正常工作了。