連載Index(読む順・公開済リンクが最新): S00_門前の誓い_総合Index
前回の 工房W01 では、FileSystemWatcher で変化を受ける話を見ました。
今回はその続きとして、共有フォルダで「だれが更新したかを後から追いたい」を扱います。
今回の主役は 4663 と 4660 です。
4663 を主軸にし、Deleted は 4660 で補います。
このサンプルが一覧へ出すのは、通知時刻や対象パスに近い監査イベントと一致した 監査アカウント候補 です。
常に更新者を確定表示できる作りではありません。
- 対象: C# / .NET で共有フォルダの更新者候補を追いたいとき
- 前提: 共有を持っている PC またはサーバーで監査設定を入れられること
- 完成サンプル: GitHubの W02 サンプル一式はこちら
W01 と今回の違い
W01 と今回を並べて見ると、役割の違いが見やすくなります。
| 記事 | 中心テーマ | まず見るもの |
|---|---|---|
| W01 | 変化通知を受ける | FileSystemWatcher |
| W02 | 更新者候補を追う | Security ログ |
W01 のあとで、次のような疑問が出たときに今回の話がつながります。
- だれがファイルを更新したのか見たい
- だれが削除したのか後から追いたい
- 共有フォルダの変更を一覧へ出したい
まず切り分けたいこと
共有フォルダまわりは、最初に「変化通知」と「更新した人の候補の確認」を分けて考えると整理しやすくなります。
| やりたいこと | まず見る場所 |
|---|---|
| 変化が起きたことをすぐに受けたい | FileSystemWatcher |
| 更新や削除を行った人の候補を知りたい | Security ログ |
| 後から追跡できる形で残したい | 監査設定 + ログ出力 |
今回は、共有フォルダで更新した人の候補を追う流れに絞って進めます。
このサンプルがやっていること
今回のサンプルは、かなり素直な流れです。
-
FileSystemWatcherで変更通知を受ける - 一覧へ仮の行をすぐ追加する
- Security ログの
4663を主軸に検索する -
Deletedは4660も見て削除候補を補う -
Created/Deletedは数回の再検索で後から埋める
ここで確認したいのは、通知を受けた瞬間に 1 回だけ見て終わりにしないことです。
監査ログは少し遅れて見えることがあるため、Created / Deleted は少し待ってから再検索した方が埋まりやすくなります。
FileSystemWatcher だけでは更新者が取れない理由
FileSystemWatcher は、ファイルやディレクトリの作成、変更、削除、名前変更を受けるための部品です。
そのため、取れる中心情報は「何が起きたか」「どのパスで起きたか」です。
一方で、共有フォルダで知りたいことは次です。
- だれが更新したか
- だれが削除したか
- いつ何を触ったか
この「だれが」の部分は、OS 側の監査ログの話になります。
つまり、変化通知と更新者特定は別の話です。
W01 の続きを考えるときも、
FileSystemWatcher の設定をさらに増やせば更新者まで分かる、という流れではありません。
ここでは、見る対象を Security ログへ切り替えて進めます。
先に確認したい設定
コードへ入る前に、まず次を確認します。
- 監査ポリシーが有効になっているか
- 対象フォルダに監査設定が入っているか
- Security ログへ実際にイベントが出ているか
- 共有経由アクセスも見たいのか、ファイル操作の証跡を見たいのか整理できているか
これらの監査設定が入っていないと、C# 側だけを整えても更新者候補は特定できません。
コードではなく、監査設定の不足で止まることが多いです。
ローカル セキュリティ ポリシーでは、
監査ポリシーの詳細な構成 > システム監査ポリシー - ローカル グループ ポリシー > オブジェクト アクセス
を開きます。
今回のサンプル本線で使うのは ファイル システムの監査 です。
これは 4663 / 4660 に対応します。
補助として共有経由アクセスも確認したい場合は、詳細なファイル共有の監査 を有効にすると 5145 が見やすくなります。
ファイル共有の監査 は 5140 側です。
最初に何を確認すると進めやすいか
いきなり C# から始めるより、先にイベント ビューアーや PowerShell で実際のイベントを確認しておくと進めやすくなります。
ここで確認したいのは次です。
- 監査設定が効いているか
- 期待したイベント ID が出ているか
- パスやアカウントが入っているか
- ログ量がどのくらいか
この確認を飛ばして C# へ入ると、
「コードが悪いのか」「監査設定が足りないのか」が見えにくくなります。
撮る場所は eventvwr.msc の
イベント ビューアー > Windows ログ > セキュリティ
です。
右側の「現在のログのフィルター」で 4663,4660 を指定した状態にして、左のツリーと中央の一覧が入る範囲を切り出すと、どこを見るのかが分かりやすくなります。
一覧から 4663 を開き、全般 タブで
Account Name、Object Name、Process Name、Accesses
が見える範囲を切り出す形が分かりやすいです。
4663 では、更新候補のアカウント名と対象パスをこの位置で確認できます。
どのイベントを見るのか
ここでは対象を広げすぎず、まずは 4663 を確認します。
削除だけ 4660 を追加し、5145 は共有経由のアクセスを確認したいときに見ます。
| イベントID | 何を確認するか | このサンプルでの扱い | 注意 |
|---|---|---|---|
4663 |
更新・作成・削除・名前変更 | 最初に確認するイベント | 対象フォルダやファイル側の監査設定が必要 |
4660 |
削除 |
Deleted を補いたいときに追加で確認する |
単体ではオブジェクト名を持たないため、4663 と合わせて見る |
5145 |
共有経由のアクセス、共有名、送信元 | 補足確認に使う | このサンプルの更新者候補表示では使っていない |
このサンプルでは、更新・作成・名前変更は 4663 を見ます。
削除は 4663 に 4660 を加えて確認します。
まず何をログへ出すと使いやすいか
最初から作り込みすぎると、どこで止まっているのか見えにくくなります。
まずは次の項目だけでも十分です。
- 時刻
- 操作種別
- 対象パス
- 実行アカウント候補
- 取得元イベント ID
この 5 つがあるだけで、後からかなり追いやすくなります。
たとえば、最初のログ出力は次のような形から始められます。
2026-03-10 09:15:23, 更新, \\FileServer\Share\A\sample.xlsx, CONTOSO\user01, 4663
2026-03-10 09:16:02, 削除候補一致, \\FileServer\Share\B\old.csv, CONTOSO\user02, 4663/4660
2026-03-10 09:17:41, 名前変更, \\FileServer\Share\A\sample_renamed.xlsx, CONTOSO\user03, 4663
最初は見やすさより、何が取れているか を確認できる形を優先します。
PowerShell で先に確認しておきたいこと
C# の前に、PowerShell で対象イベントが見えるか確認しておくと切り分けがかなり楽になります。
Get-WinEvent -LogName Security -MaxEvents 300 |
Where-Object { $_.Id -in 4663, 4660 } |
Select-Object TimeCreated, Id, Message
この段階で確認したいのは次です。
- 4663 や 4660 が本当に出ているか
- 対象の共有フォルダの操作が含まれているか
- どのくらいノイズが多いか
- ほしい項目が Message 内に入っているか
PowerShell で見えないものは、C# に持っていっても見えません。
最初の確認としてはここがかなり大事です。
C# 側の役割
C# 側で最初にやることは、複雑な分析ではなく、必要なイベントを読んで一覧で確認できる形にして出すことです。
今回のサンプルでは、主に次をやっています。
- Security ログから
4663と4660を読む - パス、アカウント、時刻を抜く
- 一覧へ仮行を出す
- 数回の再検索で後から情報を埋める
ここで確認したいのは、通知を受けた瞬間に確定しないことです。
特に Created / Deleted は、最初の 1 回だけだと空欄になりやすいため、少し待ってから再検索した方が結果が安定しやすくなります。
この画面では、変更通知だけでなく、監査ログと照合した結果も一覧で確認できます。
監視対象パス、変更種別、監査アカウント候補、イベントIDが見える状態にしておくと、サンプルの動きが追いやすくなります。
C# での最小サンプル
最初は、Security ログから対象イベントを読み取り、時刻とメッセージを確認できれば十分です。
ここでは、確認に必要な最小構成だけを示します。
using System;
using System.Diagnostics.Eventing.Reader;
class Program
{
static void Main()
{
string queryText =
"*[System[(EventID=4663 or EventID=4660)]]";
EventLogQuery query = new EventLogQuery("Security", PathType.LogName, queryText);
EventLogReader reader = new EventLogReader(query);
for (EventRecord record = reader.ReadEvent(); record != null; record = reader.ReadEvent())
{
using (record)
{
Console.WriteLine("-----");
Console.WriteLine(record.TimeCreated);
Console.WriteLine(record.Id);
Console.WriteLine(record.FormatDescription());
}
}
}
}
この段階で確認したいのは、解析の完成度ではありません。
対象イベントが取れるか、どんなメッセージが出るか の確認です。
Created / Deleted を埋めやすくするために入れたこと
今回の版では、Changed / Renamed だけでなく、Created / Deleted も空欄になりにくいように少し手を入れています。
考え方は次です。
- 通知直後に仮の行を出す
-
Created/Deletedは少し長めに再検索する -
Deletedは4663だけでなく4660も見る - 見つかったら後から行を更新する
この形にすると、一覧の表示は早いままで、監査ログが少し遅れて見えても後から追いつけます。
ただし、ここは大事です。
この版でも 100%確定 ではありません。
表示しているのは、通知時刻や対象パスに近い監査イベントと一致した 監査アカウント候補 です。
このコードで最初に確認すること
この最小コードやサンプルを動かしたら、まず次を確認します。
- 4663 や 4660 が本当に出ているか
- 対象の共有フォルダの操作が含まれているか
- アカウント名が期待した形で出ているか
-
Deletedで 4660 が拾えているか -
Created/Deletedが再検索で後から埋まるか
ここが確認できてから、必要な項目だけを抜く形へ進める方が分かりやすくなります。
実務で気をつけたい点
共有フォルダの監査は、動き始めると想像以上にログ量が増えることがあります。
そのため、最初から次を意識しておくと後で楽になります。
- 監査対象フォルダを広げすぎない
- まずは検証用フォルダで試す
- 4663 と 4660 を全部保存し続けない
- どの操作を残したいのか先に決める
- Security ログを読む権限も確認しておく
特に「更新だけでよいのか」「削除も見たいのか」で、見るイベントや絞り方が変わります。
共有経由アクセスも見たいときは 5145 を補助で使う
5145 は今回の主処理には入れていませんが、共有名、相対パス、送信元アドレスの確認には便利です。
- 本当に共有経由で触られているか
- どの共有名で入ってきたか
- 送信元の端末はどこか
このサンプルの更新者候補表示は 4663 / 4660 が中心です。
5145 は共有経由アクセス確認の補助として分けて見ると整理しやすくなります。
最初から広げすぎると切り分けしにくくなる
この用途は、最初から機能を広げると進めにくくなります。
たとえば次を一気にやると、確認点が増えます。
- 更新者候補の取得
- 操作種別の判定
- CSV 出力
- 重複排除
- 通知
- 日次ローテーション
- 画面表示
これを最初から全部入れると、どこで崩れたのか見えにくくなります。
最初は次の順で確認すると流れがつかみやすくなります。
- 監査イベントが出る
- C# で読める
- 一覧へ出せる
- 必要な項目だけ抜く
- 出力形式を整える
どういう設計だと止まりやすいか
現場で止まりやすいのは次の進め方です。
-
FileSystemWatcherだけで更新者まで取ろうとする - 監査設定を見ないままコードから始める
- 期待するイベント ID が出ているか確認しない
- いきなり業務用の出力形式まで作り込む
- ログ量を見ないまま全部保存し始める
逆に、最初に次を分けて考えるとかなり進めやすくなります。
- 監査イベントを出す
- イベントを読む
- 必要項目を抜く
- 一覧へ出す
- その後で活用先を考える
W01 と今回のつながり
前回の W01 は「変化を受ける」話でした。
今回の W02 は「更新者候補を追う」話です。
近い話に見えますが、中心は次のように分かれます。
-
FileSystemWatcher
変化通知 - 監査ログ
更新者候補や削除候補を追うための証跡
そのため、共有フォルダでやりたいことが次のどちらなのかを先に決めると整理しやすくなります。
- 変わった瞬間を受けたい
- だれが変えたかを後で追いたい
W01 の続きとして今回を読むと、
「通知」と「証跡」で役割が分かれていることが見えやすくなります。
まとめ
共有フォルダの更新者候補を追いたいとき、FileSystemWatcher だけでは足りません。
今回のサンプルでは、4663 を主軸にし、Deleted は 4660 で補い、Created / Deleted は再検索で後から埋める形を取っています。
つまり、W01 が「変化通知」なら、W02 は「監査ログ照合」です。
変化は拾えたが、だれが触ったかまでは見えない、というところで止まったときの次の一手として使いやすい構成です。
ここで表示しているのは、常に確定した更新者ではありません。
通知時刻や対象パスに近い監査イベントと一致した 監査アカウント候補 です。
動かしながら確認したい場合は、GitHub のサンプルも合わせてどうぞ。
GitHubの W02 サンプル一式はこちら
参考として見たいキーワード
- 高度な監査ポリシー
- Security ログ
- 4663
- 4660
- 5145
EventLogQueryEventLogReader
連載Index(読む順・公開済リンクが最新): S00_門前の誓い_総合Index





