Eldo.Ob Eldo.Ob - 7 days ago 6
JSON Question

Check if array of hashtables contains a hashtable

I'm collecting data from a JSON file with the cmdlet

ConvertFrom-Json
. That works so far. The JSON contains an array of hashtables.

[
{
"userSamAccountName": "jodoe",
"QuotaGroup": "AD-Group-Contoso-1"
},
{
"userSamAccountName": "jodoe",
"QuotaGroup": "AD-Group-Contoso-2"
},
{
"userSamAccountName": "frmark",
"QuotaGroup": "AD-Group-Contoso-1"
},
{
"userSamAccountName": "frmark",
"QuotaGroup": "AD-Group-Contoso-2"
}
]


Now I have another array of hashtables containing some overlapping data.

[
{
"userSamAccountName": "jodoe",
"QuotaGroup": "AD-Group-Contoso-1"
},
{
"userSamAccountName": "jodoe",
"QuotaGroup": "AD-Group-Contoso-2"
},
{
"userSamAccountName": "niwellenstein",
"QuotaGroup": "AD-Group-Contoso-1"
},
{
"userSamAccountName": "niwellenstein",
"QuotaGroup": "AD-Group-Contoso-2"
}
]


I'd like to combine them without getting duplicates.

I tried some cmdletys like
select -Unique
and
.Contains()
but it don't work like I want it to work.

Background: I got a range of AD groups. In this groups users are only allowed to be member of one group - e.g.: jodoe can be member of AD-Group-Contoso-1 or AD-Group-Contoso-2 but not to both of them. And I need to report them.
The report-file will be processed by a scheduled task which reports them to the admins. The first script runs every 20 minutes and the report-scheduled-task which processes the report-file from the first script runs once a day - so I don't want to have duplicates in my report file.

Here is my code what I tried so far:

# Group users in list to check if user is in 2 or more Groups #
$reportDuplicates = $adUserlist |
group -Property userSamAccountName |
? { $_.Count -gt 1 }
# only select the group of the duplicates #
# $reportDuplicates.Group corresponds to the Json File #
$reportDuplicates = $reportDuplicates.Group

$reportPath = "C:\\temp\\reports\\"
$reportDuplicatesPath = $reportPath + "reportADDuplicates.json"

# Check if file already exists #
if (Test-Path $reportDuplicatesPath) {
# load existing reports #
$existingDuplicatesReport = Get-Content $reportDuplicatesPath |
ConvertFrom-Json
$reportDuplicates.ForEach({
if ($existingDuplicatesReport.Contains($_)) {
$existingDuplicatesReport.Add($_)
}
})
# convert to JSON and save in file #
$existingDuplicatesReport | ConvertTo-Json | Out-File $reportDuplicatesPath
} else {
# convert to JSON and save in file #
$reportDuplicates | ConvertTo-Json | Out-File $reportDuplicatesPath
}


But it won't work, I got the feeling, that I can't check if an array of hashtables contains a hashtable?

If I push them all into the array and do a
select -Unique
I only get the first entry of the array of hashtables.

Answer

Tell Select-Object on which keys of the nested hashtables you want to establish uniqueness:

$arr1 = $json1 | ConvertFrom-Json
$arr2 = $json2 | ConvertFrom-Json

$arr1 + $arr2 | Select-Object -Unique 'userSamAccountName', 'QuotaGroup'