Как загрузить вложения Outlook на основе определенного имени файла в течение 24 часов?

#powershell #outlook #etl

Вопрос:

Я пытаюсь загрузить вложения в электронные письма на основе имени файла, которые были получены в течение последних 24 часов и являются первым совпадением. Первое совпадение-это в случае, если получено второе электронное письмо с тем же именем файла, которое необходимо вывести в указанное место. Файлы поступают в папку «Входящие», как правило, один раз в день, но бывают случаи, когда их необходимо обрабатывать с помощью «последних полученных». Таким образом, с учетом сказанного, когда есть совпадение, код должен захватить файлы и поместить первые совпадающие файлы в нужное место, а затем остановить / завершить сценарий.

Однако, похоже, он вообще не учитывает фактор времени. На этом этапе мой код находит первые два совпадающих файла на основе имени файла и сбрасывает их в нужное место. Затем он продолжает перезаписывать файлы, находя старые файлы с тем же именем в папке «Входящие».

В этой последней сборке / попытке я использую $limit = (Get-Date).AddDays(-1) , а также -and ($_.CreationTime -lt $limit) в своем коде. Я перепробовал несколько методов, но, похоже, ничего не работает.

     $account = 'blah@stihlse.com'
    $targetFolder = 'inbox'
    $f = $account.Folders | ? { $_.Name -match 'inbox'};
    $email = $f.Items|  Sort-Object ReceivedTime -Descending | Select-Object -First 1 
    $limit = (Get-Date).AddDays(-1)
    $filepath = "\servernamehomeblahDocumentsblah's emails"
    $ol = New-Object -comobject outlook.application
    $ns = $ol.GetNamespace('MAPI')
    $acct = $ns.Folders[$account]
$acct.Folders[$targetFolder].Items | foreach {
    if ($_.ReceivedTime -match $email -and ($_.CreationTime -eq $limit)) { 
            $_.attachments |
            foreach {
                Write-Host "attached file: ",$_.filename
                If ($_.filename -match 'BlahCompletions' -or $_.filename -match 'BlahCertifications'){
                    $_.saveasfile((Join-Path $filepath $_.FileName))
                } 
            } 
    }
}
 

Ответ №1:

Ты пользуешься CreationTime -eq $limit . -eq значит, равны. Так что это работает только в том случае, если CreationTime это та же самая микросекунда, $limit что и . То, что вы ищете -gt , (больше, чем) или -ge (больше или равно).

Другая проблема в том $_.ReceivedTime -match $email . Он пытается перейти -match ReceivedTime к регулярному выражению. Но регулярное выражение, которое вы предоставляете, — это целое $email . Взгляните на about_Comparison_Операторы

Комментарии:

1. Спасибо вам за ваш вклад. Я знал, что это было что-то простое, что сбивало меня с толку. Как только я внес несколько изменений, таких как переход с-ge…. это работает так, как я ожидаю.

Ответ №2:

В коде вы повторяете все элементы в папке:

 $acct.Folders[$targetFolder].Items | foreach {
    if ($_.ReceivedTime -match $email -and ($_.CreationTime -eq $limit)) { 
 

Что на самом деле не очень хорошая идея, если у вас в папке большое количество элементов. Вместо этого вам нужно использовать методы Find/FindNext или Restrict Items класса. Подробнее об этих методах читайте в следующих статьях:

Например, чтобы получить только элементы с вложениями, вы можете использовать следующее условие:

 query ="@SQL=" amp; chr(34) amp; "urn:schemas:httpmail:hasattachment" amp; chr(34) amp; "=1"
 

Комментарии:

1. Да, спасибо за информацию! Вы правы, это была одна из проблем, с которой я сталкивался, даже когда код работал так, как я хотел. У меня был «обходной путь», когда я просто создал подпапку, и все электронные письма с именем файла были сброшены туда. Ваше решение, очевидно, кажется гораздо более эффективным / лучшим решением. Мне придется погрузиться в статьи, на которые вы ссылались, чтобы узнать больше о тех методах, на которые вы ссылались.