有没有一种方法可以使用唯一的嵌套对象“ Select * -Unique”而不更改对象?

时间:2018-07-31 13:59:51

标签: powershell

假设我有以下内容:

$x = @()

$x += [pscustomobject]@{
    a=1
    b=2
    c=[pscustomobject]@{
        a=1
        b=2
    }
}

$x += [pscustomobject]@{
    a=1
    b=2
    c=[pscustomobject]@{
        a=3
        b=4
    }
}

$x | Select * -Unique 

我期望的行为是返回$x内的两个对象,因为$x.c包含唯一项。我不能简单地运行$x.c | Select * -Unique,因为我想存储和关联整个对象。

上面的代码,不管确切的对象是什么,仅返回第一个对象。

有没有一种方法可以产生我想要的行为而不只是展平所有对象?


使用invoke-expression的潜在非常混乱的解决方案:

$a = $x | gm | ? {$_.MemberType -eq 'NoteProperty' -and $_.Definition -like '*object*'} | select -ExpandProperty Name
$y = @()
$a | %{
    $p = $_
    $x.$p | gm | ? {$_.MemberType -eq 'NoteProperty'} | select -ExpandProperty Name | % { $y += "{`$_.$p.$_}" }
}

$y = ($y | convertto-json -Compress) -replace '\[' -replace '\]' -replace '\"'

iex -command ('$x | Sort (iex $y) -Unique |Select *')

2 个答案:

答案 0 :(得分:1)

如果要区分c的属性,请首先使用Sort-Object

$x |Sort {$_.c.a},{$_.c.b} -Unique |Select * 

答案 1 :(得分:0)

我想到了这一点,即排序对象可以使用脚本块来区分属性。我基本上只是拉出所有我感兴趣的属性,创建脚本块,然后将其添加到数组中。

$itemsToExpand = $x | Get-Member | Where-Object {$_.MemberType -eq 'NoteProperty' -and $_.Definition -like '*object*'} | Select-Object -ExpandProperty Name
$scriptBlockArray = @()
$itemsToExpand | ForEach-Object{
    $current = $_
    $x.$current | Get-Member | Where-Object {$_.MemberType -eq 'NoteProperty'} | Select-Object -ExpandProperty Name | ForEach-Object { 
      $scriptBlockArray += [Scriptblock]::Create("`$_.$current.$_")
    }
}

$x | Sort-Object $scriptBlockArray -Unique