代码之家  ›  专栏  ›  技术社区  ›  nlks

Powershell-与Containsky匹配&哈希表的设置值不起作用

  •  3
  • nlks  · 技术社区  · 10 年前

    我正在编写一个脚本 Richard L. Mueller 禁用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)
            }
        }
    }
    

    现在我有了我的AD用户的最新LastLogon日期。

    然后我做了:

    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)
    }
    

    我不使用此选项来禁用ID,因为LastLogonTimeStamp的更新延迟为9-14天。而对于$arrUsers中的实际最后登录日期,我希望用它替换LastLogonTimeStamp。因此,我希望使用用户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"
        }
    

    我这里有两个问题。

    1. 首先,“If($arrUsers.ContainsKey(“$inuser.samAccountName”)”似乎不起作用。我总是得到错误的结果。
    2. 其次,要使用“$inuser.LastLogonTimeStamp=$arrUsers[”$inuser.samAccountName“]”替换LastLogonTimeStamp,我的LastLogonTime Stamp将变为空白。

    有人能提供一些助手吗?

    2 回复  |  直到 10 年前
        1
  •  10
  •   Aaron Jensen    10 年前

    您没有正确使用变量扩展。对象财产未展开,因此

    "$inuser.samaccountname"
    

    实际上是:

    $inuser.ToString() + ".samaccountname"
    

    要在字符串中展开表达式,必须将其括起来 $() ,例如。

    "$($inuser.samaccountname)"
    

    然而,在你的情况下,你甚至不需要这样做。完全保留引号:

    $arrusers[$DN]
    $arrusers.ContainsKey($inuser.samaccountname)
    

    请参见 about_Quoting_Rules help topic for details .

        2
  •  1
  •   nlks    10 年前

    我通过将samAccountName值分配给另一个变量来解决这个问题:

    $tmpAccountName = $inuser.samAccountName
    

    然后

    If ($arrUsers.ContainsKey("$tmpAccountName"))
    

    而不是将$inuser.samAccountName直接抛出到检查中。不太确定为什么不能直接读取,但至少现在已经解决了=)。问题#2也是如此。