Get-ADUser по нескольким подразделениям и фильтрация результатов

Этот сценарий должен захватить пользователей из нескольких подразделений и назначить пользователей одной переменной, затем он берет пользователей из эта переменная и фильтрует каждую из них на основе дат последнего входа в систему старше 30 дней. Затем он экспортирует в CSV некоторую информацию, которая мне нужна.

Проблема в , когда я добираюсь до части foreach , она выполняет поиск по всему каталогу и не использует пользователей в переменной, которую я предоставил.

Любая критика также приветствуется.

$30days = (get-date).adddays(-30)

$Users1 = Get-ADUser -SearchBase 'OU=Users,OU=US-Location,OU=Americas,DC=Domain,DC=Domain,DC=com' -LdapFilter '(UserPrincipalName=*)(extensionAttribute9=*)'
$Users2 = Get-ADUser -SearchBase 'OU=Users-Remote,OU=US-Location,OU=Americas,DC=Domain,DC=Domain,DC=com' -LdapFilter '(UserPrincipalName=*)(extensionAttribute9=*)'
$Users3 = Get-ADUser -SearchBase 'OU=Contractors,OU=US-Location,OU=Americas,DC=Domain,DC=Domain,DC=com' -LdapFilter '(UserPrincipalName=*)(extensionAttribute9=*)'
$Users4 = Get-ADUser -SearchBase 'OU=Temps,OU=US-Location,OU=Americas,DC=Domain,DC=Domain,DC=com' -LdapFilter '(UserPrincipalName=*)(extensionAttribute9=*)'
$Users5 = Get-ADUser -SearchBase 'OU=Users,OU=US-Location,OU=Americas,DC=Domain,DC=Domain,DC=com' -LdapFilter '(UserPrincipalName=*)(extensionAttribute9=*)'
$Users6 = Get-ADUser -SearchBase 'OU=Users,OU=US-Location,OU=Americas,DC=Domain,DC=Domain,DC=com' -LdapFilter '(UserPrincipalName=*)(extensionAttribute9=*)'

$Users = $Users1,$Users2,$Users3,$Users4,$Users5,$Users6 
$useraccountsover30days = foreach ($user in $($Users)){Get-ADUser -filter {lastlogondate -le $30days} -Properties lastlogondate}

$lastlogonreadable = $useraccountsover30days | Select-Object SamAccountName,lastlogondate

    $lastlogonreadable | Export-Csv C:/Users/myname/Desktop/Usersover30days.csv 
2
задан 9 June 2016 в 02:57
3 ответа

Есть несколько рекомендаций, которые я бы дал вашему текущему скрипту.

Во-первых, один большой запрос почти всегда будет выполнять лучше, чем многие меньшие запросы. Поэтому вместо того, чтобы запускать get-aduser отдельно для каждой целевой OU, я бы объединил их в один вызов, используя в качестве базы поиска общую OU более высокого уровня. Очевидно, что в конечном итоге это может привести к возврату результатов из тех OU, которые вы не хотели включать. Но гораздо быстрее отфильтровать их позже.

Вы также снова вызываете get-aduser для каждого результата из первого набора запросов, чтобы отфильтровать их по lastLogonDate. Но вместо этого Вы можете комбинировать этот фильтр с -ldapfilter из Ваших исходных запросов. Речь идет только о преобразовании версии -filter в эквивалентную -ldapfilter. Секрет в том, чтобы сделать это, заключается в том, чтобы знать, что lastLogonDate - это просто преобразованная версия Powershell атрибута lastLogonTimestamp. И вы можете преобразовать обычное значение Powershell DateTime в формат, который использует lastLogonTimestamp с помощью метода ToFileTime() .

Последнее, что меня смутило, это (UserPrincipalName=*) часть вашего ldapfilter. В каждом домене, к которому я когда-либо прикасался, этот атрибут всегда будет иметь значение (как и SamAccountName или DistinguishedName). Он может отличаться от значения по умолчанию @, но он никогда не будет пустым. Фильтр не обязательно что-то вредит. Для AD это всего лишь одна лишняя вещь, чтобы тратить циклы процессора на оценку, когда в этом нет необходимости. Но если у вас есть основания полагать, что он может быть пустым в вашем окружении, во что бы то ни стало оставьте это в.

Так вот как я изменю ваш сценарий, если правильно понимаю ваши намерения.

# make the comparison value using ToFileTime()
$30daysago = (Get-Date).AddDays(-30).ToFileTime()

# make the combined ldapfilter value
$LdapFilter = "(&(lastLogonTimestamp<=$30daysago)(extensionAttribute9=*)"

