检查电子邮件是否在从 ADGroup 中提取的可变电子邮件列表中

Check if email is within variable list of emails pulled from ADGroup

我正在尝试检查从 excel 中的列中提取的数组中的电子邮件是否在 AD 组的电子邮件列表中,如果是,则使用 Write-Host 输出该电子邮件通知。

Clear-Host

$objExcel = New-Object -ComObject Excel.Application
$WorkBook = $objExcel.Workbooks.Open("C:\Users\Status.xlsx")
$WorkSheet = $WorkBook.Sheets.Item("PS1")
$members = Get-ADGroupMember -Identity VIP | 
Get-ADUser -Properties emailaddress | Select emailaddress

$startRow = 2
$ColValues = @()
$count = $Worksheet.Cells.Item(65536, 7).End(-4162)
for ($startRow; $startRow -le $count.row; $startRow++) {
    $ColValues += $Worksheet.Cells.Item($startRow, 6).Value()
}

foreach ($email in $ColValues) {
    if ($members -contains $email) {
        Write-Host "$email is a VIP!" -ForegroundColor Red
    } else {}
}

Write-Host " "
Write-Host "Complete!" -ForegroundColor Green

如果我 运行 上面的代码直接进入 Complete! - 但是 $email$ColValues$members 的所有内容都正确列出?

您似乎在尝试比较 $members,这是一个 对象数组 (具有 属性 和值的数组)和来自 [=13 的项目=] 这是一个 值数组

您可能希望通过这样更改 $members 变量来解决此问题:

$members = Get-ADGroupMember -Identity VIP | 
Get-ADUser -Properties emailaddress | Select -ExpandProperty emailaddress

或者这样改变if条件:

If ($members.emailaddress.Contains($email)) 

Get-ADGroupMember 函数可以 return 组、计算机和用户。我认为你应该过滤掉任何不是用户的东西。

此外,通过使用 Select emailaddress,您将获得用户 对象 的数组,正如 Kirill Pashkov 已经指出的那样。你真的只想拥有一个 strings.

数组

尝试 $members = 部分:

$members   = Get-ADGroupMember -Identity VIP -Filter {objectClass -eq "user"} |
             Get-ADUser -Properties Emailaddress | 
             Select-Object -ExpandProperty Emailaddress | 
             Sort-Object -Unique

这里不需要Sort-Object -Unique,只是为了确保其中没有重复项..

我无法检查您的代码是否确实以正确的方式从 Excel 获取了 $ColValues。也就是说:如果这导致 字符串数组 保存电子邮件地址,但如果是这样,也将该数组统一化:

$ColValues = $ColValues | Sort-Object -Unique

最后备注:

从中收集值后,您似乎没有关闭 Excel。
最好养成在完成这样的代码后关闭和释放 ComObjects 的习惯:

$objExcel.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($WorkBook) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($objExcel) | Out-Null
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()

我通过消除对数组的需要并稍微简化脚本找到了解决方案。所以基本上我只是将操作移到 for 语句中,以便在获取每个值时对其进行处理。

Clear-Host

$objExcel = New-Object -ComObject Excel.Application
$WorkBook = $objExcel.Workbooks.Open("C:\Users\Status.xlsx")
$WorkSheet = $WorkBook.Sheets.Item("PS1")
$members = Get-ADGroupMember -Identity VIP | Get-ADUser -Properties emailaddress | Select emailaddress

$startRow = 2
$count = $Worksheet.Cells.Item(65536, 7).End(-4162)
for ($startRow; $startRow -le $count.row; $startRow++) {
{

    $emails = ($Worksheet.Cells.Item($startRow, 4).Value())
    $computerName = ($Worksheet.Cells.Item($startRow, 1).Value())

    if (($members -match $emails) -and ($emails -like "*")) {

        Write-Host "$emails is a VIP! " -ForegroundColor Green -NoNewline
        Write-Host " Computer Name: $computerName"

    } else {}   

}

Write-Host " "
Write-Host "Complete!" -ForegroundColor Green

唯一的缺点是我无法轻松删除重复项并将其格式化为 table。但是考虑到它只输出了 30 个左右的值,它完美地满足了我的需要。