3

我正在编写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,我的 LastLogonTimeStamp 变为空白。

有人可以提供一些助手吗?

4

2 回答 2

9

您没有正确使用变量扩展。对象属性没有展开,所以这个

"$inuser.samaccountname"

实际上是:

$inuser.ToString() + ".samaccountname"

要扩展字符串中的表达式,您必须用 将其括起来$(),例如

"$($inuser.samaccountname)"

但是,在您的情况下,您甚至不需要这样做。完全去掉引号:

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

有关详细信息,请参阅about_Quoting_Rules 帮助主题

于 2014-08-31T18:34:31.457 回答
0

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

$tmpAccountName = $inuser.samAccountName

然后

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

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

于 2014-08-19T10:02:57.830 回答