You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何遍历AWS Describe-Instances的PowerShell JSON对象并比较启动时间?

关于AWS CLI EC2实例输出遍历与日期比较的问题

我用PowerShell ISE执行以下AWS CLI命令:

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

得到的JSON输出为:

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

尝试用以下遍历代码但无输出:

$objects = aws ec2 --profile $awsProfile --region $awsRegion describe-instances --query "Reservations[*].Instances[*].[InstanceId,LaunchTime,State]" | ConvertFrom-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)
}

问题1:遍历方式的正确性与优化方案

你的遍历方式有问题,导致无输出。AWS CLI返回的JSON是三层嵌套数组:最外层是Reservations数组,每个Reservation里是Instances数组,每个Instance里是你指定的属性数组。你当前只遍历了最外层的Reservation数组,直接取$_[0][0],但每个Reservation对应的$_是第二层的Instances数组,里面的每个元素才是单个实例的属性数组。

修正后的遍历代码

$objects = aws ec2 --profile $awsProfile --region $awsRegion describe-instances --query "Reservations[*].Instances[*].[InstanceId,LaunchTime,State]" | ConvertFrom-Json

# 先展开两层嵌套数组,拿到每个实例的属性数组
$objects | ForEach-Object { $_ } | ForEach-Object {
    $instanceProps = $_
    $instanceObj = [pscustomobject]@{
        InstanceId = $instanceProps[0]
        LaunchTime = [datetimeoffset]$instanceProps[1]
        StateCode = $instanceProps[2].Code
        StateName = $instanceProps[2].Name
    }
    # 直接输出对象,或格式化输出
    $instanceObj
    # 格式化字符串输出示例:
    # Write-Output "InstanceId: $($instanceObj.InstanceId), 启动时间: $($instanceObj.LaunchTime.LocalDateTime)"
}

更易理解的优化思路

直接修改AWS CLI的--query参数,减少嵌套层级:

# 用[]展开Reservations和Instances,直接返回实例属性的一维数组
$objects = aws ec2 --profile $awsProfile --region $awsRegion describe-instances --query "Reservations[].Instances[].[InstanceId,LaunchTime,State]" | ConvertFrom-Json

# 现在直接遍历每个实例的属性数组即可
$objects | ForEach-Object {
    [pscustomobject]@{
        InstanceId = $_[0]
        LaunchTime = [datetimeoffset]$_[1]
        StateCode = $_[2].Code
        StateName = $_[2].Name
    }
}

--query里的Reservations[]和Instances[]会自动展开嵌套,返回的JSON是一维数组,遍历逻辑更直观。

问题2:LaunchTime与其他日期的比较

只要把LaunchTime转换为DateTimeOffset或DateTime类型,就能直接和其他日期对象比较。

示例:筛选启动时间早于指定日期的实例

# 目标日期(UTC时区)
$targetDate = [datetimeoffset]"2023-07-18T00:00:00+00:00"
# 也可以用本地时间:$targetDate = [datetime]"2023-07-18"

$objects = aws ec2 --profile $awsProfile --region $awsRegion describe-instances --query "Reservations[].Instances[].[InstanceId,LaunchTime,State]" | ConvertFrom-Json

$objects | ForEach-Object {
    $launchTime = [datetimeoffset]$_[1]
    $instanceObj = [pscustomobject]@{
        InstanceId = $_[0]
        LaunchTime = $launchTime
        StateName = $_[2].Name
    }
    # 判断启动时间早于目标日期
    if ($launchTime -lt $targetDate) {
        $instanceObj
    }
}

注意事项

  • AWS返回的LaunchTime是UTC时区字符串,用[datetimeoffset]转换可保留时区信息,避免本地时区转换误差。
  • 如果要和本地日期比较,可转换为本地时间:$launchTime.LocalDateTime,再和本地DateTime对象比较。

内容的提问来源于stack exchange,提问作者Money Times

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 08:43:19