2017-02-14 9 views
1

Я пытаюсь извлечь вложения из Outlook, которые соответствуют шаблону senderemailaddress. Как видно из приведенного ниже кода, я пытаюсь использовать два фильтра, но безрезультатно.Прочтите вложения из Outlook, которые относятся к определенному отправителю с помощью подстановочных знаков

Когда я использую некомментированный фильтр, который в данный момент активен в коде, код не вызывает никаких ошибок и не загружает вложения, соответствующие тестовому примеру. Однако, если я активирую прокомментированный фильтр и запускаю его, я получаю следующую ошибку.

Exception calling "Restrict" with "1" argument(s): "Cannot parse condition. Error at 
"like"." 
At C:\Users\acer\Desktop\outlook.ps1:42 char:2 
+ $filteredItems = $folder.items.Restrict($filter) 
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : NotSpecified: (:) [], MethodInvocationException 
    + FullyQualifiedErrorId : ComMethodTargetInvocation

Код:

$filepath = "C:\folder\subfolder\subsubfolder\" 
function downloadFiles { 
    $filter = "[UnRead]=true AND [SenderEmailAddress] -match @example" 
    #$filter = "[UnRead]=true AND [SenderEmailAddress] -like '*@example*'" 

    Add-Type -Assembly "Microsoft.Office.Interop.Outlook" | Out-Null 
    $olFolders = "Microsoft.Office.Interop.Outlook.olDefaultFolders" -as [type] 

    $outlook = New-Object -ComObject Outlook.Application 
    $namespace = $outlook.GetNameSpace("MAPI") 

    $folder = $namespace.GetDefaultFolder($olFolders::olFolderInBox) 

    #$folder.Items | select SenderEmailAddress 

    $filteredItems = $folder.Items.Restrict($filter) 

    foreach ($objMessage in $filteredItems) { 
     $intCount = $objMessage.Attachments.Count 

     if ($intCount -gt 0) { 
      for ($i=1; $i -le $intCount; $i++) { 
       $objMessage.Attachments.Item($i).SaveAsFile($filepath+$objMessage.Attachments.Item($i).FileName) 
      } 
     } 
     $objMessage.Unread = $false 
    } 

    $outlook.Close 
} 

downloadFiles 

Edit1: Спасибо всем за советы. Я смог сделать это, выполнив фильтрацию с непрочитанным = true и шаблоном, сопоставляющим senderemailaddress с свойствами отфильтрованных писем.

Добавление модифицированного кода:

$filepath = "C:\folder\subfolder\subsubfolder\" 
    function downloadFiles { 
     $filter="[UnRead]=true" 
    $emailfilter = "*@xyz.co.in" 
    $subjectfilter = "test file*" 

    Add-Type -Assembly "Microsoft.Office.Interop.Outlook" | Out-Null 
     $olFolders = "Microsoft.Office.Interop.Outlook.olDefaultFolders" -as [type] 

     $outlook = New-Object -ComObject Outlook.Application 
     $namespace = $outlook.GetNameSpace("MAPI") 

     $folder = $namespace.GetDefaultFolder($olFolders::olFolderInBox) 

     #$folder.Items | select SenderEmailAddress 

     $filteredItems = $folder.Items.Restrict($filter) 

     foreach ($objMessage in $filteredItems) { 
      $subject = $objMessage.Subject 
      $emailaddress = $objMessage.SenderEmailAddress 

      if(($emailaddress -like $emailfilter) -and ($subject -like $subjectfilter)){ 
      $intCount = $objMessage.Attachments.Count 

      if ($intCount -gt 0) { 
       for ($i=1; $i -le $intCount; $i++) { 
        $objMessage.Attachments.Item($i).SaveAsFile($filepath+$objMessage.Attachments.Item($i).FileName) 
       } 
      } 
      $objMessage.Unread = $false 
      } 

      else {continue} 
     } 
     $outlook.Close 
    } 

    downloadFiles 

