Why I made this?
Opening Outlook in “normal” mode when being offline is frustrating. I am making this script so that I have the liberty to choose which mode to open Outlook in.
Credits
- Start Outlook in Offline Mode (without opening it first) | Mike Crowley’s Whiteboard
- How to Get, Edit, Create and Delete Registry Keys with PowerShell (netwrix.com)
- Build Interactive PowerShell Menus (adamtheautomator.com)
- Hide the Windows Terminal console window with PowerShell – Stack Overflow
The Script
Save the following code as open-Outlook.ps1
, and link it with shortcut. The next time you open Outlook, use the short cut whenever you want to open Outlook
$outlookPath = "C:\Program Files\Microsoft Office\root\Office16\OUTLOOK.EXE"
$outlookRegPath = "HKCU:\Software\Microsoft\Office\16.0\Outlook\Profiles\Outlook\0a0d020000000000c000000000000046"
$outlookRegProp = "00030398"
$online = New-Object System.Management.Automation.Host.ChoiceDescription 'O&nline', 'Open Outlook (online mode)'
$offline = New-Object System.Management.Automation.Host.ChoiceDescription 'O&ffline', 'Open Outlook (offline mode)'
$options = [System.Management.Automation.Host.ChoiceDescription[]]($online, $offline)
$title = 'Open-Outlook.ps1'
$message = 'Which mode do you want to open in?'
Clear-Host
# The $WindowStates hashtable had two entries for 'MAXIMIZE' and 'SHOWMAXIMIZED' with the same value. Since the ValidateSet attribute ensures that only valid strings are used as keys, and the hashtable is used to map these strings to their corresponding integer values, the duplicate entry is unnecessary and has been removed.
# The Set-Alias command was moved to the BEGIN block to keep the alias definition close to the function definition, which is a common practice for better script organization and readability.
function Hide-ConsoleWindow() {
$ShowWindowAsyncCode = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);'
$ShowWindowAsync = Add-Type -MemberDefinition $ShowWindowAsyncCode -name Win32ShowWindowAsync -namespace Win32Functions -PassThru
$hwnd = (Get-Process -PID $pid).MainWindowHandle
if ($hwnd -ne [System.IntPtr]::Zero) {
# When you got HWND of the console window:
# (It would appear that Windows Console Host is the default terminal application)
$ShowWindowAsync::ShowWindowAsync($hwnd, 0)
} else {
# When you failed to get HWND of the console window:
# (It would appear that Windows Terminal is the default terminal application)
# Mark the current console window with a unique string.
$UniqueWindowTitle = New-Guid
$Host.UI.RawUI.WindowTitle = $UniqueWindowTitle
$StringBuilder = New-Object System.Text.StringBuilder 1024
# Search the process that has the window title generated above.
$TerminalProcess = (Get-Process | Where-Object { $_.MainWindowTitle -eq $UniqueWindowTitle })
# Get the window handle of the terminal process.
# Note that GetConsoleWindow() in Win32 API returns the HWND of
# powershell.exe itself rather than the terminal process.
# When you call ShowWindowAsync(HWND, 0) with the HWND from GetConsoleWindow(),
# the Windows Terminal window will be just minimized rather than hidden.
$hwnd = $TerminalProcess.MainWindowHandle
if ($hwnd -ne [System.IntPtr]::Zero) {
$ShowWindowAsync::ShowWindowAsync($hwnd, 0)
} else {
Write-Host "Failed to hide the console window."
}
}
}
switch ($host.ui.PromptForChoice($title, $message, $options, 0))
{
# Open Outlook online mode
0 {
Write-Host "Reverting to online mode..."
Set-ItemProperty $outlookRegPath -name $outlookRegProp -Value ([byte[]](0x02,0x00,0x00,0x00))
Write-Host "Opening Outlook..."
start-process $outlookPath
}
# Open Outlook offline mode
1 {
Write-Host "Setting offline mode..."
Set-ItemProperty $outlookRegPath -name $outlookRegProp -Value ([byte[]](0x01,0x00,0x00,0x00))
Hide-ConsoleWindow
Write-Host "Opening Outlook and wait..."
start-process $outlookPath -Wait
Write-Host "Reverting to online mode..."
Set-ItemProperty $outlookRegPath -name $outlookRegProp -Value ([byte[]](0x02,0x00,0x00,0x00))
}
}