3

I found this script courtesy of Google, which remove all Local Accounts, but I would to keep these: Administrator, DefaultAccount, DevToolsUser, Guest, sshd, User, WDAGUtilityAccount Can someone help me?

Function Remove-LocalUser
{
  <#
      .Synopsis
      This function deletes a local user 
      .Description
      This function deletes a local user
      .Example
      Remove-LocalUser -userName "ed" 
      Removes a new local user named ed. 
      .Parameter ComputerName
      The name of the computer upon which to delete the user
      .Parameter UserName
      The name of the user to delete
      .Notes
      NAME:  Remove-LocalUser
      AUTHOR: ed wilson, msft
      LASTEDIT: 06/29/2011 10:07:42
      KEYWORDS: Local Account Management, Users
      HSG: HSG-06-30-11
      .Link
      Http://www.ScriptingGuys.com/blog
      #Requires -Version 2.0
  #>
  [CmdletBinding()]
  Param(
    [Parameter(Position=0,
        Mandatory=$True,
      ValueFromPipeline=$True)]
    [string]$userName
  )
  $computerName = $env:ComputerName
  $User = [ADSI]"WinNT://$computerName"
  $user.Delete('user',$userName)
} #end function Remove-LocalUser

$localUsers = Get-WmiObject -Class Win32_UserAccount -Filter  "LocalAccount='True'" | Select-Object Name
foreach ($localUser in  $localUsers.Name){
  Write-Host $localUser
  Remove-LocalUser -userName $localUser
}
5
  • You'll add a filter or whitelist of accounts you wish to exclude from deleting. Is this for a domain/business environment or your personal computer? Commented Jul 17, 2020 at 15:28
  • It's for a business environment.My problem is that I'm a newbie in scripting\coding, so I would need some examples for do it…
    – alessio89g
    Commented Jul 17, 2020 at 15:34
  • So, the script queries and stores a list of all of the local user accounts. You can manipulate this list before passing it along to the guts of the script using a Where statement or similar. Look up filtering a list of objects in PowerShell. Commented Jul 17, 2020 at 15:38
  • @alessio89g Could you please give some feedback on the provided answers? Commented Jul 28, 2020 at 5:20
  • I believed that I had already answered, but it seems I forgot it. I solved with Wasif_Hasan's script.
    – alessio89g
    Commented Jul 28, 2020 at 9:25

4 Answers 4

2

