azure - 如何从 Azure 命令 "results"的 'az group list in powershell' 数组中只选择一个属性?

标签 azure powershell

我正在尝试从 Powershell 中的 Azure 命令 az group list 返回的“结果”(对象?)数组中仅选择一个属性?

我知道这听起来微不足道,但这就是它变得奇怪的地方,我希望有一个简单的解释。

如果我运行 Azure 命令 az group list -o table (在我使用 az login 成功登录后),我会得到以下典型响应

PS src> az group list -o table             
Name              Location    Status
----------------  ----------  ---------
group0            westeurope  Succeeded
group1            westeurope  Succeeded
group2            uksouth     Succeeded
group3            westeurope  Succeeded
group4            westeurope  Succeeded
group5            westeurope  Succeeded
group6            westeurope  Succeeded
group7            uksouth     Succeeded
group8            westeurope  Succeeded
group9            westeurope  Succeeded

但是,如果我尝试通过执行仅选择 Name 属性

az group list | select -p name



然后我得到大约 2 个充满空行的屏幕,没有显示任何内容。那么问题来了,上面的命令有什么问题?我应该如何修复它?

我尝试了以下实验来深入研究返回的对象的确切类型,并得到一些我不明白的结果。我希望这对拥有更多 Azure 和 Powershell 经验的人有意义。

