如何搜索PowerShell对象数组和检索索引到匹配的字符串?

时间:2013-12-02 13:09:15

标签: arrays powershell indexing

我需要搜索自定义PowerShell对象数组(包含来自AD和Exchange的数据--5列:mail,dn,extensionAttribute7,TotalItemSize,Count)。我每天收集这些数据(对于总项目大小>指定大小的每个用户)并使用Export-Clixml将其导出到XML文件,以便我可以在随后的日子中引用该数据。每天我都会对邮箱进行新的搜索>指定大小并保存有关匹配邮箱的数据,但我需要交叉引用我现有的用户数组。如果用户已经在我的数组中,那么我想将PS对象中的count属性递增1,否则我想将用户添加到我的数组作为新的PS自定义对象。这样我就可以跟踪邮箱一直超过指定大小的用户并采取相应的行动(这是客户要求)。

我正在努力解决的问题是搜索我的自定义PS对象数组以进行匹配,以确定是否需要将用户添加为新对象,或者只是为用户增加计数器,因为它们已经在我的数组中。一开始我以为我可以使用.IndexOf或-Contains来查找我的数组中的匹配但它们似乎不适用于包含PS对象的数组。我能够让它工作的唯一方法如下:

#Check to see if this user is already in our master mbxlist array from previous days
$ndx = 0..($mbxlist.length - 1) | Where-Object {$mbxlist[$_].mail -eq $($m.mail)}
然后将 $ ndx设置为我的数组中匹配对象的索引,如果没有匹配则为$ null。但这似乎并不是非常有效,特别是当我每天检查每个单独用户的1000个对象数组时。当然必须有更好的方法来做到这一点?我确实想过创建一个单独的字符串数组,其中只包含用户的邮件地址,然后使用indexof来检查匹配项。我可以推断匹配的PS对象与我的字符串数组具有相同的索引号,然后相应地更新相应的ps对象数组中的计数:

# Create an array of strings based on the mail attribute in my PS object array
foreach ($m in $mbxlist) {[array]$lookup += $m.mail.ToString()}

#Search the lookup array for matching email address using IndexOf
$ndx=[array]::indexof($lookup,"joe.bloggs@mydomain,com")

#If ndx > 0 I've got a match so increment the count in the corresponding PS object
If ($ndx -ge 0)
{
    $mbxlist[$ndx].Count = ($mbxlist[$ndx].Count) + 1
}

这会更有效吗,因为IndexOf比我正在搜索的每个用户执行Where-Object更快?

我已经搜索并测试了几天,我无法弄清楚这一点。我对PowerShell比较新,所以我可能错过了一些非常明显的东西。谢谢!

2 个答案:

答案 0 :(得分:2)

不确定这是否有帮助,但您可以尝试使用电子邮件地址作为密钥将对象加载到哈希表中,然后通过它引用它(未经测试):

$ht = @{}
import-clixml mbxdata.xml |
 foreach {$ht[$_.mail] = $_}

$mailboxes = get-mailbox -resultsize unlimited |
  select -ExpandProperty PrimarySMTPAddress

foreach ($mbx in $mailboxes){
 if ($ht[$mbx] -eq $null)
   {
     $ht[$mbx] = new-object PSObject #Create and add new object here
   }

  if ((get-mailboxstatistics $mbx).totalitemsize -gt '<some value>')
    {
      $ht[$mbx].count ++
    }
 }

$ht.Values | export-clixml mbxdata.xml

答案 1 :(得分:0)

如果我理解你的问题。您只需要将前一个对象与当前对象进行比较,然后选择差异。

您可以使用Compare-Object执行此操作,并指定要比较的属性。

下面是比较两个对象并查找$ object2中存在的差异的示例。

  $object1 = @()
  $object2 = @()
  $FirstNames = ("Jane","James","Jen","Jim")

Foreach($fn in $FirstNames){

    $object1 += New-Object PSObject -Property @{
    Firstname = $fn
    LastName  = "Doe"
    }

}

$object2 += New-Object PSObject -Property @{
           Firstname = "Jimmy"
           LastName  = "Doe"
           }

$object2 += New-Object PSObject -Property @{
           Firstname = "Jane"
           LastName  = "Doe"
           }


Compare-Object $object1 $object2 -Property  'FirstName' | ? { $_.SideIndicator -eq "=>" }

你可以将结果传递给foreach,根据发现的差异做一些事情。

Compare-Object $object1 $object2 -Property  'FirstName' | ? { $_.SideIndicator -eq "=>" } | %{Write-Host $_.FirstName }

另请注意,在使用Sort-Object cmdlet比较对象之前,可能需要对对象进行排序。