0

I've been battling this for a couple weeks. Basically, I want to compare data in 2 multidimensional arrays.

Here's my first array:

$images = @(Get-ContentLibraryItem |
Select-Object Name, @{n='NameParts'; e={$_.Name -split '-',3}}  |
Select-Object Name, @{n='BaseName'; e={$_.NameParts[0]}},
@{n='Version'; e={[version]$_.NameParts[1]}})

Output looks like this:

Name                           BaseName               Version
----                           --------               -------
sles11sp4_jeos-1234567890      sles11sp4_jeos
sles12sp3-0.0.11               sles12sp3              0.0.11
win2012r2std_desk-0.1.23       win2012r2std_desk      0.1.23
win2012r2std_desk-0.2.34       win2012r2std_desk      0.2.34
win2016std_desk-0.3.45         win2016std_desk        0.3.45
win2016std_desk-0.4.56         win2016std_desk        0.3.33

Here's my 2nd array:

$templates = @(get-template |
Select-Object Name, @{n='NameParts'; e={$_.Name -split '-',3}}  |
Select-Object Name, @{n='BaseName'; e={$_.NameParts[0]}},
@{n='Version'; e={[version]$_.NameParts[1]}})

And the output looks like this:

Name                                            BaseName               Version
----                                            --------               -------
sles12sp3-0.0.11-infra-dr01                     sles12sp3           0.0.11
win2016std_desk-0.3.33-infra-dr01               win2016std_desk     0.3.33
win2016std_desk-0.3.42-infra-dr01               win2016std_desk     0.3.42
win2012r2std_desk-0.1.23-infra-dr01             win2012r2std_desk   0.1.23
win2012r2std_desk-0.2.22-infra-dr01             win2012r2std_desk   0.2.22
sles12sp3-0.0.31-infra-dr01                     sles12sp3           0.0.31
win2016std_desk-0.3.45-infra-dr01               win2016std_desk     0.3.45
win2012r2std_desk-0.2.34-infra-dr01             win2012r2std_desk   0.2.34
sles11sp4_jeos-1234567890-infra-dr01            sles11sp4_jeos
sles12sp3-0.0.11-oracle01                       sles12sp3           0.0.11
sles12sp3-0.0.31-oracle01                       sles12sp3           0.0.31
sles11sp4_jeos-1234567890-oracle01              sles11sp4_jeos
sles12sp3-0.0.11-stnd-linux01                   sles12sp3           0.0.11
win2016std_desk-0.3.33-stnd-win01               win2016std_desk     0.3.33
win2016std_desk-0.3.33-stnd-sql01               win2016std_desk     0.3.33
win2016std_desk-0.4.56-stnd-win01               win2016std_desk     0.4.56
win2012r2std_desk-0.1.23-stnd-win01             win2012r2std_desk   0.1.23
sles12sp3-0.1.22-stnd-linux01                   sles12sp3           0.1.22
win2016std_desk-0.3.45-stnd-sql01               win2016std_desk     0.3.45
win2012r2std_desk-0.2.22-stnd-win01             win2012r2std_desk   0.2.22
sles12sp3-0.1.33-stnd-linux01                   sles12sp3           0.1.33
win2016std_desk-0.3.42-stnd-win01               win2016std_desk     0.3.42

At the end of the day I'm looking for all $templates where $template.basename -eq $image.basename and $template.version -eq $image.version and delete everything else. The problem I'm encountering is that if I compare them one at a time in foreach loops, they will eventually delete all the templates. How do I compare the arrays together so I can either get all the "good" templates or all the "bad" templates in a new array.

This is the last iteration of my code (which didn't work...didn't delete anything).

Foreach ($image in $images){
    Foreach ($template in $templates){
        if ($template |where-object {$_.basename -eq $image.basename -and $_.version -eq $image.version}){
            Write-host "Template Name Matches, next"
        }
            Else {
                Write-host "Image and version do not match, deleting"  
                Write-log -Message "Remove-template -template $($template.name) -DeletePermanently"
            }
    }

}

Here's the final code that works! NOTE: I need to add a switch command to export the deleted to a csv, if the switch is true, it will execute the delete.

$images = @(Get-ContentLibraryItem |
Select-Object Name, @{n='NameParts'; e={$_.Name -split '-',3}}  |
Select-Object Name, @{n='BaseName'; e={$_.NameParts[0]}},
  @{n='Version'; e={[version]$_.NameParts[1]}})

$templates = @(get-template |
Select-Object Name, @{n='NameParts'; e={$_.Name -split '-',3}}  |
Select-Object Name, @{n='BaseName'; e={$_.NameParts[0]}},
  @{n='Version'; e={[version]$_.NameParts[1]}})

