WindowsOS向けSophos製品のアンインストール自動化バッチを作成してみた

## はじめに
WindowsOS向けSophos製品の自動アンインストールを可能とするスクリプトを作成しました。
需要があるかは分かりませんが、何かの役に立てれば幸いです。

## 注意
スクリプト自体は2018年頃に作成したものになります。
また、環境によっては正常に動作しないことも考えられるため、ご了承ください。

## 作成経緯
- 公式のアンインストール手順がコンパネから「プログラムの追加と削除」画面から**手動**で消す手順となっており、面倒であったため
　参考ページ：https://docs.sophos.com/esg/endpoint-security-and-control/10-6/help/ja-jp/esg/Endpoint-Security-and-Control/tasks/Uninstall_Sophos_security_software_TP.html
- 手動で行う以上、誤ってSophos以外のソフトウェアを削除する可能性もあり、運用上のリスクとなりうると判断したため ~~(普通にやればミスらないが、テキトーな自分ならミスりそうと思ったので)~~

## 対象OS
- Windows10
- WIndows Server 2012-2019
## スクリプト構成
デスクトップ
　┗Sophos_Uninstall
　　┗Script
　　　┗Syori.ps1
　　　　Win_Sophos_Uninstall.bat
　　┗[ホスト名]_Command　　　　　　 ※アンインストールコマンドが作成されるフォルダ
　　┗[ホスト名]_CommandLog　　　　　※アンインストールコマンドのログ出力先
　　┗[ホスト名]_file　　　　　　　　　　※コマンド生成用Workフォルダ
　　┗[ホスト名]_regBK　　　　　　※レジストリバックアップ用フォルダ
## 実行方法
【前提条件】タンパープロテクションを無効にする。　**※ここだけは手動です。ご了承ください。**
 参考ページ：https://docs.sophos.com/esg/endpoint-security-and-control/10-6/help/ja-jp/esg/Endpoint-Security-and-Control/tasks/Disable_tamper_protection.html

デスクトップに配置した[Sophos_Uninstall\Script\Win_Sophos_Uninstall.bat」を実行する。

## 大まかな流れ
1. 「タンパープロテクションを無効にしたか？」ポップアップを表示
    ※「はい」を選択したら後続手順へ、「いいえ」を選択すると、処理終了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2774397/5cc79974-2939-aae2-32c5-3f00115038c6.png)

1. Sophos Autoupdate Serviceの停止
1. 各WORKフォルダを作成
1. レジストリのバックアップ
1. Sophosプログラムのレジストリ情報を取得
1. 取得したレジストリ情報からアンインストールコマンドを生成
1. アンインストール可否についてのメッセージボックス出力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2774397/b461c46e-4597-6c2f-c451-312ae77c953e.png)
1. アンインストール実施

## ソースコード
```bat:Win_Sophos_Uninstall.bat
REM 処理ファイルを定義
set FILE=C:\Users\%USERNAME%%\Desktop\Sophos_Uninstall\Script\syori.ps1

REM PowerShellの実行ファイルがあるフォルダまで移動
cd C:\Windows\System32\WindowsPowerShell\v1.0

REM 処理ファイルを管理者権限で実行
powershell.exe -NoProfile -ExecutionPolicy Unrestricted %FILE%
```
<details><summary>Syori.ps1　※長いので折りたたみました。</summary><div>

```powershell:Syori.ps1
#######################################################################
#◆STEP0 タンパープロテクションを無効化したかの確認ポップアップ表示
#######################################################################
#アセンブリの読込
Add-Type -AssemblyName system.windows.forms

#メッセージボックスを定義
$result=[System.Windows.Forms.MessageBox]::Show("タンパープロテクションを無効化しましたか","Sophos_uninstall","YesNo","Question","Button2")

#「はい」を答えた場合の処理
if($result -eq "Yes"){
#######################################################################
#◆STEP1 Sophos Autoupdate Serviceの停止
#######################################################################
#ポップアップ表示
[System.Windows.Forms.MessageBox]::Show('Sophos Autoupdateを停止します','Sophos_Uninstall')

#サービス停止
Stop-Service -name "Sophos AutoUpdate Service"
#######################################################################
#◆STEP2 基本変数の定義
#######################################################################
#日付を定義(yyyymmdd形式)
$date = get-date -format "yyyyMMdd"

#ホスト名を定義
$HOSTNAME = HOSTNAME.EXE

#各WORKフォルダを定義
$FOLDER ='C:\Users\'+$env:USERNAME+'\Desktop\Sophos_Uninstall\'
$REGBK =  $FOLDER+$HOSTNAME+'_regBK\'
$FILEBK = $FOLDER+$HOSTNAME+'_file\'
$COMMAND = $FOLDER+$HOSTNAME+'_Command\'
$COMMANDLOG = $FOLDER+$HOSTNAME+'_CommandLog\'
#######################################################################
#◆STEP3 WORKフォルダを作成
#
#・各フォルダについて
#  $REGBK     ：レジストリバックアップ用フォルダ
#  $FILEBK    ：レジストリ情報用フォルダ
#  $COMMAND   ：アンインストールコマンド用フォルダ
#  $COMMANDLOG：アンインストールコマンドのログ用フォルダ
#######################################################################
New-Item $REGBK -ItemType Directory -Force
New-Item $FILEBK -ItemType Directory -Force
New-Item $COMMAND -ItemType Directory -Force
New-Item $COMMANDLOG -ItemType Directory -Force
#######################################################################
#◆STEP4 レジストリをバックアップ
#
#・対象レジストリ
#  32bitプログラム：HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
#  64bitプログラム：HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall
#######################################################################
reg save HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall $REGBK'32bit_Sophos_uninstall_'$date'.hiv' /y
reg save HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall $REGBK'64bit_Sophos_uninstall_'$date'.hiv' /y
#######################################################################
#◆STEP5 Sophosプログラムのレジストリ情報を取得
#
# Sophosレジストリ情報を「〇〇bit_Sophos_uninstall_Strings.txt」に出力
#######################################################################
reg query HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /s /f SOPHOS > $FILEBK'32bit_Sophos_uninstall_Strings.txt'
reg query HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall /s /f SOPHOS > $FILEBK'64bit_Sophos_uninstall_Strings.txt'
#######################################################################
#◆STEP6 取得したレジストリ情報をコマンド分に置き換える①
#
#・流れ
#
# STEP6-1.不要な行を削除
#     「HKEY～」と「DisplayName～」以外の行は不要のため、削除し、「〇〇bit_Sophos_uninstall_Strings2.txt」に出力
#
# STEP6-2.不要な空白行を削除
#     空白行を削除した結果を、「〇〇bit_Sophos_uninstall_Strings3.txt」に出力
#
# STEP6-3.「DisplayName～」行をプログラム名のみに
#     「〇〇bit_Sophos_uninstall_Strings4.txt」に出力
#      ※該当業はコマンド文自体には不要だが、コマンド文を入力するファイルの名前に使用する
#
# STEP6-4.「HKEY～」行をアンインストール用コマンドを置換
#      行内の「{乱数}」の前のレジストリのパス部を「MsiExec～」に置き換え、「〇〇bit_Sophos_uninstall_Strings5.txt」に出力
#      ※コマンド内のレジストリパス部は、「\」2つ付ける
#      ※現時点ではコマンド文は未完成で、STEP7-5,8-5で完成する
#      ※"{"の前にシングルコーテーションを付与する
#
# STEP6-5.{}の末尾にシングルコーテーションを付与
#######################################################################
#6-1
cat $FILEBK'32bit_Sophos_uninstall_Strings.txt' |Where-Object {$_ -notlike "*HelpLink*" } |Where-Object {$_ -notlike "*Comments*" } |Where-Object {$_ -notlike "*Contact*" }|Where-Object {$_ -notlike "*InstallSource*" }|Where-Object {$_ -notlike "*InstallLocation*" }|Where-Object {$_ -notlike "*Comments*" }|Where-Object {$_ -notlike "*Publisher*" }|Where-Object {$_ -notlike "*URLInfoAbout*" }|Where-Object {$_ -notlike "*URLUpdateInfo*" }|Where-Object {$_ -notlike "*検索の*" }|Where-Object {$_ -notlike "*DisplayIcon*" }|Where-Object {$_ -notlike "*UninstallString*" }|Where-Object {$_ -notlike "*CleanPath*" } >$FILEBK'32bit_Sophos_uninstall_Strings2.txt'
cat $FILEBK'64bit_Sophos_uninstall_Strings.txt' |Where-Object {$_ -notlike "*HelpLink*" } |Where-Object {$_ -notlike "*Comments*" } |Where-Object {$_ -notlike "*Contact*" }|Where-Object {$_ -notlike "*InstallSource*" }|Where-Object {$_ -notlike "*InstallLocation*" }|Where-Object {$_ -notlike "*Comments*" }|Where-Object {$_ -notlike "*Publisher*" }|Where-Object {$_ -notlike "*URLInfoAbout*" }|Where-Object {$_ -notlike "*URLUpdateInfo*" }|Where-Object {$_ -notlike "*検索の*" } >$FILEBK'64bit_Sophos_uninstall_Strings2.txt'

#6-2
Get-Content $FILEBK'32bit_Sophos_uninstall_Strings2.txt'|Where-Object { $_.trim() -ne ""}>$FILEBK'32bit_Sophos_uninstall_Strings3.txt'
Get-Content $FILEBK'64bit_Sophos_uninstall_Strings2.txt'|Where-Object { $_.trim() -ne ""}>$FILEBK'64bit_Sophos_uninstall_Strings3.txt'

#6-3
Get-Content $FILEBK'\32bit_Sophos_uninstall_Strings3.txt' | foreach { $_ -replace "    DisplayName    REG_SZ    ",""}>$FILEBK'32bit_Sophos_uninstall_Strings4.txt'
Get-Content $FILEBK'\64bit_Sophos_uninstall_Strings3.txt' | foreach { $_ -replace "    DisplayName    REG_SZ    ",""}>$FILEBK'64bit_Sophos_uninstall_Strings4.txt'

#6-4 
Get-Content $FILEBK'\32bit_Sophos_uninstall_Strings4.txt' | foreach { $_ -replace "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\","MsiExec.exe /X'"}>$FILEBK'32bit_Sophos_uninstall_Strings5.txt'
Get-Content $FILEBK'\64bit_Sophos_uninstall_Strings4.txt' | foreach { $_ -replace "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\","MsiExec.exe /X'"}>$FILEBK'64bit_Sophos_uninstall_Strings5.txt'

#6-5
Get-Content $FILEBK'\32bit_Sophos_uninstall_Strings5.txt' | foreach { $_ -replace "}","}'"}>$FILEBK'32bit_Sophos_uninstall_Strings6.txt'
Get-Content $FILEBK'\64bit_Sophos_uninstall_Strings5.txt' | foreach { $_ -replace "}","}'"}>$FILEBK'64bit_Sophos_uninstall_Strings6.txt'

#######################################################################
#◆STEP7 取得したレジストリ情報をコマンド分に置き換える②(32bitプログラム)
#
#・流れ
# STEP7-0.変数に元ファイルを定義
#     変数「32bitcom」にSTEP4-4で作成した「32bit__Sophos_uninstall_Strings6.txt」を代入
#     ※元ファイルは以下の構成
#       奇数行：コマンド 偶数行：プログラム名
#
#※STEP7-1から7-5は各プログラム毎に実施 ※32bitは5つのプログラムがある想定
#
# STEP7-1.変数にプログラム名を定義
#     変数「$P〇」に元ファイル($P1)の偶数行を定義 ※偶数行にはプログラム名が入力されている
#     ※[]内は行番号で、0から始まる
#
# STEP7-2.コマンド用ファイルのファイルパスを定義
#     変数「$P〇_PATH」に定義
#
# STEP7-3.コマンド用ファイルの作成
#     元ファイル($P〇)の奇数行を、STEP7-2で定義したファイルパス($P〇_PATH)に出力
#
# STEP7-4.コマンドログ出力用のファイルパスを定義
#     変数「$P〇_LOG」に定義
#
# STEP7-5.STEP7-3で作成したコマンド用ファイル($P〇_PATH)に、実行コマンドのオプションとログ出力先を追記
#######################################################################
#7-0
$32bitCom=Get-Content $FILEBK'32bit_Sophos_uninstall_Strings6.txt'
# 1つめのプログラム
#7-1
$P1=$32bitcom[1]
#7-2
$P1_PATH=$COMMAND+"$P1"+".txt"
#7-3
($32bitcom)[0] |Out-File $P1_PATH -NoNewline
#7-4
$P1_LOG='"'+$COMMANDLOG+$P1+'_Log.txt'+'"'
#7-5
Add-Content -path $P1_PATH -value " /qn REBOOT=SUPPRESS /L*v $P1_LOG" -NoNewline
#-----------------------------------------------------------------------
# ※2～5のプログラムについてのコメントは割愛
# 2つめのプログラム
$P2=$32bitcom[3]
$P2_PATH=$COMMAND+"$P2"+".txt"
($32bitcom)[2] |Out-File $P2_PATH -NoNewline
$P2_LOG='"'+$COMMANDLOG+$P2+'_Log.txt'+'"'
Add-Content -path $P2_PATH -value " /qn REBOOT=SUPPRESS /L*v $P2_LOG" -NoNewline
#-----------------------------------------------------------------------
# 3つめのプログラム
$P3=$32bitcom[5]
$P3_PATH=$COMMAND+"$P3"+".txt"
($32bitcom)[4] |Out-File $P3_PATH -NoNewline
$P3_LOG='"'+$COMMANDLOG+$P3+'_Log.txt'+'"'
Add-Content -path $P3_PATH -value " /qn REBOOT=SUPPRESS /L*v $P3_LOG" -NoNewline
#-----------------------------------------------------------------------
# 4つめのプログラム
$P4=$32bitcom[7]
$P4_PATH=$COMMAND+"$P4"+".txt"
($32bitcom)[6] |Out-File $P4_PATH -NoNewline
$P4_LOG='"'+$COMMANDLOG+$P4+'_Log.txt'+'"'
Add-Content -path $P4_PATH -value " /qn REBOOT=SUPPRESS /L*v $P4_LOG" -NoNewline
#-----------------------------------------------------------------------
# 5つめのプログラム
$P5=$32bitcom[9]
$P5_PATH=$COMMAND+"$P5"+".txt"
($32bitcom)[8] |Out-File $P5_PATH -NoNewline
$P5_LOG='"'+$COMMANDLOG+$P5+'_Log.txt'+'"'
Add-Content -path $P5_PATH -value " /qn REBOOT=SUPPRESS /L*v $P5_LOG" -NoNewline
#######################################################################
#◆STEP8 取得したレジストリ情報をコマンド分に置き換える②(64bitプログラム)
#
#基本的に、STEP7と同じ流れ
#変わっている点は、元ファイル(64bit)
#######################################################################
#8-0
$64bitCom=Get-Content $FILEBK'\64bit_Sophos_uninstall_Strings6.txt'
# 1つめのプログラム
#8-1
$P6=$64bitcom[1]
#8-2
$P6_PATH=$COMMAND+"$P6"+".txt"
#8-3
($64bitcom)[0] |Out-File $P6_PATH -NoNewline
#8-4
$P6_LOG='"'+$COMMANDLOG+$P6+'_Log.txt'+'"'
#8-5
Add-Content -path $P6_PATH -value " /qn REBOOT=SUPPRESS /L*v $P6_LOG" -NoNewline
#-----------------------------------------------------------------------
# ※2～3のプログラムについてのコメントは割愛
# 2つめのプログラム
$P7=$64bitcom[3]
$P7_PATH=$COMMAND+"$P7"+".txt"
($64bitcom)[2] |Out-File $P7_PATH -NoNewline
$P7_LOG='"'+$COMMANDLOG+$P7+'_Log.txt'+'"'
Add-Content -path $P7_PATH -value " /qn REBOOT=SUPPRESS /L*v $P7_LOG" -NoNewline
#-----------------------------------------------------------------------
# 3つめのプログラム
$P8=$64bitcom[5]
$P8_PATH=$COMMAND+"$P8"+".txt"
($64bitcom)[4] |Out-File $P8_PATH -NoNewline
$P8_LOG='"'+$COMMANDLOG+$P8+'_Log.txt'+'"'
Add-Content -path $P8_PATH -value " /qn REBOOT=SUPPRESS /L*v $P8_LOG" -NoNewline
#######################################################################
#◆STEP9 アンインストール可否についてのメッセージボックス出力
#
#以下のメッセージボックスを出力させる
#「Sophosアンインストールを実行しますか」
#→はい  ：STEP10(アンインストールの実施)
#  いいえ：処理終了
#
# 9-2.変数にメッセージボックスを定義
#     変数「$result」に定義
#
# 9-3.メッセージボックス出力
#
# 9-4.処理実行 ※「はい」「いいえ」の選択で処理分岐
#######################################################################
#9-2
$result2=[System.Windows.Forms.MessageBox]::Show("Sophosアンインストールを実行しますか","Sophos_uninstall","YesNo","Question","Button2")
#9-3
if($result2 -eq "Yes"){
#9-4 ※「はい」を選択(Sophosのアンインストール実施)
#######################################################################
#◆STEP10 アンインストール実施
#
#・削除順(上から順番に実施
#  Sophos Remote Management System
#  Sophos Network Threat Protection
#  Sophos Endpoint Defense
#  Sophos Anti-Virus
#  Sophos AutoUpdate
#  Sophos Exploit Prevention
#  Sophos Clean
#  HitmanPro.Alert
#  ※Sophos Endpoint Defense,Sophos Clean,HitmanPro.Alertは専用のアンインストール実行ファイル
#    それ以外は、STEP5,6で作成したアンインストール用コマンド
#
#・流れ(アンインストール用コマンド)
#  STEP10-1.アンインストール用コマンドを定義
#          変数「〇_Uninstall」に定義
#  STEP10-2.アンインストールコマンドを実行
#######################################################################
#Sophos Remote Management System
#10-1
$RMS_Uninstall= Get-Content $COMMAND'Sophos Remote Management System.txt'
#10-2
Invoke-Expression $RMS_Uninstall
Start-Sleep -s 60
#-----------------------------------------------------------------------
#Sophos Network Threat Protection
#10-1
$NTP_Uninstall= Get-Content $COMMAND'Sophos Network Threat Protection.txt'
#10-2
Invoke-Expression $NTP_Uninstall
Start-Sleep -s 60
#-----------------------------------------------------------------------
#Sophos Endpoint Defense
& 'C:\Program Files\Sophos\Endpoint Defense\SEDuninstall.exe'
Start-Sleep -s 60
#-----------------------------------------------------------------------
#Sophos Anti-Virus
#10-1
$SAV_Uninstall= Get-Content $COMMAND'Sophos Anti-Virus.txt'
#10-2
Invoke-Expression $SAV_Uninstall
Start-Sleep -s 60
#-----------------------------------------------------------------------
#Sophos AutoUpdate
#10-1
$SAO_Uninstall= Get-Content $COMMAND'Sophos AutoUpdate.txt'
#10-2
Invoke-Expression $SAO_Uninstall
Start-Sleep -s 60
#-----------------------------------------------------------------------
#Sophos Exploit Prevention
#10-1
$SEP_Uninstall= Get-Content $COMMAND'Sophos Exploit Prevention.txt'
#10-2
Invoke-Expression $SEP_Uninstall
#-----------------------------------------------------------------------
#Sophos Clean
& 'C:\Program Files\Sophos\Clean\uninstall.exe'
Start-Sleep -s 60
#-----------------------------------------------------------------------
#HitmanPro.Alert
& 'C:\Program Files (x86)\HitmanPro.Alert\Uninstall.exe'
Start-Sleep -s 60
#-----------------------------------------------------------------------
#10-3 「いいえ」を選択(処理終了)
}else{
}
	
}else{
}
```
</div></details>

## 結果
安全かつ楽にSophos製品のアンインストールが可能になった！！
ハッピー！！！