powershellforeachwhere-object

Foreach with Where-Object not yielding correct results


I have the following code:

               $ErrCodes = Get-AlarmIDs_XML -fileNamePath $Paper_Dialog_FullBasePath
               $excelDevice = Get_ErrorCodes -errorCodeListFilePath $outFilePath -ws "DEVICE COMPONENT MAP"
               foreach ($errCode in $ErrCodes | Where-Object{$excelDevice.Common_Alarm_Number -eq $errCode.Value }) 
               {
                  #$dataList = [System.Collections.Generic.List[psobject]]::new() 
                  #$resultHelp = [System.Collections.Generic.List[psobject]]::new() 
                  Write-Host "another:"
                  $err = $errCode.Value #get each error code to lookup in mdb file
                  $key = $errCode.Key
                  Write-Host $err
                  ...
                }

But it's definitely getting in the foreach loop when it shouldn't.

My intention is to use the foreach, and if it has a value in the $ErrCodes, then it should continue with the code that follows.

Let me know if you need to see the Functions that do the file reads, but the data structures look like this:

$excelDevice:
[Object[57]]
[0]:@{Common_Alarm_Number=12-2000}
[1]:@{Common_Alarm_Number=12-5707}
[2]:@{Common_Alarm_Number=12-9}
[3]:@{Common_Alarm_Number=12-5703}
...

$ErrCodes:
[Object[7]]
[0]:@{Key=A;Value=12-5702}
[1]:@{Key=B;Value=12-5704}
[2]:@{Key=C;Value=12-5706}
[3]:@{Key=D;Value=12-5707}
...

So we only care about the ones in $ErrCodes that are also in $excelDevice.

When I step through the code, it's getting into the foreach code for 12-5702 for some reason, when it shouldn't be there (prints 12-5702 to screen). I know I wouldn't want 12-5702 to be used because it isn't in $excelDevice list.

How would I get that Where-Object to filter out $ErrCodes that aren't in $excelDevice list? I don't want to process error codes that don't have data for this device.


Solution

  • Right now you're testing whether any of the values in $excelDevice.Common_Alarm_Number (which presumably evaluates to an array) is exactly the same value as all the values in $errCodes.Value - which doesn't make much sense.

    It looks like you'll want to test each error code for whether it is contained in the $excelDevice.Common_Alarm_Number list instead. Use $_ to refer to the individual input items received via the pipeline:

    foreach ($errCode in $ErrCodes | Where-Object{ $excelDevice.Common_Alarm_Number -contains $_.Value }) { ... }