Search code examples
vbapowershelloutlookcom

Error while restarting MS Outlook, but "sleep 30" fixes error


Script body:

$Outlook = [Runtime.InteropServices.Marshal]::GetActiveObject("Outlook.Application")
$Outlook.quit()
Get-Process OUTLOOK -ErrorAction SilentlyContinue | Wait-Process -ErrorAction SilentlyContinue
Start-Process "C:\Program Files (x86)\Microsoft Office\root\Office16\OUTLOOK.EXE"
#sleep 30
$Outlook = [Runtime.InteropServices.Marshal]::GetActiveObject("Outlook.Application")
$NameSpace = $Outlook.getNamespace("MAPI")
$NameSpace.stores | where {$_.ExchangeStoreType -eq 3} | Select-Object DisplayName,FilePath

I'd like to restart MS Outlook and get a list of PST files. The code doesn't work with an error:

Exception calling "GetActiveObject" with "1" argument(s): "Operation unavailable (Exception from HRESULT: 0x800401E3 (MK_E_UNAVAILABLE))"
At C:\open1\restart-outlook.ps1:6 char:1
+ $Outlook = [Runtime.InteropServices.Marshal]::GetActiveObject("Outloo ...

If I uncomment "sleep 30" in line 5 the code will work. But computers are different some need "sleep 120" to get MS Outlook fully operational. Is there any other way besides putting "sleep" operator in the code?


Solution

  • There is no need to use the Marshal.GetActiveObject method to get the running instance of Outlook twice. Typically, it is used when you want to get the already running instance, not started by your code. But even if you create a new Application instance for automating it you get the same results because Outlook is a singleton - you can't start two instances simultaneously.

    Instead of using the sleep statement in the code I'd suggest handling the MAPILogonComplete event of the Application class which is fired after the user has logged onto the system. So, in the event handler you may get all the required information.