The following code is trying to do one thing. Its trying to find IDs that have been added to an Active Directory group since the last time the job was run.
It does this by reading the user IDs from an Active Directory group and compares them against the IDs it saved in a file the day before.
I first read the AD group into a hashtable ($ADUsersHashtable) I then read the file into a similar hashtable ($YesterdaysADUsersFile) Both hashtables use the UserID as the key. I then check to see if each ID in $ADUsersHashtable is in $YesterdaysADUsersFile. An ID that is in $ADUsersHashtable but not in $YesterdaysADUsersFile is an ID that was added to AD since the last time this job ran.
The problem is, if $YesterdaysADUsersFile has more than one entry in it, the containskey method always returns true (see output below)
If I delete all but one entry in the file, the code works as expected.
If i have more than one entry in the file the code doesn't work as expected.
The following is the code that reads AD and the file into the hashtables and then compares the keys.
$scriptName = $MyInvocation.MyCommand.Name
$LogFile = "D:\Polarion\data\logs\User Access Dates\$scriptName.log"
$Today = Get-Date
$outDate = get-date -format "yyyy-MM-dd"
Add-content $LogFile "$Today Running $scriptName"
$MyServer = $env:computername
Add-content $LogFile "`t$Today Running on $MyServer"
#Will be populated with IDs from AD that i didn't find yesterday
$NewUsersFile = "D:\Polarion\data\logs\User Access Dates\NewUsersInPEALM_ALL_USERSADGroup.txt"
clear-content $NewUsersFile #I only want the new users from todays AD group.
$ADUsersHashtable = @{} #Contains IDs of the members in the AD Group.
Get-ADGroupMember -Identity PEALM_ALL_USERS -Recursive `
| Get-ADObject -Properties SamAccountName, mail `
| select SamAccountName, mail `
| foreach {$ADUsersHashtable.Add($_.SamAccountName, $_.mail)}
#$ADUsersHashtable
$YesterdaysADUsersFile = "D:\Polarion\data\logs\User Access Dates\UserIdFromPEALM_ALL_USERS.txt" #Contains the IDs that I knew about the last time this ran.
$YesterdaysADUsersHashTable = @{}
$YesterdaysADUsersHashTable = Get-Content($YesterdaysADUsersFile) |
foreach {$_.ToString().Replace(":", "=")} |
ConvertFrom-StringData
$YesterdaysADUsersHashTable
$NoNewUsersFound = $true
foreach ($UserIDFromAD in $ADUsersHashtable.keys){ #For each user ID in Todays AD group
if ($YesterdaysADUsersHashTable.containsKey($UserIDFromAD)){ #If the UserID is in Yesterdays list ignore it.
write-host YesterdaysADUsersHashTable contains key $UserIDFromAD
} else {
$NoNewUsersFound = $false
write-host YesterdaysADUsersHashTable Doesnt contains key $UserIDFromAD
write-host "`tadding $UserIDFromAD to the $NewUsersFile file."
Add-content $LogFile "`t$Today Adding $UserIDFromAD to $NewUsersFile file"
Add-Content $NewUsersFile "$UserIDFromAD : $outDate" #if its not in yesterdays list write it to the new users file.
}
}
if ($NoNewUsersFound){
Add-content $LogFile "`t$Today No new users IDs found in Active Directory."
}
#Clear-Content $YesterdaysADUsersFile #we want to overwrite the file, not append to it.
#$ADUsersHashtable.keys `
# | %{ Add-Content $YesterdaysADUsersFile "$_ : $($ADUsersHashtable.$_)" } #writes the content of the hashtable to a file.
The following is the output when the file (and hence $YesterdaysADUsersHashTable) has two entries in it. The first four lines are the dump of $YesterdaysADUsersHashTable. The next five lines are from the output from the write-host commands in the if-containskey block. They show that hashtable.containskey is returning true for every key in $ADUsersHashtable. But those keys are not in $YesterdaysADUsersHashTable, this is what i don't understand.
Name Value
---- -----
QZMRW2 [email protected]
dzrbcn [email protected]
YesterdaysADUsersHashTable contains key QZMRW2
YesterdaysADUsersHashTable contains key dzrbcn
YesterdaysADUsersHashTable contains key MZDP2G
YesterdaysADUsersHashTable contains key BZ5LBQ
YesterdaysADUsersHashTable contains key FZ080Y
$YesterdaysADUsersHashTable clearly doesn't contain "MZDP2G", "BZ5LBQ", or "FZ080Y"
And, if I remove everything from the file except one user ID, the code seems to work. $YesterdaysADUsersHashTable now has only one entry "QZMRW2" and the code seems to work.
Name Value
---- -----
QZMRW2 [email protected]
YesterdaysADUsersHashTable contains key QZMRW2
YesterdaysADUsersHashTable Doesnt contains key dzrbcn
adding dzrbcn to the D:\Polarion\data\logs\User Access Dates\NewUsersInPEALM_ALL_USERSADGroup.txt file.
YesterdaysADUsersHashTable Doesnt contains key MZDP2G
adding MZDP2G to the D:\Polarion\data\logs\User Access Dates\NewUsersInPEALM_ALL_USERSADGroup.txt file.
YesterdaysADUsersHashTable Doesnt contains key BZ5LBQ
adding BZ5LBQ to the D:\Polarion\data\logs\User Access Dates\NewUsersInPEALM_ALL_USERSADGroup.txt file.
YesterdaysADUsersHashTable Doesnt contains key FZ080Y
I am clearly not understanding somehting.
Any suggestions would be greatly appreciated.
Just because a key exists doesn't mean that the corresponding value is not
$null.See below for an example:
Without details about how you populate your hashtables it's hard to say why :)