none
Rename Outlook ost file using Powershell and SCCM

    Question

  • Hello,

    I have written a Powershell script that closes Outlook and renames the current logged on user's outlook ost file so that when they start Outlook again it will download all their mail afresh and fix an issue we are currently having after an Exchange server fault.

    This works really well when I run it locally on any machine. The variable used to get the path of the ost file $userprofile = gc env:userprofile returns the correct result.

    However if I run it via SCCM it fails. The reason is that the $userprofile = gc env:userprofile does not give the correct result. 

    I would like to know the best way to run this script on remote machines. If SCCM is not able to do this I am open to any other ideas.

    All clients are running Windows 7

    Tuesday, April 24, 2012 9:10 PM

Answers

  • $userprofile = gwmi win32_userprofile | 
    select @{l="path";e={Join-Path $_.localpath "\AppData\Local\Microsoft\Outlook" }} |
    select -exp path
    
    Get-ChildItem -path $userprofile -Filter "*.ost" -ea silentlycontinue #and do rest to rename
    • Marked as answer by crongity Wednesday, April 25, 2012 10:54 AM
    Wednesday, April 25, 2012 8:51 AM
  • Here is my lastest offering, with a rename instead of delete:

    $computers = Get-Content -Path 'ComputerList.txt'
    foreach ($computer in $computers) {
        $ols = gwmi -Class win32_process -ComputerName $computer | ? { $_.name -eq 'Outlook.exe' }
        foreach ($ol in $ols) { $ol.terminate() | Out-Null }
        Start-Sleep 5
        $ostFiles = gwmi -ComputerName $computer -Query "Select * from CIM_DataFile Where Drive = 'C:' and Extension = 'ost'" 
        foreach ($ostFile in $ostFiles) { $ostFile.rename($ostFile.name + '.old') | Out-Null }
        
        Start-Sleep 2
        Invoke-WmiMethod -ComputerName $computer -Class Win32_Process -Name Create -ArgumentList "c:\Program Files\Microsoft Office\Office14\outlook.exe"
        }


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)


    • Marked as answer by crongity Friday, April 27, 2012 3:38 AM
    • Edited by Bigteddy Friday, April 27, 2012 7:33 AM
    Wednesday, April 25, 2012 9:29 AM

