我尝试从Outlook中提取与senderemailaddress
属性的通配符匹配的附件。从下面的代码中可以看出,我尝试使用两个过滤器,但无济于事。
当我在代码中使用当前处于活动状态的未注释过滤器时,代码不会抛出任何错误,也不会下载与测试用例匹配的附件。但是,如果我激活注释过滤器并运行它,我会收到以下错误。
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:感谢大家的建议。 我能够通过使用unread = 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路径运行此脚本时,它运行正常。但是,当我安排相同时,它没有完成。我可以在TaskManager中看到任务调度程序生成的outlook进程,并且必须手动终止进程以终止进程。有什么想法吗?
答案 0 :(得分:0)
提供商不允许在此方法的过滤器中使用Like
。从MSDN article:
没有办法执行"包含"操作。例如,你 无法使用“查找”或“限制”来搜索具有特定项目的项目 主题字段中的单词。相反,您可以使用AdvancedSearch 方法,或者您可以遍历文件夹中的所有项目并使用 InStr函数在字段中执行搜索。
答案 1 :(得分:0)
我会使用EWS。保存必须允许以编程方式访问Outlook。
最简单的方法是从nuget下载。您可以通过首先下载nuget:
在PowerShell中执行此操作$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 = "your.email@domain.com"
# 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互动的更多信息,请参阅EWS link。
另外,请参阅我的其他SO post,其中有关从哪里获取EWS程序集的过时,但确实有一些关于额外EWS方法/属性的有用信息。如果您没有使用自己的凭据(或运行PowerShell的流程没有Exchange帐户),它还会详细介绍如何使用备用凭据。