1

我确信这很容易,但是今天下午我变得更好了(我对 Powershell 还比较陌生)。另外,我敢肯定我的代码会更优雅。

首先,我有一些代码进入我们的交换服务器,并返回来自特定用户的发送消息。它将它放入一个名为@Results 的数组中。因此,一些条目将如下所示(为保护隐私而编辑):

C:\Windows\system32>$Results[3..5]

Timestamp         MessageSubject        Recipients
---------         --------------        ----------
01/09/2013 09:12:57   Subject1      {user1@gmail.com}
01/09/2013 09:30:44   Subject2      {recipient@yahoo.com}
01/09/2013 09:42:11   Subject3      {person1@globocorp.com, recipient2@gmail...

所以,我对此很满意。但是,我的问题在于上面的多个收件人列表。实际上,这是它自己的数组。从已发送邮件列表中,我对内部邮件不感兴趣,所以我想排除带有我们域的条目(假设上面是 globocorp.com)。所以,我的解决方案是有几个循环来列出所有条目作为它们自己的行。这是我必须要做的:

For ($k=0; $k -eq $Results.count; $k++)
    {
    For ($j=0; $j -eq $Results[$k].Recipients.Count; $j++)
        {write-host $Results[$k].timestamp, $Results[$k].Recipients[$j], $Results[$k].MessageSubject 
        }
    }

这可行,但使用了几个我认为不优雅的循环。必须有一种更简洁的方式来实现上述目标(也许是 for-each 命令?)。但是,我的主要问题是如何处理输出。我不想使用“write-host”,而是将输出创建为对象,然后我可以将其制成表格或从中创建一个 csv。然后我可以使用 'where-object ToUpper(Recipients) -notlike "*@GLOBOCORP.COM"' 功能排除内部邮件。

但是,我不能只列出输出,然后在出现“不允许空管道元素”错误时对其进行管道传输,并且列出对象会将每个条目粘贴在新行上,即:

04 September 2013 18:19:12
user@globocorp.com
Message subject

任何建议都非常感谢!

4

3 回答 3

0
$Results | 
Foreach-Object {$Entry=$_;$Entry.Recipeints |
    Where-Object {$_ -notlike '*@globocorp.com'} | 
    Foreach-Object {Write-Output ([PSCustomObject]@{TimeStamp=$Entry.TimeStamp;MessageSubject=$Entry.MessageSubject;Recipeint=$_)}}
}

It's pretty much the same thing that you did except it's using the power of the PIPE with foreach-ing and where-ing. It's pretty easy to create custom objects just use the [PSCustomObject] accelerator. It takes a hash table. Now you should be able to export to a cvs, just add this at the end | Exprot-CSV C:\foo.csv

Hope this helps. Get great PS tips here.

于 2013-09-06T16:54:27.667 回答
0

Something like this might work:

$Results | % {
  foreach ($recipient in $_.Recipients) {
    if ($recipient -notlike '*@globocorp.com') {
      Write-Host $_.Timestamp, $recipient, $_.MessageSubject
    }
  }
}

or like this:

$Results | % {
  $timestamp = $_.Timestamp
  $subject   = $_.MessageSubject
  $_.Recipients | ? { $_ -notlike '*@globocorp.com' } | % {
    Write-Host $timestamp, $_, $subject
  }
}
于 2013-09-06T16:54:34.977 回答
0

我会创建(实际上是重新创建)一个扁平对象,如下所示:

Foreach ($result in $Results) { 
    foreach ($recipient in $result.recipients) {
        if ($recipient -notmatch '@globalcorp.com') {
            [PSCustomObject]@{
                TimeStamp = $result.timestamp;
                MessageSubject = $result.MessageSubject;
                Recipient = $recipient 
            }
        }
    }
}

最后,您将为每个收件人(不包括内部电子邮件)获得(一系列)新对象。

如果您希望结果的数量相当大,以至于您可能会遇到内存问题,那么您可能会避免使用 foreach,而是使用“管道”来降低速度:

$Results| % { 
    $result = $_;
    foreach ($recipient in $result.$recipients) {
        if ($recipient -notmatch '@globalcorp.com') {
            [PSCustomObject]@{
                TimeStamp = $result.timestamp;
                MessageSubject = $result.MessageSubject;
                Recipient = $recipient 
            }
        }
    }
}
于 2013-09-09T15:05:28.403 回答