ファイルサーバのアクセスログをPowerShellで取得する


はじめに

監査ログを調べると「いつ・誰が・何をしたか」を知ることができ、システムの運用が法規制、セキュリティ評価基準、社内規定等の監査基準に準拠していることを証明できる。内部統制の構築には欠かせないものと言えよう。
Windowsでは、監査ポリシーを設定するだけで、イベントログに監査ログを出力できる。

前提環境

本記事では Windows Server 2016 Datacenter で解説するが、すべてのエディションで使える。

Datacenter とは文字通りデータセンタ環境用のエディションだ。
仮想化により多数のサーバを運用する大企業や、大量のサーバを保有してデータセンタを運用する企業(=クラウド事業者)向けのエディションである。

監査ポリシーの設定手順

ActiveDirectory環境下でドメインコントローラの監査をする場合と、ローカル環境下でファイルサーバなどの監査をする場合とで、最初の手順が異なる。
本記事では、ローカルグループポリシーから、ファイルサーバの監査ポリシーを設定する。
なお、ActiveDirectoryのグループポリシーでは、ドメインやOU単位で監査ポリシーを設定できる。

ローカルグループポリシーエディタの設定

まず、ファイルサーバに管理者権限を持ったユーザーでログオンしよう。

gpedit.msc を実行

ローカルグループポリシーエディタで [オブジェクトアクセス]-[ファイルシステムの監査] をクリックする。

ファイルシステムの監査のプロパティ

監査のプロパティが表示されるので、今回は、成功・失敗ともにチェックする。

監査対象フォルダの設定

  • エクスプローラで、監査対象にしたいフォルダまたはファイルを右クリックし、[プロパティ] を選択する。
  • [セキュリティ] タブで [詳細設定] をクリックする。

監査エントリの追加

[監査] タブで [追加] をクリックする。

[プリンシパルの選択] をクリックする。

「選択するオブジェクト名を入力してください」Everyone(すべてのユーザー)と入力する。
もちろん Everyone の代わりにユーザー名やグループ名を入力することもできる。

ファイルに対するアクセスに、成功しても失敗しても検知したいので「すべて」を選択する。

[高度なアクセス許可] を表示し、今回は、次のようにチェックする。

監査ログの確認

これで監査ログの記録が開始されるので、さっそくイベントビューアから [Windowsログ]-[セキュリティ] で監査ログを確認してみよう。
アクセスのあったファイル/フォルダ名が、オブジェクト名に表示されているはずだ。

ついでに [XMLで表示] に切り替えて、取得したいデータのXML階層イメージも確認しておこう。
PowerShellGet-WinEventコマンドレットからXML階層を辿るときに必要な情報だ。

[プロパティ] からログの最大サイズを変更できる。取りこぼしの無いよう、充分なサイズを確保しておこう。

PowerShellのコーディング例

ファイルサーバでPowerShellコンソールを起動し、下のコードをそのまま貼り付けるだけで動くはずだ。
今回は、セキュリティイベントのIDに4663(ファイルアクセス)を指定しフィルタリングしている。

PowerShell
$AccessMaskHash = @{ '0x1' = '読込'; '0x2' = '書込'; '0x4' = '追加'; '0x10000' = '削除'}
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ProviderName = 'Microsoft-Windows-Security-Auditing'
    ID = 4663
} | %{
    $xml = [XML]$_.ToXml()   # EventDataにアクセスするためにXML化

    $FileName = ($xml.Event.EventData.Data | ?{$_.Name -eq 'ObjectName'}).'#text'
    if (! $FileName.StartsWith('E:\SHARED\')) { return }

    $AccessMaskCode = ($xml.Event.EventData.Data | ?{$_.Name -eq 'AccessMask'}).'#text'
    if (! $AccessMaskHash.ContainsKey($AccessMaskCode)) { return }
    $AccessMaskName = $AccessMaskHash[$AccessMaskCode]

    $TimeCreated = ([DateTime]$xml.Event.System.TimeCreated.SystemTime).ToString('yyyy/MM/dd hh:mm:ss')
    $UserName = ($xml.Event.EventData.Data | ?{$_.Name -eq 'SubjectUserName'}).'#text'

    echo "$TimeCreated,$AccessMaskName,$UserName,$FileName"
}
  • すべてのセキュリティイベントの一覧は Windows security audit events からExcel形式でダウンロードできるので参考にして欲しい。ちょっと書き換えればログオン/ログオフの追跡もできるはずだ。
  • Get-WinEventコマンドレットの使い方は Windows PowerShell のヘルプ - Get-WinEvent が詳しいので併せて参照して欲しい。

実行結果

出力をExcelに貼り付けたものを示す。(アカウント名やファイル名は架空)