【问题标题】:Export all AD account which has not authenticating in All AD domain controllers?导出所有 AD 域控制器中未认证的所有 AD 帐户?
【发布时间】:2023-02-25 02:35:54
【问题描述】:

我想列出所有域控制器中根本没有经过身份验证的用户帐户。从不登录所有域控制器意味着在 LastLogon 属性中没有设置日期。

例子:

I have 36 DCs in total
User1 has LastLogonDate in DC1 and 2 --> do not show this user.
User2 has LastLogonDate in DC2 only --> do not show this user.
User3 has LastLogonDate in DC32 only --> do not show this user.

User4 has no LastLogonDate value in all 36 dcs --> this is the user to be added into the .CSV file.
User5 has no LastLogonDate value in all 36 dcs --> this is the user to be added into the .CSV file.

如何修改该功能,使其仅显示或导出 AD 用户帐户,其中最后一次登录返回或所有 $allDCs 中的 '1/01/1601 11:00:00 AM' | ForEach 对象循环?

不知何故,下面的脚本仍然返回或显示仅登录一个 AD 域控制器的帐户。

我拥有的 AD 域控制器总数是 36,所以当 AD 帐户没有在所有 36 个 DC 中填充上次登录日期时,这就是我想要的。

Function Get-ADLastLogonNever {
[CmdletBinding()]
Param (
    [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
    [ValidateNotNullOrEmpty()]
    [String]$SAMAccountName
)
    Begin {
        $allDCs = Get-ADDomainController -Filter *
    }
    Process {
        $neverLoggedOn = $true
        ForEach ($dc in $allDCs) {
            $adUser = Get-ADUser -Identity $SAMAccountName -Properties LastLogon, DisplayName -Server $dc.Name
            If ($_.lastLogon -gt 0) {
                $neverLoggedOn = $false
                Break
            }
        }
        If ($neverLoggedOn) {
            $adUser | Select-Object -Property `
                SamAccountName,
                DisplayName,
                @{n = 'DC'; e = {'<All>'}},
                @{n = 'LastLogon'; e = {'<Never>'}}
        }
    }
}

'IT Team', 'Finance Team', 'HR Team' |
    Get-ADGroupMember |
    Get-ADLastLogonNever |
    Export-Csv -Path C:\result.csv -NoTypeInformation

谢谢。

【问题讨论】:

  • 你真的应该在这里使用广告过滤器

标签: powershell active-directory


【解决方案1】:

以下是this answer中使用的代码稍作修改,应该可以帮助你找到所有从未登录过的用户这是一个memberOf任何目标群体。

使用 AD Filter 是解决这个问题的方法,过滤不应该尽可能用 完成。

$AllDCs = Get-ADDomainController -Filter *
$logons = @{}

# filter those objects being a `memberof` these groups
$groupFilter = '(|'
'IT Team', 'Finance Team', 'HR Team' | Get-ADGroup | ForEach-Object {
    $groupFilter += '(memberOf={0})' -f $_.DistinguishedName
}
$groupFilter += ')'

$params = @{
    LDAPFilter = -join @(
        "(&"                                                 # AND, all conditions must be met
            "(!samAccountName=krbtgt)"                       # exclude krbtgt from this query
            "(!samAccountName=Guest)"                        # exclude Guest from this query
            "(userAccountControl:1.2.840.113556.1.4.803:=2)" # object is Disabled
            "(|"                                             # OR, any of the conditions must be met
                "(!lastLogon=*)"                             # lastLogon is not set
                "(lastLogon=0)"                              # never logged on
            ")"                                              # close OR clause
            $groupFilter                                     # object is a member of any of the target Groups
        ")"                                                  # close AND clause
    )
    Properties = 'lastLogon', 'DisplayName'
}

foreach($DC in $AllDCs) {
    $params['Server'] = $DC

    foreach($user in Get-ADUser @params) {
        # if this user has not yet been hashed
        if(-not $logons.ContainsKey($user.DistinguishedName)) {
            # use its DN as Key and the value holds the instance and the counter
            $logons[$user.DistinguishedName] = @{
                Counter  = 1
                Instance = $user
            }
            continue
        }
        # if this user has been hashed before we only need to increase the counter
        $logons[$user.DistinguishedName]['Counter']++
    }
}

# for all collected users, filter them where the Counter equals to the amount of DCs
# meaning, they were found having the same LastLogon condition in all
$logons.Values | Where-Object { $_['Counter'] -eq $AllDCs.Count } | ForEach-Object {
    # here you can construct your desired output
    $instance = $_.Instance

    [PSCustomObject]@{
        Name              = $instance.Name
        SamAccountName    = $instance.SamAccountName
        DistinguishedName = $instance.DistinguishedName
        DisplayName       = $instance.DisplayName
        lastLogon         = [datetime]::FromFileTimeUtc($instance.lastLogon).ToString('u')
    }
} | Export-CSV C:
esult.csv -NoTypeInformation

【讨论】:

    【解决方案2】:

    我会将 adUser 变量替换为:

    $adUser = Get-ADUser -Identity $SAMAccountName -Properties LastLogonDate, DisplayName -Server $dc.Name | ? {$_.LastLogonDate -eq $null}
    

    然后对于下面的检查只需将其更改为:

    if ($adUser -ne $null){
        $neverLoggedOn = $false
        break
    }
    

    如果我错了,请有人纠正我,但是,我很确定您甚至不需要循环来检查每个 DC,因为 lastlogondate 属性应该在整个域中复制。但是,如果您坚持这样做,并且正在使用 PowerShell Core,我建议使用 -Parallel 参数运行您的 ForEach

    【讨论】:

    • lastlogondate 不是 AD 属性,lastlogontimestamp 是,是的,它被复制但不准确。 “域功能级别提升后的初始更新计算为 14 天减去 5 天的随机百分比。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多