首页 文章

如何使用Powershell读取登录事件和查找用户信息?

提问于
浏览
2

如何使用Powershell从Windows事件日志中读取登录和注销事件,并从Active Directory检索每个用户的相应信息?

2 回答

  • 0

    以下脚本将从系统日志中读取Winlogon事件,根据每个用户的SID从AD检索信息,并在生成的HTML页面中显示结果 . 缓存每个AD查找的结果,以防止不必要的往返AD服务器 .

    # event id 7001 is Logon, event id 7002 is Logoff
    function WinlogonEventIdToString($EventID) {switch($EventID){7001{"Logon";break}7002{"Logoff";break}}}
    
    # look up SID in Active Directory and cache the results in a hashtable
    $AdUsers = @{}
    function SidToAdUser($sid) {
      $AdUser = $AdUsers[$sid]
      if ($AdUser -eq $null) {
        $AdUser = $AdUsers[$sid] = [adsi]("LDAP://<SID=" + $sid + ">")
      }
      return $AdUser
    }
    
    $outputFilename = [System.IO.Path]::GetTempPath() + "DisplayLatestLogonEvents.html"
    
    # the first Select extracts the SID from the event log entry and converts the event id to a descriptive string
    # the second Select is responsible for looking up the User object in Active Directory, using the SID
    # the final Select picks the various attribute data from the User object, ready for display in the table
    # to retrieve only recent log entries, one can use something like this in Get-EventLog: -After (Get-Date).AddDays(-14)
    Get-Eventlog -Logname "System" -Source "Microsoft-Windows-Winlogon" -InstanceId 7001,7002 `
      | Select TimeGenerated, @{n='Operation';e={WinlogonEventIdToString $_.EventID}}, @{n='SID';e={$_.ReplacementStrings[1]}} `
      | Select TimeGenerated, Operation, @{n='AdUser';e={(SidToAdUser $_.SID)}} `
      | Select TimeGenerated, Operation, `
               @{n='Username';e={$_.AdUser.sAMAccountName}}, `
               @{n='Full name';e={$_.AdUser.firstname + " " + $_.AdUser.lastname}}, `
               @{n='Title';e={$_.AdUser.title}}, `
               @{n='Department';e={$_.AdUser.department}}, `
               @{n='Company';e={$_.AdUser.company}} `
      | ConvertTo-HTML -Head "<style>td, th { border:1px solid grey }</style>" | Out-File $outputFilename
    
    # this will open the default web browser
    Invoke-Expression $outputFilename
    
  • 5

    对于Windows 10专业版,Active Directory域的成员,此脚本将生成所选用户的登录/注销时间列表,包括来自屏幕保护程序锁屏的事件 . Powershell脚本记录活动工作时间,无需应用程序 .

    # original source: https://community.spiceworks.com/topic/764481-get-logon-off-workstation-lock-unlock-times 
    # cleaned up, filtered by username, and included lock by screensaver timeout by kevin, Dec 2018
    # must enable auditing via secpol.msc
    # Security Settings -> Advanced Audit Policy -> System Audit -> Logon/Logoff -> Audit Other Logon/Off Events -> On Success
    
    $days = 30
    $username = "kevin"
    
    Write-Host "Retrieving last $days days of user: $username, logon/logoff activity... please wait
    
    $events = @()
    $events += Get-WinEvent -FilterHashtable @{
        LogName='Security'
        Id=@(4624,4800,4634)
        StartTime=(Get-Date).AddDays(-$days)
    }
    
    $type_lu = @{
        4624 = 'Logon'
        4800 = 'Logoff' # screensaver lock
        4634 = 'Logoff' # explicit
    }
    
    $ns = @{'ns'='http://schemas.microsoft.com/win/2004/08/events/event'}
    $target_xpath = "//ns:Data[@Name='TargetUserName']"
    $usersid_xpath = "//ns:Data[@Name='UserSid']"
    
    If($events) {
        $results = ForEach($event in $events) {
            $xml = $event.ToXml()
            Switch -Regex ($event.Id) {
                '4...' {
                    $user = (
                        Select-Xml -Content $xml -Namespace $ns -XPath $target_xpath
                    ).Node.'#text'
                    Break
                }
                '7...' {
                    $sid = (
                        Select-Xml -Content $xml -Namespace $ns -XPath $usersid_xpath
                    ).Node.'#text'
                    $user = (
                        New-Object -TypeName 'System.Security.Principal.SecurityIdentifier' -ArgumentList $sid
                    ).Translate([System.Security.Principal.NTAccount]).Value
                    Break
                }
            }
            if($username -eq $user) {
                New-Object -TypeName PSObject -Property @{
                    Time = $event.TimeCreated
                    Id = $event.Id
                    Type = $type_lu[$event.Id]
                    User = $user
                }
            }
        }
    
        If($results) {
            $results
        }
    }
    

    示例输出:

    C:\WINDOWS\system32>powershell -file C:\desk\path\timetracker.ps1
    Retrieving last 10 days of user: kevin, logon/logoff activity
    
    Time                   User    Id Type
    ----                   ----    -- ----
    12/4/2018 1:39:22 PM   kevin 4634 Logoff
    12/4/2018 1:39:19 PM   kevin 4800 Logoff
    12/4/2018 1:10:28 PM   kevin 4634 Logoff
    12/4/2018 1:10:28 PM   kevin 4624 Logon
    12/4/2018 12:57:32 PM  kevin 4634 Logoff
    12/4/2018 12:57:32 PM  kevin 4624 Logon
    12/4/2018 12:29:43 PM  kevin 4624 Logon
    12/4/2018 11:48:11 AM  kevin 4634 Logoff
    

    为了调试这个脚本,我打开了事件查看器eventvwr.msc,并使用了这个自定义过滤器(XML) .

    <QueryList>
      <Query Id="0" Path="Security">
        <Select Path="Security">*[System[(EventID=4624)] and EventData[Data[@Name='TargetUserName']='kevin']]</Select>
      </Query>
    </QueryList>
    

    Powershell还有Get-EventLog cmdlet,但我发现它缺少选项 .

相关问题