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

  • 6
    Like
  • 0
    Comment
More than 1 year has passed since last update.

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

'
' アプリケーションをアンインストールする
'
'  ※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