构造一个自定义对象,其属性将按照它们的定义顺序进行枚举

时间:2017-07-24 19:26:20

标签: powershell serialization reflection

我有一个在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。在Excel中查看时,我基本上需要按顺序组织CSV标题。

2 个答案:

答案 0 :(得分:4)

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

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

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

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

请注意,这仅适用于哈希表文字,前面有[pscustomobject] ,在PowerShell v3 + 语法糖使PowerShell按照指定的顺序 构建带有哈希表条目自定义对象实例,即使单独使用哈希表文字的条目({ {1}})本质上是无序(它们的排序是一个实现细节)。

您可以将@{ ... }视为[pscustomobject] @{ ... }的隐式快捷方式,其中[pscustomobject] [ordered] @{ ... }是带有有序条目(键)的哈希表的PSv3 +语法,其中true类型为[ordered] @{ ... }

至于您尝试的内容

与上面讨论的语法糖不同,[System.Collections.Specialized.OrderedDictionary]与哈希表文字(New-Object)结合起来 not 保证结果对象的属性在同一枚举中得到枚举命令作为(固有无序)输入哈希表的条目。

@{ ... }New-Object -TypeName PSObject -Property @{ ... }都会创建一个New-Object -TypeName PCustomSObject -Property @{ ... }实例,其属性由于属性定义已作为哈希表文字提供 - 在没有语法糖 - 以枚举哈希表文字的条目的不可预测的顺序定义:

[pscustomobject]

如您所见,属性按特定顺序枚举。

可以传递一个有序的哈希表(PSv3 +),但这相当于更加冗长 - 效率更低 - 等同于> 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 : 句法上面的糖溶液:

[pscustomobject] @{ ... }

答案 1 :(得分:1)

你想要的是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