Ishan
Ishan

Reputation: 4339

combine object properties into one object in PowerShell

I am trying to combine multiple object properties into one object.

When I have the following code the objects properties are combined.

$computer = gwmi win32_computersystem | select numberOfProcessors, NumberOfLogicalProcessors, HypervisorPresent

$osInfo = gwmi win32_operatingsystem | select version, caption, serialnumber, osarchitecture

Foreach($p in Get-Member -InputObject $osInfo -MemberType NoteProperty)
{

 Add-Member -InputObject $computer -MemberType NoteProperty  -Name $p.Name -Value $osInfo.$($p.Name) -Force

}

$computer

However, if I replace the above computer and osInfo variables with

$computer = Get-Process | Select processname, path
$osInfo = Get-Service | Select name, status

then the $computer variables does not have the properties of the $osInfo variable after the for loop is executed. ie: the second object is not combined with the first object.

Upvotes: 8

Views: 41627

Answers (2)

JPBlanc
JPBlanc

Reputation: 72610

Your problem comes from the bad usage of Get_Member in the case of a collection.

Get-Member -InputObject ACollection gives the members of the collection.

ACollection | Get-Member gives the members of each element of the collection.

So in you case it will work with :

Foreach($p in ($osInfo | Get-Member  -MemberType NoteProperty))
{
}

Edited

$computer is also à collection so what do you expect. I add the code of what I think you expect.

$processes = Get-Process | Select processname, path, Id

Foreach($p in $processes)
{
 $services = Get-WmiObject "Win32_Service" -filter "ProcessId=$($p.Id)"
 Add-Member -InputObject $p -MemberType NoteProperty  -Name "Services" -Value $(($services | % {$_.name}) -join ',') -Force
}

$processes

Upvotes: 2

Jeter-work
Jeter-work

Reputation: 801

The original code deals with cmdlets that returns two single objects relating to the same source.

You're trying to use it with cmdlets that return arrays of multiple objects.

The following basically merges the two arrays.

$computer = 'Server01'

$collection = @()

$services = Get-Service | Select name, status

$processes = Get-Process | Select processname, path

foreach ($service in $services) {
    $collection += [pscustomobject] @{
        ServiceName   = $service.name
        ServiceStatus = $service.status
        ProcessName   = ""
        ProcessPath   = ""
    }
}

foreach ($process in $processes) {
    $collection += [pscustomobject] @{
        ServiceName   = ""
        ServiceStatus = ""
        ProcessName   = $process.processname
        ProcessPath   = $process.path
    }
}

$collection

Personally, I'd just use the two lines for $services and $processes and be done.

Upvotes: 6

Related Questions