0

我正在尝试创建一个脚本,该脚本将从 AD 中提取组成员列表并运行 foreach 循环以确定每个用户最后一次登录任何给定域控制器的时间。我在这里得到了一些最新测量功能的代码。我想让脚本通过 foreach 循环运行,并为组中的每个用户打印 samAccountName(用户名)和最后登录时间戳(measure-latest),但到目前为止还不能让它工作。我认为我的逻辑有问题,但我似乎无法弄清楚。任何帮助表示赞赏,谢谢。

# Get a list of last login times for a group of users
# Script Requires Quest Cmdlet features: https://support.software.dell.com/activeroles-server/download-new-releases
Add-PSSnapin Quest.ActiveRoles.ADManagement

# filter out $nulls and produce the latest of them
function Measure-Latest {
    BEGIN { $latest = $null }
    PROCESS {
            if (($_ -ne $null) -and (($latest -eq $null) -or ($_ -gt $latest))) {
                $latest = $_ 
            }
    }
    END { $latest }
}

# Get list of group users by username
Get-ADGroupMember -identity "Domain Admins" | select samAccountName | Export-csv -path C:\Scripts\UserInformationByGroup\Groupmembers.csv -NoTypeInformation

# Get list of users from group, assign user value
$userlist = import-csv C:\Scripts\UserInformationByGroup\Groupmembers.csv
$user = $userlist | Select samAccountName

# Loop through list of users and print Username ------ Last Login time 
foreach ($user in $userlist) {
Get-QADComputer -ComputerRole DomainController | foreach {
(Get-QADUser -Service $_.Name -SamAccountName $user).LastLogon
} | Measure-Latest $samAccountName | out-file -filepath C:\Scripts\UserInformationByGroup\userListLastLogin.txt -append
}

我应该提到,当我像这样运行脚本时,只需手动输入每个用户名,它就可以工作并打印最后一次登录时间:

Add-PSSnapin Quest.ActiveRoles.ADManagement

function Measure-Latest {
    BEGIN { $latest = $null }
    PROCESS {
            if (($_ -ne $null) -and (($latest -eq $null) -or ($_ -gt $latest))) {
                $latest = $_ 
            }
    }
    END { $latest }
}
Get-QADComputer -ComputerRole DomainController | foreach {
(Get-QADUser -Service $_.Name -SamAccountName USER_NAME_HERE).LastLogon
} | Measure-Latest
4

1 回答 1

0

管道的这一部分没有意义:

| Measure-Latest $samAccountName |

由于没有为变量分配任何内容$samAccountName

您需要为您的函数添加管道支持,如下所示:Measure-Latest

function Measure-Latest {
  [CmdletBinding]
  param(
    [parameter(ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
    $LastLogon
  )

  # rest of the script (begin-process-end blocks) goes here
}

LastLogon现在您可以将值直接通过管道传递给函数:

(Get-QADUser -SamAccountName $user).LastLogon |Measure-Latest | Out-File #or whatever

多亏了该ValueFromPipelineByPropertyName标志,您现在还可以将整个对象通过管道传递给函数:

Get-QADUser -SamAccountName $user | Measure-Latest

因为参数名称 ( $LastLogon) 无论如何都匹配该属性


除此之外,我可能会稍微更改逻辑,这样您就不会为每个用户的每个 DC 执行 1 个 LDAP 查询。如果您有 5 个域控制器和 200 个用户,那么现在对目录服务有 1000 个单独的查询。

您可以在单个查询中使用以下-LdapFilter参数简单地检索每个 DC 中的所有用户Get-QADUser

$LDAPClauses = @()

foreach($user in $userlist){
  $LDAPClauses += "(samaccountname={0})" -f $user
}

# The | in an LDAP filter means logical OR
$LDAPFilter = "(&(LastLogon=*)(|$(-join($LDAPClauses))))"

现在您可以对每个 DC 运行一个查询:

Get-QADUser -LdapFilter $LDAPFilter

并且它将检索 $userlist 中在该特定 DC 上具有属性值的所有用户(无论如何,您对-valuesLastLogon并不真正感兴趣,对吧?)$null

于 2015-01-24T17:38:17.747 回答