Problem overview
When critical security incidents occur or a device falls into the wrong hands, administrators need an immediate way to ensure no one can log into or remain logged on to that system. This script addresses that challenge by instantly logging out active sessions and disabling local or domain accounts, delivering peace of mind in high-pressure circumstances.
<#
This resource is provided as a convenience for Level users. We cannot
guarantee it will work in all environments. Please test before deploying
to your production environment. We welcome contributions to our community
library
Level Library
https://level.io/library/script-windows-lock-device
#>
# We use a script-scoped variable so that all functions can modify it.
# Initialize $script:errors to $false at the start.
$script:errors = $false
# Function to check if the device is domain-joined
function Is-DomainJoined {
$domain = (Get-WmiObject Win32_ComputerSystem).PartOfDomain
return $domain
}
# Function to log out all users
function LogOut-Users {
try {
$sessions = query session 2>$null | ForEach-Object {
$fields = $_ -split '\s{2,}'
if ($fields.Count -ge 3) {
[PSCustomObject]@{
SessionName = $fields[0]
UserName = $fields[1]
SessionID = $fields[2]
}
}
}
foreach ($session in $sessions) {
if ($session.UserName -and $session.SessionID -match '^\d+$') {
try {
logoff $session.SessionID
Write-Host "User $($session.UserName) has been logged out."
} catch {
Write-Host "ALERT: Failed to log out user $($session.UserName): $_"
$script:errors = $true
}
}
}
} catch {
Write-Host "ALERT: Error retrieving user sessions: $_"
$script:errors = $true
}
}
# Function to disable all local accounts
function Disable-LocalAccounts {
try {
$localUsers = Get-LocalUser
foreach ($user in $localUsers) {
try {
Disable-LocalUser -Name $user.Name
Write-Host "Local account $($user.Name) has been locked."
} catch {
Write-Host "ALERT: Failed to lock local account $($user.Name): $_"
$script:errors = $true
}
}
} catch {
Write-Host "ALERT: Error retrieving local accounts: $_"
$script:errors = $true
}
}
# Function to disable Active Directory accounts (only if domain-joined)
function Disable-ADAccounts {
try {
$adUsers = Get-WmiObject Win32_ComputerSystem | Select-Object -ExpandProperty UserName
if ($adUsers -and $adUsers -match '\\') {
foreach ($adUser in $adUsers) {
try {
# Extract just the username (DOMAIN\Username format)
$adUserName = $adUser -split '\\' | Select-Object -Last 1
Disable-ADAccount -Identity $adUserName -Confirm:$false
Write-Host "AD account $adUserName has been locked."
} catch {
Write-Host "ALERT: Failed to lock AD account $($adUserName): $($_.Exception.Message)"
$script:errors = $true
}
}
}
} catch {
Write-Host "ALERT: Failed to retrieve AD users: $_"
$script:errors = $true
}
}
# Execute actions
LogOut-Users
Disable-LocalAccounts
# If the system is domain-joined, disable AD users
if (Is-DomainJoined) {
Write-Host "Domain detected. Locking AD users..."
Disable-ADAccounts
} else {
Write-Host "No domain detected. Skipping AD account lock."
}
if ($script:errors) {
Write-Host "ALERT: Errors occurred during execution. Exiting with code 1."
exit 1
}
Write-Host "All users have been logged out and locked successfully."
This script forcefully logs out all currently active user sessions on a Windows system. It then disables every local user account to prevent any subsequent logins. If the device is domain-joined, it also attempts to disable Active Directory user accounts by connecting to the relevant domain environment, ensuring a comprehensive lock on all potential user access points.
Use cases
- Urgent lockdown for lost or stolen devices
- Quick response to a suspected security breach
- Regulatory or compliance requirement for secure device decommissioning
- Rapid removal of access for recently terminated employees
Recommendations
- Test thoroughly in a non-production environment before widespread deployment
- Consider building a script-based monitor in Level to trigger this script on demand when a security alert occurs
- For scheduled security routines, set up a recurring automation in Level with a schedule trigger to run this script
- Review all locked accounts afterward to ensure legitimate users retain appropriate access in non-emergency scenarios