迭代多个 Outlook COM 对象失败

Iterating multiple Outlook COM Object fails

我们遇到了一个非常奇怪的问题。当遍历 public 文件夹名称数组中的多个元素时,PowerShell 有时会引发错误。但并非总是如此。

当运行下面的代码只有一个元素作为输入时,它工作正常,但是当定义了多个元素时,第二次迭代会抛出错误。

根据 this Microsoft 文章,应该 Release COM-Object,但这也不起作用。

代码

Param (
    [String]$Mail         = 'User@donain.com',
    [String]$ImportFile   = 'C:\Scripts\Import.txt'
)

$Import = Get-Content $ImportFile

$Start = "\Public Folders - $Mail"
Add-Type -AssemblyName 'Microsoft.Office.Interop.Outlook'

foreach ($L in $Import) {
    $PSTFile = "$ExportFolder$($L -replace '[^A-Za-z0-9-_ \.\[\]]', ' ').pst"

    $Outlook = New-Object -ComObject Outlook.Application -Verbose:$false
    $Namespace = $Outlook.GetNameSpace('MAPI')

    $AllPublicFolders = $Namespace.Folders | where FolderPath -EQ $Start | ForEach-Object {
        $Start = $Start + '\All Public Folders'
        $_.Folders | where FolderPath -EQ $Start
    }

    $Split = $L.Split('\')

    $Folder = Switch ($Split.Count) {
        1 {$AllPublicFolders.Folders.Item($Split[0])}
        2 {$AllPublicFolders.Folders.Item($Split[0]).Folders.Item($Split[1])}
        3 {$AllPublicFolders.Folders.Item($Split[0]).Folders.Item($Split[1]).Folders.Item($Split[2])}
        4 {$AllPublicFolders.Folders.Item($Split[0]).Folders.Item($Split[1]).Folders.Item($Split[2]).Folders.Item($Split[3])}
        5 {$AllPublicFolders.Folders.Item($Split[0]).Folders.Item($Split[1]).Folders.Item($Split[2]).Folders.Item($Split[3]).Folders.Item($Split[4])}
        6 {$AllPublicFolders.Folders.Item($Split[0]).Folders.Item($Split[1]).Folders.Item($Split[2]).Folders.Item($Split[3]).Folders.Item($Split[4]).Folders.Item($Split[5])}
        7 {$AllPublicFolders.Folders.Item($Split[0]).Folders.Item($Split[1]).Folders.Item($Split[2]).Folders.Item($Split[3]).Folders.Item($Split[4]).Folders.Item($Split[5]).Folders.Item($Split[6])}
        8 {$AllPublicFolders.Folders.Item($Split[0]).Folders.Item($Split[1]).Folders.Item($Split[2]).Folders.Item($Split[3]).Folders.Item($Split[4]).Folders.Item($Split[5]).Folders.Item($Split[6]).Folders.Item($Split[7])}
        9 {$AllPublicFolders.Folders.Item($Split[0]).Folders.Item($Split[1]).Folders.Item($Split[2]).Folders.Item($Split[3]).Folders.Item($Split[4]).Folders.Item($Split[5]).Folders.Item($Split[6]).Folders.Item($Split[7]).Folders.Item($Split[8])}
    }

    Write-Verbose "Folder '$($Folder.FolderPath.TrimStart($Start))'"

    Write-Verbose "Add PST"
    $NameSpace.AddStore($PSTFile)
    $PSTStore = $NameSpace.Stores | where {$_.FilePath -eq $PSTFile}

    Write-Verbose "Copy content to PST"
    $Folder.CopyTo($PSTStore) | Out-Null

    Write-Verbose "Remove PST"
    $PST = $NameSpace.Stores | where {$_.FilePath -eq $PSTFile}
    $PSTRoot= $PST.GetRootFolder()
    $PSTFolder= $NameSpace.Folders.Item($PSTRoot.Name)
    $NameSpace.GetType().InvokeMember('RemoveStore',[System.Reflection.BindingFlags]::InvokeMethod,$null,$Namespace,($PSTFolder))

    $Outlook.Quit()
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Outlook)
    Remove-Variable Outlook

    Start-Sleep -Seconds 5
}

导入文件

WEUR - COMPANY\DAF\Tableau de bord IB\Année 2002 juillet
WEUR - COMPANY\DAF\Tableau de bord IB\Année 2002 Août

错误

Failed for path 'WEUR - DOMAIM\DAF\Tableau de bord IB\Année 2002 Août': You cannot call a method on a null-va
lued expression.

发现问题:

$AllPublicFolders = $Namespace.Folders | where FolderPath -EQ "\Public Folders - $Mail" | ForEach-Object {
    $_.Folders | where FolderPath -EQ "\Public Folders - $Mail\All Public Folders"
}