Powershell:检查广告中的重复电子邮件

Powershell:检查广告中的重复电子邮件,powershell,validation,oop,active-directory,powershell-3.0,Powershell,Validation,Oop,Active Directory,Powershell 3.0,背景: 我正在尝试制作一个脚本,以查看新用户的电子邮件$email是否与已存在的相同,从而导致错误。我对物体有一个很好的理解,所以这就是我到目前为止所拥有的是的,它是丑陋的: $email = "smithj@company.com" $mailcheck = Get-ADUser -filter * -Properties * | ForEach-Object {$_.mail} $mailcheck | ForEach-Object {if ($email -eq $_.mail){"

背景: 我正在尝试制作一个脚本,以查看新用户的电子邮件$email是否与已存在的相同,从而导致错误。我对物体有一个很好的理解,所以这就是我到目前为止所拥有的是的,它是丑陋的:

$email = "smithj@company.com"   
$mailcheck = Get-ADUser -filter * -Properties * | ForEach-Object {$_.mail}
$mailcheck | ForEach-Object {if ($email -eq $_.mail){"$email = $($_.mail) - Matching email"}else{"$email = $($_.mail) - No duplicate email"}}
问题1: 脚本与电子邮件不匹配。当我有一个匹配的电子邮件在广告中,它不承认它

问题2:仅执行第二行时,索引无法正常工作。虽然它看起来像是一个连续的电子邮件列表,但如果用户没有一封空白的电子邮件,它可能是这样的:

smithj@company.com

johnsonj@company.com


robertsr@company.com
doej@company.com
smithj@company.com    
johnsonj@company.com             
robertsr@company.com
doej@company.com
所以$mailcheck[0]返回smithj@company.com虽然$mailcheck[1]返回空白,但实际上列表如下所示:

smithj@company.com

johnsonj@company.com


robertsr@company.com
doej@company.com
smithj@company.com    
johnsonj@company.com             
robertsr@company.com
doej@company.com

结论:我真的只需要解决问题1,但问题2激发了我的好奇心。谢谢。

你这样做的效率实在太低了-Properties*将返回用户的所有属性,有些属性返回的处理能力非常昂贵。只使用您需要的属性。默认情况下返回的属性没有指定参数,不需要使用-properties指定,只需要使用其他非默认属性-Filter*还将匹配任何字段的任何值,有效地返回每个ADUser,进一步增加脚本执行所需的资源,因为您现在必须处理每个用户以查找与该电子邮件匹配的任何帐户

现在,这已经过时了,下面是一个更有效的方法来实现您的要求:

# Set the email address to search for
$emailAddress = 'box@domain.tld'

# Get all users where the email address matches what is set above
# Force it as an array so you can treat it like one even if only
# one or zero users are returned
$adUsers = @( Get-ADUser -Filter "EmailAddress -eq '${emailAddress}'" )

# Make sure no accounts were returned
# If there are, throw an error with the number of users and who they are
if( $adUsers ) {
  throw "Found $($adUsers.Count) users matching EmailAddress ${emailAddress}: $($adUsers.SamAccountName -join ', ')"
}
通过使用筛选器仅匹配特定的电子邮件地址,Powershell不需要收集系统中的每个广告用户,也不需要迭代所有用户来查找特定的电子邮件地址。这将需要很长时间进行检查,尤其是在较大的环境中,而根据电子邮件地址或任何其他属性筛选返回的对象将导致更快的操作和更少的数据筛选

然后,您可以检查$adUsers是否包含任何内容。数组计数除0以外的任何内容的计算结果为$True,您还可以使用if$adUsers.count-gt 0作为条件,如果是,则抛出一个包含更多信息的错误,如上所述

最新评论问题: 要回答您在评论中的另一个问题,我不知道将$email与哪个对象进行比较,EmailAddress和Mail看起来都是有效属性,但我不知道它们之间的区别。在我的环境中,Mail和EmailAddress都使用我的电子邮件地址填充,但始终使用EmailAddress,并且没有遇到使用该地址的问题。也许一个是不推荐的,另一个是新的或者什么的,但是我不确定


还有另一个属性叫做proxyAddresses,初步研究表明EmailAddress和Mail都与之相关,但我对它了解不多。它没有在我的ADUser对象上填充,所以我不能随意使用它。

您上面的操作方式效率很低-Properties*将返回用户的所有属性,有些属性返回的处理能力非常昂贵。只使用您需要的属性。默认情况下返回的属性没有指定参数,不需要使用-properties指定,只需要使用其他非默认属性-Filter*还将匹配任何字段的任何值,有效地返回每个ADUser,进一步增加脚本执行所需的资源,因为您现在必须处理每个用户以查找与该电子邮件匹配的任何帐户

现在,这已经过时了,下面是一个更有效的方法来实现您的要求:

# Set the email address to search for
$emailAddress = 'box@domain.tld'

# Get all users where the email address matches what is set above
# Force it as an array so you can treat it like one even if only
# one or zero users are returned
$adUsers = @( Get-ADUser -Filter "EmailAddress -eq '${emailAddress}'" )

# Make sure no accounts were returned
# If there are, throw an error with the number of users and who they are
if( $adUsers ) {
  throw "Found $($adUsers.Count) users matching EmailAddress ${emailAddress}: $($adUsers.SamAccountName -join ', ')"
}
通过使用筛选器仅匹配特定的电子邮件地址,Powershell不需要收集系统中的每个广告用户,也不需要迭代所有用户来查找特定的电子邮件地址。这将需要很长时间进行检查,尤其是在较大的环境中,而根据电子邮件地址或任何其他属性筛选返回的对象将导致更快的操作和更少的数据筛选

然后,您可以检查$adUsers是否包含任何内容。数组计数除0以外的任何内容的计算结果为$True,您还可以使用if$adUsers.count-gt 0作为条件,如果是,则抛出一个包含更多信息的错误,如上所述

最新评论问题: 要回答您在评论中的另一个问题,我不知道将$email与哪个对象进行比较,EmailAddress和Mail看起来都是有效属性,但我不知道它们之间的区别。在我的环境中,Mail和EmailAddress都使用我的电子邮件地址填充,但始终使用EmailAddress,并且没有遇到使用该地址的问题。也许一个是不推荐的,另一个是新的或者什么的,但是我不确定

还有另一个属性称为proxyAddresses,初步研究表明EmailAddress和Mail都与之相关
,但我对它知之甚少。它没有在我的ADUser对象上填充,所以我不能随意使用它。

我正在写一个正确的答案,但仅供参考,doing-Properties*是一个非常好的方法,它会严重阻碍Get ADUser的性能。默认情况下返回的属性不需要指定,如果需要,只需指定默认情况下不返回的属性,如EmailAddress,这是一条非常好的信息。谢谢。我也会在我的回答中提到这一点,但您只需要使用-Properties来指定以后需要处理的属性。-Filter参数将能够检查任何非默认属性,而无需在-properties中指定它们。我正在写一个正确的答案,但仅供参考,doing-properties*是一个显著影响Get ADUser性能的极好方法。默认情况下返回的属性不需要指定,如果需要,只需指定默认情况下不返回的属性,如EmailAddress,这是一条非常好的信息。谢谢。我也会在我的回答中提到这一点,但您只需要使用-Properties来指定以后需要处理的属性。-Filter参数将能够检查任何非默认属性,而无需在-properties中指定它们。这正是我所寻找的,并且解释得很好。这帮助我克服了我所面临的问题。我想知道您是否可以解释或链接${emailAddress}部分是如何工作的,特别是括号的使用,因为我的部分问题是我不知道将$email与哪个对象进行比较。${variableName}称为字符串描述。当您希望在变量值后面立即添加其他字符,但又不希望将其他字符解释为变量名的一部分时,它最有用。我倾向于选择它,因为它清楚地表明了我的字符串插值在哪里。下面是有关它的更多信息:$$\u adUsers.Count称为命令替代。该语法类似于字符串描述,但允许您指定要计算的表达式,其输出将成为字符串的一部分。使用字符串描述,您无法访问变量的属性,这就是为什么我们在这里使用替换。在同一个抛出行中可以看到一个更高级的示例,其中我用逗号和尾随空格连接所有SamAccountName值。这正是我所寻找的,并且解释得很好。这帮助我克服了我所面临的问题。我想知道您是否可以解释或链接${emailAddress}部分是如何工作的,特别是括号的使用,因为我的部分问题是我不知道将$email与哪个对象进行比较。${variableName}称为字符串描述。当您希望在变量值后面立即添加其他字符,但又不希望将其他字符解释为变量名的一部分时,它最有用。我倾向于选择它,因为它清楚地表明了我的字符串插值在哪里。下面是有关它的更多信息:$$\u adUsers.Count称为命令替代。该语法类似于字符串描述,但允许您指定要计算的表达式,其输出将成为字符串的一部分。使用字符串描述,您无法访问变量的属性,这就是为什么我们在这里使用替换。在同一个抛出行中可以看到一个更高级的示例,其中我使用逗号和尾随空格连接所有SamAccountName值。