Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

PowerShellを使って共有フォルダのアクセスログを取る

More than 1 year has passed since last update.

個人ブログから過去記事を移転。
方法2に関してはこちらのほうが良記事 → ファイルサーバのアクセスログをPowerShellで取得する


サーバーの共有フォルダへのアクセスがどれだけあるのか統計を取りたい。

以下要件

  • Windowsの標準機能で実装
  • 同時接続100人程度

方法1:SMBを監視する

ネットワーク上にある共有フォルダなら、SMBのイベントを監視すればいいじゃない。
ということでプロトコルの監視。

  • 利点
    • 事前の仕掛けが必要ない
  • 欠点
    • 常時プロセスが動きっぱなし
    • ローカルのアクセスは把握できない

WMIEventを使う方法を紹介。
NetEventを使う場合は注釈参照1
永続化するにはMOF作成が必要っぽい。

$smb_namespace = "root\Microsoft\Windows\SMB"
$smb_query = "Select * From __InstanceCreationEvent WITHIN 1 Where TargetInstance ISA 'MSFT_SmbOpenFile'"
$fs = New-Object System.IO.StreamWriter("D:\log.txt",$true,[Text.Encoding]::GetEncoding("UTF-8"))
$fs.AutoFlush = $true

#イベントが発生すると実行されるAction
$smb_event = {
    $e = $Event.SourceEventArgs.NewEvent
    $out = [DateTime]::FromFileTime($e.TIME_CREATED).ToString() + "|" + $e.TargetInstance.ClientUserName + "|" + $e.TargetInstance.Path
    $fs.WriteLine($out)
}

#「SMBLog」という名前のイベントを作成
Register-WmiEvent -Namespace $smb_namespace -Query $smb_query -SourceIdentifier "SMBLog" -Action $smb_event

#Get-EventSubscriberで動作中のイベントを確認
#Unregister-eventでイベント停止

方法2:Windowsログの監査ログを利用する

Windowsの監査ログを使って特定のファイルアクセスを監視する
上記記事を参考に監査ポリシーの設定をいじると、イベントビューアで閲覧可能なログを吐いてくれる。

  • 利点
    • 常時ジョブを走らせなくていい
  • 欠点
    • ログの取得が細かく取捨選択出来ないため、不要なログが貯まる。例えば、1ファイル開くだけでハンドル操作やらオープンやらのログが大量に発生する。

XPathで抽出条件を指定

$fromDay = -20
$days = 20
$startTime = [DateTime](Get-Date).AddDays($fromDay).ToString("yyyy/MM/dd 00:00:00")
$startUTCTime = [System.TimeZoneInfo]::ConvertTimeToUtc($startTime).ToString("yyyy-MM-ddTHH:mm:ssZ")
$endUTCTime = [System.TimeZoneInfo]::ConvertTimeToUtc($startTime.AddDays($days)).ToString("yyyy-MM-ddTHH:mm:ssZ")

#ログ抽出処理
#対象のEvent=4656
#explorerのアクセスは取得しない
$filter = @"
    Event/System/EventID='4656' and
    Event/EventData[
    Data[@Name='ProcessName']!='C:\Windows\explorer.exe'
    ] and
    Event/EventData[
    Data[@Name='ObjectType']='File'
    ] and
    Event/System/TimeCreated[@SystemTime>='$startUTCTime'] and
    Event/System/TimeCreated[@SystemTime<'$endUTCTime']
"@

#ログ抽出
try{
    Get-WinEvent -LogName security -FilterXPath $filter | % {
        $eventxml = [xml]$_.toXML()
        #名前空間を指定しないと抽出不可能
        $ns = New-Object Xml.XmlNamespaceManager $eventxml.NameTable
        $ns.AddNamespace("e", "http://schemas.microsoft.com/win/2004/08/events/event")

        $prop = @{"Time"=[DateTime]$eventxml.SelectSingleNode('e:Event/e:System/e:TimeCreated', $ns).Attributes.GetNamedItem("SystemTime").Value;
                  "User"=$eventxml.SelectSingleNode('e:Event/e:EventData/e:Data[@Name="SubjectUserName"]', $ns).InnerText;
                  "Domain"=$eventxml.SelectSingleNode('e:Event/e:EventData/e:Data[@Name="SubjectDomainName"]', $ns).InnerText;
                  "Path"=$eventxml.SelectSingleNode('e:Event/e:EventData/e:Data[@Name="ObjectName"]', $ns).InnerText;
                  "Process"=$eventxml.SelectSingleNode('e:Event/e:EventData/e:Data[@Name="ProcessName"]', $ns).InnerText}
                  return New-Object -TypeName PSObject -Property $prop
        }
}
catch {
    Write-Host "該当ログなし"
    $error | Select-Object -Last 1
}
Hijiri_Ishi
場末のSIer
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away