Level Verified

Windows Lock Device Script

Quickly logs out all user sessions and disables local or domain accounts on a Windows device. Ideal for emergency lockdown scenarios, stolen hardware, or security compliance efforts to protect systems from unauthorized access.

Import into Level

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.

PowerShell 100s timeout Runs as Local system Windows
<#
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

Frequently asked questions.

Does this script require admin privileges?

Yes, it must run with administrative permissions to log out sessions and modify accounts. Level executes scripts at system or root level by default.

What happens if the device is not domain-joined?

The script skips the domain user lockout steps and only locks local accounts.

Will this script affect system processes?

No, it only targets user sessions and accounts, leaving essential system processes untouched.

How can I confirm it worked correctly?

Review the script output in the Level console for any error messages and confirm users are no longer able to log in.

Can this process be reversed automatically?

Yes. See our Windows Unlock Device Script.

Ready when you are.

No credit card. No sales call. Just sign up and start managing.