グループポリシーとログオンスクリプトでログオン・ログオフ時間を記録する

windows-logon-logoff-sam

監査法人による監査や、クライアントの業務管理でActive Directory上のユーザーアカウントがドメインへログオン、ログオフした時間を取得したいというニーズは多いと思います。今回は、このログオン、ログオフした時間をグループポリシーとログオン・ログオフスクリプトを利用してイベントビューワーへ出力する設定について手順を紹介します。

実はWindows Serverでは、ログオンを取得するための機能が実装されています。ただ、この機能は痒いところに手が届かない。ログオフの記録を取得できません。また、時間についても仕様上、正確な取得が出来ず、結果として、余りログ取得の意味を成さない機能になっています。その為、今回、紹介するような手順での取得が必要となってしまいます。有償のログ取得ツールを利用すれば良いのですが、そういったツールは高価なことが多い。それなら運用でカバーしてしまおうというのが、今回の発端です。

Windowsの監査ログには、ログオン、ログオフを記録する機能が実装されていますが、この機能は仕様上、正確なログオン・ログオフ時間が記録できず、実運用で利用するには、難しい実装になっています。ログオンは記録されるが、ログオフが記録できないなど、機能としては不十分な点も挙げられます。そこで、監査ログを利用せず、ログオン・ログオフ時間を記録するために利用されてきた設定がログオン・ログオフスクリプトとグループポリシーの組み合わせになります。
ユーザーアカウントのドメインログオン、ログオフ時にスクリプトを実行して、ドメインコントローラーのイベントビューワーに時間とユーザーアカウント名、コンピューター名を出力させるという方法です。

最近では、Windows Server 2012をドメインコントローラーにしての、Windowsドメイン環境も増えてきたかと思いますので、2012でこのログオン・ログオフ時の記録を行う設定を試してみました。ドメインコントローラーのOSバージョンはWindows Server 2012 R2ですが、2008 R2でも利用できるかと思います。Windows Server 2012でのActive Directory構築については

Windows
activedirectory-2012-ad-setting
Windows Server 2012 R2へのActive Directoryインストールと基本設定

Windows Server 2012に関する以前の記事でWindows Server 2012 R2の基本セットアップまで完了しましたので、この環境を利用して、2012サーバーでActive Directoryの構築をしてみたいと思います ...

を参照下さい。

1. ログオン、ログオフスクリプトの準備

ログオン・ログオフスクリプトの準備を行います。スクリプトを記載したファイルを作成後、必要な部分の変更を行い、所定のパスへ保存します。ログの出力についてはスクリプトを二つ記載しました。運用している環境に応じて、使い分けて下さい。

1-1. スクリプトの変更

スクリプトは任意で変更を行います。以下のスクリプトはWindows Server 2003以上のActive Directory環境で利用できるスクリプトになり、ウェブサイトでよく見かけるWSHのLogEventメソッドを利用したものとなります。
ログオン用スクリプト パターン1

Const AUDIT_SUCCESS = 8

REM Create Objects
Set objShell = WScript.CreateObject("WScript.Shell")
Set objNetwork = WScript.CreateObject("WScript.Network")
Set objADsys = CreateObject("ADSystemInfo")

REM Build a message string
strMsg = " ユーザ" + objNetwork.UserName + " が、ドメイン" + _
objNetwork.Userdomain + " (サーバー" + objADsys.GetAnyDCName + _
")にログオンしました。"

REM Write to Eventlog
objShell.LogEvent AUDIT_SUCCESS,strMsg,objADSys.GetAnyDCName

Set objShell = Nothing
Set objNetwork = Nothing
Set objADSys = Nothing

ログオフ用スクリプト 1

Const AUDIT_SUCCESS = 8

REM Create Objects
Set objShell = WScript.CreateObject("WScript.Shell")
Set objNetwork = WScript.CreateObject("WScript.Network")
Set objADsys = CreateObject("ADSystemInfo")

REM Build a message string
strMsg = " ユーザ" + objNetwork.UserName + " が、ドメイン" + _
objNetwork.Userdomain + " (サーバー" + objADsys.GetAnyDCName + _
")にログオフしました。"

