我有这个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
我想在不使用属性名称的情况下迭代属性,例如bool
。
我试图像这样索引对象:
$document[0]
但这没有给我什么,但它也不会导致任何错误。
Select-Object
有点作品,但后来我必须使用属性名称,我不想要它。
$documents | Select-Object bool,str
ForEach
不会迭代属性。
$documents | ForEach {
$_.name
}
返回doc,这是包含bools,int和字符串的标记(XML)的名称。
答案 0 :(得分:39)
可以使用隐藏属性PSObject
:
$documents.PSObject.Properties | ForEach-Object {
$_.Name
$_.Value
}
答案 1 :(得分:6)
我更喜欢使用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
}
通常,foreach
的效果高于Foreach-Object
。
是的,foreach
实际上与Foreach-Object
不同。
答案 2 :(得分:3)
与stej mentioned一样,您可以使用Get-Member
cmdlet,其中包含-MemberType
参数:
$documents | Get-Member -MemberType Property | ForEach-Object {
$_.Name
}
答案 3 :(得分:3)
Get-Member也可能需要NoteProperty。
movmskps
答案 4 :(得分:0)
我使用以下命令枚举属性并将它们放在表中:
$Object.PSObject.Properties | Format-Table @{ Label = 'Type'; Expression = { "[$($($_.TypeNameOfValue).Split('.')[-1])]" } }, Name, Value -AutoSize -Wrap
我为此编写了以下函数,该函数还迭代了嵌套属性。
function Enumerate-ObjectProperties {
param (
[psobject] $Object,
[string] $Root
)
Write-Output $($Object.PSObject.Properties | Format-Table @{ Label = 'Type'; Expression = { "[$($($_.TypeNameOfValue).Split('.')[-1])]" } }, Name, Value -AutoSize -Wrap | Out-String)
foreach ($Property in $Object.PSObject.Properties) {
# Strings always have a single property "Length". Do not enumerate this.
if (($Property.TypeNameOfValue -ne 'System.String') -and ($($Object.$($Property.Name).PSObject.Properties))) {
$NewRoot = $($($Root + '.' + $($Property.Name)).Trim('.'))
Write-Output "Property: $($NewRoot)"
Enumerate-ObjectProperties -Object $($Object.$($Property.Name)) -Root $NewRoot
}
}
}
Enumerate-ObjectProperties $YourObject
但是请记住,某些对象的构造有些典型,因为它们在嵌套中具有“循环”。引用父对象的子属性。 一个例子是:
Get-Date 'somebogusdata'
Enumerate-ObjectProperties $Error[0]
这将创建一个循环。 您当然可以添加“ depth”参数来添加深度计数器,从而指定您只想进入某个深度。 看起来像这样:
$script:Level = 1
function Enumerate-ObjectProperties {
param (
[psobject] $Object,
[int32] $Depth = 1,
[string] $Root
)
Write-Output $($Object.PSObject.Properties | Format-Table @{ Label = 'Type'; Expression = { "[$($($_.TypeNameOfValue).Split('.')[-1])]" } }, Name, Value -AutoSize -Wrap | Out-String)
foreach ($Property in $Object.PSObject.Properties) {
# Strings always have a single property "Length". Do not enumerate this.
if (($Property.TypeNameOfValue -ne 'System.String') -and ($($Object.$($Property.Name).PSObject.Properties)) -and ($Level -le $Depth)) {
$NewRoot = $($($Root + '.' + $($Property.Name)).Trim('.'))
$Level++
Write-Output "Property: $($NewRoot) (Level: $Level)"
Enumerate-ObjectProperties -Object $($Object.$($Property.Name)) -Root $NewRoot
$Level--
}
}
}
Enumerate-ObjectProperties -Object $Error[0] -Depth 2