Vergelijk Arrays Gemakkelijk met PowerShell

Met behulp van wat PowerShell-kung-fu kun je gemakkelijk Powershell-arrays van allerlei soorten objecten vergelijken. Er zijn veel verschillende scenario’s waarin je jezelf kunt bevinden, dus laten we eens kijken hoe we PowerShell kunnen gebruiken om arrays te vergelijken.

Om de beste manier te bepalen om arrays te vergelijken, moet je eerst uitvinden welke soorten elementen beide arrays bevatten.

  • Bevatten beide arrays allemaal hetzelfde type objecten?
  • Hebben beide arrays hetzelfde aantal elementen?
  • Zijn er verschillende soorten objecten in elke array?

Je moet het antwoord op elk van deze vragen weten voordat je nauwkeurig arrays kunt vergelijken. Laten we elk scenario behandelen.

Arrays van strings vergelijken

Een van de gemakkelijkste manieren om arrays met PowerShell te vergelijken, is als je twee arrays hebt die alleen strings bevatten. Wanneer je jezelf in deze positie bevindt, heb je een paar verschillende manieren om de strings in de arrays te vergelijken.

Gebruik van de -Contains of -In Operators

De -contains-operator is een PowerShell-operator waarmee je kunt controleren of een object zich in een verzameling bevindt. De -contains-operator begrijpt van nature geen verzamelingen, maar je kunt code schrijven om dit voor je te laten werken.

Laten we zeggen dat een verzameling (array) vier strings bevat zoals hieronder.

$array = @('blue','red','purple','pink')

De -contains-operator werkt door te controleren of een enkele string zich in die array bevindt, zoals dit:

$array -contains 'pink'

Wanneer de collectie aan de linkerkant die string bevat, zal PowerShell True retourneren. Zo niet, dan retourneert het False.

PowerShell -contains Operator

We kunnen arrays vergelijken met de -contains-operator door elke string in een array te lezen en te controleren of de andere array die string bevat.

Stel dat ik twee arrays wil vergelijken om te zien welke strings in de eerste array voorkomen in de tweede array.

$array = @('blue','red','purple','pink')
$array2 = @('brown','red','black','yellow')

$array | ForEach-Object {
    if ($array2 -contains $_) {
        Write-Host "`$array2 contains the `$array1 string [$_]"
    }
}

Je kunt ook de -in-operator gebruiken, die identiek is aan de -contains-operator, maar de syntaxis is omgekeerd. Bij het gebruik van de -contains-operator wordt de array gedefinieerd aan de linkerkant. Bij het gebruik van de -in-operator wordt de array gedefinieerd aan de rechterkant zoals hieronder:

$array | ForEach-Object {
    if ($_ -in $array2) {
        Write-Host "`$array2 contains the `$array1 string [$_]"
    }
}

Met Where-Object

Je kunt ook de Where-Object-cmdlet gebruiken om alle strings in de ene array in de andere te retourneren, zoals hieronder.

$array | Where-Object -FilterScript { $_ -in $array2 }

Met de Compare-Object Cmdlet

Je kunt ook PowerShell gebruiken om arrays te vergelijken met behulp van de Compare-Object-cmdlet. Deze cmdlet neemt een referentieobject en een verschilobject en retourneert een zijindicator die aangeeft welke elementen wel en niet in beide arrays voorkomen.

Compare-Object -ReferenceObject $array -DifferenceObject $array2
Using Compare-Object

Je kunt hieronder zien dat de Compare-Object-cmdlet je in staat stelt beide arrays tegelijkertijd te vergelijken. Als de eigenschap SideIndicator => is, betekent dit dat de waarde van InputObject in de DifferenceObject voorkomt en niet in de ReferenceObject, en vice versa voor de <= SideIndicator.

Standaard retourneert Compare-Object verschillen. Je kunt ook alle strings in elke array retourneren die in beide voorkomen door de IncludeEqual-parameter te gebruiken.

Comparing arrays with Compare-Object

Vergelijken van Arrays van Complex Objects

Simpel genoeg, toch? Laten we nu objecten erbij betrekken. Stel dat we een veld hebben in deze HR-database van ons en we willen dit veld invullen in het Active Directory-omschrijvingsveld. Voordat we dit doen, moeten we eerst een gemeenschappelijke identificatie hebben. In mijn omgeving is er een werknemersnummer zowel in de HR-database als in de aangepaste Active Directory-attribuut. Laten we proberen dit te matchen.

Eerst kijken we wat er gebeurt als we onze vorige benadering proberen. Hier is het CSV-bestand dat we gebruiken.

CSV output

Zo krijg ik onze twee datasets.

$ad_users = Get-AdUser -Filter {enabled -eq $true} -Properties employeeNumber | select employeenumber,samaccountname,description
$users_from_database = Import-Csv 'database_users.csv' | select employee number

Wat gebeurt er als we deze twee arrays door hetzelfde scenario laten lopen als onze strings? Absoluut niets. Waarom?

De reden is dat je doorgaans niet kunt zeggen $object1 -eq $object2 omdat objecten complexer zijn dan een eenvoudige string, boolean of integer. Er zijn enkele andere omstandigheden waarin dit niet het geval is, maar ik probeer er een gewoonte van te maken om objecteigenschappen te vergelijken; niet hele objecten. Dus in dit geval moeten we iets als dit doen:

$ad_user[0].employeeNumber -eq $users_from_database[0].employeeNumber

Wat is de oplossing? Momenteel heb ik twee oplossingen. Als je met duizenden objecten te maken hebt, is het niet snel maar het werkt. Ik zou graag willen weten of iemand anders nog andere suggesties heeft.

$ad_employee_numbers = $ad_users | % {$_.employeenumber}

## Maak een array van strings van alleen het AD-gebruikers werknemersnummer
$users_from_database | Where-Object -FilterScript { $ad_employee_numbers -contains $_.employeeNumber }

We kunnen ook Compare-Object gebruiken, hoewel dit langzamer is.

$ad_employee_numbers = $ad_users | ForEach-Object {$_.employeenumber}

## Maak een array van strings van alleen het personeelsnummer van de AD-gebruiker
$database_user_employee_numbers = $users_from_database | ForEach-Object {$_.employeenumber}

## Maak een array van strings van alleen het personeelsnummer van de databasegebruiker
(Compare-Object $ad_employee_numbers $database_user_employee_numbers -IncludeEqual | Where-Object -FilterScript {$_.SideIndicator -eq '=='}).InputObject

Conclusie

Er zijn veel verschillende manieren om PowerShell te gebruiken om arrays te vergelijken. Arrays kunnen complex zijn en een grondig begrip van de objecten binnen de arrays zal je enorm helpen om ze te vergelijken.

Source:
https://adamtheautomator.com/powershell-compare-arrays/