locked
Comparing Object Arrays RRS feed

  • Question

  • I am creating two arrays for Computer names and ports as such:

    $list += New-Object psobject -Property @{Asset=$AssetTag;PTTYs=$PTTY

    $SDlist += New-Object psobject -Property @{Asset=$SDAssetTag;PTTYs=$SDPTTY}

    The AssetTag and PTTYs are variables read and parsed through two separate host.cfg files.  I want to make $SDlist identical to $list.  My fist attempt was to use:

    Compare-Object -ReferenceObject $list -DifferenceObject $SDlist

    However this does not seem to work and only yields last 30 lines (there is roughly 1800 objects) and using $list.Asset throws errors.

    I then tried:

    $list | where { $SDlist -NotContains $_.Asset }

    but that ended up just listing the entire $list array.  Here is an example of the array itself:

    $list
     @{PTTYs=2962; Asset=6s4w9z1}
     @{PTTYs=2963; Asset=6s3x9z1}
     @{PTTYs=2964; Asset=fp7m8z1}
     @{PTTYs=2965; Asset=9yb1jm1}
     @{PTTYs=2966; Asset=hzxkvr1}
     @{PTTYs=2967; Asset=6qmlg72}

    Ultimately, what I want is to add the PC from $list that doesn't exist in $SDlist and remove the PCs from $SDlist that are not in $list.  I think I am on the right track.  Can anyone tell me what is the missing piece?


    Monday, June 19, 2017 9:10 PM

All replies

  • You must create the objects individually.

    Without the code used to create the variables it is not possible to give you a direction.


    \_(ツ)_/

    Monday, June 19, 2017 9:25 PM
  • for $list:

    $Data = Get-Content "S:\Operations\Server1\host.cfg" | Select -Skip 23
    
    #Parses through the HOST.CFG file
    ForEach ($line in $Data) 
    {
        $AssetTag = $($line -split '\s+|\t+')[0].Trim() #Splits the line at the Asset tag.  This will split whether there is a space or a tab.
        $PTTY = $($line.Split("`=")[1]).Trim() -as [int] #Grabs the PTTY number.  Inside the HOST.CFG it appears as PTTY=####
    
        If ($AssetTag -eq "ANY") { Continue } Else { $list += New-Object psobject -Property @{Asset=$AssetTag;PTTYs=$PTTY} }
    }

    Again, Just parsing through the data and creating an object entry for each PC inside the array.  Fairly straight forward.  The other object array is created in the same manner.  Is it not possible to simply compare the two or do I need to use nested for loops to compare each line?



    • Edited by Trey_b Tuesday, June 20, 2017 12:51 PM
    Tuesday, June 20, 2017 12:50 PM
  • Change this line:

     $list += New-Objectpsobject -Property @{Asset=$AssetTag;PTTYs=$PTTY}

    to this:

    [array]$list += New-Objectpsobject -Property @{Asset=$AssetTag;PTTYs=$PTTY}

    Without that you will not get an array.  You will get a string.

    A better approach would be this:

    Get-Content S:\Operations\Server1\host.cfg | 
    	Select-Object -Skip 23 |
    	ForEach-Object{
    		$AssetTag = (($_ -split '\s+|\t+')[0]).Trim()
    		If ($AssetTag -ne 'ANY') {
    			[pscustomobject]@{
    				Asset = $AssetTag
    				PTTY  = [int]($_.Split("`=")[1]).Trim()
    			}
    		}
    	}
    

    Once you have to good object arrays you can use Compare-Object.


    \_(ツ)_/


    • Edited by jrv Tuesday, June 20, 2017 8:51 PM
    • Proposed as answer by I.T Delinquent Wednesday, June 21, 2017 4:17 PM
    Tuesday, June 20, 2017 8:50 PM
  • So many ways to skin a cat..... I am always to open to learning new things to expand my knowledge.  I will give it a try and let you know.
    Wednesday, June 21, 2017 3:53 PM
  • Hi,

    Be careful with Compare-Object. It doesn't work as expected in many cases.

    Example:

    PS> $list=@()
    PS> 5..10 | %{$list+=([pscustomobject]@{Asset="sdf$_";PTTY="sdfsd$_"})}
    PS> $list1=@()
    PS> 0..10 | %{$list1+=([pscustomobject]@{Asset="sdf$_";PTTY="sdfsd$($_-1)"})}
    PS> $list
    
    Asset PTTY
    ----- ----
    sdf5  sdfsd5
    sdf6  sdfsd6
    sdf7  sdfsd7
    sdf8  sdfsd8
    sdf9  sdfsd9
    sdf10 sdfsd10
    
    PS> $list
    
    Asset PTTY
    ----- ----
    sdf0  sdfsd-1
    sdf1  sdfsd0
    sdf2  sdfsd1
    sdf3  sdfsd2
    sdf4  sdfsd3
    sdf5  sdfsd4
    sdf6  sdfsd5
    sdf7  sdfsd6
    sdf8  sdfsd7
    sdf9  sdfsd8
    sdf10 sdfsd9
    PS> Compare-Object -ReferenceObject $list -DifferenceObject $list1
    InputObject                 SideIndicator
    -----------                 -------------
    @{Asset=sdf6; PTTY=sdfsd5}  =>
    @{Asset=sdf7; PTTY=sdfsd6}  =>
    @{Asset=sdf8; PTTY=sdfsd7}  =>
    @{Asset=sdf9; PTTY=sdfsd8}  =>
    @{Asset=sdf10; PTTY=sdfsd9} =>

    You should use -Property parameter with Compare-object to solve that:

    Compare-Object -ReferenceObject $list -DifferenceObject $list1 -Property Asset,PTTY
    Sergei


    Wednesday, June 21, 2017 4:50 PM