powershell 构造一个自定义对象,该对象的属性将按定义顺序枚举

hrysbysz  于 2022-12-18  发布在  Shell
关注(0)|答案(2)|浏览(138)

我在PowerShell中创建了一个用于从AWS获取信息的对象。

$list = New-Object -TypeName PSObject -Property @{
  'name'          = ($instance.Tags | Where-Object {$_.Key -eq 'Name'}).Value
  'baseAmi'       = ""
  'patchDate'     = ""
  'baseName'      = ""
  'owner'         = ($instance.Tags | Where-Object {$_.Key -eq 'Owner'}).Value
  'instanceID'    = $instance.InstanceID
  'imageID'       = $instance.ImageId
  'env'           = ($instance.Tags | Where-Object {$_.Key -eq 'EnvName'}).Value
  'instanceState' = $instance.State.Name
}
$baseAmi = Get-EC2Image -ImageId $list.imageID
$list.baseAmi = ($baseAmi.Tags | Where-Object{$_.Key -eq 'BaseAmi'}).Value
$baseAmi = Get-Ec2Image -ImageId $list.baseAmi
$list.patchDate = ($baseAmi.Tags | Where-Object{$_.Key -eq 'PatchDate'}).Value
$list.baseName = ($baseAmi.Tags | Where-Object{$_.Key -eq 'Name'}).Value

我想按以下顺序输出对象的字段:

baseName,baseAmi,patchDate,name,owner,instanceID,env,instanceState

然后将此对象导出为CSV。我基本上需要CSV标题在Excel中查看时按此顺序组织。

txu3uszq

txu3uszq1#

假定PSv 3 +,始终使用[pscustomobject] @{ ... }创建自定义对象,其属性应按照定义顺序进行枚举。

$customObj = [pscustomobject] @{
  name          = $null
  baseAmi       = $null
  patchDate     = $null
  baseName      = $null
  owner         = $null
  instanceID    = $null
  imageID       = $null
  env           = $null
  instanceState = $null
}

您可以验证生成的[pscustomobject]示例是否按定义顺序枚举其属性,如下所示:

PS> $customObj | Format-List
name          : 
baseAmi       : 
patchDate     : 
baseName      : 
owner         : 
instanceID    : 
imageID       : 
env           : 
instanceState :

请注意,这仅适用于哈希表 * 文本 * 前面加上[pscustomobject],在PowerShellv3+中,这是语法糖,使PowerShell按照指定的顺序*构造哈希表条目的自定义对象示例,即使在隔离情况下,散列表文字(@{ ... })的条目本质上是“无序的”(它们的排序是实现细节)。
您可以将[pscustomobject] @{ ... }视为[pscustomobject] [ordered] @{ ... }的隐式快捷方式,其中[ordered] @{ ... }是具有 ordered 条目(键)的散列表的PSv 3+语法,其真实类型为[System.Collections.Specialized.OrderedDictionary]
至于你所尝试的
与上面讨论的语法糖不同,New-Object与哈希表字面量(@{ ... })组合 * 并不 * 保证结果对象的属性以与(固有无序的)输入哈希表条目相同的顺序枚举。
New-Object -TypeName PSObject -Property @{ ... }New-Object -TypeName PCustomSObject -Property @{ ... }都创建了一个[pscustomobject]示例,由于属性定义已经作为 hashtable literal 提供--在没有语法糖的情况下--其属性以不可预测的顺序定义,其中hashtable literal的条目被枚举:

> New-Object -TypeName PSCustomObject -Property @{
  'name'          = $null
  'baseAmi'       = $null
  'patchDate'     = $null
  'baseName'      = $null
  'owner'         = $null
  'instanceID'    = $null
  'imageID'       = $null
  'env'           = $null
  'instanceState' = $null
} | Format-List

imageID       : 
instanceID    : 
owner         : 
env           : 
patchDate     : 
name          : 
baseName      : 
baseAmi       : 
instanceState :


正如您所看到的,这些属性没有按照特定的顺序枚举。
您 * 可以 * 传递一个 ordered hashtable来代替(PSv 3+),但这相当于上面的[pscustomobject] @{ ... }语法糖解决方案更冗长-而且效率更低:

New-Object -TypeName PSCustomObject -Property ([ordered] @{
  'name'          = $null
  'baseAmi'       = $null
  'patchDate'     = $null
  'baseName'      = $null
  'owner'         = $null
  'instanceID'    = $null
  'imageID'       = $null
  'env'           = $null
  'instanceState' = $null
}) | Format-List
ncgqoxb0

ncgqoxb02#

您需要的是一个ordered dictionary,使用有序字典,您定义标签的顺序会被保留,因此您可以按照您希望它们出现的顺序来创建它们:

$list =[ordered] @{
    'baseName' = ""
    'baseAmi' = ""
    'patchDate' = ""
    'name' = ($instance.Tags | Where-Object {$_.Key -eq 'Name'}).Value
    'owner'      = ($instance.Tags | Where-Object {$_.Key -eq 'Owner'}).Value
    'instanceID' = $instance.InstanceID
    'env'    = ($instance.Tags | Where-Object {$_.Key -eq 'EnvName'}).Value
    'instanceState' = $instance.State.Name
    'imageID'      = $instance.ImageId
}

$baseAmi = Get-EC2Image -ImageId $list.imageID
$list.baseAmi = ($baseAmi.Tags | Where-Object{$_.Key -eq 'BaseAmi'}).Value
$baseAmi = Get-Ec2Image -ImageId $list.baseAmi
$list.patchDate = ($baseAmi.Tags | Where-Object{$_.Key -eq 'PatchDate'}).Value
$list.baseName = ($baseAmi.Tags | Where-Object{$_.Key -eq 'Name'}).Value

相关问题