当前,我正在从SQL数据库中提取电子邮件列表,并将这些电子邮件存储在名为$emaildata
的变量中。我正在尝试从Active Directory过滤$emaildata
中的所有电子邮件。现在没有错误弹出,但是绝对不是从变量中显示的列表中删除电子邮件。
$ADUsers = Get-AdUser -Filter * -Properties SamAccountName, EmailAddress, Title, LastLogonDate, Name, GivenName, Surname, Company, Department, Country, EmployeeNumber, Enabled | Where {
($_.LastLogonDate -ge (Get-Date).AddDays(-30)) -and
($_.LastLogonDate -ne $null) -and
($_.EmailAddress -ne $null) -and
($_.EmployeeNumber -like '1000*') -and
($_.Enabled -eq 'True') -and
($_.EmailAddress -ne $emaildata)
} | Select GivenName, Surname, EmailAddress, Title
$ADUsers | Export-Csv C:\Lists\MainList.csv -NoTypeInformation
这就是我要尝试的这段代码。
($_.EmailAddress -ne $emaildata)
我一直在寻找很长时间,而我尝试的所有方法都没有用,所以我希望你们能够帮助我。谢谢!
$emaildata
中的数据看起来像这样
EmailAddress ------------ test1@test.com test2@test.com test3@test.com test4@test.com test5@test.com
答案 0 :(得分:0)
$emailDataStringList = @( $emailData | Foreach-Object { return $_.EmailAddress.Trim() } )
.... | Where-Object { ...
($_.EmailAddress -ne $null) -and
($_.EmailAddress -ne '') -and
($emailDataStringList -notcontains $_.EmailAddress)
}
您的$emailData
不是字符串数组([string[]]
),它是具有单个属性的对象数组:EmailAddress
(根据您的输出)。有很多选项可以检查$ adUser.EmailAddress是否在$ emailData列表中,但最简单的方法是将对象数组转换为字符串数组:
$emailDataStringList = @( $emailData | Foreach-Object { return $_.EmailAddress.Trim() } )
肯定Enabled
有问题:您将其与字符串进行比较,应将其与bool进行比较:
$_.Enabled -eq $true
另外,lastLogonDate
可能有问题:
在-and
表达式中,应首先检查-ne $null
,只有下一步,您才能确定要使用有效值。否则,您可能会遇到$null -comparsionOperator [DateTime]
($_.LastLogonDate -ne $null) -and
($_.LastLogonDate -ge (Get-Date).AddDays(-30))
还要设置变量$dateToCheck = [DateTime]::Today.AddDays(-30)
,然后在Where-Object
表达式中比较$_.LastLogonDate -ge $dateToCheck
。这样会更快,powershell将LastLogonDate
与预定义的值进行比较,并且每次迭代都不会计算新的DateTime
。
根据Get-ADUser
,您可以使用-LDAPFilter '(&(mail=*)(LastLogonTimeStamp=*))'
并丢弃-ne $null
检查并最大程度地减少内存使用和网络使用。 LDAPFilter
和Filter
是在服务器端处理的
下一步,请注意重要:AD中没有属性LastLogonDate
。在Get-AD*
中,它是根据LastLogonTimeStamp
动态计算的。 LastLogonTimeStamp
不会立即复制-它仅存储在DC上,DC仅在另一个DC的值相差超过ms-DS-Logon-Time-Sync-Interval
的值(默认14天)时处理用户登录并复制到另一个DC。因此,您应该了解一下:DC上的 LastLogonDate
可能已过期14天。(See detailed explanation)。如果您确实需要准确的LastLogonDate
,则必须检查林中的每个DC。这是一项繁重且耗时的工作。
接下来,强制Get-ADUser
和$... | Where { ... }
为一个数组(使用数组转换括号@()
)。否则,当这些表达式返回单用户或无用户($null
)时,您的代码可能会出现问题。括在@()
括号内,可以确保您的变量将是一个包含0、1或多个元素的数组。
接下来,请注意,您可以在此处遇到类似超时的错误,因为Get-AD*
cmdlet上存在超时,并且如果管道后的表达式花费大量时间,Get-ADUser
将终止,管道将被破坏,并且您遇到错误。
更好的存储Get-ADUser
的结果为变量,并在单独的表达式中过滤:
$attributes = @('samaccountname', 'lastlogondate', '.....')
$ADUsers = @( Get-ADUser -options.... -Properties $attributes )
$ADUsers = @( $ADUsers | Where-object { ... } )
$ADUsers | Select $attributes | Export-Csv -options...
P.S。您的广告或数据库中可能存在空格。在检查位置使用.Trim():
$emailAddresses = @( $emailAddresses | Foreach-Object { return $_.Trim() } )
$... | Where { $emailAddresses -contains $_.EmailAddress.Trim() }
您的代码将如下所示:
$dateToCheck = [DateTime]::Today.AddDays(-30)
$emailDataStringList = @( $emailData | Foreach-Object { return $_.EmailAddress.Trim() } )
$ADUserProperties = @('SamAccountName', 'EmailAddress', 'Title', 'LastLogonDate', 'Name', 'GivenName', 'Surname', 'Company', 'Department', 'Country', 'EmployeeNumber', 'Enabled')
$ADUserList = @( Get-AdUser -LDAPFilter '(&(mail=*)(LastLogonTimeStamp=*)(employeeNumber=1000*))' -Properties $ADUserProperties )
$ADuserList = @( $ADUserList |
Where-Object { $_.Enabled -eq $True} | # This is simplies check, this should be first
Where-Object { $_.LastLogonDate -ge $dateToCheck } |
Where-Object { $emailDataStringList -notcontains $_.EmailAddress.Trim()} | # This is hardest cpu-taking check, this should be last
Select @('GivenName', 'Surname', 'EmailAddress', 'Title')
)
$ADuserList | Export-Csv C:\Lists\MainList.csv -NoTypeInformation
如果您需要更准确的LastLogonDate
,则应该从环境中的每个DC 获取ADUsers。像这样:
$DCList = @(get-addomaincontroller -filter *)
$ADUserList = @( $DCList | ForEach-Object { Get-ADUser -Server $_.DNSName ... -properties @('SID', 'lastlogontimestamp', ...) } )
$ADUserList = @( $ADUserList | Sort-Object -Descending -Property 'lastlogontimestamp' | Sort-Object -Property 'SID' -Unique )
根据MS文档,-Unique
占据列表中的第一个对象,因此它应为每个用户获得最准确的LastLogonDate