Outputting 2 arrays with matching values

Hi guys,

So I have been stuck on a problem and I think I need a bit of guidance in dealing with it.

My issue is that I have two arrays and I need to output an object with elements of both arrays in it. Each Element in both arrays has an opposite element that is similar and I’d like to output each line with the corresponding element… (hope this makes sense)

For Example - consider this below. You will see that each disk has a snapshot with a similar name (I did get this code off the Internet)

$Snapshots = 'Server1_disk1_Snapshot','Server_disk2_Snapshot','Server_disk3_Snapshot','Server_disk4_Snapshot'

$Drives = 'Server1_disk1','Server_disk2','Server_disk3','Server_disk4'

$h = @{}
if ($Drives.Length -ne $Snapshots.Length) {
    Write-Error -Message "Array lengths do not match" `
    -Category InvalidData `
} else {
    for ($i = 0; $i -lt $Drives.Length; $i++) {
    $h[$Drives[$i]] = $Snapshots[$i]
    }
}
Write-Output $h

Now the above gave me a output like:

Name         Value 
----         ----- 
Server_disk4 Server_disk4_Snapshot 
Server_disk3 Server_disk3_Snapshot 
Server_disk6 Server_disk6_Snapshot 
Server_disk5 Server_disk5_Snapshot 
Server_disk2 Server_disk2_Snapshot 
Server1_disk1 Server1_disk1_Snapshot

Id like to be sure that if the order in the array is out, that it displays with the corresponding drive.

Example (note the different position of the Server_disk6 and Server_disk5 in $Drives

 

$Snapshots = 'Server1_disk1_Snapshot','Server_disk2_Snapshot','Server_disk3_Snapshot','Server_disk4_Snapshot','Server_disk5_Snapshot','Server_disk6_Snapshot'

$Drives = 'Server1_disk1','Server_disk2','Server_disk3','Server_disk4','Server_disk6','Server_disk5'

$h = @{}
if ($Drives.Length -ne $Snapshots.Length) {
    Write-Error -Message "Array lengths do not match" `
    -Category InvalidData `
} else {
    for ($i = 0; $i -lt $Drives.Length; $i++) {
    $h[$Drives[$i]] = $Snapshots[$i]
    }
}
Write-Output $h

I get output like

Name         Value 
----         ----- 
Server_disk4 Server_disk4_Snapshot 
Server_disk3 Server_disk3_Snapshot 
Server_disk6 Server_disk5_Snapshot 
Server_disk5 Server_disk6_Snapshot 
Server_disk2 Server_disk2_Snapshot 
Server1_disk1 Server1_disk1_Snapshot

I also considered adding these directly into a hash table without the for statement (I don’t usually use for but as I said, I took this from another source)

But still was not sure as to how to ensure that the elements were “like”

Well it kind of depends on how you gather the data in the first place.
Since I doubt that you’ll use static variables as in the example.

So what you want to do is make sure that you have something that can act as an ID for both arrays.
Instead of iterating through both arrays, you use one as the “key” and the other as a lookup table.
However if the Drives and Snapshots are not called the same except the prefix “_snapshot” you would need some other identifier.
You probably also want to have some sort of check or add information if a snapshot is not found etc.

E.g.
[pre]
$Snapshots = ‘Server1_disk1_Snapshot’,‘Server_disk2_Snapshot’,‘Server_disk3_Snapshot’,‘Server_disk4_Snapshot’,‘Server_disk5_Snapshot’,‘Server_disk6_Snapshot’

$Drives = ‘Server1_disk1’,‘Server_disk2’,‘Server_disk3’,‘Server_disk4’,‘Server_disk6’,‘Server_disk5’

$result = @()

foreach($d in $Drives) {
$snapshot = $Snapshots | Where-Object {$_ -like “$d*”}

$result += [PSCustomObject]@{Drive = $d
                             Snapshot = $snapshot
           }

}
[/pre]

$Snapshots = @(
    'Server1_disk1_Snapshot'
    'Server_disk3_Snapshot'
    'Server_disk4_Snapshot'
    'Server_disk2_Snapshot' # notice order of this array element has changed
)

$Drives = @(                
    'Server_disk4'          # notice order of this array element has changed as well
    'Server1_disk1'
    'Server_disk2'
    'Server_disk3'
)

$myOutput = $Drives | foreach { 
    [PSCustomObject]@{      # I think it's better to return a PS object not a hash table
        Drive    = $_
        Snapshot = $(if ($Snapshots -match $_) {$Snapshots -match $_} else {'No matching snapshots found'} ) 
    }
}

$myOutput | FT -a 

output:

Drive         Snapshot              
-----         --------              
Server_disk4  Server_disk4_Snapshot 
Server1_disk1 Server1_disk1_Snapshot
Server_disk2  Server_disk2_Snapshot 
Server_disk3  Server_disk3_Snapshot 

Perfect.

Sam - thanks for the assistance. Much appreciated.

Fredrik - your explanation makes sense and thanks for taking the time to explain to me how to best handle this in future.

Much appreciated.