在PowerShell中迭代PSObject属性

use*_*448 29 powershell

我有这个PSObject(来自XML):

bool : {IsActive, ShowOnB2C, ShowOnB2B, IsWebNews}
str  : {id, ProductId, GroupName, Unit...}
int  : {ProductIdNumeric, Prices_SalesOne, Prices_Treater, Prices_B2C...}
arr  : {EnvironmentBrands, Catalogs, NavisionLevels}
long : long
Run Code Online (Sandbox Code Playgroud)

例如,我想在不使用属性名称的情况下迭代属性bool.

我试图像这样索引对象:

$document[0]
Run Code Online (Sandbox Code Playgroud)

但这没有给我什么,但它也不会导致任何错误.

Select-Object 有点作品,但后来我必须使用属性名称,我不希望这样.

$documents | Select-Object bool,str
Run Code Online (Sandbox Code Playgroud)

ForEach 不要迭代属性.

$documents | ForEach {
    $_.name
}
Run Code Online (Sandbox Code Playgroud)

返回doc,这是包含bools,int和字符串的标记(XML)的名称.

bri*_*ist 50

这可以使用隐藏属性PSObject:

$documents.PSObject.Properties | ForEach-Object {
    $_.Name
    $_.Value
}
Run Code Online (Sandbox Code Playgroud)


js2*_*010 17

您可能还需要 NoteProperty 和 Get-Member。

$documents | Get-Member -membertype property,noteproperty | 
  Foreach name
Run Code Online (Sandbox Code Playgroud)

编辑:类型“属性”似乎是一个更通用的包罗万象

$documents | get-member -type properties | % name
Run Code Online (Sandbox Code Playgroud)

编辑:转储所有值:

$obj = ls test.ps1
$obj | Get-Member -Type properties | foreach name | 
  foreach { $_ + ' = ' + $obj.$_ }

Attributes = Normal
CreationTime = 06/01/2019 11:29:03
CreationTimeUtc = 06/01/2019 15:29:03
Directory = /Users/js
DirectoryName = /Users/js
Exists = True
Extension = .ps1
FullName = /Users/js/test.ps1
IsReadOnly = False
LastAccessTime = 06/05/2019 23:19:01
LastAccessTimeUtc = 06/06/2019 03:19:01
LastWriteTime = 06/01/2019 11:29:03
LastWriteTimeUtc = 06/01/2019 15:29:03
Length = 55
Name = test.ps1
Run Code Online (Sandbox Code Playgroud)

另一种没有“| foreach name”的方法,需要额外的括号:

$obj | Get-Member -Type properties | 
  foreach { $_.name + ' = ' + $obj.($_.name) }
Run Code Online (Sandbox Code Playgroud)

另一种方法会产生更易于使用的数组,并且可能适合从 json 转换的对象:

$a = '{ prop1:1, prop2:2, prop3:3 }' | convertfrom-json     
$a

prop1 prop2 prop3
----- ----- -----
    1     2     3

$a.PSObject.Properties | select name,value

name  value
----  -----
prop1     1
prop2     2
prop3     3
Run Code Online (Sandbox Code Playgroud)


Kol*_*yon 9

我更喜欢使用foreach遍历PowerShell对象的方法:

foreach($object_properties in $obj.PsObject.Properties)
{
    # Access the name of the property
    $object_properties.Name

    # Access the value of the property
    $object_properties.Value
}
Run Code Online (Sandbox Code Playgroud)

通常,foreach具有比更高的性能Foreach-Object

是的,foreach实际上与内幕不同Foreach-Object


Mar*_*ndl 5

就像stej 提到的那样,有Get-Member一个带有-MemberType参数的cmdlet,您可以使用:

$documents | Get-Member -MemberType Property | ForEach-Object {
    $_.Name
}
Run Code Online (Sandbox Code Playgroud)