从.CSV中提取表格以便在电子邮件中使用

时间:2017-02-01 19:39:00

标签: powershell csv powershell-v5.0

我有一个.csv文件,其中包含我工作的公司前雇员的1000多个条目,我试图将员工拆分为可以插入电子邮件模板的格式。为了加剧事情,很多(但不是全部)员工都有多个条目,而.csv包含大量信息,这些信息对于我将发送电子邮件的人来说完全没有必要。理想情况下,我想排除这些列,但我遇到了相当多的困难。在我看来,format-table将是我需要的cmdlet,但我不是100%肯定的。到目前为止,我尝试过:

import-csv C:\filepath\xx.csv | format-table -groupby (key value)

确实以我想要的方式返回组织的信息,但是我不知道如何从那里分割信息,因此我只能为特定员工发送信息。如前所述,这还包括相当多的无关信息。我也尝试过:

import-csv C:\filepath\xx.csv | format-table -groupby (key value) -property (properties I want,separated by commas)

但是,这仍然会返回相同的无关信息。我还尝试使用foreach循环迭代.csv,将我想要的信息存储在变量中,然后将这些变量存储在数组中,然后将该数组传输到format-table中,这会导致混乱。我也尝试将.csv放入一个按我想要的键值分组的哈希表中,但这会导致其余的信息被放入一个字符串中。我相信我应该能够使用正则表达式拆分这个字符串,但是我对熟悉正则表达式并不熟悉,也不知道从哪里开始。我在这一点上很难过。任何帮助将不胜感激。

修改

按照@ 4c74356b41的建议(我非常感谢),我能够输出一个只包含相关信息的表格列表。但是,我仍然无法将此表列表拆分为我需要的各个表。我目前有一个.txt文件,我将其用作模板,我想为各个用户添加表格。到目前为止,我已经成功使用get-content来检索.txt,-replace的内容,以便从原始.csv中的信息(例如名称,经理等)替换模板上的其他几个字段,然后输出 - 用于将已编辑的模板存储到临时文件中的文件,然后将其另存为Outlook草稿。我试图在前一个foreach循环中添加另一个foreach循环,以将表添加到模板中,但这将返回带有“Microsoft.PowerShell.Commands.Internal.Format.FormatStartData”行代替表的模板。它还为每个条目创建草稿,而不是为每个唯一用户ID创建一个草稿。这是我到目前为止的所有代码:

$olFolderDrafts = 16
$ol = New-Object -comObject Outlook.Application 
$ns = $ol.GetNameSpace("MAPI")
$file= import-csv H:\filepath\term_rep.csv
$data= import-csv H:\filepath\term_rep.csv | select-object "Inactive Emp Name","User ID","Loc","Equipment Descr","Tag Number","Serial Number"
$table= $data | Format-Table -GroupBy "User ID"
foreach($i in $file)
    {$user = $i | select-object -expandproperty "Inactive Emp Name"
    $uid= $i | select-object -expandproperty "User ID"
    $manager = $i | Select-Object -expandproperty "Manager"
    $loc= $i | select -ExpandProperty "Loc"
    $tagnum= $i | select -ExpandProperty "Tag Number"
    $sernum= $i | select -ExpandProperty "Serial Number"
    $path="C:\filepath\term_email.txt"
    $newpath = [system.io.path]::GetTempFileName() 
    (Get-content $path) -replace "USER_NAME",$user `
    -replace "USER_ID",$uid | out-file $newpath
    foreach($id in $table){
        (Get-Content $newpath) -replace "EQUIPMENT_LIST", $id | out-file $newpath
    }
    $subject="Equipment for user $uid"
    $body= get-content $newpath
    $mail = $ol.CreateItem(0)
    $mail.To = $manager 
    $mail.CC = $null
    $mail.Subject = $subject  
    $mail.Body = $body -join "`n"
    $mail.save()}

2 个答案:

答案 0 :(得分:2)

为了减少噪音和重复,我会找到一个特定于用户的列,例如UserName或Email。然后将其分组,并选择每个组中的第一个项目。然后你可以通过管道Select来减少来自无关列的噪音。类似的东西:

import-csv C:\filepath\xx.csv | Group UserName | ForEach{$_.Group[0]} | Select FirstName,LastName,Email,UserName,SeparationDate 

然后你可以用它做你想要的...管道到另一个ForEach循环,一次处理一个记录,或者将它传递给Export-CSV以生成一个新的CSV减少你可以使用的混乱。您甚至可以让PowerShell为您创建电子邮件,具体取决于您希望获得的内容。

如果您需要进一步的帮助,请更新您的问题,并举例说明您希望输出的内容,或者您​​要为每个条目完成的目标。