假设您有一个 azure 帐户,以下是很容易重现问题的步骤。
  • 启动 powershell,例如在 mac 终端上,输入 pwsh
  • 登录azure az login
  • 类型 az group list -o table

  • 观察列表返回并正确格式化。
  • 类型 az group list | select -p name

  • 观察几个充满空行的屏幕。没有文字。
  • 挠头,想知道刚刚发生了什么? (咧嘴笑)

  • 情节变厚
    az group list 本身会返回几个充满这个的屏幕
    [
     ... lots of these ...
     {
        "id": "/subscriptions/this-is-super-wierd-i-cant-select-name-prop/resourceGroups/spikes",
        "location": "westeurope",
        "managedBy": null,
        "name": "spikes",
        "properties": {
          "provisioningState": "Succeeded"
        },
        "tags": {},
        "type": null
      }
    ]
    

    然而,(az group list).getType() 返回

    PS src> (az group list).getType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     Object[]                                 System.Array
    

    最后,希望拼图的最后两块

    PS src> (az group list)[0].getType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     String                                   System.Object
    

    所以 az group list 的返回类型似乎是一个 array of objects 或者它可能是一个 object[] 数组,我的 powershell 在这里很粗糙。因此,为了仔细检查,我通过执行... (az group list)[0..10] 来查询该数组的前 10 个元素,并奇怪地返回 10 strings! 。好的,我知道它应该是 10 个字符串,只是因为它是一台计算机,如果它是这样,那么它就是它真正的样子。我只是不明白为什么。

    [
      {
        "id": "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/somegroup",
        "location": "westeurope",
        "managedBy": null,
        "name": "admin",
        "properties": {
          "provisioningState": "Succeeded"
        },
        "tags": {},
        "type": null
    

    所以所有这些,长话短说,我想知道,你如何从 azure 查询的结果中只选择一个属性?就我而言,我只想显示我所有资源组的名称。

    这个 az group list | select -p name 应该可以工作,但没有,我想知道如何正确地做到这一点,并在此过程中找出它不起作用的原因,我们都可以在此过程中了解有关 Azure 和 powershell 的知识,以及生活可以很美好!

    爱你们,
    艾伦

    最佳答案

    让我们解决这个问题。当我们指定 -o table 例如:

    az group list -o table
    

    我们告诉 Azure PowerShell CLI 获取您获得的 JSON 内容,并将其格式化为一个漂亮的表格。通常,我们不想使用 RAW JSON,也不想使用格式化表。在 PowerShell 中使用字符串数组也不是一件好事。在 PowerShell 中,我们希望使用“漂亮”的简单对象。那么,让我们看看其他获取信息的方法。让我们以你的例子为例,简单地将它保存到一个我们可以查看的变量中:
    $GroupList = az group list
    

    然后,如果我们看一下类型:
    PS C:\> $GroupList.GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     Object[]                                 System.Array
    

    事实上,我们有一个对象数组。他们一定是我们的一群人……对吗?……不。这不是你想的那样。如果我们查看数组的大小并返回数组的前几个元素,我们将看到发生了什么:
    PS C:\> $GroupList.Count
    125
    PS C:\Temp> $GroupList[0..2]
    [
      {
        "id": "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/somegroup",
    

    嗯,这不是我们想要的。该数组太大了......查看内容表明我们实际拥有的是JSON 文本 的每一行的数组。这意味着运行:
    az group list | select -p name
    

    或者:
    $GroupList | select -p name
    

    就是说,遍历数组,只输出“Name”属性。由于文本字符串中不存在“Name”属性,因此它只是输出一个空行。由于有几百行文本,我们得到了几百行空白。

    那么为什么 PowerShell 接受输入并将其分解为由新行分隔的字符串数组?这不是很难用吗?这不是处理 JSON 格式文本的“好”方法吗?为什么我们不得到一根巨大的弦呢?这不是更容易处理和解析吗?这种奇怪的原因之一是什么?

    使用 PowerShell,支持管道的需求插入了我们如何输出对象的决策:

    "The primary purpose ... is to provide a way to ensure that the result of a pipeline execution is always an indexable collection." Quote



    这就是为什么我们要输出一组对象(参见:@mklement0 answer here for more in depth discussion)来支持管道操作。如果我们看看文本文件是如何被读取和写入的,我们可以准确地强调为什么我们最终会出现这种特定的咳嗽 程序员咳嗽方便咳嗽......我的意思是奇怪。

    为了进行设置,我们可以将输出直接通过管道传输到文本文件:
    az group list | Out-File -FilePath List.json
    

    哇,等一下,为什么这行得通? (在这种情况下,我想说 PowerShell 执行 魔术! ),我们不必纠结于遍历数组,附加以换行符结尾的字符串以获得一个以 EOF 结尾的巨大连续文本块,和我们想要的文本文件完全匹配?

    真正发生的事情背后的简化原因?好吧,出于程序员的方便,Out-File 获取字符串数组,遍历它,并为每个字符串执行一个简单的 File.WriteLine()(对于 3 行 for 循环来说还不错!)。因此,我们毫不费力地生成了一个带有换行符的漂亮的 JSON 格式的文本文件。回读:
    PS C:\> $ListFromFile = Get-Content .\List.json
    PS C:\> $ListFromFile.GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     Object[]                                 System.Array
    
    
    PS C:\> $ListFromFile.Count
    125
    

    是否相反。它获取文件,执行 File.ReadLine() ,将字符串附加到数组中,然后返回它。这就是为什么我们最终得到一个包含字符串的对象数组。

    现在,我们 真的 想要什么?我们从一开始就知道,我们不想使用一个巨大的字符串,我们 特别是 不想使用对象数组中的字符串,我们想要使用的是一个很好的原生 PSCustomObject 我们可以访问。这就是 PowerShell 最适合使用的东西,也是我们最适合使用的东西。所以,我们只需要转换我们的(大引号)“文本输入”,我们知道它被格式化为 JSON,并将其转换为一个对象:
    $List = $GroupList | ConvertFrom-Json
    

    并查看计数和属性:
    PS C:\> $List.Count
    10
    PS C:\> $List.GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     Object[]                                 System.Array
    
    
    PS C:\> $List[0].GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     False    PSCustomObject                           System.Object
    

    我们看到计数现在与我们拥有的组数相匹配,并且类型不再是字符串数组,而是实际的对象。所以... 现在 ,我们可以开始排序和选择:
    PS C:\> $List | select -Property Name
    
    Name            
    ----
    group0
    group1
    group2
    group3
    group4
    group5
    group6
    group7
    group8
    group9
    

    我们得到了我们真正想要的输出。

    关于azure - 如何从 Azure 命令 "results"的 'az group list in powershell' 数组中只选择一个属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58738011/

    相关文章:

    Azure Durable Functions - 无法更改任务中心名称以支持并行版本控制

    powershell - 如何使用 powershell 过滤 vim 中的行

    powershell - Azure 自动化获取-AzureRmStorageAccountKey

    python - 使用 Python 的 PowerShell 中的 Unicode? Windows 中的替代 shell?

    azure - 迭代数据工厂中的文件

    Azure API 管理 - 如何将正文与我的请求一起发送

    c# - 在 Microsoft.Graph 客户端中查询组成员时出现异常

    c# - 是否可以使用 "FlatFile Source"将 "CosmosDB"上传到 "SSIS"? (CoreSQL)总是出现此错误

    powershell - 列出所有源安全链接文件的工具

    python-2.7 - PowerShell 中的 Python 版本