PowerShell
ログ
運用
監視
WindowsServer

PowerShellでファイルアクセスログを出力する


はじめに

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

Windowsでは、監査ポリシーを設定するだけでイベントログに監査ログを出力できるので、さっそく設定してみよう。


前提環境

Windows Server 2016 Datacenter を使用。

image.png

ちなみに Datacenter とは、文字通りデータセンタ環境用のエディションだ。

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


監査ポリシーの設定手順

ActiveDirectory環境下でドメインコントローラの監査をする場合と、ローカル環境下でファイルサーバなどの監査をする場合とで、最初の手順が異なる。

本記事では、ローカルグループポリシーから、ファイルサーバの監査ポリシーを設定してみよう。

なお、ActiveDirectoryのグループポリシーでは、ドメインやOU単位で監査ポリシーを設定できる。


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

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


gpedit.msc を実行

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

image.png


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

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

image.png


監査対象フォルダの設定


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


  • [セキュリティ] タブで [詳細設定] をクリックする。


監査エントリの追加

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

image.png

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

image.png

「選択するオブジェクト名を入力してください」Everyone(すべてのユーザー)と入力する。

もちろん Everyone の代わりにユーザー名やグループ名を入力することもできる。

image.png

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

image.png

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

image.png


監査ログの確認

これで監査ログの記録が開始されるので、さっそくイベントビューアから [Windowsログ]-[セキュリティ] で監査ログを確認してみよう。

アクセスのあったファイル/フォルダ名が、オブジェクト名に表示されているはずだ。

image.png

ついでに [XMLで表示] に切り替えて、取得したいデータのXML階層イメージも確認しておこう。

PowerShellGet-WinEventコマンドレットからXML階層を辿るときに必要になる。

image.png


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に貼り付けたものを示す。(アカウント名やファイル名は架空)

image.png