PowerShell Script to delete 100+ local user accounts from 50+ desktops

Hi,
I am looking for a powershell script to delete 100+ Local user accounts from 50+ desktops that are in the Domain. Instead of logging into each individual PC’s and deleting the users one by one, I prefer to run a powershell script from somewhere like the domain controller to delete the users from each of these desktops.

I have the details in an excel spreadsheet as below

Any other forums that you suggest, for me to get help regarding this?

PowerShell is capable of doing this. But we would like you to try this. You need to find the way to do it locally first, then execute the same command against you target systems using PowerShell’s remoting capability. Below documentations will help you.

  • Get-Help Invoke-Command -Full
<li><a href="https://www.powershellgallery.com/packages/ImportExcel/5.2.0" rel="noopener" target="_blank">ImportExcel</a> module by Douge Finke</li>

We will be here to help you when encountering problems with your script.

Depending on what version of PS you are on, there are built-in cmdlet to do this for a single host.

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.localaccounts/remove-localuser?view=powershell-5.1
Otherwise use this...
https://www.powershellgallery.com/packages/localaccount/1.4
As pointed out by , you then just need to run this for multiple computers by using a ForLoop targeting those remote systems using the noted cmdlet.

There are plenty of samples all over the web showing how to delete local user accounts.

https://berkenbile.wordpress.com/2013/04/26/manage-local-user-accounts-with-powershell/

https://learn-powershell.net/2011/01/27/use-powershell-to-remove-local-profiles/

https://sysadminguides.org/2017/04/30/delete-local-user-profiles-remotely-using-a-powershell-script-delprof-exe/


 

 

 

 

@jj, It would be great if you update the post by formating the code using code posting tags , this makes other to easily understand your code, below link will help you.

Thanks for the replies…

#Prompt for a computer to connect to
$computer = Read-Host “Please enter a computer name”
#Test network connection before making connection
If ($computer -ne $Env:Computername) {
If (!(Test-Connection -comp $computer -count 1 -quiet)) {
Write-Warning “$computer is not accessible, please try a different computer or verify it is powered on.”
Break
}
}
Try {
#Verify that the OS Version is 6.0 and above, otherwise the script will fail
If ((Get-WmiObject -ComputerName $computer Win32_OperatingSystem -ea stop).Version -lt 6.0) {
Write-Warning “The Operating System of the computer is not supported.`nClient: Vista and above`nServer: Windows 2008 and above.”
Break
}
}
Catch {
Write-Warning “$($error[0])”
Break
}
Do {
#Gather all of the user profiles on computer
Try {
[array]$users = Get-WmiObject -ComputerName $computer Win32_UserProfile -filter “LocalPath Like ‘C:\Users\%’” -ea stop
}
Catch {
Write-Warning "$($error[0]) "
Break
}
#Cache the number of users
$num_users = $users.count

Write-Host -ForegroundColor Green “User profiles on $($computer):”

#Begin iterating through all of the accounts to display
For ($i=0;$i -lt $num_users; $i++) {
Write-Host -ForegroundColor Green “$($i): $(($users[$i].localpath).replace(‘C:\Users’,’’))”
}
Write-Host -ForegroundColor Green “q: Quit”
#Prompt for user to select a profile to remove from computer
Do {
$account = Read-Host “Select a number to delete local profile or ‘q’ to quit”
#Find out if user selected to quit, otherwise answer is an integer
If ($account -NotLike “q*”) {
$account = $account -as [int]
}
}
#Ensure that the selection is a number and within the valid range
Until (($account -lt $num_users -AND $account -match “\d”) -OR $account -Like “q*”)
If ($account -Like “q*”) {
Break
}
Write-Host -ForegroundColor Yellow “Deleting profile: $(($users[$account].localpath).replace(‘C:\Users’,’’))”
#Remove the local profile
($users[$account]).Delete()
Write-Host -ForegroundColor Green “Profile: $(($users[$account].localpath).replace(‘C:\Users’,’’)) has been deleted”

#Configure yes choice
$yes = New-Object System.Management.Automation.Host.ChoiceDescription “&Yes”,“Remove another profile.”

#Configure no choice
$no = New-Object System.Management.Automation.Host.ChoiceDescription “&No”,“Quit profile removal”

#Determine Values for Choice
$choice = [System.Management.Automation.Host.ChoiceDescription[]] @($yes,$no)

#Determine Default Selection
[int]$default = 0

#Present choice option to user
$userchoice = $host.ui.PromptforChoice("",“Remove Another Profile?”,$choice,$default)
}
#If user selects No, then quit the script
Until ($userchoice -eq 1)

 