$goodtemplates = @()
$goodtemplates = $templates |% {compare-object $_ -DifferenceObject $images -property basename,version -excludedifferent -includeequal -passthru | Select Name,BaseName,Version}

$badtemplates = diff $goodtemplates.name $templates.name

Foreach ($badtemplate in $badtemplates){
    Write-host "Image and version do not match, deleting"  
    Remove-template -template $($badtemplate.inputobject) -DeletePermanently -confirm:$false
}

2 Answers 2

1

I think this may work. This should output the things that meet your criteria:

$templates | foreach-object {
   compare-object $_ -ReferenceObject $templates -DifferenceObject $images -property basename,version -excludedifferent -includeequal -passthru | select Name,BaseName,Version
}

Here is a test of it:

PS H:\> $obj1 = [pscustomobject]@{"Name"="sles11sp4_jeos-1234567890";"BaseName"= "sles11sp4_jeos";"Version"=""}

PS H:\> $obj3 = [pscustomobject]@{"Name"="sles12sp3-0.0.11-infra-dr01";"BaseName"= "sles12sp3";"Version"="0.0.11"}

PS H:\> $obj2 = [pscustomobject]@{"Name"="sles12sp3-0.0.11";"BaseName"= "sles12sp3";"Version"="0.0.11"}

PS H:\> $obj4 = [pscustomobject]@{"Name"="win2016std_desk-0.3.33-infra-dr01";"BaseName"= "win2016std_desk";"Version"="0.
3.33"}
PS H:\> $obj5 = [pscustomobject]@{"Name"="win2016std_desk-0.3.45";"BaseName"= "win2016std_desk";"Version"="0.3.45"}

PS H:\> $obj6 = [pscustomobject]@{"Name"="win2016std_desk-0.3.45-infra-dr01";"BaseName"= "win2016std_desk";"Version"="0.
3.45"}
PS H:\> $obj7 = [pscustomobject]@{"Name"="win2016std_desk-0.3.45-stnd-sql01";"BaseName"= "win2016std_desk";"Version"="0.
3.45"}
PS H:\>
PS H:\> $images = @()
PS H:\> $images += @($obj1,$obj2,$obj5)
PS H:\> $templates = @()
PS H:\> $templates += ($obj3,$obj4,$obj6,$obj7)
PS H:\>
PS H:\> $images

Name                      BaseName        Version
----                      --------        -------
sles11sp4_jeos-1234567890 sles11sp4_jeos
sles12sp3-0.0.11          sles12sp3       0.0.11
win2016std_desk-0.3.45    win2016std_desk 0.3.45


PS H:\> $templates

Name                              BaseName        Version
----                              --------        -------
sles12sp3-0.0.11-infra-dr01       sles12sp3       0.0.11
win2016std_desk-0.3.33-infra-dr01 win2016std_desk 0.3.33
win2016std_desk-0.3.45-infra-dr01 win2016std_desk 0.3.45
win2016std_desk-0.3.45-stnd-sql01 win2016std_desk 0.3.45


PS H:\>
PS H:\> $templates |% {compare-object $_ -DifferenceObject $images -property basename,version -excludedifferent -include
equal -passthru | Select Name,BaseName,Version}

Name                              BaseName        Version
----                              --------        -------
sles12sp3-0.0.11-infra-dr01       sles12sp3       0.0.11
win2016std_desk-0.3.45-infra-dr01 win2016std_desk 0.3.45
win2016std_desk-0.3.45-stnd-sql01 win2016std_desk 0.3.45
Sign up to request clarification or add additional context in comments.

3 Comments

I think we're on the right path. Unfortunately, it didn't return all of the matching templates. It only returned one of each that matched the $image.
I made a change that may help
That was it! You don't know how long I struggled to get this output. I can't thank you enough! Thanks!
0

You were on the right path yourself, but you were creating just too many loops (considering the Where-Object cmdlet initiats a third loop).

$Images = ConvertFrom-SourceTable '

Name                           BaseName               Version
----                           --------               -------
sles11sp4_jeos-1234567890      sles11sp4_jeos
sles12sp3-0.0.11               sles12sp3              0.0.11
win2012r2std_desk-0.1.23       win2012r2std_desk      0.1.23
win2012r2std_desk-0.2.34       win2012r2std_desk      0.2.34
win2016std_desk-0.3.45         win2016std_desk        0.3.45
win2016std_desk-0.4.56         win2016std_desk        0.3.33
'

$Templates= ConvertFrom-SourceTable '

Name                                            BaseName            Version
----                                            --------            -------
sles12sp3-0.0.11-infra-dr01                     sles12sp3           0.0.11
win2016std_desk-0.3.33-infra-dr01               win2016std_desk     0.3.33
win2016std_desk-0.3.42-infra-dr01               win2016std_desk     0.3.42
win2012r2std_desk-0.1.23-infra-dr01             win2012r2std_desk   0.1.23
win2012r2std_desk-0.2.22-infra-dr01             win2012r2std_desk   0.2.22
sles12sp3-0.0.31-infra-dr01                     sles12sp3           0.0.31
win2016std_desk-0.3.45-infra-dr01               win2016std_desk     0.3.45
win2012r2std_desk-0.2.34-infra-dr01             win2012r2std_desk   0.2.34
sles11sp4_jeos-1234567890-infra-dr01            sles11sp4_jeos
sles12sp3-0.0.11-oracle01                       sles12sp3           0.0.11
sles12sp3-0.0.31-oracle01                       sles12sp3           0.0.31
sles11sp4_jeos-1234567890-oracle01              sles11sp4_jeos
sles12sp3-0.0.11-stnd-linux01                   sles12sp3           0.0.11
win2016std_desk-0.3.33-stnd-win01               win2016std_desk     0.3.33
win2016std_desk-0.3.33-stnd-sql01               win2016std_desk     0.3.33
win2016std_desk-0.4.56-stnd-win01               win2016std_desk     0.4.56
win2012r2std_desk-0.1.23-stnd-win01             win2012r2std_desk   0.1.23
sles12sp3-0.1.22-stnd-linux01                   sles12sp3           0.1.22
win2016std_desk-0.3.45-stnd-sql01               win2016std_desk     0.3.45
win2012r2std_desk-0.2.22-stnd-win01             win2012r2std_desk   0.2.22
sles12sp3-0.1.33-stnd-linux01                   sles12sp3           0.1.33
win2016std_desk-0.3.42-stnd-win01               win2016std_desk     0.3.42
'

Just use an If statement:

Foreach ($image in $images){
    Foreach ($template in $templates){
        if ($template.basename -eq $image.basename -and $template.version -eq $image.version){
            Write-host "Template Name Matches, next"
        }
        Else {
            Write-host "Image and version do not match, deleting"  
            Write-Warning "Remove-template -template $($template.name) -DeletePermanently"
        }
    }
}

And you will see some results like:

Image and version do not match, deleting
WARNING: Remove-template -template sles12sp3-0.0.11-infra-dr01 -DeletePermanently
Image and version do not match, deleting
WARNING: Remove-template -template win2016std_desk-0.3.33-infra-dr01 -DeletePermanently
Image and version do not match, deleting
WARNING: Remove-template -template win2016std_desk-0.3.42-infra-dr01 -DeletePermanently
Image and version do not match, deleting
WARNING: Remove-template -template win2012r2std_desk-0.1.23-infra-dr01 -DeletePermanently
 ...

You might also use this Join-Object cmdlet:

$Templates | Join $Images -On BaseName, Version `
    -Property @{TemplateName = {$Left.Name}; ImageName = {$Right.Name}}, BaseName, Version

Result:

ImageName                 TemplateName                         BaseName          Version
---------                 ------------                         --------          -------
sles12sp3-0.0.11          sles12sp3-0.0.11-infra-dr01          sles12sp3         0.0.11
win2016std_desk-0.4.56    win2016std_desk-0.3.33-infra-dr01    win2016std_desk   0.3.33
win2012r2std_desk-0.1.23  win2012r2std_desk-0.1.23-infra-dr01  win2012r2std_desk 0.1.23
win2016std_desk-0.3.45    win2016std_desk-0.3.45-infra-dr01    win2016std_desk   0.3.45
win2012r2std_desk-0.2.34  win2012r2std_desk-0.2.34-infra-dr01  win2012r2std_desk 0.2.34
sles11sp4_jeos-1234567890 sles11sp4_jeos-1234567890-infra-dr01 sles11sp4_jeos
sles12sp3-0.0.11          sles12sp3-0.0.11-oracle01            sles12sp3         0.0.11
sles11sp4_jeos-1234567890 sles11sp4_jeos-1234567890-oracle01   sles11sp4_jeos
sles12sp3-0.0.11          sles12sp3-0.0.11-stnd-linux01        sles12sp3         0.0.11
win2016std_desk-0.4.56    win2016std_desk-0.3.33-stnd-win01    win2016std_desk   0.3.33
win2016std_desk-0.4.56    win2016std_desk-0.3.33-stnd-sql01    win2016std_desk   0.3.33
win2012r2std_desk-0.1.23  win2012r2std_desk-0.1.23-stnd-win01  win2012r2std_desk 0.1.23
win2016std_desk-0.3.45    win2016std_desk-0.3.45-stnd-sql01    win2016std_desk   0.3.45

1 Comment

I'll take a look at the join-object method as I have not used it before.. Right now comparing the arrays rather than looping through them seems to work very quickly so I'll stick with that method (I updated my original post with the working code). Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.