通过PowerShell迭代describe-instances json对象的输出+比较启动日期

jgovgodb  于 2023-08-08  发布在  Shell
关注(0)|答案(1)|浏览(104)

当我以下面的方式查询describe-instances时:

aws ec2 --profile $profile --region $region describe-instances --query "Reservations[*].Instances[*].[InstanceId,LaunchTime,State]"

字符串
输出按以下顺序显示:

[
    [
        [
            "i-0123456789",
            "2023-07-17T04:00:18+00:00",
            {
                "Code": 8,
                "Name": "running"
            }
        ]
    ],
    [
        [
            "i-9876543210",
            "2023-07-17T04:00:16+00:00",
            {
                "Code": 16,
                "Name": "running"
            }
        ]
    ]
]


在迭代的帮助下,我希望看到以下格式或任何其他方式的输出,以便对于一个值/项,我将过滤/迭代其他项

instanceid            launchdateb               code        Name       
i-0123456789       2023-07-17T04:00:18+00:00      8        running   
i-9876543210       2023-07-17T04:00:16+00:00     16        running


我尝试过for-each/foreach-object循环,但没有成功,希望你能提供一些建议和帮助。
在进行循环/迭代时-我如何将Launchdate与任何其他日期分别进行比较?
代码段的最新更新,但无法看到迭代值:

$objects = aws ec2 --profile $profile --region $region describe-instances --query "Reservations[*].Instances[*].[InstanceId,LaunchTime,State]" | Convertform-json 
  $objects | ForEach-Object {  
    # Construct and implicitly output a [pscustomobject]
    # instance from the elements of each nested array.
    $a = [pscustomobject] @{
      instanceid = $_[0][0]
      launchdateb = [datetimeoffset] $_[0][1]
      code = $_[0][2].Code
      name = $_[0][2].Name
      
   }
   Write-Output ("instanceid :"+$a.ToString())
}

fcipmucu

fcipmucu1#

给定嵌套JSON数组的固定结构,将它们转换为[pscustomobject]示例,如下所示:

# Note: Note how the whole ConvertFrom-Json call
#       must be enclosed in (...) in *Windows PowerShell*.
(ConvertFrom-Json (
  aws ec2 --profile $profile --region $region describe-instances --query "Reservations[*].Instances[*].[InstanceId,LaunchTime,State]"
)) | 
  ForEach-Object {  
    # Construct and implicitly output a [pscustomobject]
    # instance from the elements of each nested array.
    [pscustomobject] @{
      instanceid = $_[0][0]
      launchdateb = [datetimeoffset] $_[0][1]
      code = $_[0][2].Code
      name = $_[0][2].Name
   }
}

字符串
注意事项:

  • ConvertFrom-Json调用作为一个整体封装在(...)中,可以确保从解析的JSON中得到的数组在管道中被 * 枚举 *,这意味着它的 * 元素 * 被一个接一个地发送到ForEach-Object
  • 这仅在 Windows PowerShell 中是必需的,其中ConvertFrom-Json意外地输出数组 * 作为一个整体 *;这个问题在PowerShell (Core) 7+中已经被修正了,所以你并不需要(...) shell ,详情请看this answer

上面的代码直接输出结果[pscustomobject]示例,并生成类似于您在问题中请求的显示输出;要在变量中捕获这些对象,作为数组,请在整个命令前添加类似$objects =的内容。
请注意,仅在 Windows PowerShell 中需要将.launchdateb属性值强制转换为[datetimeoffset][datetime];在PowerShell (Core) 7+中,包含ISO 8601时间戳字符串的JSON字符串属性值被ConvertFrom-Json * 自动 * 转换为-始终 * 本地 * -[datetime]示例。

  • PowerShell 7+的行为-至少到v7.3.6 -有点不幸,因为自动转换到本地[datetime]System.DateTime)涉及JSON数据中特定UTC偏移量 *(数据中的+00:00)的 * 丢失(后续[datetimeoffset]无法恢复)。
  • GitHub issue #13598是一个向ConvertFrom-Json添加-DateKind参数的提议,这将启用-DateKind Offset,从而导致返回保留UTC偏移量的[datetimeoffset]System.DateTimeOffset)示例。该提案已被批准,但在撰写本文时尚未实施。

[datetimeoffset]/[datetime]示例存储在.launchdateb属性中应该可以轻松执行日期比较。
要详细说明如何在变量中捕获每个[pscustomobject]并在ForEach-Object脚本块中对其进行操作,通过here字符串提供JSON输入:

(@'
[
  [
      [
          "i-0123456789",
          "2023-07-17T04:00:18+00:00",
          {
              "Code": 8,
              "Name": "running"
          }
      ]
  ],
  [
      [
          "i-9876543210",
          "2023-07-17T04:00:16+00:00",
          {
              "Code": 16,
              "Name": "running"
          }
      ]
  ]
]
'@ | ConvertFrom-Json) |
  ForEach-Object {  
    $obj = 
      [pscustomobject] @{
        instanceid = $_[0][0]
        launchdateb = [datetimeoffset] $_[0][1]
        code = $_[0][2].Code
        name = $_[0][2].Name
      }
    # Output a string representation of the captured object.
    "Object: $obj"
}


上面的结果(注意在 string interpolation 的上下文中[pscustomobject] s的hashtable-like 表示(在"..."内部,一个可扩展的(双引号)字符串)):

Object: @{instanceid=i-0123456789; launchdateb=07/17/2023 04:00:18 +00:00; code=8; name=running}
Object: @{instanceid=i-9876543210; launchdateb=07/17/2023 04:00:16 +00:00; code=16; name=running}


注意事项:

  • 请勿使用"Object: " + $obj.ToString()代替上述"Object: $obj":由于一个长期存在的错误-请参阅GitHub issue #6163-在[pscustomobject]示例上调用.ToString()会产生 * 空字符串 ,最高可达PowerShell v7.3.6;相比之下,string interpolation"$obj" 不 * 受影响。

相关问题