Monitoring Active Windows Users in Grafana Using Windows Exporter, Prometheus, and PowerShell

Introduction

Monitoring logged-in Windows users is a common requirement for IT administrators and operations teams. Knowing who is currently logged in, when they logged in, and whether their session is active can help with system auditing, compliance, and operational monitoring.

In this article, we will build a real-time Windows User Monitoring Dashboard in Grafana using:

  • Windows Exporter
  • Prometheus
  • PowerShell
  • Grafana

The final dashboard will display:

  • Logged-in user names
  • Login time
  • User state (Active/Disconnected)
  • Active user count

Step 1: Verify Windows Exporter Installation

Verify that Windows Exporter is running:

sc query windows_exporter

Expected:
STATE : 4 RUNNING


Step 2: Verify Textfile Collector Configuration
Run:
sc qc windows_exporter
Example Output:

BINARY_PATH_NAME :

"C:\Program Files\windows_exporter\windows_exporter.exe"

--log.file eventlog

--collector.textfile.directory="C:\Program Files\windows_exporter\textfile_inputs"

The presence of:

–collector.textfile.directory

confirms that the Textfile Collector is enabled.


Step 3: Create Textfile Collector Directory
C:\Program Files\windows_exporter\textfile_inputs

This directory will contain custom Prometheus metrics.
Step 4: Create PowerShell Script
C:\Program Files\windows_exporter\users.ps1

Paste the following script:

$output = query user
$lines = $output | Select-Object -Skip 1

$metrics = @()

foreach ($line in $lines) {

    $line = $line -replace "^\s*>", ""

    $clean = ($line -replace "\s{2,}", "|").Trim()
    $parts = $clean -split "\|"

    if ($parts.Count -ge 5) {

        if ($parts.Count -eq 6) {
            $username    = $parts[0].Trim()
            $sessionname = $parts[1].Trim()
            $id          = $parts[2].Trim()
            $state       = $parts[3].Trim()
            $idle        = $parts[4].Trim()
            $logon       = $parts[5].Trim()
        }
        else {
            $username    = $parts[0].Trim()
            $sessionname = "none"
            $id          = $parts[1].Trim()
            $state       = $parts[2].Trim()
            $idle        = $parts[3].Trim()
            $logon       = $parts[4].Trim()
        }

        $username = $username -replace "\s+", " "

        if ($state -match "Active| Disc") {
            $value = 1
        }
        else {
            $value = 0
        }

        $metrics += "windows_user_info{username=""$username"",session=""$sessionname"",id=""$id"",state=""$state"",idle_time=""$idle"",logon_time=""$logon""} $value"
    }
}

$metrics | Out-File "C:\Program Files\windows_exporter\textfile_inputs\users.prom" -Encoding ascii

Step 5: Execute the Script

Run:

powershell.exe -ExecutionPolicy Bypass -File “C:\Program Files\windows_exporter\textfile_inputs\users.ps1”

Step 6: Verify Generated Metric File

Open:

C:\Program Files\windows_exporter\textfile_inputs\users.prom

Example: windows_user_info{username=“dell”,session=“console”,id=“3”,state=“Active”,idle_time=“none”,logon_time=“09-06-2026 10:29 AM”} 1

Step 7: Verify Windows Exporter Metrics

Open:

http://localhost:9182/metrics

Search:

windows_user_info


Expected:
windows_user_info{username=“dell”,session=“console”,state=“Active”} 1
Step 8: Configure Task Scheduler

To update the metric automatically every minute:

General Tab

Program:

powershell.exe

Arguments:

-ExecutionPolicy Bypass -File “C:\Program Files\windows_exporter\textfile_inputs\users.ps1”


Conditions Tab

Settings Tab
Enable:
• Allow task to be run on demand
• Run task as soon as possible after a scheduled start is missed

Save the task.
Step 9: Verify Prometheus

Open Prometheus:

http://localhost:9090

Execute:

windows_user_info

Expected result:

windows_user_info{username=“dell”} 1

Step 10: Create Grafana Dashboard


Dashboard Output

The dashboard successfully displays:

User Name Logon Time State
dell 09-06-2026 10:29 AM Active

Administrators can instantly identify who is logged in and their current session status.
Benefits

  • Real-time Windows user monitoring
  • No additional agents required
  • Uses existing Prometheus infrastructure
  • Easily scalable across multiple Windows servers
  • Customizable Grafana dashboards

Conclusion

By combining PowerShell, Windows Exporter Textfile Collector, Prometheus, and Grafana, we created a lightweight and efficient solution for monitoring active Windows users. This approach provides real-time visibility into user sessions and can be extended to include additional system audit information as needed.

This is a very nice write up @infofcc3

Question for you though, can this scale and if so how would it be implemented in an environment with 500 laptops and desktops?

Thank you @yosiasz
Thank you for your question.
This blog demonstrates the concept on a Windows machine, but I have also tested it in a multi-machine environment. In my setup, Prometheus is installed on a central server, and Windows Exporter with the PowerShell script is deployed on multiple Windows servers.

For example, I currently have two Windows machines (M1 and M2) sending user session metrics to a central Prometheus server (M3). Grafana is able to display different active user counts and user session details for each machine independently using hostname and instance labels.

As shown in my implementation, M1 reports 15 active users, while M2 reports 13 active users, proving that Prometheus can collect and Grafana can visualize user session data from multiple machines simultaneously.