Powershell - сопоставить с Containskey и установить значение хеш-таблицы не работает
Я работаю над сценарием Ричарда Л. Мюллера, чтобы отключить неактивную учетную запись в нашей 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)
}
}
}
Теперь у меня самая последняя дата LastLogon моих пользователей AD.
Тогда я делаю:
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)
}
Я не использую это для отключения идентификатора, потому что LastLogonTimeStamp имеет задержку обновления с 9-14 дней. И с реальной датой последнего входа в систему в $arrUsers я хотел бы заменить LastLogonTimeStamp на нее. Поэтому я хочу сопоставить их, используя идентификатор пользователя:
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"
}
У меня есть 2 проблемы здесь.
- Во-первых, "If ($arrUsers.ContainsKey("$inuser.samAccountName"))" не работает. Я всегда получаю ложный результат.
- Во-вторых, чтобы заменить LastLogonTimeStamp, используя "$inuser.LastLogonTimeStamp = $arrUsers["$inuser.samAccountName"]", мой LastLogonTimeStamp станет пустым.
Может ли кто-нибудь предоставить несколько помощников?
2 ответа
Я решил это, назначив значение samAccountName другой переменной:
$tmpAccountName = $inuser.samAccountName
затем
If ($arrUsers.ContainsKey("$tmpAccountName"))
вместо того, чтобы бросить $inuser.samAccountName непосредственно в проверку. Не уверен, почему это не может быть прочитано напрямую, однако, по крайней мере, теперь это решается =). То же самое касается проблемы № 2.
Вы не используете расширение переменной правильно. Свойства объекта не раскрываются, поэтому
"$inuser.samaccountname"
на самом деле:
$inuser.ToString() + ".samaccountname"
Чтобы развернуть выражение в строке, вы должны окружить его $()
например,
"$($inuser.samaccountname)"
В вашем случае, однако, вам даже не нужно это делать. Оставьте цитаты полностью:
$arrusers[$DN]
$arrusers.ContainsKey($inuser.samaccountname)
Подробности смотрите в разделе справки about_Quoting_Rules.