Теперь проблема планирования этого сценария? Когда я запускаю этот скрипт, используя путь powershell в командной строке, он работает нормально. Но когда я планирую то же самое, это не завершается. Я мог видеть процесс Outlook, созданный диспетчером задач в TaskManager, и должен вручную убить процесс для его завершения. Есть идеи?

ответ

0

Я бы использовал EWS. Сохраняет возможность разрешить программный доступ к Outlook.

Самый простой способ скачать с nuget. Вы можете сделать это в PowerShell, загрузив NuGet:

$sourceNugetExe = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" 
$targetNugetExe = "D:\Program Files\nuget\nuget.exe" # chaneg path to suit 
Invoke-WebRequest $sourceNugetExe -OutFile $targetNugetExe 
Set-Alias nuget $targetNugetExe -Scope Global -Verbose 

Затем загрузите пакет EWS NuGet:

Set-Location D:\Temp # change to suit 
nuget install 'Microsoft.Exchange.WebServices' 

Теперь вы можете начать использовать :)

# load the assembly 
[void][Reflection.Assembly]::LoadFile("D:\Temp\Microsoft.Exchange.WebServices.2.2\lib\40\Microsoft.Exchange.WebServices.dll") 

# set ref to exchange - may need to change the version 
$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2) 

# replace with your email address 
$email = "[email protected]" 

# grab your own credentials 
$s.UseDefaultCredentials = $true 

# discover the url from your email address 
$s.AutodiscoverUrl($email) 

# get a handle to the inbox 
$inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox) 

#create a property set (to let us access the body & other details not available from the FindItems call) 
$psPropertySet = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties) 
$psPropertySet.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text 

$items = $inbox.FindItems(100) # change to suit 

# loop through the emails - at this point, we don't have full info - we have to Load the email 
# restrict on what we do know - if the email is read and if it has attachments 
$items | where { !$_.IsRead -and $_.HasAttachments } | ForEach-Object { 
    # load the email, so we can get to other properties, like attachments, sender, etc 
    $_.Load() 
    # does the sender match our wildcard? 
    if ($_.Sender -like '*lmnopqr*') { 
    # loop through all file attachments 
    $_.Attachments | Where-Object { $_ -is [Microsoft.Exchange.WebServices.Data.FileAttachment] } | ForEach-Object { 
     # save them (yes, Load = Save in this instance!) 
     $_.Load("D:\Temp\$($_.Name)") 
    } 
    } 
} 

Смотрите EWS link для больше информации о том, как взаимодействовать с EWS.

Кроме того, см. Мой другой SO post, который устарел, откуда можно получить сборку EWS, но имеет некоторую полезную информацию о дополнительных методах/свойствах EWS. Он также содержит сведения о том, как использовать альтернативные учетные данные, если вы не используете свои собственные (или в процессе запуска PowerShell нет учетной записи Exchange).

+0

я неспособен access isread свойство в скрипте, даже если оно отображается в списке свойств объекта. Ant предложения –

+0

$ items | select * показывает isread свойство как часть элементов –

+0

Что делает '$ items [0] .IsRead' yield? – TechSpud

0

Поставщик не разрешает использовать Like в своем формате для этого метода. Из этого MSDN article:

Невозможно выполнить операцию «содержит». Например, вы, , не можете использовать Find или Restrict для поиска элементов, имеющих определенное слово в поле Subject. Вместо этого вы можете использовать метод AdvancedSearch , или вы можете прокручивать все элементы в папке и использовать функцию InStr для выполнения поиска в поле, используя .

+0

Но я мог использовать, когда строка является числом. Пример: если мой sendermailaddress был этот/O = ххххх/OU = ОБМЕН административной группы (FYDIBOHF23SPDLT)/CN = реципиентов/CN = 02DE69998DE7457BBC1CAA86E82818DA-lmnopqr я мог бы использовать фильтр -contains lmnopqr сделать то же самое –

 Смежные вопросы

  • Нет связанных вопросов^_^