Combining Arrays of Object

Croll, Joe 1 Reputation point
2020-09-15T20:06:50.02+00:00

Hello,

I'm trying to combine the arrays below into a single array for audit purposes using powershell. Do you have any suggestions for marrying this data together besides looping each array? The idea is to track which devices may be missing from Intune or be missing required software. I understand I can use Graph to query installed software, but I need to verify additional components which can only be accessed using API's.

$IntuneDevices =
@([pscustomobject]@{ComputerName="Computer1";IntuneName="Computer1";DeviceOS="Windows10";Notes="Joe's Computer"},
[pscustomobject]@{ComputerName="Computer2";IntuneName="Computer2";DeviceOS="Windows10";Notes="Bob's Computer"}
)
$SoftwareADevices =
@([pscustomobject]@{ComputerName="Computer1";SoftwareAName="AdobeReader";SoftwareAVersion="20.1"},
[pscustomobject]@{ComputerName="Computer2";SoftwareAName="AdobeReader";SoftwareAVersion="20.2"}
)
$SoftwareBDevices =
@([pscustomobject]@{ComputerName="Computer1";SoftwareBName="Notepad";SoftwareBVersion="2.1"},
[pscustomobject]@{ComputerName="Computer3";SoftwareBName="Notepad";SoftwareBVersion="2.2"}
)

End Result:
$InventoriedDevices=
@([pscustomobject]@{ComputerName="Computer1";IntuneName="Computer1";DeviceOS="Windows10";Notes="Joe's Computer";SoftwareAName="AdobeReader";SoftwareAVersion="20.1";SoftwareBName="Notepad";SoftwareBVersion="2.1"},
[pscustomobject]@{ComputerName="Computer2";IntuneName="Computer1";DeviceOS="Windows10";Notes="Joe's Computer";SoftwareAName="AdobeReader";SoftwareAVersion="20.1";SoftwareBName="Notepad";SoftwareBVersion="2.1"}
[pscustomobject]@{ComputerName="Computer3";IntuneName="Not Found";DeviceOS="Windows10";Notes="Joe's Computer";SoftwareAName="AdobeReader";SoftwareAVersion="20.1";SoftwareBName="Notepad";SoftwareBVersion="2.1"}
)

Windows for business Windows Server User experience PowerShell
Microsoft Security Microsoft Entra Microsoft Entra ID
Developer technologies C++
{count} votes

2 answers

Sort by: Most helpful
  1. Rich Matheisen 47,901 Reputation points
    2020-09-16T19:21:35.407+00:00

    Combining arrays is straightforward: $array3 = $array1 + $array2

    Your question poses a very different problem. You want to aggregate the properties/values of several different data sets, arriving at a new set containing the complete set of properties and values from all of them on unique objects.

    See if this fits you needs:

    # get a list of all NoteProperties from all data
    $Props = @()
    $IntuneDevices, $SoftwareADevices, $SoftwareBDevices |      # if large lists, use [0]th element of each array instead of the whole lot
        ForEach-Object{
            $Props += $_ |
                Get-Member -MemberType NoteProperty |
                    Select-Object -ExpandProperty Name
        }
    $Props = $Props | Select-Object -Unique     # only need one of each
    
    $All=[ordered]@{}                           # use this to accumulate properties
    $CurrentComputer = $null
    $IntuneDevices + $SoftwareADevices + $SoftwareBDevices |
        Sort-Object ComputerName |
            ForEach-Object{
                $Obj = $_
                if ($null -eq $CurrentComputer){
                    $CurrentComputer = $_.ComputerName
                }
                elseif ($_.ComputerName -ne $CurrentComputer) {
                    [PSCustomObject]$All        # emit the completed computer aggregate
                    $CurrentComputer = $_.ComputerName
                    $All.Clear()                # start with empty hash
                }
                $Props |                        # look for all properties on all objects
                    ForEach-Object{
                        if (-not $All.$_){      # don't overwrite an existing value
                            $All.$_ = $Obj.$_
                        }
                    }
                }
                [PSCustomObject]$All            # emit the last computer's stuff
    
    0 comments No comments

  2. Anonymous
    2020-09-17T06:26:10.117+00:00

    Hi,
    Please check if this meets your requirements.

    #If there are other arrays add them to $AllDevices  
    $AllDevices = $IntuneDevices + $SoftwareADevices +$SoftwareBDevices  
    $InventoriedDevices = [PSCustomObject]@()   
    foreach($Device in $AllDevices)      
    {  
        $IfAdded = $False  
        foreach($InventoriedDevice in $InventoriedDevices)  
        {     
            if($InventoriedDevice.ComputerName -eq $Device.ComputerName)  
            {   
                foreach($Property in $Device.psobject.Properties)  
                {  
                    $InventoriedDevice.psobject.Properties.Add($Property)  
                }  
                $IfAdded = $True  
            }  
        }  
        if($IfAdded -eq $False)  
        {  
            $InventoriedDevices += $Device  
        }      
     }      
    $InventoriedDevices | Format-Table     
    

    Best Regards,
    Ian

    ============================================

    If the Answer is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.