REM Write to Eventlog
objShell.LogEvent AUDIT_SUCCESS,strMsg,objADSys.GetAnyDCName

Set objShell = Nothing
Set objNetwork = Nothing
Set objADSys = Nothing

作成したのスクリプトを、LogOnScript.vbs LogOffScript.vbsなど、任意の名前で保存します。

1-2. スクリプトの配置

以下のフォルダへスクリプトを移動します。
移動先フォルダは「ファイル名を指定して実行」ダイアログボックスに以下のパスを入力します。
パスは設定を行う環境に合わせて読み替えて下さい。
\\DC名\SYSVOL\ドメイン名\scrpits\
ここでは
\\win13r2ev\sysvol\testdom.local\scripts\
を入力しています。

path-to-script

以下のようにフォルダが開きますので、ここへスクリプトをドラッグ&ドロップします。

scripts-folder

スクリプトを移動したら、フォルダを閉じます。これでスクリプトの準備は完了です。

2. グループポリシーの作成

ログオン・ログオフスクリプトをドメインに適用するために、グループポリシーを利用します。グループポリシーの作成と適用については

Windows
windows-group-policy-sam
Windows ServerのActive Directory環境でグループポリシーを設定する方法

こんにちは、レムシステムITエンジニアのKomura(@system_kom)です。 ここ最近、当社ではActive Directoryを構築する案件が増えています。Active Directoryはリソースの一括管理に強力な機能を備えてい ...

を参照してください。

任意の名前でグループポリシーを作成して、ロギングしたいドメインやOUにリンクします。
ここではLogon_loggingとしてグループポリシーを作成しました。

group-policy-log

グループポリシー作成後は以下の点を変更します。
[ユーザーの構成][ポリシー][Windowsの設定][スクリプト][ログオン] => 先程配置したログオンスクリプトを指定

gp-logon-script

[ユーザーの構成]>[ポリシー]>[Windowsの設定][スクリプト][ログオフ]には先程配置したログオフスクリプトを指定

gp-logoff-log

3. アクセス権の設定

通常、イベントビューワーへの書き込みはDomain_Adminsグループに属するアカウントでしか、行うことができません。その為、一般ユーザーで書き込みができるようにログを出力させるドメインコントローラー上で、以下のコマンドを実行します。

wevtutil sl application /ca:O:BAG:SYD:(A;;0xf0007;;;SY)(A;;0x7;;;BA)(A;;0x7;;;SO)(A;;0x3;;;IU)(A;;0x3;;;SU)(A;;0x3;;;S-1-5-3)(A;;0x3;;;S-1-5-33)(A;;0x1;;;S-1-5-32-573)(A;;0x3;;;DU)

gp-cmd

エラーなどが出力されなければ、コマンドは正常に実行できています。

4. スクリプト実行用グループポリシーの有効化

ドメインに所属するクライアント側でグループポリシーを有効化するために、コマンドプロンプトから

gpupdate /force

を実行します。
グループポリシーが更新されたことが表示されれば、適用は完了です。
ここでは明示的にグループポリシーを更新していますが、一定時間後には伝播されます。
直ぐに確認を行いたい場合は、上記のコマンドを実行することで、反映されます。

5. スクリプトの動作確認

クライアントPCでドメインへのログオン、ログオフを行い、ドメインコントローラーの「アプリケーション」ログに該当するログが出力されていることを確認します。

5-1. ドメインログオン時のログ (スクリプト1の場合)

ドメインログオン時に以下のようなログが出力されます。

gp-log-logon01

5-2. ドメインログオフ時のログ(スクリプト1の場合)

ドメインからのログオフ時には以下のようなログが出力されます。

gp-log-logon02

6. イベントログの「ユーザー」フィールドが必要な場合

今までに紹介したスクリプトの場合、イベントログの「ユーザー」フィールドにユーザー名が含まれません。ユーザーフィールドの項目が必要な場合、以下のスクリプトを利用します。
本スクリプトは「2008 Active Directoryでログオン・ログオフ監査.sys」
を参考にさせて頂きました。

