#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
класса. Подробнее об этих методах читайте в следующих статьях:
- Как: Используйте методы поиска и FindNext для извлечения почтовых элементов Outlook из папки (C#, VB.NET)
- Как: Используйте метод ограничения для извлечения почтовых элементов Outlook из папки
Например, чтобы получить только элементы с вложениями, вы можете использовать следующее условие:
query ="@SQL=" amp; chr(34) amp; "urn:schemas:httpmail:hasattachment" amp; chr(34) amp; "=1"
Комментарии:
1. Да, спасибо за информацию! Вы правы, это была одна из проблем, с которой я сталкивался, даже когда код работал так, как я хотел. У меня был «обходной путь», когда я просто создал подпапку, и все электронные письма с именем файла были сброшены туда. Ваше решение, очевидно, кажется гораздо более эффективным / лучшим решением. Мне придется погрузиться в статьи, на которые вы ссылались, чтобы узнать больше о тех методах, на которые вы ссылались.