2016-04-08 1 views
0

У меня есть массив MailItems из Outlook. Я хочу искать каждый элемент почты и возвращать Subject и Category на основе списка поисковых запросов, содержащихся в массиве, - в примере с именем $searchArray.Как искать коллекцию с массивом в Powershell

Например:

$mailbox = "[email protected]" 

$outlook = New-Object -com Outlook.Application 
$ns = $outlook.GetNamespace("MAPI") 
$inbox = $ns.Folders.Item($mailbox).Folders.Item("Inbox") 
$searchItems = $inbox.Folders.Item("MySubFolder").Folders.Item("MyNestedSubFolder").Items 

$searchArray = (
    "Category1", ("searchTerm1","searchTerm2","searchTerm3"), 
    "Category2", ("searchTerm4","searchTerm5"), 
    "Category3", ("searchTerm6") 
) 

foreach ($msg in $searchItems) { 
    $msg | select Subject, # <Category where email address contains one of the search terms> 
} 

Я хочу вернуть Subject, а затем столбец с названием Category, который будет смотреть на $msg.SenderEmailAddress, и если какой-либо из searchTerms в $searchArray содержится в адрес, восстановите категория, в которой был найден этот поисковый запрос.

Например, если один из значений SenderEmailAddress был «[email protected]», тогда возвращайте Category1 как Category.

+0

придираться: использовать [ 'example.com'] (https://en.wikipedia.org/wiki/Example.com) для примеров домена. –

+2

Nit был выбран –

+0

В вашем представлении: чтобы все элементы возвращали правильные данные, они должны возвращать одинаковое количество свойств. Таким образом, вам нужно либо вернуть все категории, либо выделить то, что вы хотите, или создать настраиваемое поле, в котором показана соответствующая категория. Может ли электронная почта соответствовать нескольким категориям? Что происходит, когда это происходит? Вы частично относитесь к структуре, которую вы сейчас используете для '$ searchArray'? Некоторые изменения в нем облегчат процесс – Matt

ответ

2

Я бы перевернул этот массив на голове и создал из него хеш-таблицу. Затем используйте первый критерий поиска соответствия в качестве ключа поиска для категории:

$searchArray = (
    "Category1", ("searchTerm1","searchTerm2","searchTerm3"), 
    "Category2", ("searchTerm4","searchTerm5"), 
    "Category3", ("searchTerm6") 
) 

# Create hashtable 
$searchTable = @{} 

# Populate hash table with values from array 
for($i=0;$i-lt$searchArray.Count;$i+=2){ 
    foreach($term in $searchArray[$i+1]) 
    { 
     $searchTable[$term] = $searchArray[$i] 
    } 
} 

# Select Category based on first matching search term 
$msg |Select-Object Subject,@{Name="Category";Expression={ 
     $sender = $_.SenderEmailAddress 
     $searchTable[$($searchTable.Keys |Where-Object{$sender -like "*$_*"} |Select -First 1)] 
    } 
} 
1

Еще нужно использовать вычисляемое выражение так же, как сделал Матиас (Это действительно простой способ). Однако я хотел показать подход, в котором у вас был настраиваемый массив объектов для $searchArray. Если бы вы его скроете с нуля, это будет выглядеть так. Я также преобразовал термины в соответствие шаблонам регулярных выражений, так как вы говорите, что они уникальны. Только остерегайтесь того, что вам нужно быть уверенным, что метасимволы регулярных выражений в ваших поисковых запросах отсутствуют.

$searchArray = (
    [pscustomobject]@{ 
     Category = "1" 
     Pattern = "searchTerm1|searchTerm2|searchTerm3" 
    }, 
    [pscustomobject]@{ 
     Category = "2" 
     Pattern = "searchTerm4|searchTerm5" 
    }, 
    [pscustomobject]@{ 
     Category = "3" 
     Pattern = "searchTerm6"} 
) 

foreach ($msg in $searchItems) { 
    $msg | select Subject, @{ 
     Name="Category"; 
     Expression={$searchArray | Where-Object{$msg.SenderEmailAddress -match $_.pattern } | Select-Object -ExpandProperty Category} 
    } 
} 

Решение зависит от PowerShell 3.0 от типа ускорителя [pscustomobject]. В случае необходимости можно легко вернуть его 2.0.


Чтобы продемонстрировать аналогичную структуру, используя 2.0 и автоматическое преобразование вашего массива в один, который работает с моим кодом.

$newSearchArray = for($categoryIndex=0;$categoryIndex-lt$searchArray.Count;$categoryIndex+=2){ 
    New-Object -TypeName pscustomobject -Property @{ 
     Category = $searchArray[$categoryIndex] 
     Pattern = ($searchArray[$categoryIndex+1] | ForEach-Object{[regex]::Escape($_)}) -join "|" 
    } 
} 

Теперь условия поиска автоматически экранируются и объединяются в шаблон поиска.

0

Используя переключатель:

$mailbox = "[email protected]" 

$outlook = New-Object -com Outlook.Application 
$ns = $outlook.GetNamespace("MAPI") 
$inbox = $ns.Folders.Item($mailbox).Folders.Item("Inbox") 
$searchItems = $inbox.Folders.Item("MySubFolder").Folders.Item("MyNestedSubFolder").Items 

foreach ($msg in $searchItems) { 
    $object = $msg | select Subject,Category # <Category where email address contains one of the search terms> 
    Switch -Regex ($msg.SenderEmailAddress) 
    { 
     'searchTerm1|searchTerm2|searchTerm3' { $object.Catetory = 'Category1' ; break } 
     'searchTerm4|searchTerm5'    { $object.Catetory = 'Category2' ; break } 
     'searchTerm6'       { $object.Catetory = 'Category3' ; break } 
    } 
    $object 
}