Many Thanks for the replies…

The above code from https://learn-powershell.net/2011/01/27/use-powershell-to-remove-local-profiles/ for deleting the selected local users from a system. I would like the script to read from an excel file or csv file.

Is this possible? Can anyone please modify the code?

 

As a reminder, format the code for the forums. The instructions are in bold a the top of every reply. “To format code…”

If you want to read from a csv file https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/import-csv?view=powershell-6

And you will want a for each loop so https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/foreach-object?view=powershell-6

Give it a try and let us know where you run into issues with using it.

I have modified the previous code as it was too complicated. Please see the following code and let me know whether it would work.

For deleting Local User Accounts from remote computers

clear
$hostdetail = Import-CSV C:\Users\oj\Desktop\Test\hosts.csv

ForEach ($item in $hostdetail)
{
$hostname = $($item.hostname)
$username = $($item.username)
$computer = $hostname

#Test network connection before making connection and Verify that the OS Version is 6.0 and above

If ((!(Test-Connection -comp $computer -count 1 -quiet)) -Or ((Get-WmiObject -ComputerName $computer Win32_OperatingSystem -ea stop).Version -lt 6.0))
{
Write-Warning “$computer is not accessible or The Operating System of the computer is not supported.`nClient: Vista and above`nServer: Windows 2008 and above.”
}
else
{
Invoke-Command -ComputerName $computer -ScriptBlock $scriptBlock
}

}

$scriptBlock = {
function Remove-UserProfile
{
Remove-LocalUser -Name $username
}
Remove-UserProfile
}

}

IMHO, there are things wrong with your script and you’ve over complicated this

clear
$hostdetail = Import-CSV C:\Users\oj\Desktop\Test\hosts.csv

ForEach ($item in $hostdetail)
{
    # You really don't need any of this

 
    $hostname = $($item.hostname)
    $username = $($item.username)

    # This is redundant since you already have this in $hostname
    $computer = $hostname


    # Test network connection before making connection and Verify that the OS Version is 6.0 and above

    # Break long lines by natural break lines where possible, to prevent unnecessary long scrolling line commands, or use splatting to make things easier to read.

    If ((!(Test-Connection -comp $computer -count 1 -quiet)) -Or 
    ((Get-WmiObject -ComputerName $computer Win32_OperatingSystem -ea stop).Version -lt 6.0))
    {
         Write-Warning "$computer is not accessible or The Operating System of the computer is not supported.`nClient: Vista and above`nServer: Windows 2008 and above."
    }
    else
    {
         # You cannot use local variables in a remote session, unless you set the scope properly.
         Invoke-Command -ComputerName $computer -ScriptBlock $scriptBlock
    }

}

# Any function, scriptblock should be loaded before you use it.
# Load all this sort of stuff at the top of your script

$scriptBlock = {
function Remove-UserProfile
{
# This is only an PSv5 cmdlet, if you have legacy PS versions, OS versions not running PSv5, then this will fail.
# So, plan for this using ADSI
Remove-LocalUser -Name $username
}
Remove-UserProfile
}

}

this last brace is an unneeded, since it is not associated with a beginning brace.
You only have one command here, so why the separate script block.

Here is how I’d do this, but others may / will have their take on this.

See help information https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_remote_variables?view=powershell-6
# For deleting Local User Accounts from remote computers

clear
$hostdetail = Import-CSV 'C:\Users\oj\Desktop\Test\hosts.csv'


ForEach ($item in $hostdetail)
{
    # Test network connection before making connection and Verify that the OS 
    # Version is 6.0 and above

    If ((!(Test-Connection -comp $item.hostname -count 1 -quiet)) -Or 
    ((Get-WmiObject -ComputerName $item.hostname Win32_OperatingSystem -ea stop).Version -lt 6.0))
    { 
        $UserMessage = "$($item.hostname) is not accessible or The Operating System of the computer is not supported.
        `nClient: Vista and above`nServer: Windows 2008 and above."

        Write-Warning -Message $UserMessage
    }
    else
    { 
        If ($PSVersionTable.PSVersion.Major -ge 5)
        { Invoke-Command -ComputerName $Using:item.hostname -ScriptBlock {Remove-LocalUser -Name $Using:item.username} }
        Else
        { 
        Invoke-Command -ComputerName $Using:item.hostname -ScriptBlock {

        
        # See this article for ADSI / WMI way to do this
        # https://www.petri.com/managing-local-user-accounts-with-powershell
        
         -Name $Using:item.username} 
       }
    }
}

I can’t test this right now as I am not in a position to do so. Mkae sure you test in a lab first,
or wait for another response form someone who can test it.