6-1. スクリプトの変更 2

ユーザーフィールドを利用する場合、Logeventではなく、eventcreateを利用したスクリプトを使用します。
最低限、変更が必要な部分はドメインコントローラーの指定部分である
Const EVENTLOG_DC_NAME = "\\DC_NAME"
になります。
ここをスクリプトを配置するドメインコントローラー名に変更して下さい。
以下がログオンスクリプトです。
ログオンスクリプト

On Error Resume Next

Const EVENTLOG_DC_NAME = "\\DC_NAME"
Const SCRIPT_PRE_MESSAGE = "[LOGON SUCCESS] "

Set objShell = WScript.CreateObject("WScript.Shell")
Set objADSystemInfo = WScript.CreateObject("ADSystemInfo")

Set objUser = GetObject("LDAP://" & objADSystemInfo.UserName)

strGroupNames = "MemberOf: CN=Domain Users"
For Each objGroup In objUser.Groups
strGroupNames = strGroupNames & "," & objGroup.Name
Next

objShell.Run "EVENTCREATE /S " & EVENTLOG_DC_NAME & " /T INFORMATION /L APPLICATION /ID 8 /D " & """" & SCRIPT_PRE_MESSAGE & strGroupNames & """", 7

Set objShell = Nothing
Set objADSystemInfo = Nothing
Set objUser = Nothing

以下、ログオフスクリプトになります。
ログオフスクリプト

On Error Resume Next

Const EVENTLOG_DC_NAME = "\\DC_NAME"
Const SCRIPT_PRE_MESSAGE = "[LOGOFF SUCCESS] "

Set objShell = WScript.CreateObject("WScript.Shell")
Set objADSystemInfo = WScript.CreateObject("ADSystemInfo")

Set objUser = GetObject("LDAP://" & objADSystemInfo.UserName)

strGroupNames = "MemberOf: CN=Domain Users"
For Each objGroup In objUser.Groups
strGroupNames = strGroupNames & "," & objGroup.Name
Next

objShell.Run "EVENTCREATE /S " & EVENTLOG_DC_NAME & " /T INFORMATION /L APPLICATION /ID 8 /D " & """" & SCRIPT_PRE_MESSAGE & strGroupNames & """", 7, True

Set objShell = Nothing
Set objADSystemInfo = Nothing
Set objUser = Nothing

スクリプトが用意できたら、それ以外の手順は、スクリプト1の場合と同じになります。
項目1-2. から2の最後までと同様に設定を行うことで、ログの取得が可能です。

6-2. ドメインログオン時のログ スクリプト2の場合

ドメインログオン時に以下のようなログが出力されます。
ユーザーフィールドが含まれた形となります。

gp-logon-success

6-3. ドメインログオフ時のログ スクリプト2の場合

ドメインからのログオフ時には以下のようなログが出力されます。
ログオン時と同様に、ユーザーフィールドが含まれた形となります。

gp-logoff-success

この際、セキュリティログではなく、アプリケーションログに出力されることに注意してください。

7. まとめ

ユーザーのドメインログオン・ログオフ時間を取得しようとした場合、資産管理やミドルウェアなどの導入が必要になると考えがちですが、この記事で紹介したようにグループポリシーとログオンスクリプトを利用することによって、AD単体での取得もできます。
イベントに出力されるログからログオン・ログオフ時間をトレースするのは、他のログも出力されることから、少し大変ですが、まずは取得するということが大切な環境もあります。そういった環境の場合、本設定はADがあれば追加の費用無しで導入できます。コストが厳しい状況や、予算が無い場合は、このような方法もあるということを、頭の隅にでも置いておくと、何かと役に立つかと思います。

因みにログを見やすい形に生成するためのアプリケーション(Log Parser)もマイクロソフトでは無償でリリースしていますので、こちらについてもいずれ、記事にしていきたいと思います。

  • この記事を書いた人
rem-profile-photo

レムシステム

レムシステムはPC・サーバー・ネットワークでの業務効率化を主な業務としている会社です。全国に対応しています。

-Windows