【问题标题】:Compare two different csv files & send email比较两个不同的 csv 文件并发送电子邮件
【发布时间】:2017-05-10 21:59:09
【问题描述】:

我有两个要比较的 csv 文件。

第一个有两个标题(ComputerName、IsOnLine)

第二个有两个标题(计算机名、联系人)

我想比较两个文件中的“ComputerName”,然后我需要向该计算机的联系人发送电子邮件。

“联系人”包含该计算机的电子邮件地址

所以 1.csv

计算机名 IsOnLine

PC1 离线

2.csv

计算机名联系人

PC1 联系人@company.com

PC2 不同@company.com

我只需要向 PC1 的联系人发送电子邮件。

    $Contacts = Import-Csv -Path "C:\Remote_Contacts.csv"
    $NExport = Import-Csv -Path "C:\Offline-computers_$(get-date -formt `"yyyy_MM_dd_HH`").csv"
    #Not really getting what I want here
    Compare-Object $NExport $Contacts  -Property ComputerName -IncludeEqual -PassThru

我已经在其他 powershell 脚本中发送了电子邮件,但我需要能够从 2.csv 中提取它并将其添加到电子邮件代码中。

【问题讨论】:

    标签: powershell csv email


    【解决方案1】:

    为了使其更易于理解,我将简单地遍历第一个列表并过滤第二个列表以获取所需信息。如果您的计算机数量不超过数千台,这将可行。

    $Contacts = Import-Csv -Path "C:\Remote_Contacts.csv"
    $NExport = Import-Csv -Path "C:\Offline-computers_$(get-date -format "yyyy_MM_dd_HH").csv"
    
    foreach ($PCStatus in $NExport) {
        if ($PCStatus.ComputerName -in ($Contacts.ComputerName)) {
            $ContactDetails = $Contacts | Where-Object Computername -eq ($PCStatus.ComputerName)
            $Subject = ($PCStatus.Computername) + ' is ' + ($PCStatus.IsOnline)
            Send-MailMessage -Subject $Subject -To ($ContactDetails.Contact) -SmtpServer smtp.example.com
        }
    }
    

    说明: 我们遍历每台我们拥有状态的计算机。 我们检查我们是否有它的联系方式,如果没有,我们什么也不做。 如果我们有联系方式,我们会发送消息。

    【讨论】:

    • $PCStatus | where { $_.ComputerName -in $Contacts.ComputerName }
    • 请记住where 仍然是Where-Object 的别名。我们应该努力在我们的示例代码中使用完整的 cmdlet,并向新的 PowerShell 编码人员介绍别名以及如何删除别名(尽管不常见)。
    • 我喜欢这个,但是在“-Subject ($PCStatus.Computername + ' is ' + $PCStatus.IsOnline)”中唯一出现的是“is”我没有得到计算机名称或状态
    • 嗯...试试这个: $Subject = ($PCStatus.Computername) + ' is ' + ($PCStatus.IsOnline) Send-MailMessage -Subject $Subject -To 。 . .注意额外的括号。如果它不起作用,请在发送邮件命令之后使用以下行检查正确的 csv 解析,Write-Host $PCStatus.Computername Write-Host $PCStatus.IsOnline Write-Host $ContactDetails.Contact
    • 表示import-csv有问题。尝试使以下测试起作用。它应该只显示来自 CSV 的联系人电子邮件地址。并与其他文件/列类似。 $Contacts = Import-Csv -Path "C:\Remote_Contacts.csv" $Contacts.Contact
    【解决方案2】:

    $csv1 | where-object { $_.computername -in $csv2.computername } 之类的东西应该可以工作

        PS C:\bjm\pwrshl> get-content .\csv1.csv
        computername,contact
        computer1,me@mysite.com
        computer2,you@yoursite.com
        computer3,them@theirsite.com
        PS C:\bjm\pwrshl> get-content .\csv2.csv
        computername,status
        computer1,up
        computer3,down
        computer22,up
        PS C:\bjm\pwrshl> $csv1 = Import-Csv .\csv1.csv
        PS C:\bjm\pwrshl> $csv2 = import-csv .\csv2.csv
        PS C:\bjm\pwrshl> $csv1 | where-object { $_.computername -in $csv2.computername }
    
        computername contact
        ------------ -------
        computer1    me@mysite.com
        computer3    them@theirsite.com
    

    如果您在使用 PowerShell 发送电子邮件时需要帮助,您可能应该问一个特定的问题(例如,您遇到了什么问题)。

    【讨论】:

    • 我以为我做到了。我不确定如何从结果中将计算机名和联系人电子邮件添加到“send-MailMessage cmdlet”中。
    【解决方案3】:

    如果我们直接比较两个变量的属性,然后过滤等于比较==,那么您应该有一个可以循环的列表。

    在循环期间,您可以过滤联系人 CSV 以获取您需要联系的电子邮件:

    $Contacts = Import-Csv -Path "C:\Remote_Contacts.csv"
    $NExport = Import-Csv -Path "C:\Offline-computers_$(get-date -formt 'yyyy_MM_dd_HH').csv"
    
    # Compare the ComputerName property on both CSV variables
    $comparison = Compare-Object -ReferenceObject $Contacts.ComputerName -DifferenceObject $NExport.ComputerName -IncludeEqual
    
    # Filter the comparison to get all the ComputerNames that were equal
    $equalComparison = $comparison | Where-Object -FilterScript { $_.SideIndicator -eq '==' } | Select-Object -ExpandProperty InputObject
    
    # Loop through each computer
    foreach($computer in $equalComparison)
    {
        # Get the contact details for this computer
        $computerContact = $contacts | Where-Object -FilterScript { $_.ComputerName -eq $computer }
    
        # $computer is the name of the computer that appears in both CSVs
        # add code to send an email here...
    }
    

    【讨论】:

    • Compare-Object 与 -Passthru (正如 mr_evans2u 在他的脚本中开始的那样)将为我们提供我们需要的确切对象,而无需过滤 == 和扩展 InputObject 属性。它会从 ReferenceObject 返回记录,因此根据后面的脚本,在其中交换 $Contacts 和 $NExport 可能会更好。
    • 虽然-PassThru 会起作用,但我认为最好解释一下对比较对象的简单过滤,而不是一起使用-IncludeEqual-ExcludeDifferent-PassThru :)
    • Where-Object -FilterScript { $_.SideIndicator -eq '==' } 可以在没有 FilterScript 的情况下以更易于理解的方式编写 Where-Object SideIndicator -eq '=='
    • 是的,可以。我选择不使用该语法,因为它特定于较新版本的 PowerShell,并且不知道正在使用哪个版本 Where-Object SideIndicator -eq '==' 可能最终成为无效语法,从而导致更多混乱。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-29
    • 1970-01-01
    • 2018-01-08
    • 1970-01-01
    • 1970-01-01
    • 2015-01-20
    • 1970-01-01
    相关资源
    最近更新 更多