リモートレジストリでOutlook PSTファイルの場所を取得する

Outlookが入ったPCを複数台同時に入れ替えるような場面でPSTファイルの場所をすぐに特定できれば便利です。

PSTファイルのパスはこのレジストリに保管されているのですが、デコードしなければ読むことができません。
(Outlook2003ではMAPI経由で読み出しができない模様)

HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles

こういうニーズに答えてくれるPowerShellがなかなか見つからなかったので自分で作ってみました。

HIVEはユーザーのSIDとなります。ユーザー名からSIDを取得する方法はこのあたりの記事が参考になります。

$computername = "COMPUTERNAME"
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('Users', $computername)
$HIVE = "S-1-2-34-5678901234-5678901234-5678901234-56789"

$MAPI_PROFILE_KEY = "Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles"
$MAPI_SERVICES_KEY = "9207f3e0a3b11019908b08002b2a56c2"
$PR_STORE_PROVIDERS = "01023d00"
$PR_PST_PATH = "001f6700"

$regKey= $reg.OpenSubKey("$($HIVE)\$($MAPI_PROFILE_KEY)")
$strDefaultProfile = $regkey.GetValue("DefaultProfile")
$strProfileKey = $MAPI_PROFILE_KEY + "\" + $strDefaultProfile + "\"

$regKey= $reg.OpenSubKey("$($HIVE)\$($strProfileKey)$($MAPI_SERVICES_KEY)")
$arrStoreUIDs = $regkey.GetValue($PR_STORE_PROVIDERS)

$iCount = $arrStoreUIDs.Length/16

$results = @()
$num = 0
for( $i=0 ; $i -lt $iCount ; $i++ ){
	$strServiceKey = ""
	for( $j=0 ; $j -lt 16 ; $j++ ){
		$hex = "0" + "{0:X}" -f $arrStoreUIDs[$i*16+$j]
		if( $hex.length -gt 2 ){
			$hex = $hex.substring( $hex.length - 2  , 2 )
		}
		$strServiceKey += $hex
	}
	$regKey= $reg.OpenSubKey("$($hive)\$($strProfileKey)$($strServiceKey)")
	$pstPath = $regkey.GetValue($PR_PST_PATH)
	if( $pstPath ){
		$pstPath = [System.Text.Encoding]::Unicode.GetString($pstPath)
		if( $pstPath.EndsWith([char]0) ){
			$pstPath = $pstPath.substring( 0, $pstPath.length-1 )
		}
		write-host $pstPath
	}
}