イベントログの一覧は以下のような形で取得できる。
PS>Get-EventLog -List Max(K) Retain OverflowAction Entries Log ------ ------ -------------- ------- --- 20,480 0 OverwriteAsNeeded 30,480 Application 20,480 0 OverwriteAsNeeded 0 HardwareEvents 512 7 OverwriteOlder 0 Internet Explorer 20,480 0 OverwriteAsNeeded 0 Key Management Service 8,192 0 OverwriteAsNeeded 0 Media Center 128 0 OverwriteAsNeeded 2,359 OAlerts 20,480 0 OverwriteAsNeeded 29,732 Security 20,480 0 OverwriteAsNeeded 58,985 System 15,360 0 OverwriteAsNeeded 19,325 Windows PowerShell |
この結果から、Entriesがゼロのログを除外するには、普通に考えると以下のようになる。
PS>Get-EventLog -List | ?{$_.Entries} Max(K) Retain OverflowAction Entries Log ------ ------ -------------- ------- --- 20,480 0 OverwriteAsNeeded 30,480 Application 128 0 OverwriteAsNeeded 2,359 OAlerts 20,480 0 OverwriteAsNeeded 29,732 Security 20,480 0 OverwriteAsNeeded 58,985 System 15,360 0 OverwriteAsNeeded 19,325 Windows PowerShell |
結果は期待通りのものが取得できているのだが、何かがおかしい。
試してみると分かるがやけに時間がかかるのである。最初の一覧表示がノータイムで帰ってきていることを思えば、そこからEntriesがゼロの4行をフィルターするだけの処理もノータイムで返ってきて然るべき。
そこで、その原因を調べてみた。
PS>Get-EventLog -List | gm Entries TypeName: System.Diagnostics.EventLog Name MemberType Definition ---- ---------- ---------- Entries Property System.Diagnostics.EventLogEntryCollection Entries {get;} |
これを見ると判るように、そもそもEntriesプロパティは
EventLogEntryCollectionを返してきている。
にも関わらず単純に画面出力したときは、その数が表示されているということはそこに何かが介在していることになる。
PowershellではdotNETのオブジェクトを出力するときにDotNetTypes.format.ps1xmlというファイルの定義に従って表示する仕掛けになっている。(パスは通常C:\WINDOWS\system32\WindowsPowerShell\v1.0)
そこでこの中身を確認してみると
Diagnostics.EventLogクラスは以下のように定義されている。
<View> <Name>System.Diagnostics.EventLog</Name> <ViewSelectedBy> <TypeName>System.Diagnostics.EventLog</TypeName> </ViewSelectedBy> <TableControl> <TableHeaders> <TableColumnHeader> <Label>Max(K)</Label> <Alignment>Right</Alignment> <Width>8</Width> </TableColumnHeader> <TableColumnHeader> <Label>Retain</Label> <Alignment>Right</Alignment> <Width>6</Width> </TableColumnHeader> <TableColumnHeader> <Label>OverflowAction</Label> <Width>18</Width> </TableColumnHeader> <TableColumnHeader> <Label>Entries</Label> <Alignment>Right</Alignment> <Width>10</Width> </TableColumnHeader> <TableColumnHeader> <Label>Log</Label> </TableColumnHeader> </TableHeaders> <TableRowEntries> <TableRowEntry> <TableColumnItems> <TableColumnItem> <ScriptBlock>$_.MaximumKilobytes.ToString('N0')</ScriptBlock> </TableColumnItem> <TableColumnItem> <PropertyName>MinimumRetentionDays</PropertyName> </TableColumnItem> <TableColumnItem> <PropertyName>OverflowAction</PropertyName> </TableColumnItem> <TableColumnItem> <ScriptBlock>$_.Entries.Count.ToString('N0')</ScriptBlock> </TableColumnItem> <TableColumnItem> <PropertyName>Log</PropertyName> </TableColumnItem> </TableColumnItems> </TableRowEntry> </TableRowEntries> </TableControl> </View>
|
Entriesプロパティは、そのCountを表示する仕掛けになっていることが解る。
そこで先のフィルターを以下のように書き換える。
PS>get-eventlog -List | ? {$_.entries.count} Max(K) Retain OverflowAction Entries Log ------ ------ -------------- ------- --- 20,480 0 OverwriteAsNeeded 30,480 Application 128 0 OverwriteAsNeeded 2,359 OAlerts 20,480 0 OverwriteAsNeeded 29,732 Security 20,480 0 OverwriteAsNeeded 58,987 System 15,360 0 OverwriteAsNeeded 19,325 Windows PowerShell |
すると期待通り、ノータイムで結果が帰ってきた。(最初のやり方では各Entrieの中身を全件なめて抽出が行われているのだろう)
0 件のコメント:
コメントを投稿