Unraveling User Login History with PowerShell

PowerShell scripts play an invaluable role in IT operations and security, automating tasks and extracting vital information for analysis. Today, we will delve into a script that allows you to view user login history, an important function for auditing and monitoring system access.

Background

Access logs are a gold mine for IT professionals. They help monitor system usage, detect unauthorized access, and uphold accountability. The provided script fetches user session start and stop events, an essential dataset for any robust IT security strategy. By excluding system accounts and focusing only on genuine users, it presents a clean and concise history of user access, making the lives of IT professionals and Managed Service Providers (MSPs) simpler and more efficient.

The Script


#Requires -Version 5.1

<#
.SYNOPSIS
    This will return user session start and stop events.
.DESCRIPTION
    This will return user session start and stop events. Excluding system accounts.
.EXAMPLE
    No params needed
    Returns all login events for all users.
.EXAMPLE
     -UserName "Fred"
    Returns all user login events of the user Fred.
.EXAMPLE
     -Days 7
    Returns the last 7 days of login events for all users.
.EXAMPLE
     -Days 7 -UserName "Fred"
    Returns the last 7 days of login events for the user Fred.
.EXAMPLE
    PS C:> Get-User-Login-History.ps1 -Days 7 -UserName "Fred"
    Returns the last 7 days of login events for the user Fred.
.NOTES
    Minimum OS Architecture Supported: Windows 10, Windows Server 2016
    Release Notes:
    Initial Release
.OUTPUTS
    Time                  Event        User  ID
    ----                  -----        ----  --
    10/7/2021 3:51:48 PM  SessionStop  User1 4634
    10/7/2021 3:51:48 PM  SessionStart User1 4624
.COMPONENT
    ManageUsers
By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://www.ninjaone.com/terms-of-use.
    Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. 
    Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. 
    Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. 
    Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. 
    Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. 
    Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. 
    EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).
#>

[CmdletBinding()]
param (
    # Specify one user
    [Parameter(Mandatory = $false)]
    [String]
    $UserName,
    # How far back in days you want to search, this is in 24 hour increments from the time it executes
    [Parameter(Mandatory = $false)]
    [int]
    $Days
)

begin {
    function Test-IsElevated {
        $id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
        $p = New-Object System.Security.Principal.WindowsPrincipal($id)
        if ($p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator))
        { Write-Output $true }
        else
        { Write-Output $false }
    }

    # System accounts that we don't want
    $SystemUsers = @(
        "SYSTEM"
        "NETWORK SERVICE"
        "LOCAL SERVICE"
    )
    # Filter for only getting session start and stop events from Security event log
    $FilterHashtable = @{
        LogName = "Security";
        id      = 4634, 4624
    }
    # If Days was specified then add this parameter
    if ($Days) {
        $FilterHashtable.Add("EndTime", (Get-Date).AddDays(-$Days))
    }
    # Creating a hash table for parameter splatting
    $Splat = @{
        FilterHashtable = $FilterHashtable
    }
}

process {
    if (-not (Test-IsElevated)) {
        Write-Error -Message "Access Denied. Please run with Administrator privileges."
        exit 1
    }
    # Get windows events, filter out everything but logins and logouts(Session starts and ends)
    Get-WinEvent @Splat | ForEach-Object {
        # UserName in the two event types are in different places in the Properties array
        if ($_.Id -eq 4634) {
            # Events with ID 4634 the user name is the second item in the array. Arrays start at 0 in PowerShell.
            $User = $_.Properties[1].Value
        }
        else {
            # Events with ID 4634 the user name is the sixth item in the array. Arrays start at 0 in PowerShell.
            $User = $_.Properties[5].Value
        }

        # Filter out system accounts and computer logins(Active Directory related)
        # DWM-0  = Desktop Window Manager
        # UMFD-0 = User Mode Framework Driver
        if ($SystemUsers -notcontains $User -and $User -notlike "DWM-*" -and $User -notlike "UMFD-*" -and $User -notlike "*$") {
            # If the UserName parameter was specified then only return that user's events
            if ($UserName -and $UserName -like $User) {
                # Write out to StandardOutput
                [PSCustomObject]@{
                    Time  = $_.TimeCreated
                    Event = if ($_.Id -eq 4634) { "SessionStop" } else { "SessionStart" }
                    User  = $User
                    ID    = $_.ID
                }
            } # If the UserName parameter was not specified return all users events
            elseif (-not $UserName) {
                # Write out to StandardOutput
                [PSCustomObject]@{
                    Time  = $_.TimeCreated
                    Event = if ($_.Id -eq 4634) { "SessionStop" } else { "SessionStart" }
                    User  = $User
                    ID    = $_.ID
                }
            }
        }
        # Null $User just in case the next loop iteration doesn't set it, we can then see that the user name is missing
        $User = $null
    }
}

