将旧的公共文件夹导出到文件系统上的共享的脚本

将旧的公共文件夹导出到文件系统上的共享的脚本

是否有 PowerShell cmdlet 可以将公共文件夹的内容从 Exchange 2007 导出到网络上的 PST?我有大约 100 个公共文件夹需要归档到网络上的不同位置,并且想自动执行该过程。

然后还需要能够删除公共文件夹。

如果不是 PowerShell,是否有其他实用程序可以从命令行执行相同操作?

谢谢,罗布。

答案1

我相信如果没有第三方工具,您将需要使用 Outlook 来导出公共文件夹。

答案2

即使五年过去了,我还是找不到任何如何做到这一点的例子,所以我使用了 Glen Scales 出色的 EWS 和 PowerShell 博客文章来拼凑它。它针对 Exchange 2013 SP1 进行了调整,但功能非常基础,因此它也应该适用于早期版本。

将旧的公共文件夹导出到文件系统上的共享的脚本

#Needs to run an account with PublishingAuthor rights to the PFs
#
# Kev Maitland 08/09/15

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://yourMailServer.yourDomain.local/PowerShell/ -Authentication Kerberos 
Import-PSSession $Session -AllowClobber

$EWSServicePath = '\\yourMailServer\C$\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll'
Import-Module $EWSServicePath

#If necessary, grant Owner permissions to each folder the Public Folder hierarchy to ensure we export everything
#Get-PublicFolder -Identity "\" -Recurse | Add-PublicFolderClientPermission -AccessRights Owner -User "yourDomain\HighlyPriveligedAccount"


#Set some variables
$ExchVer = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013_SP1
$ewsUrl = "https://mail.yourDomain.co.uk/EWS/Exchange.asmx"
$upnExtension = "yourDomain.local"
$smtpServer = "yourMailServer.yourDomain.local"
$pFRootPath = "\"
$outputPathRoot = "\\HV05\PF"

#Prepare some functions From Glen Scales http://gsexdev.blogspot.co.uk/2013/08/public-folder-ews-how-to-rollup-part-1.html
function FolderIdFromPath{  
    param ($FolderPath = "$( throw 'Folder Path is a mandatory Parameter' )")  
    process{  
        ## Find and Bind to Folder based on Path    
        #Define the path to search should be seperated with \    
        #Bind to the MSGFolder Root    
        $folderId = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::PublicFoldersRoot)     
        $tfTargetFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderId)    
        #Split the Search path into an array    
        $fldArray = $FolderPath.Split("\")  
         #Loop through the Split Array and do a Search for each level of folder  
        for ($lint = 1; $lint -lt $fldArray.Length; $lint++) {  
            #Perform search based on the displayname of each folder level  
            $fvFolderView = new-object Microsoft.Exchange.WebServices.Data.FolderView(1)  
            $SfSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,$fldArray[$lint])  
            $findFolderResults = $service.FindFolders($tfTargetFolder.Id,$SfSearchFilter,$fvFolderView)  
            if ($findFolderResults.TotalCount -gt 0){  
                foreach($folder in $findFolderResults.Folders){  
                    $tfTargetFolder = $folder                 
                }  
            }  
            else{  
                "Error Folder Not Found"   
                $tfTargetFolder = $null   
                break   
            }      
        }   
        if($tfTargetFolder -ne $null){ 
            return $tfTargetFolder.Id.UniqueId.ToString() 
        } 
    } 
} 
function getPublicFolderViaEws([string]$publicFolderPath){
    $folderId = new-object Microsoft.Exchange.WebServices.Data.FolderId(FolderIdFromPath -FolderPath $publicFolderPath)
    [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderId)    
    }

#Get set up using the current user's security context
$windowsIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$sidbind = "LDAP://<SID=" + $windowsIdentity.user.Value.ToString() + ">"
$aceuser = [ADSI]$sidbind
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService($exchver)
$service.Url = $ewsUrl
$service.AutodiscoverUrl($aceuser.mail.ToString())

$propertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)  #Get all the default properties of the items in the Public Folders
$propertySet.Add([Microsoft.Exchange.WebServices.Data.ItemSchema]::MimeContent)  #Add the MimeContent property too, so that we can send it directy to the filestream later



foreach ($folderPS in Get-PublicFolder -Recurse){
    New-Item -Path "$outputPathRoot$($folderPS.ParentPath)\$($folderPS.Name)" -ItemType Directory #Make a filesystem folder to match the Public Folder hierarchy
    $folderEws = getPublicFolderViaEws -publicFolderPath "$($folderPS.ParentPath)\$($folderPS.Name)".Replace("\\","\") #Bodge the odd occasion where we end up with two backslashes in a folder name
    $itemView =  New-Object Microsoft.Exchange.WebServices.Data.ItemView(10)  
    $foundItems = $null  
    do{  
        $foundItems = $service.FindItems($folderEws.Id,$itemView) #Get the first batch of objects in the current Public Folder
        [Void]$service.LoadPropertiesForItems($foundItems,$propertySet) #Load the properties we specified earlier
        $i = $null
        foreach($email in $foundItems.Items){
            while(Test-Path "$outputPathRoot$($folderPS.ParentPath)\$($folderPS.Name)\$($email.Subject.Replace(":",'').Replace("/",'').Replace("\",'').Replace("*",'').Replace("?",'').Replace("<",'').Replace(">",'').Replace("|",''))$i"){ #Remove all illegal filesystem characters from the subject of the e-mail. If the result already exists on the filesystem, add an incremented number until it is unique (so that we don't accidentally overwrite e-mail threads)
                $i++
                }
            [System.IO.File]::WriteAllBytes("$outputPathRoot$($folderPS.ParentPath)\$($folderPS.Name)\$($email.Subject.Replace(":",'').Replace("/",'').Replace("\",'').Replace("*",'').Replace("?",'').Replace("<",'').Replace(">",'').Replace("|",''))$i.eml", $email.MimeContent.Content) #Stream the MimeContent to a file on the filesystem
            }
        $itemView.Offset += $foundItems.Items.Count  #Get ready to process the next batch of e-mails in the Public Folder
        }
    while($foundItems.MoreAvailable -eq $true) 
    }

答案3

您不能使用 PowerShell 将公用文件夹导出到 PST:

您可以使用以下方法进行操作:

  1. 使用 Outlook:导入/导出向导

  2. 使用第三方工具

您还可以查看TechNet 讨论以获得更多帮助。

相关内容