PowerShell:如何初始化自定义对象数组

时间:2013-06-27 21:48:33

标签: powershell pscustomobject

首先,由于这引出了我的问题,我将首先注意到我在PowerShell中使用了XML,并且喜欢如何将XML文件中的数据快速地读取到自定义对象的数组中。例如,如果我有以下XML文件:

<stuff>
 <item name="Joe" age="32">
  <info>something about him</info>
 </item>
 <item name="Sue" age="29">
  <info>something about her</info>
 </item>
 <item name="Cat" age="12">
  <info>something else</info>
 </item>
</stuff>

如果我简单地阅读它,就像这样:

[xml]$myxml = Get-Content .\my.xml

然后我可以得到这样的项目数组:

[array]$myitems = $myxml.stuff.Item
$myitems

name   age  info
----   ---  ----
Joe    32   something about him
Sue    29   something about her
Cat    12   something else

所以,现在我的问题是:

如何创建自定义对象数组的类似结构,并在我的脚本中初始化它们,而不用读取文件?

我可以做很多循环和/或大量创建/初始化单个对象,然后一次添加一个数组......

但似乎应该有一种方法以更简单的方式执行此创建/初始化。请注意,这里的关键是我的自定义对象有两个以上的元素(否则,我已经使用了哈希)。

我甚至考虑过创建一个大的XML字符串,并使用Select-XML,但我无法正确理解语法(如果这是正确的方向,那就是正确的方向)。

9 个答案:

答案 0 :(得分:60)

我会沿着这些方向做点什么:

$myitems =
@([pscustomobject]@{name="Joe";age=32;info="something about him"},
[pscustomobject]@{name="Sue";age=29;info="something about her"},
[pscustomobject]@{name="Cat";age=12;info="something else"})

请注意,这仅适用于 PowerShell 3 ,但由于您未在问题中提及该版本,因此我认为这对您无关紧要。

<强>更新

评论中提到过,如果您执行以下操作:

$younger = $myitems | Where-Object { $_.age -lt 20 } 
Write-Host "people younger than 20: $($younger.Length)" 

您不会像预期的那样得到1。返回单个pscustomobject时会发生这种情况。现在这对于PowerShell中的大多数其他对象来说不是问题,因为它们具有LengthCount的代理属性。不幸的是pscustomobject没有。这在Powershell 6.1.0中得到修复。您可以使用运算符@()来解决此问题:

$younger = @($myitems | Where-Object { $_.age -lt 20 })

有关更多背景信息,请参阅herehere

答案 1 :(得分:25)

这是在PowerShell中初始化自定义对象数组的简明方法。

> $body = @( @{ Prop1="1"; Prop2="2"; Prop3="3" }, @{ Prop1="1"; Prop2="2"; Prop3="3" } )
> $body

Name                           Value
----                           -----
Prop2                          2
Prop1                          1
Prop3                          3
Prop2                          2
Prop1                          1
Prop3                          3  

答案 2 :(得分:21)

也许你的意思是这样的?我喜欢创建一个对象并使用Format-Table:

PS C:\Users\Joel> $array = @()
PS C:\Users\Joel> $object = New-Object -TypeName PSObject
PS C:\Users\Joel> $object | Add-Member -Name 'Name' -MemberType Noteproperty -Value 'Joe'
PS C:\Users\Joel> $object | Add-Member -Name 'Age' -MemberType Noteproperty -Value 32
PS C:\Users\Joel> $object | Add-Member -Name 'Info' -MemberType Noteproperty -Value 'something about him'
PS C:\Users\Joel> $array += $object
PS C:\Users\Joel> $array | Format-Table

Name                                                                        Age Info
----                                                                        --- ----
Joe                                                                          32  something about him

这将根据属性将数组中的所有对象放在列中。

提示:使用-auto更好地调整表格

PS C:\Users\Joel> $array | Format-Table -Auto

Name Age Info
---- --- ----
Joe   32 something about him

您还可以在表格中指定所需的属性。只需用逗号分隔每个属性名称:

PS C:\Users\Joel> $array | Format-Table Name, Age -Auto

Name Age
---- ---
Joe   32

答案 3 :(得分:9)

这是一个更简洁的接受答案的版本,它避免重复NoteProperty标识符和[pscustomobject] - cast:

$myItems =  ("Joe",32,"something about him"), ("Sue",29,"something about her")
            | ForEach-Object {[pscustomobject]@{name = $_[0]; age = $_[1]; info = $_[2]}}

结果:

> $myItems

name           age         info
----           ---         ----
Joe            32          something about him
Sue            29          something about her

答案 4 :(得分:8)

初始化数组的最简单方法

创建数组

$array = @()

创建标题

$line = "" | select name,age,phone

填写

$line.name = "Leandro"
$line.age = "39"
$line.phone = "555-555555"

将行添加到$ array

$array += $line

<强>结果

$array

name                                                     age                                                      phone
----                                                     ---                                                      -----
Leandro                                                  39                                                       555-555555

答案 5 :(得分:1)

使用&#34; Here-String&#34;并转换为XML。

[xml]$myxml = @"
<stuff>
 <item name="Joe" age="32">
  <info>something about him</info>
 </item>
 <item name="Sue" age="29">
  <info>something about her</info>
 </item>
 <item name="Cat" age="12">
  <info>something else</info>
 </item>
</stuff>
"@

[array]$myitems = $myxml.stuff.Item

$myitems

答案 6 :(得分:0)

我必须创建一个预定义类型的数组,并且我成功地执行了以下操作:

{{1}}

答案 7 :(得分:0)

鉴于上述数据,这就是我的处理方式:

# initialize the array
[PsObject[]]$people = @()

# populate the array with each object
$people += [PsObject]@{ Name = "Joe"; Age = 32; Info = "something about him" }
$people += [PsObject]@{ Name = "Sue"; Age = 29; Info = "something about her" }
$people += [PsObject]@{ Name = "Cat"; Age = 12; Info = "something else" }

即使您在Where-Object之后只有1个项目,以下代码也可以使用:

# display all people
Write-Host "People:"
foreach($person in $people) {
    Write-Host "  - Name: '$($person.Name)', Age: $($person.Age), Info: '$($person.Info)'"
}

# display with just 1 person (length will be empty if using 'PSCustomObject', so you have to wrap any results in a '@()' as described by Andrew Savinykh in his updated answer)
$youngerPeople = $people | Where-Object { $_.Age -lt 20 }
Write-Host "People younger than 20: $($youngerPeople.Length)"
foreach($youngerPerson in $youngerPeople) {
    Write-Host "  - Name: '$($youngerPerson.Name)'"
}

结果:

People:
  - Name: 'Joe', Age: 32, Info: 'something about him'
  - Name: 'Sue', Age: 29, Info: 'something about her'
  - Name: 'Cat', Age: 12, Info: 'something else'
People younger than 20: 1
  - Name: 'Cat'

答案 8 :(得分:0)

关于班级的一些变化。用哈希表对其进行初始化。

class Point { $x; $y }

$a = [Point[]] (@{ x=1; y=2 },@{ x=3; y=4 })

$a

x y        
- -          
1 2
3 4

$a.gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Point[]                                  System.Array

$a[0].gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    Point                                    System.Object