Repository navigation
Releases: paulmann/Windows-LogOff
Release list
Initial Release — Windows-LogOff v1.0.0
Windows-LogOff v1.0.0 — Initial Release
What Is This?
Windows-LogOff (logoff.ps1) is a production-grade PowerShell 7+ utility that provides system administrators with a reliable, two-stage pipeline for forcibly terminating user sessions on Windows systems and cleaning up any residual processes.
This is not a simple logoff.exe wrapper. It is a carefully engineered tool that combines graceful shutdown attempts with aggressive cleanup to ensure complete user removal from multi-session Windows environments.
Release Badge
The Two-Stage Pipeline
Stage 1 — Graceful Session Logoff
The script enumerates active user sessions via quser / query user, then invokes logoff.exe <SessionId> /SERVER:localhost for each matching session. This triggers Windows to send WM_QUERYENDSESSION messages to all GUI applications in that session, giving them approximately 5 seconds to save data and exit cleanly before the OS forcibly terminates them.
Stage 2 — Residual Process Sweep
After a configurable delay (default: 3 seconds), the script performs a system-wide process scan using Get-Process -IncludeUserName, identifying any processes still owned by the target user that survived Stage 1. These include orphaned background tasks, detached services, and Session 0 processes. Each one is terminated via Stop-Process -Force (Win32 TerminateProcess), which immediately unloads the process from memory.
Key Features
- Dual-Stage Cleanup — Graceful logoff + forced process termination for complete user removal
- PowerShell 7.0+ Native — Built on modern PowerShell with
$PSStylecolor output, null-conditional operators, and advanced function patterns - SupportsShouldProcess — Full
-WhatIfand-Confirmsupport for safe dry-run testing - Structured Output — Returns
PSCustomObjectwithSummaryandDetailsproperties for logging and automation pipelines - Session Safety — Automatically skips the current controller session unless explicitly overridden
- Locale-Aware Parsing — Regex-based parsing of
quseroutput instead of fragile column indexing - Elevation Enforcement —
#Requires -RunAsAdministratorensures required privileges - Built-in Help — Comprehensive comment-based help via
Get-Helpor-Help - Domain & Local User Support — Works with both local accounts and domain-joined users
- Configurable Delay — Adjustable pause between logoff and process sweep (0–120 seconds)
- Selective Stage Execution — Skip either stage independently
Quick Start
# Display help
.\logoff.ps1 -Help
# Dry run (no changes made)
.\logoff.ps1 -UserName 'targetuser' -WhatIf -Verbose
# Standard execution
.\logoff.ps1 -UserName 'targetuser' -Verbose
# Log off sessions only (skip process cleanup)
.\logoff.ps1 -UserName 'targetuser' -SkipProcessTermination -Verbose
# Process cleanup only (skip session logoff)
.\logoff.ps1 -UserName 'targetuser' -SkipLogoff -Verbose
# Allow logoff of your own session (dangerous!)
.\logoff.ps1 -UserName 'targetuser' -AllowCurrentSession -Confirm:$false -Verbose
# Export results to JSON for auditing
.\logoff.ps1 -UserName 'targetuser' | ConvertTo-Json -Depth 5 | Out-File 'result.json'Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
-UserName |
string |
Yes | — | Target username without domain prefix |
-UserContext |
string |
No | $env:COMPUTERNAME |
Computer/domain prefix for process owner matching |
-SkipLogoff |
switch |
No | $false |
Skip session logoff; only terminate processes |
-SkipProcessTermination |
switch |
No | $false |
Skip process termination; only log off sessions |
-AllowCurrentSession |
switch |
No | $false |
Allow logoff of the current controller session |
-PostLogoffDelaySeconds |
int |
No | 3 |
Delay between logoff and process sweep (0–120) |
-Help / -? / -H |
switch |
No | $false |
Display built-in help and exit |
-Verbose |
switch |
No | — | Enable detailed diagnostic output |
-WhatIf |
switch |
No | — | Show what would happen without making changes |
-Confirm |
switch |
No | — | Prompt for confirmation before each action |
Safety Warning
This script is destructive by design. When executed, it will terminate all active sessions for the target user and force-kill all processes owned by that user. Any unsaved work will be permanently lost.
Always test with
-WhatIffirst. Never run this on a user who may have unsaved documents unless the situation demands it.
Safety Measures Implemented
| Protection | Description |
|---|---|
| Current Session Skip | Your own session is never logged off unless -AllowCurrentSession is provided |
| Current Process Skip | The PowerShell host process ($PID) is excluded from termination |
| Elevation Check | Administrator privileges validated at startup |
| Platform Check | #Requires -Version 7.0 and $IsWindows validation |
| Input Validation | Username validated with regex ^[\w.\-]+$ to prevent injection |
| WhatIf Support | Full dry-run simulation via -WhatIf before any real changes |
| Structured Audit | Every action produces an auditable record with timestamp and exit code |
Release Changelog
v1.0.0 — Initial Release (2026-04-29)
New Features:
- Complete two-stage user session cleanup pipeline (graceful logoff + residual process sweep)
quser/query usersession enumeration with regex-based, locale-aware parsingGet-Process -IncludeUserNameprocess discovery with domain and local user supportStop-Process -Forcetermination with automatic exclusion of the running PowerShell hostSupportsShouldProcessintegration for-WhatIf/-Confirmdry-run testing- Structured
PSCustomObjectoutput withSummaryandDetailsproperties - Comprehensive comment-based help system (
Get-Help/-Help) - Configurable post-logoff delay (
-PostLogoffDelaySeconds, 0–120s) - Selective stage execution (
-SkipLogoff,-SkipProcessTermination) - Current session protection with
-AllowCurrentSessionoverride $PSStylecolored console output with graceful fallback#Requires -RunAsAdministratorelevation enforcement#Requires -Version 7.0PowerShell version enforcement- Stopwatch-based execution time tracking
- Per-operation result records with stage, status, target, timestamp, and message
Technical Improvements:
- Regex-based session ID extraction (no fragile column-index parsing)
Win32_ProcessCIM query for reliable current session ID detection- Graceful error handling with structured failure records
- Splatting pattern for parameter passing to internal function
- Script-scoped helper functions for consistent visibility across begin/process/end blocks
Topics & Tags
Primary Tags:
powershell powershell-script windows-admin session-management logoff process-kill system-administrator windows-server rds terminal-services
Secondary Tags:
ps7 powershell-7 automation it-operations helpdesk remote-desktop user-cleanup forced-logoff windows-utility admin-tool
Installation
# Clone the repository
git clone https://github.com/paulmann/Windows-LogOff.git
cd Windows-LogOff
# Unblock the script (Windows may block downloaded scripts)
Unblock-File -Path ".\logoff.ps1"
# Set execution policy for current session
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
# Run with help to verify
.\logoff.ps1 -HelpSystem Requirements
| Component | Requirement |
|---|---|
| OS | Windows 10, Windows 11, Windows Server 2016–2025 |
| PowerShell | 7.0 or higher (7.5+ recommended) |
| Privileges | Administrator (elevated) |
| Dependencies | Built-in Windows utilities: quser, query user, logoff.exe |
Author & Credits
Author: Mikhail Deynekin
Website: deynekin.com
Email: Mikhail@Deynekin.com
GitHub: @paulmann
License
Distributed under the MIT License. See LICENSE for details.
Always test in a non-production environment before deploying.
Backup important data before running destructive operations.