复制outlook文件夹时出现Powershell错误

时间:2022-11-26 00:27:01

I try to make copy of all folders from user account into pst file. Script works fine for all folders except Inbox. When I try to copy data from inbox at end of copying I have error

我尝试将用户帐户中的所有文件夹复制到pst文件中。脚本适用于除收件箱之外的所有文件夹。当我在复制结束时尝试从收件箱中复制数据时,我有错误

Exception calling "CopyTo" with "1" argument(s): "Cannot move or copy folders. Cannot copy folder. A top-level folder cannot be copied to one of its subfolders. Or, you may not have appropriate permissions for the folder. To check your permissions for the folder, right-click the folder, and then click Properties on the shortcut menu."

使用“1”参数调用“CopyTo”的异常:“无法移动或复制文件夹。无法复制文件夹。*文件夹无法复制到其子文件夹之一。或者,您可能没有该文件夹的相应权限。要检查文件夹的权限,请右键单击该文件夹,然后单击快捷菜单上的“属性”。

Script below

$start = Get-Date

#checking if outlook is running
$isRunning = (@(Get-Process -ea silentlycontinue OUTLOOK).count -gt 0)

#showing dialog to choose direcotry where pst should be saved
$app = new-object -com Shell.Application
$folder = $app.BrowseForFolder(0, "Select Folder", 0, "C:\")
if ($folder.Self.Path -ne "") {
    $path = $folder.Self.Path+"\"+$env:USERNAME+".pst"
} else {
    Write-Host "directory not selected. Exiting.."
    [Environment]::Exit(1)
}

#reference to outlook
Add-Type -Assembly "Microsoft.Office.Interop.Outlook" | out-null
$outlook = New-Object -ComObject outlook.application
$ns = $outlook.GetNamespace("MAPI")

#adding personal archive file
$ns.AddStoreEx($path, 1)
Write-Host created $path
$dst = $ns.Folders.GetLast()
Write-Host folder name: $dst.Name

#list of directory types to copy. more details https://msdn.microsoft.com/en-us/library/office/ff861868.aspx
$folderTypes = 9,10,3,16,6,12,4,5,30,13,28

#iterating trough list of directories and for each dir make copy in pst file. next counting of objects in archive and pst
foreach ($id in $folderTypes) { 
    $src = $ns.GetDefaultFolder($id)
    $tmp = $src.copyTo($dst)
    Write-Host copied to $tmp.name 
}

#deattaching personal store from outlook
$ns.GetType().InvokeMember('RemoveStore',[System.Reflection.BindingFlags]::InvokeMethod, $null, $ns, ($dst))
Write-Host $dst.name closed

#if outlook wasn't running on start we must close it
if (-not $isRunning) {
    Write-Host closing outlook
    $outlook.Quit()
}

$end = Get-Date
$diff = New-TimeSpan -start $start -end $end
Write-Host done
"time elapsed {0:g}" -f $diff

Any ideas why this error occurs? Thanks in advace

有什么想法发生这个错误?谢谢你的推荐

1 个解决方案

#1


Make sure that you don't have the DisableCrossAccountCopy key in the windows registry set. Here is what the CopyTo method description states:

确保Windows注册表集中没有DisableCrossAccountCopy键。以下是CopyTo方法描述所述的内容:

Setting the REG_MULTI_SZ value, DisableCrossAccountCopy, in HKCU\Software\Microsoft\Office\14.0\Outlook in the Windows registry has the side effect of disabling this method.

在Windows注册表中的HKCU \ Software \ Microsoft \ Office \ 14.0 \ Outlook中设置REG_MULTI_SZ值DisableCrossAccountCopy具有禁用此方法的副作用。

Also I'd suggest releasing underlying COM objects in the code instantly. Use System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Outlook object when you have finished using it. This is particularly important if your add-in attempts to enumerate more than 256 Outlook items in a collection that is stored on a Microsoft Exchange Server. Then set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. Read more about that in the Systematically Releasing Objects article.

此外,我建议立即在代码中释放基础COM对象。使用System.Runtime.InteropServices.Marshal.ReleaseComObject释放Outlook对象。如果您的加载项尝试枚举存储在Microsoft Exchange Server上的集合中超过256个Outlook项目,这一点尤为重要。然后在Visual Basic中将变量设置为Nothing(C#中为null)以释放对该对象的引用。在“系统释放对象”一文中了解更多相关信息。

#1


Make sure that you don't have the DisableCrossAccountCopy key in the windows registry set. Here is what the CopyTo method description states:

确保Windows注册表集中没有DisableCrossAccountCopy键。以下是CopyTo方法描述所述的内容:

Setting the REG_MULTI_SZ value, DisableCrossAccountCopy, in HKCU\Software\Microsoft\Office\14.0\Outlook in the Windows registry has the side effect of disabling this method.

在Windows注册表中的HKCU \ Software \ Microsoft \ Office \ 14.0 \ Outlook中设置REG_MULTI_SZ值DisableCrossAccountCopy具有禁用此方法的副作用。

Also I'd suggest releasing underlying COM objects in the code instantly. Use System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Outlook object when you have finished using it. This is particularly important if your add-in attempts to enumerate more than 256 Outlook items in a collection that is stored on a Microsoft Exchange Server. Then set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. Read more about that in the Systematically Releasing Objects article.

此外,我建议立即在代码中释放基础COM对象。使用System.Runtime.InteropServices.Marshal.ReleaseComObject释放Outlook对象。如果您的加载项尝试枚举存储在Microsoft Exchange Server上的集合中超过256个Outlook项目,这一点尤为重要。然后在Visual Basic中将变量设置为Nothing(C#中为null)以释放对该对象的引用。在“系统释放对象”一文中了解更多相关信息。