我想将电子邮件从一个文件夹移动到另一个文件夹。我知道我需要找到文件夹 ID。这就是我的问题所在。我看到收件箱有一个FindFolders
方法,但我只需要在收件箱中找到文件夹的 ID。
[void] [Reflection.Assembly]::LoadFile("C:Program Files (x86)MicrosoftExchangeWeb Services2.1Microsoft.Exchange.WebServices.dll")
$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
$s.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
$s.AutodiscoverUrl($email)
$inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)
$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($inbox.TotalCount)
# this doesn't work
$TargetFolder = $inbox.FindFolders('MyFolder')
foreach ($item in $items.Items) {
$item.Move($TargetFolder)
}
我还在Outlook中使用VB查找了FolderID
。但这也没有用。我想我需要通过PowerShell找到ID?
$TargetFolder = '00000000DBDD150E618BD0489CDE09859DC24F7A0100949BEDD21F6B4245BEEA6999720A0B090013516500830000'
$item.Move($TargetFolder)
我添加了using namespace
并将其转换为Data.FolderID
.但是,我收到一个错误,它希望它是一个众所周知的文件夹。我创建了一个客户主文件夹。
$TargetFolder = '00000000DBDD150E618BD0489CDE09859DC24F7A0100949BEDD21F6B4245BEEA6999720A0B090013516500830000'
$id = [Data.FolderId]::new($TargetFolder)
$item.Move($id.UniqueId)
我收到这些错误:
无法将参数"
destinationFolderName
"转换为",值为:"00000000DBDD150E618BD0489CDE09859DC24F7A0100949BEDD21F6B4245BEEA6999720A0B090013516500830000
",对于"Move
"键入"Microsoft.Exchange.WebServices.Data.WellKnownFolderName
":无法将值"
00000000DBDD150E618BD0489CDE09859DC24F7A0100949BEDD21F6B4245BEEA6999720A0B090013516500830000
"转换为类型"Microsoft.Exchange.WebServices.Data.WellKnownFolderName
"。错误:"无法将标识符名称
00000000DBDD150E618BD0489CDE09859DC24F7A0100949BEDD21F6B4245BEEA6999720A0B090013516500830000
与有效的枚举器名称匹配。指定以下枚举器名称之一,然后重试:日历, 联系人, 已删除的项目, 草稿, 收件箱, 日记, 便笺, 发件箱, 已发送邮件, 任务, 消息文件夹根, 公用文件夹根, 根, 垃圾邮件, 搜索文件夹, 语音邮件, 可恢复项目根, 可恢复项目删除, 可恢复项目版本, 可恢复项目清除, 存档根, 存档Msg文件夹根, 存档已删除项目, 存档可恢复项目根目录, 存档可恢复项目删除, 存档可恢复项目版本, 存档可恢复项目清除, 同步问题, 冲突, 本地故障, ServerFailures, RecipientCache, QuickContacts, ConversationHistory, ToDoSearch">
At C:UsersjpbDesktopliteratumliteratum.ps1:261 char:1 + $item.Move($id.UniqueId) + ~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodException + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
当我用登录方式尝试您的代码时,我仍然出错。
Using namespace "Microsoft.Exchange.WebServices"
[CmdletBinding()]
param(
[parameter(Mandatory=$true)]
[string]$MailAddress
)
# need to download this!!!!!!!!!!!!
[void] [Reflection.Assembly]::LoadFile("C:Program Files (x86)MicrosoftExchangeWeb Services2.1Microsoft.Exchange.WebServices.dll")
$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
$s.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
$s.AutodiscoverUrl($MailAddress)
$objExchange = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::msgFolderRoot) ###Inbox
<#
Define Extended properties
PR_FOLDER_TYPE: Contains a constant that indicates the folder type.
https://msdn.microsoft.com/en-us/library/office/cc815373.asp
PR_MESSAGE_SIZE_EXTENDED: Contains the sum, in bytes, of the sizes of all properties on a message object.
int64 version of PR_MESSAGE_SIZE
https://msdn.microsoft.com/en-us/library/office/cc839933.aspx
PR_DELETED_MESSAGE_SIZE_EXTENDED: Could not find official reference.
PR_FOLDER_PATH: Could not find official reference.
#>
$PR_FOLDER_TYPE = [Data.ExtendedPropertyDefinition]::new(13825,[Data.MapiPropertyType]::Integer)
$PR_MESSAGE_SIZE_EXTENDED = New-Object Data.ExtendedPropertyDefinition(3592,[Data.MapiPropertyType]::Long);
$PR_DELETED_MESSAGE_SIZE_EXTENDED = New-Object Data.ExtendedPropertyDefinition(26267,[Data.MapiPropertyType]::Long);
$PR_FOLDER_PATH = New-Object Data.ExtendedPropertyDefinition(26293, [Data.MapiPropertyType]::String);
$folderIDCount = [Data.FolderId]::new([Data.WellKnownFolderName]::MsgFolderRoot,$MailAddress)
# Define the FolderView used for Export. Should not be any larger then 1000 folders due to throttling
$folderView = [Data.FolderView]::new(1000)
# Deep Traversal will ensure all folders in the search path are returned
$folderView.Traversal = [Data.FolderTraversal]::Deep;
$ewsPropertySet = [Data.PropertySet]::new([Data.BasePropertySet]::FirstClassProperties)
# Add Properties to the Property Set
$ewsPropertySet.Add($PR_MESSAGE_SIZE_EXTENDED);
$ewsPropertySet.Add($PR_FOLDER_PATH);
$folderView.PropertySet = $ewsPropertySet;
# Exclude any Search Folders in the filter
$searchFilter = [Data.SearchFilter+IsEqualTo]::new($PR_FOLDER_TYPE,"1")
# The Do loop will handle any paging that is required if there are more the 1000 folders in a mailbox
do {
$filterResult = $objExchange.FindFolders($folderIDCount, $searchFilter, $folderView)
foreach ($singleFolder in $filterResult.Folders) {
# Try to get the FolderPath Value and then covert it to a usable String
$folderPathValue = $null
$singleFolder.TryGetProperty($PR_FOLDER_PATH, [ref]$folderPathValue) | Out-Null
# Output folder object to pipeline
$singleFolder | Select-Object Id,DisplayName,@{Name="FolderPath";Expression={$folderPathValue}},FolderClass,ParentFolderId
}
$folderView.Offset += $filterResult.Folders.Count
} while($filterResult.MoreAvailable)
我收到FindFolders
方法的错误:
找不到 "
FindFolders
" 的重载,参数计数:"3
"。At line:50 char:9 + $filterResult = $objExchange.FindFolders($folderIDCount, $sea ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodException + FullyQualifiedErrorId : MethodCountCouldNotFindBest
我可以连接$objExchange
,我得到这些值以及更多:
Id : AAMkADk5ZDNmODk2LTk0NzAtNDZkNi05Mjk1LTNhMjNlYmYzNzg1ZAAuAAAAAADb3RUOYYvQSJzeCYWdwk96AQD+Gq9HeAtSSLFM1nhOxNIuAAAAMAqcAAA=
ParentFolderId : AAMkADk5ZDNmODk2LTk0NzAtNDZkNi05Mjk1LTNhMjNlYmYzNzg1ZAAuAAAAAADb3RUOYYvQSJzeCYWdwk96AQD+Gq9HeAtSSLFM1nhOxNIuAAAAMAqbAAA=
ChildFolderCount: 20
这里的信息会比所需的多一点,但我想展示如何在我为与邮箱交互而创建的 cmdlet 中获取此信息。
如果您查看重载FindFolders()
他们想要的不仅仅是一个字符串来获得您正在寻找的结果。我下面的示例使用最后一个重载
FindFolders(WellKnownFolderName, SearchFilter, FolderView)
使用指定的搜索筛选器和指定的文件夹视图搜索已知文件夹。
这是我必须获取邮箱中所有文件夹的功能。
[CmdletBinding()]
param(
[parameter(Mandatory=$true)]
[string]$MailAddress
)
# Create a reference to Exchange 2010 to match our current environment.
$objExchange = Connect-ExchangeService -MailAddress $MailAddress -DefaultCredentials
<#
Define Extended properties
PR_FOLDER_TYPE: Contains a constant that indicates the folder type.
https://msdn.microsoft.com/en-us/library/office/cc815373.asp
PR_MESSAGE_SIZE_EXTENDED: Contains the sum, in bytes, of the sizes of all properties on a message object. int64 version of PR_MESSAGE_SIZE
https://msdn.microsoft.com/en-us/library/office/cc839933.aspx
PR_DELETED_MESSAGE_SIZE_EXTENDED: Could not find official reference.
PR_FOLDER_PATH: Could not find official reference.
#>
$PR_FOLDER_TYPE = [Data.ExtendedPropertyDefinition]::new(13825,[Data.MapiPropertyType]::Integer)
$PR_MESSAGE_SIZE_EXTENDED = New-Object Data.ExtendedPropertyDefinition(3592,[Data.MapiPropertyType]::Long);
$PR_DELETED_MESSAGE_SIZE_EXTENDED = New-Object Data.ExtendedPropertyDefinition(26267,[Data.MapiPropertyType]::Long);
$PR_FOLDER_PATH = New-Object Data.ExtendedPropertyDefinition(26293, [Data.MapiPropertyType]::String);
$folderIDCount = [Data.FolderId]::new([Data.WellKnownFolderName]::MsgFolderRoot,$MailAddress)
# Define the FolderView used for Export. Should not be any larger then 1000 folders due to throttling
$folderView = [Data.FolderView]::new(1000)
# Deep Traversal will ensure all folders in the search path are returned
$folderView.Traversal = [Data.FolderTraversal]::Deep;
$ewsPropertySet = [Data.PropertySet]::new([Data.BasePropertySet]::FirstClassProperties)
# Add Properties to the Property Set
$ewsPropertySet.Add($PR_MESSAGE_SIZE_EXTENDED);
$ewsPropertySet.Add($PR_FOLDER_PATH);
$folderView.PropertySet = $ewsPropertySet;
# Exclude any Search Folders in the filter
$searchFilter = [Data.SearchFilter+IsEqualTo]::new($PR_FOLDER_TYPE,"1")
#The Do loop will handle any paging that is required if there are more the 1000 folders in a mailbox
do {
$filterResult = $objExchange.FindFolders($folderIDCount, $searchFilter, $folderView)
foreach($singleFolder in $filterResult.Folders){
#Try to get the FolderPath Value and then covert it to a usable String
$folderPathValue = $null
$singleFolder.TryGetProperty($PR_FOLDER_PATH, [ref]$folderPathValue) | Out-Null
# Output folder object to pipeline
$singleFolder | Select-Object Id,DisplayName,@{Name="FolderPath";Expression={$folderPathValue}},FolderClass,ParentFolderId
}
$folderView.Offset += $filterResult.Folders.Count
}while($filterResult.MoreAvailable)
Connect-ExchangeService
只是一个函数,它或多或少地执行了前几行正在做的事情。使用FindFolders()
我从根文件夹搜索并将所有具有一些自定义属性的文件夹返回到$filterResult
中。$filterResult
现在包含有关每个文件夹的信息。特别是他们的身份证。
因此,如果我想将邮件项目移动到另一个文件夹,我可以做这样的事情。
$targetFolderID = ($folders | Where-Object{$_.Displayname -eq $sourceFolder}).ID.UniqueID
$item.Move($targetFolderID)
许多 EWS 参数都需要一个类型dID,而不仅仅是一个字符串。在上一个例子中,我认为这应该触发一个错误,说明类似的东西。无论哪种方式,如果你有一个像这样的字符串来获得 EWS 可以使用的东西
$id = [Data.FolderId]::new($targetFolderID)
您可能会注意到此处的类型名称较短。我的脚本中有Using namespace "Microsoft.Exchange.WebServices"
来减少我的行长。
额外阅读
我很难让我的头被 EWS 包裹起来。这个博客对许多例子提供了极大的帮助,展示了它是如何完成的。作者也是这里经常回答EWS问题的成员。
好的。所以我尝试了一种深入旅行的新方法,以查找从msgFolderRoot
开始的文件夹。
$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
$s.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
$s.AutodiscoverUrl($MailAddress)
#$objExchange = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::msgFolderRoot) ###Inbox
$objExchange = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::msgFolderRoot) ###Inbox
$fv = [Microsoft.Exchange.WebServices.Data.FolderView]100
$fv.Traversal = 'Deep'
$objExchange.Load()
$folders = $objExchange.FindFolders($fv)|select DisplayName,ID
$folders = $objExchange.FindFolders($fv)
foreach ($folder in $folders) {
if ($folder.DisplayName -eq 'LiteratumLicenseInventoryReportArchive') {
$folderMoveTo = $folder;
}
}
$folderMoveTo
然后我通过搜索收件箱找到电子邮件,然后将文件夹转换为文件夹ID并移动该电子邮件。
$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
$s.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
# discover the url from your email address
$s.AutodiscoverUrl($email)
$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($inbox.TotalCount)
foreach ($item in $items.Items) {
$item.load($psPropertySet)
if ($item.Subject.Contains('Subject Test')) {
$convertedFolder = [Data.FolderId]::new($folderMoveTo.Id)
$item.Move($convertedFolder)
break
}
}