Сценарий Powershell извлекает членов группы AD - находит время последнего входа для каждого пользователя
Я пытаюсь создать скрипт, который будет извлекать список членов группы из AD и запускать цикл foreach, чтобы определить, когда в последний раз каждый пользователь входил в тот или иной контроллер домена. Я получил часть кода для самой последней меры здесь. Я хотел бы, чтобы скрипт выполнялся через цикл foreach и печатал samAccountName (имя пользователя) и отметку времени последнего входа в систему (последнее измерение) для каждого пользователя в группе, но до сих пор не смог заставить его работать. Я думаю, что у меня что-то не так в логике, но я не могу понять это. Любая помощь приветствуется, спасибо.
# 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
1 ответ
Эта часть конвейера не имеет смысла:
| 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
) соответствует этому свойству в любом случае
В дополнение к этому, я бы, вероятно, немного изменил логику, чтобы вы не выполняли 1 LDAP-запрос на DC на пользователя. Если у вас 5 контроллеров домена и 200 пользователей, то теперь 1000 отдельных запросов к службе каталогов.
Вы можете просто получить ВСЕХ пользователей от каждого DC в одном запросе, используя -LdapFilter
параметр с 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, который имеет LastLogon
значение атрибута на этом конкретном DC (вы на самом деле не заинтересованы в $null
-значения в любом случае, верно?)