コマンドラインからアプリをアンインストールするVBScript

大量のPCを新規セットアップする際に不要なプレインストールソフトをアンインストールするのが面倒だったので、バッチからアンインストールできるスクリプトを作成。

```vbnet
'
' アプリケーションをアンインストールする
'
'  ※msiexecの場合は管理者権限で実行
'
' 使い方：
'   アンインストールコマンドを表示
'     cscript uninst.bat show [名前]
'   アンインストールコマンドを実行
'     cscript uninst.bat uninstall [名前]
'
' 戻り値：
'   0 = 成功
'   1 = 引数が不正
'   2 = アンインストール失敗
'

'========================================
' Function RegGetUninstStr(<レジストリのパス>, <アプリケーション名>)
'   指定されたレジストリからアンインストールコマンドを取得
'========================================
Function RegGetUninstStr(strRegSoft, strAppName)
	'レジストリのサブキーを取得するために、
	'WMIのStdRegProvを使用する
	Set objReg = GetObject("winmgmts://./root/default:StdRegProv")

	Const HKLM = &H80000002

	'アンインストーラ情報の場所
	strBaseKey = strRegSoft & "Microsoft\Windows\CurrentVersion\Uninstall\"

	'レジストリパスから、サブキーを取得
	objReg.EnumKey HKLM, strBaseKey, arrSubKeys

	'サブキーからアンインストールコマンドを検索
	RegGetUninstStr = ""
	For Each strSubKey In arrSubKeys
		'アプリケーション名を取得
		intRet = objReg.GetStringValue(HKLM, strBaseKey & strSubKey, _
		"DisplayName", strValue)
		If intRet <> 0 Then
			intRet = objReg.GetStringValue(HKLM, strBaseKey & strSubKey, _
			"QuietDisplayName", strValue)
		End If
		'指定されたアプリケーションであれば..
		If strValue <> "" Then
			If strValue = strAppName Then
				'アンインストールコマンドを取得
				intRet = objReg.GetStringValue(HKLM, strBaseKey & strSubKey, _
				"UninstallString", strUninst)
				If strUninst <> "" Then
					'戻り値にセットして検索終了
					RegGetUninstStr = strUninst
					Exit For
				End If
			End If
		End If
	Next
End Function

'========================================
' Function UninstallString(<アプリケーション名>)
'   アンインストールコマンドを取得
'========================================
Function UninstallString(strAppName)
	'64bit用アンインストールコマンドを取得
	strVal = RegGetUninstStr("Software\", strAppName)
	'見つからなければ32bit用アプリから検索
	If strVal = "" Then
		strVal = RegGetUninstStr("Software\Wow6432Node\", strAppName)
	End If
	'アンインストールコマンドを返す
	UninstallString = strVal
End Function

'========================================
' Sudo <実行コマンド名>, <引数>
'   管理者権限でコマンド実行
'========================================
Sub Sudo(strCmd, strArg)
	' 管理者権限チェック
	flagPermitted = false
	Set objWMI = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\.\root\cimv2")
	Set osInfo = objWMI.ExecQuery("SELECT * FROM Win32_OperatingSystem")
	For Each os in osInfo
		If left(os.Version, 3) >= 6.0 Then
			flagPermitted = true
		End If
	Next

	' カレントディレクトリ取得
	Set objWShell = WScript.CreateObject("WScript.Shell")
	strCD = objWShell.CurrentDirectory

	' コマンド実行
	Set objApp = WScript.CreateObject("Shell.Application") 
	If flagPermitted Then
		' 権限が無いので昇格して実行
		objApp.ShellExecute strCmd, strArg, strCD, "runas", 1
	Else
		' 権限があるのでそのまま実行
		objApp.ShellExecute strCmd, strArg, strCD, "", 1
	End If
End Sub

'========================================
' Run <実行コマンド(引数付き)>
'   一般ユーザー権限でコマンド実行
'========================================
Sub Run(strCmd)
	Set objShell = WScript.CreateObject("WScript.Shell")
	if Left(strCmd, 1) = """" Then
		'コマンド文字列がダブルクオートで括られていればそのまま実行
		objShell.Run strCmd, 1, TRUE
	Else
		'コマンド文字列をダブルクオートで括って実行
		objShell.Run """" & strCmd & """", 1, TRUE
	End If
End Sub

'========================================
' メイン
'========================================
'引数チェック
If WScript.Arguments.Count < 2 Then
	' 引数が不正
	WScript.Quit(1)
End If

'実行する処理の選択
Select Case UCase(WScript.Arguments(0))
	Case "UNINSTALL"
		'「アンインストール実行」を選択
		flagRun = true
	Case "SHOW"
		'「アンインストールコマンド表示」を選択
		flagRun = false
	Case Else
		' 引数が不正
		WScript.Quit(1)
End Select

'アプリケーション名取得
strAppName = WScript.Arguments(1)

If flagRun Then
	WScript.echo "アンインストール開始: " & strAppName
Else
	WScript.echo "アンインストールコマンド: " & strAppName
End If
strVal = UninstallString(strAppName)
If strVal <> "" Then
	'アンインストーラが見つかった
	Set objFS = WScript.CreateObject("Scripting.FileSystemObject")

	'アンインストールコマンドをコマンド名と引数に分割
	' ※msiexecかどうかを調べるだけなので複雑なパースは不要
	aryStr = Split(strVal, " ", 2)
	strCmd = aryStr(0)
	strArg = aryStr(1)

	'コマンドによって処理を切り替え(MSIEXECかそれ以外)
	If StrComp(objFS.getBaseName(strCmd), "msiexec", 1) = 0 Then
		'コマンドが MSIEXEC だった
		If StrComp(Left(strArg, 2), "/X", 1) = 0 Then
			'アンインストールコマンドなのでオプション追加(リセットなし、確認なし)
			strArg = strArg & " /norestart /qn"
		ElseIf StrComp(Left(strArg, 2), "/I", 1) = 0 Then
			'構成コマンドなのでコマンドを書き換えてオプション追加(リセットなし、確認なし)
			strArg = "/X" & Mid(strArg, 3) & " /norestart /qn"
		Else
			'不明なオプションなのでそのまま実行
		End If
		If flagRun Then
			'MSIEXECは管理者権限で実行
			Sudo strCmd, strArg
		Else
			'アンインストールコマンドを表示して終了
			WScript.echo strCmd & " " & strArg
			WScript.Quit(0)
		End If
	Else
		' その他
		If flagRun Then
			' 一般ユーザー権限で実行
			Run strVal
		Else
			'アンインストールコマンドを表示して終了
			WScript.echo strVal
			WScript.Quit(0)
		End If
	End If

	' アンインストールチェック
	strVal = UninstallString(strAppName)
	If strVal = "" Then
		' アンインストール完了
		WScript.Quit(0)
	Else
		' アンインストール失敗
		WScript.Quit(2)
	End If
Else
	' アンインストーラが見つからなかった
	WScript.Quit(0)
End If
```