# make an array of the OU DNs you care about
$TargetOUs = @()
$TargetOUs += "OU=Users,OU=US-Location,OU=Americas,DC=Domain,DC=Domain,DC=com"
$TargetOUs += "OU=Users-Remote,OU=US-Location,OU=Americas,DC=Domain,DC=Domain,DC=com"
$TargetOUs += "OU=Contractors,OU=US-Location,OU=Americas,DC=Domain,DC=Domain,DC=com"
$TargetOUs += "OU=Temps,OU=US-Location,OU=Americas,DC=Domain,DC=Domain,DC=com"

# define your common search base
$base = "OU=US-Location,OU=Americas,DC=Domain,DC=Domain,DC=com"

# get your combined results and the additional attributes you care about
$OldUsers = get-aduser -ldapfilter $LdapFilter -searchbase $base -pr lastLogonDate

# convert the target OU list into a regular expression we can compare each DN against in a single comparison call
$regex = ""
$TargetOUs | %{ $regex += ".*," + [Regex]::Escape($_) + "$|" }
$regex = $regex.Substring(0,$regex.Length-1)

# filter the results that aren't in your target OUs
# (depending on your OU layout, it might be more efficient to flip this
#  and define the OUs you explicitly want to leave out)
$FilteredUsers = $OldUsers | ?{ $_.DistinguishedName -match $regex }

# export your CSV (sorted for good measure)
$FilteredUsers | select SamAccountName,LastLogonDate | sort LastLogonDate | export-csv C:/Users/myname/Desktop/Usersover30days.csv

P.S. Остерегайтесь относиться к lastLogonTimestamp (или lastLogonDate) как к 100% точному. Она может находиться в любом месте от 9 до 14 дней, устаревших по дизайну .

.
4
ответ дан 3 December 2019 в 10:37

Вы никогда не используете значение $user в вызове Get-ADUser... попробуйте изменить значение $UsersX на параметры, которые нужно отправить в Get-ADUser и заменить их в... и так как вы используете тот же LdapFilter, возможно, также сделаете его переменной. (Также, вы используете "OU=Users,OU=US-Location" три раза, я предполагаю, что это только для примера?)

$30days = (get-date).adddays(-30)

$LdapFilter = '(UserPrincipalName=*)(extensionAttribute9=*)'

$Users1 = 'OU=Users,OU=US-Location,OU=Americas,DC=Domain,DC=Domain,DC=com'

$Users2 = 'OU=Users-Remote,OU=US-Location,OU=Americas,DC=Domain,DC=Domain,DC=com' 

$Users3 = 'OU=Contractors,OU=US-Location,OU=Americas,DC=Domain,DC=Domain,DC=com'

$Users4 = 'OU=Temps,OU=US-Location,OU=Americas,DC=Domain,DC=Domain,DC=com'

$Users5 = 'OU=Users,OU=US-Location,OU=Americas,DC=Domain,DC=Domain,DC=com'

$Users6 = 'OU=Users,OU=US-Location,OU=Americas,DC=Domain,DC=Domain,DC=com' 

$Users = $Users1,$Users2,$Users3,$Users4,$Users5,$Users6 
$useraccountsover30days = foreach ($user in $($Users)){Get-ADUser -SearchBase $user -LdapFilter $LdapFilter -filter {lastlogondate -le $30days} -Properties lastlogondate}

$lastlogonreadable = $useraccountsover30days | Select-Object SamAccountName,lastlogondate

    $lastlogonreadable | Export-Csv C:/Users/myname/Desktop/Usersover30days.csv 
-1
ответ дан 3 December 2019 в 10:37

Я решил аналогичный запрос для нескольких OU с повторением одного и того же набора, как показано ниже, несколько раз с указанным OU:

get-aduser -filter 'enabled -eq $true' -Properties Name, LastLogonDate, AccountExpirationDate, description, Department, title, UserPrincipalName -SearchBase "OU=Users,OU=US-Location,OU=Americas,DC=Domain,DC=Domain,DC=com" | Where-object {$_.lastlogondate -lt (get-date).AddDays(-30)} | Select-Object Name, LastLogonDate, AccountExpirationDate, description, Department, title, UserPrincipalName | Export-csv C:\temp\users-nologin-30.csv -Encoding UTF8 -Append -NoTypeInformation -Force -Delimiter ";"

Он получает все включенные учетные записи со свойствами Name, LastLogonDate, AccountExpirationDate, description, Department, title, UserPrincipalName и добавляет его в csv-файл. Как указано в другом ответе, 30 дней может быть неточным, поэтому лучше позвонить в течение 44 дней, чтобы быть уверенным.

Если «LastLogonDate» пусто, пользователь никогда не входил в систему, возможно, это новая Учетная запись.

0
ответ дан 10 March 2020 в 14:43

Теги

Похожие вопросы