Get-ADUser通过多个OU并过滤结果

该脚本应该从多个OU中获取用户,并将用户分配给一个variables,然后根据该variables的用户,并根据30天以上的最后logindate对每个用户进行筛选。 然后它会导出到一个CSV文件,并提供一些我想要的信息。

问题是 ,当我到达foreach部分时,它将search整个目录,并且不会使用我提供的variables中的用户。

任何批评也非常感激。

$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 

有几个build议,我会用你当前的脚本。

首先,单个大型查询几乎总是比许多较小的查询执行得更好。 因此,不要为每个目标OU单独运行get-aduser ,而是将它们组合为使用更高级别公用OU作为search基础的单个调用。 显然,这可能最终会返回你不想包含的OU的结果。 但后来过滤出来要快得多。

您还要为第一组查询中的每个结果再次调用get-aduser ,只是为了过滤lastLogonDate。 但是您可以将该filter与原始查询中的-ldapfilter结合使用。 这只是将-filter版本与等效的-ldapfilter版本进行转换。 这样做的秘诀是知道lastLogonDate只是lastLogonTimestamp属性的Powershell转换版本。 您可以将普通Powershell DateTime值转换为lastLogonTimestamp与ToFileTime()方法一起使用的格式。

最让我困惑的是你的ldapfilter的(UserPrincipalName=*)部分。 在每一个我碰过的领域中,这个属性总是有一个值(就像SamAccountName或DistinguishedName一样)。 它可能与<SamAccoutnName>@<DomainFQDN>的默认值不同,但它永远不会为空。 filter不会伤害任何东西。 对于AD来说,花费CPU周期进行评估时,这只是一个额外的事情。 但是如果你有理由相信在你的环境中它可能是空的,那就千万别把它留在里面。

因此,如果我正确理解你的意图,我将如何修改你的脚本。

 # 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 

PS请谨慎对待lastLogonTimestamp (或lastLogonDate )为100%准确。 devise可能会过时9到14天 。

你从来没有在Get-ADUser调用中使用$ user值…尝试将$ UsersX值更改为需要发送给Get-ADUser的参数,并将其replace为…并且由于您正在重复使用相同的LdapFilter,也可以做一个variables。 (另外,您正在重复使用“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