编辑:好的,所以当它涉及到它时,您希望为与特定用户匹配的任何记录插入一个事物表到电子邮件中,以便您可以从他们的电子邮件中取回他们的东西经理与公司分开后。很酷,我们可以做到这一点。首先,您正在使用Outlook ComObject,并以此方式生成您的电子邮件。太棒了,我自己也做过,你可以做那些伟大的事情!我强烈建议在这里使用HTML。它使电子邮件看起来更专业,并允许我们在电子邮件中插入一个漂亮的表格,而不是一些格式化的文本,由于在电子邮件中的间隔,它看起来很有趣。

所以,让我们从头发中解决问题,然后重做你的电子邮件模板。弹出打开MS Word并打开您的模板。现在,转到文件并另存为。选择“网页,已过滤”作为您的文档类型,并将其命名为您已有的相同内容。

所以,不是把列表加载两次,然后导出,等等,等等,等等,我们会稍微缩短一下。我们加载您的CSV一次。就此而言,我们不需要为每个用户读取一次电子邮件的正文,所以让我们在循环之前将其加载一次。然后我们使用Select-Object开关将用户ID字段传递给-Unique,这样我们每个用户只能生成一封电子邮件。所以,到那里的脚本看起来像这样:

$olFolderDrafts = 16
$ol = New-Object -comObject Outlook.Application 
$ns = $ol.GetNameSpace("MAPI")
$file= import-csv H:\filepath\term_rep.csv
$path="C:\filepath\term_email.txt"
$body = (Get-content $path) -join "`n"
foreach($i in ($file.'User ID'|Select -Unique))
    {

现在,没有必要像你那样分配所有这些变量,所以我正在跳过那部分。因此,我们将找到当前用户的第一个实例,并将其保存到变量中。

    $User = $File|Where{$_.'User ID' -eq $i}|Select -First 1

一旦我们得到它,我们将在列表中找到所有记录,只选择您感兴趣的属性,并使用ConvertTo-HTML将输出转换为HTML表。

    $Equip = $File|Where{$_.'User ID' -eq $i}|select-object "Inactive Emp Name","User ID","Loc","Equipment Descr","Tag Number","Serial Number"|ConvertTo-Html -Property '*' -As Table -Fragment

现在这是一个相当长的路线,但大多数只是选择正确的属性。魔术发生在我们告诉它将数据转换为HTML的最后一位。具体来说,我们希望所有内容(由-Property '*'指定),我们希望它被转换为一个表,并且这只是一个片段,因此它不会尝试将所有前面和后面的标记放在那里(所以没有<HTML></HTML>类型标记,因为它被注入到现有HTML的中间。)

然后我们做替换,制作电子邮件,分配属性,yada,yada,yada,你几乎已经拥有了所有这些...

    $HTMLbody = $body -replace "USER_NAME",$user.'Inactive Emp Name' -replace "USER_ID",$user.'User ID' -replace "EQUIPMENT_LIST", $Equip
    $subject="Equipment for user " + $User.'User ID'
    $mail = $ol.CreateItem(0)
    $mail.To = $User.Manager 
    $mail.Subject = $subject  
    $mail.HTMLBody = $HTMLbody
    $mail.save()
    }

保存,完成!循环到下一个用户,然后重复。所以把它放在一起,你得到:

$olFolderDrafts = 16
$ol = New-Object -comObject Outlook.Application 
$ns = $ol.GetNameSpace("MAPI")
$file= import-csv H:\filepath\term_rep.csv
$path="C:\temp\email.htm"
$body = (Get-content $path) -join "`n"
foreach($i in ($file.'User ID'|Select -Unique))
    {
    $User = $File|Where{$_.'User ID' -eq $i}|Select -First 1
    $Equip = $File|Where{$_.'User ID' -eq $i}|select-object "Inactive Emp Name","User ID","Loc","Equipment Descr","Tag Number","Serial Number"|ConvertTo-Html -Property '*' -As Table -Fragment
    $HTMLbody = $body -replace "USER_NAME",$user.'Inactive Emp Name' -replace "USER_ID",$user.'User ID' -replace "EQUIPMENT_LIST", $Equip
    $subject="Equipment for user " + $User.'User ID'
    $mail = $ol.CreateItem(0)
    $mail.To = $User.Manager 
    $mail.Subject = $subject  
    $mail.HTMLBody = $HTMLbody
    $mail.save()
    }

答案 1 :(得分:1)

说你的csv有一些列:name,surname,bla-bla,bla-bla,bla-bla。

$data = import-csv C:\filepath\xx.csv | select name, surname
$data | format-table -groupby (key value)