≡ Menu

How to Test Outlook (PST) Personal Folder File Access with PowerShell

So, let’s say you’ve got a few hundred or thousand PST’s sitting in a folder somewhere. Some may be corrupt or password protected. You want to verify which ones are accessible, but it will take hours to open each of them in Outlook to check. What do you do? PowerShell of course. Luckily, automating Outlook via PowerShell is easy. Below you will find a function you can use to check tons of PST files in no time. You just need a machine with PowerShell and Outlook installed. I used Outlook 2013 and PowerShell v3 to write and test this code.

function Test-PSTFile {
  param(
    [Parameter(Position=1, ValueFromPipeline=$true, Mandatory=$true)]
    $FilePath,
    [Parameter(Position=2, Mandatory=$false)]
    $ErrorLog
    )

  process {
         #Create an instance of Outlook
         $null = Add-type -assembly Microsoft.Office.Interop.Outlook 
         $olFolders = 'Microsoft.Office.Interop.Outlook.olDefaultFolders' -as [type]  
         $outlook = new-object -comobject outlook.application

         #Open the MAPI profile
         $namespace = $outlook.GetNameSpace('MAPI')
     try {
         #Try to add the PST file to the profile
         $namespace.AddStore($FilePath)

         #Try to read the root folder name
         $PST = $namespace.Stores | ? {$_.FilePath -eq $FilePath}
         $PSTRoot = $PST.GetRootFolder()         

         if($PSTRoot) {
            New-Object PSObject -Property @{
                FileName = $FilePath
                Valid = $True
            }
         }

         #Disconnect the PST
         $PSTFolder = $namespace.Folders.Item($PSTRoot.Name)
         $namespace.GetType().InvokeMember('RemoveStore',[System.Reflection.BindingFlags]::InvokeMethod,$null,$namespace,($PSTFolder))
     }
     catch {
         #If logging is on, save the error to the log
         if($ErrorLog) {
            Add-Content -Path $ErrorLog -Value ("Ran into a problem with {0} at {1}. The error was {2}" -f $FilePath, (Get-Date).ToString(),$_.Exception.Message)
         }

         #Output a failure record
         New-Object PSObject -Property @{
            FileName = $FilePath
            Valid = $False
         }
     }
  }
}

The way this thing works is it adds the PST to your existing Outlook MAPI profile. If the PST file can be opened and read from you can assume everything is good. Otherwise, this function can optionally record the bad file names and the exception messages to an error log for later review. To run this, add the function to your shell session and you’re ready to go. Here’s a few examples of how you might use it.

First, of course, you could run it one file at a time. Cool, but not really that impressive.

Test-PSTFile c:\emails.pst -ErrorLog c:\errors.txt

The real productivity comes from doing this in bulk, as shown in this one liner that tests all the PST files in a particular directory. This is much cooler.

dir C:\PSTs *.pst | 
	select -ExpandProperty fullname | 
		Test-PSTFile -ErrorLog c:\errors.txt

The output would be similar to the following.

Valid FileName
----- --------
 True C:\PSTs\dave.pst
 True C:\PSTs\joe.pst
False C:\PSTs\sarah.pst
 True C:\PSTs\steve.pst

Other useful and related code samples can be found here and here.

3 comments… add one

  • Ayanna December 3, 2013, 1:20 am

    Hi,

    is it possible to add pst to outlook using powershell? I have been searching the internet all night and your script is the closest script I found. I am new to Powershell Thanks

  • -Jason February 27, 2014, 7:32 am

    Is there a way to make this recursive for all pst files in all sub folders. The archive is broken up into folders by employeeno.firstname.lastname/email

  • Mike Pfeiffer February 27, 2014, 7:36 am

    Yeah, just add the recursion to the Dir/Get-Childitem command:

    dir C:\PSTs *.pst -Recurse | 
    	select -ExpandProperty fullname | 
    		Test-PSTFile -ErrorLog c:\errors.txt
    

Leave a Comment