Powershell - match with Containskey & set value of hashtable don't work
Solution 1
I have solved this by assign the samAccountName value to another variable:
$tmpAccountName = $inuser.samAccountName
then
If ($arrUsers.ContainsKey("$tmpAccountName"))
instead of throw the $inuser.samAccountName directly to the checking. Not so sure why it cannot be read directly however at least it is solved now =). Same goes to the problem #2.
Solution 2
You're not using variable expansion correctly. Object properties aren't expanded, so this
"$inuser.samaccountname"
is actually:
$inuser.ToString() + ".samaccountname"
To expand an expression in a string, you must surround it with $()
, e.g.
"$($inuser.samaccountname)"
In your case, however, you don't even need to do that. Leave the quotes out entirely:
$arrusers[$DN]
$arrusers.ContainsKey($inuser.samaccountname)
See the about_Quoting_Rules help topic for details.
nlks
Updated on June 04, 2022Comments
-
nlks about 2 years
I am working on a script by Richard L. Mueller to disable inactive account in our AD.
Trap {"Error: $_"; Break;} $D = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() $Domain = [ADSI]"LDAP://$D" $Searcher = New-Object System.DirectoryServices.DirectorySearcher $Searcher.PageSize = 200 $Searcher.SearchScope = "subtree" $Searcher.Filter = "(&(objectCategory=person)(objectClass=user))" $Searcher.PropertiesToLoad.Add("samAccountName") > $Null $Searcher.PropertiesToLoad.Add("lastLogon") > $Null $Searcher.PropertiesToLoad.Add("accountExpires") > $Null # Create hash table of users and their last logon dates. $arrUsers = @{} # Enumerate all Domain Controllers. ForEach ($DC In $D.DomainControllers) { $Server = $DC.Name $Searcher.SearchRoot = "LDAP://$Server/" + $Domain.distinguishedName $Results = $Searcher.FindAll() #$Results[100].Properties.item("samAccountName") #$Results[100].Properties.item("lastlogon") ForEach ($Result In $Results) { $DN = $Result.Properties.Item("samAccountName") $LL = $Result.Properties.Item("lastLogon") If ($LL.Count -eq 0) { $Last = [DateTime]0 } Else { $Last = [DateTime]$LL.Item(0) } If ($Last -eq 0) { $LastLogon = $Last.AddYears(1600) } Else { $LastLogon = $Last.AddYears(1600).ToLocalTime() } If ($arrUsers.ContainsKey("$DN")) { If ($LastLogon -gt $arrUsers["$DN"]) { $arrUsers["$DN"] = $LastLogon } } Else { $arrUsers.Add("$DN", $LastLogon) } } }
Now I have the most updated LastLogon date of my AD users.
Then I do:
Foreach ($ou in $searchRoot) { $inactiveUsers += @(Get-QADUser -SearchRoot $ou -Enabled -PasswordNeverExpires:$false -CreatedBefore $creationCutoff -SizeLimit $sizeLimit | Select-Object Name,SamAccountName,LastLogonTimeStamp,Description,passwordneverexpires,canonicalName | Sort-Object Name) }
I do not use this to disable the ID because LastLogonTimeStamp has a delay being updated from 9-14 days. And with the real last logon date in $arrUsers, I would like to replace LastLogonTimeStamp with it. So I want to match them using the user ID:
Foreach ($inuser in $inactiveUsers) { If ($arrUsers.ContainsKey("$inuser.samAccountName")) { write-host "True" $inuser.LastLogonTimeStamp = $arrUsers["$inuser.samAccountName"] $inuser.LastLogonTimeStamp = $inuser.LastLogonTimeStamp.adddays(30) If ((Get-Date) -gt $inuser.LastLogonTimeStamp) { write-host $inuser.samAccountName "should be disabled" } Else { write-host $inuser.samAccountName "is still active" } } } Else { write-host "False" }
I have 2 problems here.
- First the "If ($arrUsers.ContainsKey("$inuser.samAccountName"))" doesn't seems working. I always get a false result.
- Second, to replace the LastLogonTimeStamp using "$inuser.LastLogonTimeStamp = $arrUsers["$inuser.samAccountName"]", my LastLogonTimeStamp become blank.
Could someone able to provide some assistants?