8

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.

3
  • It does when I run it. Commented Oct 28, 2015 at 0:51
  • @MikeShepard, Did you replace the $computer and $osInfo assignment of variables with the get-process and get-service respectively as shown above. Commented Oct 28, 2015 at 1:13
  • 1
    Nope...I guess I should give up reading tonight. Commented Oct 28, 2015 at 1:15

2 Answers 2

6

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.

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

1 Comment

This was a great explanation, and by itself worked wonderfully. I had to change the following for use in a script: $collection = @() to $collection = [pscustomobject]@()
2

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

1 Comment

@Ishan It normal, why don't you try to understand what you code. $computer is also à collection so what do you expect. I add the code of what I think you expect.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.