PowerShell has built-in cmdlets for managing local user accounts, so those should be preferred over a custom module (provided you're running a high enough version of PowerShell):

$KeepUsers = "Administrator", "DefaultAccount", "DevToolsUser", "Guest", "sshd", "User", "WDAGUtilityAccount"
Get-LocalUser | ? { $KeepUsers -notcontains $_.Name } | Remove-LocalUser

From left to right:

  1. Get all local users.
  2. Pipe it into Where-Object (? is an alias).
  3. Filter only for users whose usernames don't appear in the $KeepUsers array.
  4. Pipe the newly filtered users into Remove-LocalUser which deletes them.
0
1

Try this:

Get-WMIObject -Class Win32_UserAccount -Filter "LocalAccount='True'" | Where-Object {$_.Name -notin @("Administrator", "DefaultAccount", "DevToolsUser", "Guest", "sshd", "User", "WDAGUtilityAccount")} | Foreach {net user "$_.Name" /delete}
  • First list all local user accounts through WMI.
  • Then use Where-Object filter to exclude the user accounts to keep.
  • Then the pass the objects to Foreach block.
  • Now delete the user accounts using net user.

Footnotes

  • This script must be run with adminstrative priviliges.
  • You must do this from an user account not to be marked for deletion.
0
1

There is a PowerShell module on the PowerShellGallery.com for just this use case.

Find-Module -Name '*localuser*' | Format-Table -AutoSize
# Results
<#
Version Name                Repository Description                                                   
------- ----                ---------- -----------                                                   
3.0     LocalUserManagement PSGallery  a module that performs various local user management functions
#>

In PowerShell v5x and PowerShell Core6x or higher.

Get-Command -Name '*localuser*' | Format-Table -Autosize
# Results
<#
CommandType Name              Version Source                            
----------- ----              ------- ------                            
Cmdlet      Disable-LocalUser 1.0.0.0 Microsoft.PowerShell.LocalAccounts
Cmdlet      Enable-LocalUser  1.0.0.0 Microsoft.PowerShell.LocalAccounts
Cmdlet      Get-LocalUser     1.0.0.0 Microsoft.PowerShell.LocalAccounts
Cmdlet      New-LocalUser     1.0.0.0 Microsoft.PowerShell.LocalAccounts
Cmdlet      Remove-LocalUser  1.0.0.0 Microsoft.PowerShell.LocalAccounts
Cmdlet      Rename-LocalUser  1.0.0.0 Microsoft.PowerShell.LocalAccounts
Cmdlet      Set-LocalUser     1.0.0.0 Microsoft.PowerShell.LocalAccounts
#>

So you could just do this...

Get-LocalUser | 
Where Name -NotMatch 'Administrator|DefaultAccount|Guest|WDAGUtilityAccount'

You could do the same thing for the Remove cmdlet.

0

Deleting a local account sounds like one task, but it will at least consist of the following three steps:

  1. Delete the account from the local account database
  2. Delete the profile directory of this account
  3. Delete the account profile from the registry

There might be even more steps, but I have not found any documentaion on them so far. As there are several steps to perform, it is probably a bad idea to use too atomic functions for that. The Remove-LocalUser cmdlet and the net tool (with net user <username> /delete) are such atomic functions. They suggest to delete a local user - which sounds good - but they actually (only) delete the user from the local user account database. This might be sufficient for some scenarios, but be aware that registry keys and the profile directory will remain!

Microsoft offers a macro function to completely delete a local user account, unfortunately only in the GUI. You can find it through Settings > Accounts > Family & other users. Just select a user and click on Remove, then on Delete account and data. This will perform all three steps from above.

There is also a macro function to (just) remove the profile of a user. You can open it via Control Panel > System > Advanced system settings > Settings... (button in the User Profiles panel):

enter image description here

You can also open this window directly by executing rundll32 sysdm.cpl,EditUserProfiles in an elevated PowerShell. It is important to open this window with administrative privileges to see all user accounts and not only the own account (even when opening via GUI).

Deleting a user account through this window will perform steps 2 and 3 from above.

Wondering what the two unknown accounts are? They are the remains of two deleted accounts, one deleted by the Remove-LocalUser cmdlet and one by the net tool.

As you are looking for a PowerShell solution, we can at least perform the three steps from above manually, as long PowerShell does not provide a cmdlet to do all the work at once:

function Remove-LocalUserCompletely {

    Param(
        [Parameter(ValueFromPipelineByPropertyName)]
        $Name
    )

    process {
        $user = Get-LocalUser -Name $Name -ErrorAction Stop

        # Remove the user from the account database
        Remove-LocalUser -SID $user.SID

        # Remove the profile of the user (both, profile directory and profile in the registry)
        Get-CimInstance -Class Win32_UserProfile | ? SID -eq $user.SID | Remove-CimInstance
    }
}

# Example usage:
Remove-LocalUserCompletely -Name 'myuser'

This function is ready to be used in a pipeline, so you could delete all users except the ones you want to keep like this:

Get-LocalUser | ? Name -NotIn Administrator, DefaultAccount, DevToolsUser, Guest, sshd, User, WDAGUtilityAccount | Remove-LocalUserCompletely

But currently (in PS v5.1.18362.752) the pipeline between Get-LocalUser and Remove-LocalUser is bugged, which will also affect my function above. The following pipeline (without Remove-LocalUserCompletely) will only remove every second user account from the account database of the accounts that should be deleted:

Get-LocalUser | ? Name -NotIn Administrator, DefaultAccount, DevToolsUser, Guest, sshd, User, WDAGUtilityAccount | Remove-LocalUser

You can work around this by using a loop instead of a pipeline (now with Remove-LocalUserCompletely):

$users = Get-LocalUser | ? Name -NotIn Administrator, DefaultAccount, DevToolsUser, Guest, sshd, User, WDAGUtilityAccount
foreach ($user in $users) {
    Remove-LocalUserCompletely -Name $user.Name
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .