Windows Defender スキャンと戦う(MpPreference)

Windows Defender はウイルス対策（含め総合的なセキュリティ対策）としてだいぶ優秀になってきており、目にする機会も増えてきた。が、こいつはすこぶる重く、デフォの設定では正直しんどい。

幸いにも最新の Windows では、Set-MpPreference を使ってスキャンのスケジュールや挙動を変えることができる。

このあたりの話（設定方法や設定内容）について雑多にまとめた。

# 前提
- Windows 10 Home or Pro

古い Win10 では該当しないかも。

# 設定画面を呼び出すコマンドライン
`ms-settings:windowsdefender`

いちいち画面から呼ぶのが面倒くさいのでコマンドを使いたい派。

でもこのコマンドも長いので、適宜エイリアスなどを設定すると良い。

# タスクスケジューラ上のスケジュール
`"\Microsoft\Windows\Windows Defender` にいくつか存在する。

## 「リアルタイム保護」を勝手にオンにする犯人
※ :warning: 割と極端な設定であり万人向けではない

「リアルタイム保護」を勝手にオンにするのもコイツらの仕業なので、これらスケジュールを消してやれば勝手にオンになるのを防げる。

以下はコマンド例。

```
schtasks /delete /tn "\Microsoft\Windows\Windows Defender\Windows Defender Scheduled Scan" /f
schtasks /delete /tn "\Microsoft\Windows\Windows Defender\Windows Defender Cache Maintenance" /f
schtasks /delete /tn "\Microsoft\Windows\Windows Defender\Windows Defender Cleanup" /f
schtasks /delete /tn "\Microsoft\Windows\Windows Defender\Windows Defender Verification" /f
```

ただし上記スケジュールは Windows Update で復活するので、（本当に勝手にオンにされるのが嫌なら）こまめに叩いてやるのが理想。あるいは上記コマンドをバッチファイルで書いて、そのバッチファイルを「定期的に実行するタスクスケジュール」にしてしまうとか。

# スキャン設定を変える
本題。

Windows 10 では Set-MpPreference コマンドを用いてスキャンの設定（スケジュールや挙動や機能の無効化など）を行える。

## 要約
- PowerShell の Set-MpPreference コマンドレットで各種設定をいじれる
- 設定値は英語ドキュメント読んで頑張って調べる
- defender.ps1 ← 設定はスクリでまとめちゃうと管理が楽か

## ドキュメント
[Set-MpPreference - Microsoft Docs](https://docs.microsoft.com/en-us/powershell/module/defender/set-mppreference?view=win10-ps)

- 基本的にここを読む
- 日本語なし、英語のみなのでちょっとしんどいが、単語拾えばなんとか読める

[Search · Set-MpPreference](https://github.com/search?l=PowerShell&q=Set-MpPreference&type=Code)

- GitHub にアップされてる設定例
- コマンド例は GitHub で実例を探すと「どう書けばいいか」がわかりやすい

## 設定手順
- defender.ps1 など powershell スクリプトを書く
- この中に Set-MpPreference の設定を書き並べる
- 実行は `powershell ./defender.ps1`

powershell 実行にはいくつかハマリポイントがあるので、動かないようなら適当に調べること（手抜き）。

## 設定例

### Disable 系
特定の機能や挙動を無効化する系

```powershell
# キャッチアップ(指定スケジュール時に動作できなかった時に後で追加でやる)を無効に
Set-MpPreference -DisableCatchupFullScan $True
Set-MpPreference -DisableCatchupQuickScan $True

# ネットワークファイル(ってなんだ？)をスキャンしない
Set-MpPreference -DisableScanningNetworkFiles $True

# リアルタイム保護を無効にする
Set-MpPreference -DisableRealtimeMonitoring $True
```

### スキャン系
- フルスキャンとクイックスキャンがある
- スキャンする時間帯、曜日、方向などの設定がある

```powershell
# スキャン
# 7=Saturday なので「土曜日に」
Set-MpPreference -ScanScheduleDay 7

# Remediation(Windows Update 適用失敗時の治療処理？) 完了後のフルスキャン
# 8: never なので「やらない」
Set-MpPreference -RemediationScheduleDay 8

# スキャンする日時
# フルスキャンは 午前 1:00、クイックスキャンは午前 3:00
Set-MpPreference -ScanScheduleTime "01:00:00"
Set-MpPreference -ScanScheduleQuickScanTime "03:00:00"

# スキャンとして何をするか
# 1 がクイック、2 がフル
# ここでは「クイック」
Set-MpPreference -ScanParameters 1

# NTFS アクセス時のリアルタイム保護のスキャン方向
# 0 は双方向、1 は In 方向のみ、2 は Out 方向のみ
# ここでは「In 方向のみ」
Set-MpPreference -RealTimeScanDirection 1
```

### 除外系
- ExclusionExtension では拡張子
- ExclusionPath では指定フォルダ配下をまるごと
- ExclusionProcess では指定プロセス **から読み込まれるファイル**

```powershell
Set-MpPreference -ExclusionExtension css,html,js,ts,py,rb,md,txt,yml,yaml,json,rst,
                                     lib,obj,db,pyc
Set-MpPreference -ExclusionPath "D:\data",
                                "C:\Program Files\Git"
Set-MpPreference -ExclusionProcess "C:\Program Files\Mozilla Firefox\firefox.exe",
                                   "C:\Program Files\bin\git.exe"
```

## 現在の設定内容を出力する
必要に応じて設定内容を出力できると便利。

たとえば設定作業前に「今の設定」を before.txt に出しておき、設定時は after.txt に出しつつ WinMerge で比較しながら作業するなど。こうすると差分がわかるし、「ちゃんと設定できてるか（設定値がおかしければ設定されないので差分見てる時にわかる）」ので設定作業のデバッグもしやすい。

### 基本

```terminal
$ powershell -Command "Get-MpPreference > preferences.txt"
```

ただし ExclusionPath など一部表示が見切れる。

### 決め打ちで漏れなく
いったん変数に入れた後にアクセス。

ただし普通に `> hoge.txt` で出しても UTF-16 で扱いづらいので、ここでは UTF-8 で出すおまじないを使っている。

```powershell
$pref = Get-MpPreference
$pref.ExclusionPath | Out-File -Encoding UTF8 exclusion_path.txt
```