end {}

 

Access over 300+ scripts in the NinjaOne Dojo

Get Access

Detailed Breakdown

  • The script begins with a series of comments outlining its usage and output format.
  • It then specifies its parameters, allowing the user to filter results by username or a specific number of past days.
  • In the begin block, the script establishes its requirements, including omitting system accounts and specifying relevant event IDs from the Windows security log.
  • The process block is where the magic happens. First, it ensures the script is run with administrator privileges. It then fetches the windows events corresponding to login and logout activities, filtering out system or irrelevant accounts.
  • For each event, it determines the username and whether the event was a login (SessionStart) or logout (SessionStop), outputting these details.

Potential Use Cases

Consider an IT administrator named Alex. Recently, there have been instances of unauthorized data access in the company. Alex decides to review the login history over the past week. By using this script with the -Days 7 parameter, Alex can get a comprehensive list of all user access events, helping him pinpoint any suspicious activity.

Comparisons

While there are dedicated tools and platforms that offer user activity tracking, many are often coupled with bulky software suites or carry a hefty price tag. This PowerShell script offers a lightweight, customizable, and cost-effective alternative. Furthermore, other methods might require extensive configurations, whereas this script is plug-and-play, requiring minimal setup.

FAQs

  • Is it necessary to run the script with administrator privileges?
    Yes, accessing the security logs requires elevated permissions.
  • Can I fetch logs older than a month?
    Absolutely, adjust the -Days parameter to your desired range.

Implications

Knowing user access patterns can be a double-edged sword. While it empowers IT professionals to maintain system integrity, mishandling this information could breach privacy guidelines. Moreover, persistent monitoring might raise concerns about workplace trust. Thus, while the script is a powerful tool, it’s essential to use it judiciously, adhering to both ethical and legal standards.

Recommendations

  • Always ensure you’re running the latest version of PowerShell for optimal performance and security.
  • Document all instances where you utilize this script for auditing purposes.
  • Regularly back up your logs to avoid potential data loss.

Final Thoughts

Managing user access is a crucial facet of IT security. This PowerShell script provides an efficient way to view login history, aiding in timely threat detection and response. While the script is a standalone solution, integrating it with platforms like NinjaOne can elevate its capabilities, offering a holistic IT management solution.

Using NinjaOne alongside such scripts can consolidate logging, enhance alert mechanisms, and provide a unified dashboard for all IT operations, ensuring a robust, streamlined, and secure IT infrastructure.

Next Steps

Building an efficient and effective IT team requires a centralized solution that acts as your core service deliver tool. NinjaOne enables IT teams to monitor, manage, secure, and support all their devices, wherever they are, without the need for complex on-premises infrastructure.

Learn more about NinjaOne Remote Script Deployment, check out a live tour, or start your free trial of the NinjaOne platform.

Categories:

You might also like

×

See NinjaOne in action!

By submitting this form, I accept NinjaOne's privacy policy.

NinjaOne Terms & Conditions

By clicking the “I Accept” button below, you indicate your acceptance of the following legal terms as well as our Terms of Use:

  • Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms.
  • Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party.
  • Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library belonging to or under the control of any other software provider.
  • Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations.
  • Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks.
  • Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script.
  • EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).