6

I've got two CMDlets that return lists of objects. One returns objects of the type SPSolution, which contains the property Id, the other returns objects of the type SPFeature with a property SolutionId.

Now I want to join/merge this data something like this:

$f = Get-Feature
$s = Get-Solution
$result = <JOIN> $f $s
          <ON> $f.SolutionId = $s.Id
          <SELECT> FeatureName = $f.DisplayName, SolutionName = $s.Name

5 Answers 5

5

It's not efficient, and it assumes PowerShell 2 but it should do the job:

$solutions = Get-Solution

foreach ($f in Get-Feature) {

    $filteredSolutions = $solutions |
        where-object { $_.Id -eq $f.SolutionId }

    foreach ($s in $filteredSolutions) {
        new-object PSObject -prop @{
            FeatureName = $f.DisplayName
            SolutionName = $s.Name
        }
    }
}

Note that I don't have SharePoint installed so I'm afraid that I can't test this!

Sign up to request clarification or add additional context in comments.

7 Comments

Thank you, it did the job. But I was really hoping that there is a CMDlet for this kind of operation...
Here's something very, very old (from when PowerShell was still known as Monad) which describes a Join-Object cmdlet. It's so old it uses a different syntax though: leeholmes.com/blog/CreatingSQLsJoinlikeFunctionalityInMSH.aspx
There is no Join-Object cmdlet even in PowerShell 2.0.
@Kieth Hill: the article describes a potential implementation, not something that is part of PowerShell.
thanks for the article, I like the implementation. A pity that it only allows to return the first OR the second data source. I'm thinking about building my own Join-Object from there ... or starting a bounty for building it ;-)
|
3

Building off what Keith Hill said Making it a 2 liner can greatly improve efficiency. This way you only run Get-Solution once instead of again for every object returned by Get-Feature

$Solutions = Get-Solution
Get-Feature | % {$f = $_; $Solutions | ? {$f.SolutionId -eq $_.Id} | 
                 Select Name,@{n='FeatureName';e={$f.DisplayName}}}

Comments

2

Here's a one-liner that should do the trick (relies on nested pipelines):

Get-Feature | % {$f = $_; Get-Solution | ? {$f.SolutionId -eq $_.Id} | 
                 Select Name,@{n='FeatureName';e={$f.DisplayName}}}

2 Comments

Nice. Didn't realise you could abbreviate 'Name' and 'Expression' to 'n' and 'e'. Works in PS1 too. Although, not hugely readable! ;)
No, not hugely readable but if you're banging stuff out at the prompt, it is nice to be able to do.
1

It's simple and could probably use more work, but it does the job.

function Join-Object {
  param ( [PSObject[]] $objects, $where, $proplist)
    for ($i=0;$i -le $objects.length;$i++) {
      if ($objects[$i+1] -ne $null) {$out += $objects[$i] | %{$o=$_;$objects[$i+1] | where $where | Select -property $proplist} } };
  $out
}

$where is a script block, and $proplist is an array of properties formatted for Select-Object.
It works for passing in two objects. Hope it would work for more, but haven't tried it yet.

Comments

0
(Get-Feature | Select @{Name="FeatureName";Expression={$_.DisplayName}) | Join (Get-Solution | Select @{Name="SolutionName";Expression={$_.Name}) SolutionId -eq Id

See: In Powershell, what's the best way to join two tables into one?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.