Public/Select-Join.ps1
|
Function Select-Join { <# .Synopsis Select from two object lists the items that share a common property (INNER JOIN). .Description Performs an SQL-like INNER JOIN on two object arrays, matching on a named property. Output objects have Left* and Right* prefixed property names. .Parameter Left The left-side object list .Parameter Right The right-side object list .Parameter On The name of the property to join on .Example $A | Select-Join -Right $B -On Name .Example Select-Join $A $B Name #> [CmdletBinding()] [OutputType([Object[]])] param( [Parameter(ValueFromPipeline = $true, Position = 0, Mandatory = $true)] [Object[]]$Left, [Parameter(Position = 1, Mandatory = $true)] [Object[]]$Right, [Parameter(Position = 2, Mandatory = $true)] [String]$On ) Begin { Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function Started" $OutputObjectList = @() } Process { Write-Verbose "[$($MyInvocation.MyCommand.Name)] PSBoundParameters: $($PSBoundParameters | Out-String)" $Left | ForEach-Object { $L = $_ $Right | Where-Object { $L.$On -eq $_.$On } | ForEach-Object { $R = $_ $ObjectProperties = @{} ($L | Get-Member -MemberType Properties).Name | ForEach-Object { $Name = ('Left{0}' -f $_) $Value = $L.$_ $ObjectProperties += @{$Name = $Value} } ($R | Get-Member -MemberType Properties).Name | ForEach-Object { $Name = ('Right{0}' -f $_) $Value = $R.$_ $ObjectProperties += @{$Name = $Value} } $OutputObjectList += (New-Object PSObject -Property $ObjectProperties) } } } End { Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function Ended" return $OutputObjectList } } |