All replies

  • Hi,

    When you run script from SCCM, you run it with other credentials then user from specific machines. And if you run PowerShell script with other credential then 'gc env:userprofile' get path not to logged user but user from credentials. Environment variables used in Powershell are taken from the user who run script.

    To solve this problem you need to check what users log into the machine and then get path to it profiles.

    Wednesday, April 25, 2012 6:15 AM
  • Thanks MichalGajda.

    Unfortunately I have a few hundred computers that I need to run this on. I need the script to find the path for each logged on user if possible 

    Wednesday, April 25, 2012 7:11 AM
  • This article may some help:
    http://blogs.technet.com/b/heyscriptingguy/archive/2011/11/10/use-powershell-to-find-user-profiles-on-a-computer.aspx

    gwmi win32_userprofile -ComputerName $comp | select localpath, sid
    Wednesday, April 25, 2012 7:47 AM
  • Why are you using

    gc env:userprofile

    I would use:

    $env:userprofile

    I don't know if this will make any difference, but I've never seen your usage before.


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Wednesday, April 25, 2012 8:09 AM
  • Thanks that looks really useful.

    gwmi win32_userprofile ¦ select localpath

    Is there a way I can take the results from this line and add them to "\AppData\Local\Microsoft\Outlook" 

    This will allow me to rename every profile's ost file:

    Get-ChildItem -path $userprofile\AppData\Local\Microsoft\Outlook  -Filter "*.ost" | 
    Foreach-Object { Rename-Item -Path $_.fullname -newname ($_.name + ".ostold") }

    Wednesday, April 25, 2012 8:26 AM
  • This is the script that I would use to do what you want.  I haven't tested it completely, but it should work to process a list of remote computers:

    $computers = Get-Content -Path 'ComputerList.txt'
    foreach ($computer in $computers) {
        $ols = gwmi -Class win32_process -ComputerName $computer | ? { $_.name -eq 'Outlook.exe' }
        foreach ($ol in $ols) { $ol.terminate() | Out-Null }
        
        $ostFiles = gwmi -ComputerName $computer -Query "Select * from CIM_DataFile Where Drive = 'C:' and Extension = 'ost'" 
        foreach ($ostFile in $ostFiles) { $ostFile.delete() | Out-Null }
        
        Start-Sleep 2
        & "\\$computer\c$\Program Files\Microsoft Office\Office14\outlook.exe"
        }


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Wednesday, April 25, 2012 8:51 AM
  • $userprofile = gwmi win32_userprofile | 
    select @{l="path";e={Join-Path $_.localpath "\AppData\Local\Microsoft\Outlook" }} |
    select -exp path
    
    Get-ChildItem -path $userprofile -Filter "*.ost" -ea silentlycontinue #and do rest to rename
    • Marked as answer by crongity Wednesday, April 25, 2012 10:54 AM
    Wednesday, April 25, 2012 8:51 AM
  • $ostFiles = gwmi -ComputerName $computer -Query "Select * from CIM_DataFile Where Drive = 'C:' and Extension = 'ost'"     foreach ($ostFile in $ostFiles) { $ostFile.delete() | Out-Null }

    Hi Grant,
    Why use $ostFile.delete() method, shouldn't be Rename method ?

    $ostFiles = gwmi -ComputerName $computer -Query "Select * from CIM_DataFile Where Drive = 'C:' and Extension = 'ost'" 
    foreach ($ostFile in $ostFiles) 
    { 
    	$newname = $ostFile.name -replace ".ost",".oldost"
    	$ostFile.rename($newname)| Out-Null
    }
    
    Wednesday, April 25, 2012 9:11 AM
  • You can rename them, but there's not much point.  These are simply off-line copies of your Mailbox.  I recently had to delete a whole bunch of these due to corruption.  Outlook will build a new .ost file if it can't find one.  I'm sure you know this.

    One mistake in my solution is the restarting of Outlook.  That last line won't work, so I took it out.


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Wednesday, April 25, 2012 9:18 AM
  • Here is my lastest offering, with a rename instead of delete:

    $computers = Get-Content -Path 'ComputerList.txt'
    foreach ($computer in $computers) {
        $ols = gwmi -Class win32_process -ComputerName $computer | ? { $_.name -eq 'Outlook.exe' }
        foreach ($ol in $ols) { $ol.terminate() | Out-Null }
        Start-Sleep 5
        $ostFiles = gwmi -ComputerName $computer -Query "Select * from CIM_DataFile Where Drive = 'C:' and Extension = 'ost'" 
        foreach ($ostFile in $ostFiles) { $ostFile.rename($ostFile.name + '.old') | Out-Null }
        
        Start-Sleep 2
        Invoke-WmiMethod -ComputerName $computer -Class Win32_Process -Name Create -ArgumentList "c:\Program Files\Microsoft Office\Office14\outlook.exe"
        }


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)


    • Marked as answer by crongity Friday, April 27, 2012 3:38 AM
    • Edited by Bigteddy Friday, April 27, 2012 7:33 AM
    Wednesday, April 25, 2012 9:29 AM
  • That's magic MichalGajda!

    Here's the script that did the job:

    $erroractionpreference = "silentlycontinue"

    $userprofile = gwmi win32_userprofile | select @{l="path";e={Join-Path $_.localpath "\Appdata\Local\Microsoft\Outlook"}} | select -exp path

    Get-Process outlook | % { $_.CloseMainWindow() }

    Start-Sleep -s 120

    Get-ChildItem -path $userprofile -Filter "*.ost" | ForEach-Object {Rename-Item -path $_.fullname -newname ($_.name + ".ostold")}

    Wednesday, April 25, 2012 10:56 AM
  • Hi Bigteddy,

    I really needed the script to rename the file not to delete, thanks for your help

    Wednesday, April 25, 2012 10:57 AM
  • I thought you wanted a script that could be run on remote computers.  The script you are using will only work on the local computer.

    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Wednesday, April 25, 2012 11:05 AM
  • It worked perfectly on all the remote computers, I pushed it out and executed it using SCCM.
    Thursday, April 26, 2012 10:55 PM