0

私がやろうとしていること: get-winevent (ID: 4624) を使用して、Powershell でユーザー ログオン統計を取得します。あなたがより良い方法を知っているなら、私は他の提案に反対しません. 私はそれを機能させましたが、必要な方法でフォーマットされていません。これは私が持っているPowershellコードです(私はPowershellの初心者ですが、PHPに似ているものもあり、慣れています):

$LogonIDs = "4624"
$computers = get-content "c:\computers.txt"
foreach($pc in $computers) {
    if(test-connection $pc -count 1 -quiet) {
        write-host "Acquiring information for $pc"
        foreach ($item in $LogonIDs) {
            (Get-WinEvent -computername $pc -max 2000 -FilterHashtable @{Logname='security';Id=$item} `
                | Select TimeCreated,Message `
                | fl * `
                | findstr /G:c:\search.lst) `
                -replace "^[\s]+","" `
                -replace "[\s]+"," " `
                | out-file -append "c:\scripts\winevent\$LogonIDs.txt" 
        }
    }
    else {
        write-host "Couldn't ping $pc"
    }
}

search.lst には次の情報があります。

TimeCreated
Account Name:
Logon Type:
Logon GUID:
Logon Type:
Process Name:

スクリプトは次のようにエクスポートします。

TimeCreated : 5/2/2013 7:19:39 AM
Account Name: COMPUTERNAME$
Logon Type: 2
Account Name: [USERNAME]
Logon GUID: {00000000-0000-0000-0000-000000000000}
Process Name: C:\Windows\System32\winlogon.exe
TimeCreated : 5/2/2013 7:19:39 AM
Account Name: COMPUTERNAME$
Logon Type: 2
Account Name: [USERNAME]
Logon GUID: {AKEJ38DJ-3K45-3LKD-3LKD-DKEJ3787DJJ3}
Process Name: C:\Windows\System32\winlogon.exe
TimeCreated : 5/2/2013 6:50:42 AM
Account Name: -
Logon Type: 3
Account Name: COMPUTERNAME$
Logon GUID: {K458D890-3KJ8-DK3J-DK39-3LDJK23LD909}
Process Name: -
TimeCreated : 5/2/2013 6:27:22 AM
Account Name: COMPUTERNAME$
Logon Type: 5
Account Name: SYSTEM
Logon GUID: {00000000-0000-0000-0000-000000000000}
Process Name: C:\Windows\System32\services.exe

このスクリプトはすべて素晴らしいものをエクスポートしますが、私は Powershell で不要な情報をフォーマットして解析するのが苦手です。必要なものはすべて PHP でフォーマットできますが、Powershell で特定の情報を取り除くのを手伝ってくれる人がいれば、それは素晴らしいことです。

1) Explode at TimeCreated to create array
2) If Logon Type = 2, proceed, else skip to next value;
3) If Process Name contains winlogon.exe, proceed, else skip to next value;
4) If GUID = {00000000-0000-0000-0000-000000000000}, skip to next value;
5) If GUID != {00000000-0000-0000-0000-000000000000}, Account Name[0] = computername, Account Name[1] = Username, build new array with this information

これを行うために使用したPHPは次のとおりです。

$file = "4624.txt";
$file_explode = explode("TimeCreated",$file);
while(list($k,$v) = each($file_explode)) {
    $account_name = "";
    $time = "";
    if(preg_match("/Logon Type\:[\s]+2/msU",$v)) {
        if(preg_match("/winlogon\.exe/msU",$v)) {
            if(strstr($v,"{00000000-0000-0000-0000-000000000000}")) {
                continue;
            }
            else {
                preg_match("/[\s]+\:[\s]+(.*)$/msU",$v,$time);
                preg_match_all("/Account Name\:[\s]+(.*)$/msU",$v,$account_name);
                $new_arr[] = array(
                    "time" => $time[1],
                    "computer_name" => $account_name[1][0],
                    "user" => $account_name[1][1]
                );
            }
        }
    }
}

私がその PHP を使用できない理由 (これは私が見つけたばかりです) は、4624.txt に PII (個人を特定できる情報) が含まれているため、Web サーバーに投稿できないためです。もし誰かが私を助けてくれるなら、私は永遠にあなたの借金の中にいるでしょう;]

-アダム

4

1 に答える 1

0

一般に、この種の問題には、PowerShell で必要なすべてのデータのプロパティがあるカスタム オブジェクトを作成することで対処します。オブジェクトを取得したら、Sort-Object、Group-Object、Format-Object を使用してデータを操作する方がはるかに簡単です。

 $LogonIDs = 4624
 $IgnoreLogonGuid = '{00000000-0000-0000-0000-000000000000}'

 function Parse-LogonID4624Event
 {
    param(
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
        [psobject[]]
        $EventLogEntry
    )

    Process {
        foreach ($ev in $EventLogEntry)
        {
            $TimeCreated = [DateTime]::Parse($ev.TimeCreated)

            $AccountName = 'not found'
            if ($ev.Message -match '(?ims)New Logon:.*?Account Name:\s*(\S+)')
            {
                $AccountName =  $matches[1]
            }

            $LogonGuid = 'not found'
            if ($ev.Message -match '(?ims)^\s+Logon GUID:\s*(\S+)')
            {
                $LogonGuid =  $matches[1]
            }

            $obj = [pscustomobject] @{
                    TimeCreated = $TimeCreated
                    AccountName = $AccountName
                    LogonGuid = $LogonGuid
                    Message = $ev.Message
            }
            $obj
        }
    }
 }

 Get-WinEvent -max 20 -FilterHashtable @{LogName='Security';ID=$LogonIDs} | 
     Parse-LogonID4624Event |
     Where LogonGuid -ne $IgnoreLogonGuid 

この実装は、必要なすべてのフィールドを取得するわけではありませんが、必要な他のフィールドを洗い流して繰り返す方法を簡単に確認できると思います。この実装では、PowerShell v3 固有の機能を使用することに注意してください。v2 でこれが必要な場合はお知らせください。ほんの少しの調整が必要です。

于 2013-05-10T00:05:00.870 に答える