跨域Get-ADUser-需要帮助 [英] Get-ADUser across domains - Help needed

查看:68
本文介绍了跨域Get-ADUser-需要帮助的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码

$FilePath_Prefix = "C:\temp\UserLastLogon-" 

function Msg ($Txt="") { 
    Write-Host "$([DateTime]::Now)    $Txt" 
} 

#Cycle each DC and gather user account lastlogon attributes 
$List = @() #Define Array 
(Get-ADDomain).ReplicaDirectoryServers | Sort | % { 
    $DC = $_ 
    Msg "Reading $DC" 
    $List += Get-ADUser -Server $_ -Filter "samaccountname -like '*'" -Properties LastLogon |
             Select samaccountname, lastlogon, @{n='DC';e={$DC}} 
} 

Msg "Sorting for most recent lastlogon" 

$LatestLogOn = @() #Define Array 
$List | Group-Object -Property samaccountname | % { 
    $LatestLogOn += ($_.Group | Sort -prop lastlogon -Descending)[0] 
} 

$List.Clear() 
$FileName = "$FilePath_Prefix$([DateTime]::Now.ToString("yyyyMMdd-HHmmss")).csv" 

try { 
    $LatestLogOn |
        Select samaccountname, lastlogon,
            @{n='lastlogondatetime';e={[datetime]::FromFileTime($_.lastlogon)}}, DC |
        Export-CSV -Path $FileName -NoTypeInformation -Force
    Msg "Exported results. $FileName" 
} catch { 
    Msg "Export Failed. $FileName" 
}

我用它来查询AD用户有关我所有域中最新的lastLogon信息。 。它可以正常工作,而且运行起来非常快。

I use it to interrogate AD Users for most up-to-date lastLogon information across all my domains. It works, and it works really fast.

现在,我需要在输出中获取更多详细信息,例如 givenName 姓氏可以说。
达到此目的的最佳方法是什么,因为我不想冗余询问所有DC的此类属性。

Now, I need to get more details into my output, such as givenName and Surname lets say. What would be the best approach to achieve this, because I don't want to interrogate redundantly all my DC's for those kind of attributes.

我的想法在这里,是用 Get-ADuser -Filter * -Properties namedName,surname等创建另一个数组。 code>然后将两个数组绑定在一起。而且我似乎没有做好。有人可以帮忙,或者指向正确的方向来完成此任务。

My idea here, is to create another array with Get-ADuser -Filter * -Properties givenName, surname, etc..etc and then bind together the two arrays. And I don't seem to get it right. Could someone help, or point me in the right direction to achieve this task.

推荐答案

我将获取所有最近的登录信息,然后将其保存到用于快速查找的哈希表中。我会尝试这样的事情:

I would fetch all the last logon information and save it into a hash table, which is designed for fast lookups. I'd try something like this:

$FileName = 'C:\temp\UserLastLogon-{0:yyyyMMdd-HHmmss}.csv' -f [DateTime]::Now
$DCs = (Get-ADDomain).ReplicaDirectoryServers | Sort-Object

# This *may* be more semantically accurate; I don't remember how it works with multiple domains
# $DC = Get-ADDomainController -Filter * | Select-Object -ExpandProperty HostName | Sort-Object

# Create the hash table
$UserLogonInfo = @{}

foreach ($DC in $DCs) {
    Write-Host "Reading logon data from $DC..."
    # Fetch all users that have a LastLogon value from the current DC
    # We specify LastLogon>=1 because some users that never log on have LastLogon of
    # 0 or null, both of which would show up as Jan 1, 1601.
    Get-ADUser -Server $DC -LDAPFilter '(LastLogon>=1)' -Properties LastLogon | ForEach-Object {
        if (!$UserLogonInfo.ContainsKey($_.DistinguishedName)) {
            # If the accountname doesn't exist, add it
            $UserLogonInfo[$_.DistinguishedName] = @{
                LastLogon         = $_.LastLogon
                LastLogonDateTime = ([DateTime]::FromFileTime($_.LastLogon))
                LastLogonDC       = $DC
            }
        }
        elseif (($UserLogonInfo[$_.DistinguishedName].LastLogon -lt $_.LastLogon)) {
            # If the account name exists, update it if it's more recent
            $UserLogonInfo[$_.DistinguishedName] = @{
                LastLogon         = $_.LastLogon
                LastLogonDateTime = ([DateTime]::FromFileTime($_.LastLogon))
                LastLogonDC       = $DC
            }
        }
    }
}

Write-Host "Fetching user data..."
Get-ADUser -Filter * -Properties LastLogon, givenName, surname |
    Select-Object -Property SamAccountName, givenName, surname,
        @{n='LastLogonDateTime';e={$UserLogonInfo[$_.DistinguishedName].LastLogonDateTime}},
        @{n='LastLogonDC';e={$UserLogonInfo[$_.DistinguishedName].LastLogonDC}} |
    Export-CSV -Path $FileName -NoTypeInformation -Force

如果帐户中有空白 LastLogonDateTime 和空白的 LastLogonDC ,则该帐户从未登录过。

If an account has a blank LastLogonDateTime and blank LastLogonDC, then that account has never logged on.

使用 DistinguishedName 代替 SamAccountName 作为的密钥更为正确$ UserLogonInfo 哈希表,如果您一次查询多个域,则本质上这是必需的更改。请注意,我确实是指多个域,而不仅仅是同一个域中的多个域控制器(这是我认为尽管有标题却实际上在做的事情)。

It's more correct to use DistinguishedName instead of SamAccountName as the key for the $UserLogonInfo hash table, and that is essentially a required change if you are querying multiple domains at once. Note that I do mean multiple domains and not merely multiple domain controllers in the same domain (which is what I believe you're actually doing in spite of the question title).

在我的域中,拥有3个DC和大约10,000个用户的整个过程大约需要15秒。

This whole process on my domain with 3 DCs and ~10,000 users takes about 15 seconds.

有种 ton 方式可以使LastLogon不准确。可以在没有完整登录或没有交互式登录的情况下进行更新,并且某些登录不会强制更新该字段。如果您真的想跟踪登录,则应该对登录事件使用安全审核。

Note that there are a ton of ways that LastLogon can be inaccurate. It can be updated without a full logon or without an interactive logon and some logons won't force an update of the field. If you really want to track logons, you should use security auditing for logon events.

编辑:

当我们填充 $ UserLogonInfo 时,我们将获取所有帐户,除了没有的帐户LogonDate 属性,或者该属性为0或null时。这些都表明没有登录。因此,我们知道,任何不在 $ UserLogonInfo 哈希表中的用户都从未登录过。

When we populate $UserLogonInfo we're fetching all accounts except for accounts that either don't have a LogonDate attribute at all or when that attribute is 0 or null. Each of those indicate that there has been no login. So, we know that any user that isn't in the $UserLogonInfo hash table has never logged in.

如果要在用户帐户从未登录时使用一些特殊值,则应仅使用 if 语句并检查用户是否在<$中c $ c> $ UserLogonInfo 哈希表:

If you want to use some special value for when a user account has never logged on, you should just use an if statement and check to see if the user is in the $UserLogonInfo hash table:

Get-ADUser -Filter * -Properties LastLogon, givenName, surname |
    Select-Object -Property SamAccountName, givenName, surname,
        @{n = 'LastLogonDateTime'; e = {if ($UserLogonInfo.ContainsKey($_.DistinguishedName)) { $UserLogonInfo[$_.DistinguishedName].LastLogonDateTime } else { 'Never' }}},
        @{n = 'LastLogonDC'; e = {if ($UserLogonInfo.ContainsKey($_.DistinguishedName)) { $UserLogonInfo[$_.DistinguishedName].LastLogonDC } else { 'N/A' }}} |
        Export-CSV -Path $FileName -NoTypeInformation -Force

这篇关于跨域Get-ADUser-需要帮助的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