AutomoxAutomox

Deleting a local user account

slammert
April 3, 2025 at 6:06 pm UTC

We are trying to remove an old local account that is on most of our windows computers.  The code removed the account when I ran it locally but not when I run it through automox.

 

powershell11 lines
# Delete a local account named "tommyboy" 
$AccountName = "tommyboy"

# Check if the account exists
if (Get-LocalUser -Name $AccountName -ErrorAction SilentlyContinue) {
    # Forcefully delete the account
    Remove-LocalUser -Name $AccountName -Force
    Write-Host "The account '$AccountName' has been deleted successfully."
} else {
    Write-Host "The account '$AccountName' does not exist."
}

 

This discussion is archived and closed to replies. Continue it in the Automox Community Slack.

Discuss on Slack

Replies (3)

MarkH-AutomoxApril 3, 2025
#1

Hi Slammert,

This is a situation where get-localuser is not available for 32-bit powershell

 

 

I was able to get this pieced together which worked, using 32-bit available commands:

 

powershell16 lines
# ======================
# Otto AI Generated Code
# ======================
# Define the username of the account you want to delete
$username = "delete-me"  # Replace with the actual username

# Check if the user exists using net user command
$userExists = net user | Select-String -Pattern $username

if ($userExists) {
    # Remove the user account using net user command
    net user $username /delete
    Write-Host "User account '$username' has been deleted."
} else {
    Write-Host "User account '$username' does not exist."
}

 

slammertApril 3, 2025
#2

Thanks Mark!!!

 

ASkrodzki-AutomoxAugust 19, 2025
#3
powershell76 lines
<#  Local User Removal
    Flow:
      1) If logged in, try up to 3 times to force logoff; stop on first success
      2) Disable (optional)
      3) Delete account (optional)
      4) Delete profile by SID (optional)
    Exit: 0 ok/done, 1 error
#>

# ------------ User Variables ------------
$RemoveUsername        = @('Firstname Surname')  
$ProtectedNames  = @('Administrator','svc_','WDAGUtilityAccount','svc_VeeamBackup')  

$DisableAccount  = $true         # disable after sign-off
$DeleteAccount   = $true         # delete the account
$DeleteProfile   = $true         # delete Windows profile

$LogoffTries     = 3             # attempts to force logoff
$BetweenTriesSec = 2             # seconds between attempts
# -----------------------------------------------------

function Get-UserSessionIds {
    param([string]$User)
    $raw = quser "$User" 2>$null
    if (-not $raw) { return @() }
    ($raw -split "`n" | Select-Object -Skip 1 | ForEach-Object {
        $m = [regex]::Match($_, '\s+(\d+)\s+\S+\s')
        if ($m.Success) { [int]$m.Groups[1].Value }
    }) | Where-Object { $_ -ne $null }
}

try {
    if ($ProtectedNames -contains $RemoveUsername) { throw "Avoiding operation on protected account '$RemoveUsername'." }

    $user = Get-LocalUser -Name $RemoveUsername -ErrorAction SilentlyContinue
    if (-not $user) { Write-Output "User '$RemoveUsername' not found. Nothing to do."; exit 0 }

    # Capture SID once (profile deletion can occur after account deletion)
    $sid = $user.SID.Value

    # 1) If logged in, try up to N times to force logoff; stop on first success
    $sessions = Get-UserSessionIds -User $RemoveUsername
    for ($i = 1; $i -le $LogoffTries -and $sessions.Count -gt 0; $i++) {
        foreach ($sidSession in $sessions) { try { logoff $sidSession 2>$null } catch {} }
        Start-Sleep -Seconds $BetweenTriesSec
        $sessions = Get-UserSessionIds -User $RemoveUsername
        if ($sessions.Count -eq 0) { break }
    }

    # 2) Disable (optional)
    if ($DisableAccount -and $user.Enabled) {
        Disable-LocalUser -Name $RemoveUsername -ErrorAction Stop
        Write-Output "Disabled '$RemoveUsername'."
    }

    # 3) Delete account (optional)
    if ($DeleteAccount) {
        Remove-LocalUser -Name $RemoveUsername -ErrorAction Stop
        Write-Output "Deleted account '$RemoveUsername'."
    }

    # 4) Delete profile (optional)
    if ($DeleteProfile -and $sid) {
        $prof = Get-CimInstance Win32_UserProfile -Filter "SID='$sid'" -ErrorAction SilentlyContinue
        if ($prof) {
            Remove-CimInstance $prof -ErrorAction SilentlyContinue
            Write-Output "Deleted profile for SID $sid."
        }
    }

    exit 0
}
catch {
    Write-Output "ERROR: $($_.Exception.Message)"
    exit 1
}


Looks good, a few improvements that I’d suggest:
 

  • check if a user is logged on
  • if logged on, include a timer or force logoff with 3 or more tries with verification between each step
  • an exclusion filter ensuring certain accounts do not get removed; such as administrative service accounts

Building safety into the script ensures more flexibility in the long-term; without breaking any existing processes or workflows. And, this does not need a scheduled task.

Possible future considerations: 

  • add function to measure how long script to run
  • add timestamp for each step with verbose logging
  • add simple loop to deleting user accounts
  • add simple loop to remove user profile
  • add a singular loop instead of having many (more code to maintain)
  • return the username with SID once queried before any removal
  • account lockout considerations
  • force password reset
  • remove users from local group