PowerShell:拆分包含数组的数组

时间:2013-09-06 16:25:12

标签: arrays powershell

我确信这是一个简单的,但今天下午我的表现更好(我对Powershell来说相对较新)。另外,我很确定我的代码会更优雅。

首先,我有一些代码发送到我们的Exchange服务器,并返回来自特定用户的已发送消息。它将它放入一个名为@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

非常感谢任何建议!

3 个答案:

答案 0 :(得分:0)

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

除了它使用PIPE的功能与foreaching和where-ing之外,它与你所做的几乎完全相同。只使用[PSCustomObject]加速器创建自定义对象非常容易。它需要一个哈希表。现在您应该可以导出到cvs,只需在末尾添加| Exprot-CSV C:\foo.csv

希望这会有所帮助。 Get great PS tips here

答案 1 :(得分:0)

这样的事可能有用:

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

或者像这样:

$Results | % {
  $timestamp = $_.Timestamp
  $subject   = $_.MessageSubject
  $_.Recipients | ? { $_ -notlike '*@globocorp.com' } | % {
    Write-Host $timestamp, $_, $subject
  }
}

答案 2 :(得分: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而是使用“pipe”来减速:

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