A couple of days ago at work, I was asked a question concerning whether a specific one-liner of code would work remotely. That one-liner was (Get-WMIObject Win32_UserProfile | ? {$_.localpath –like “*username).Delete()} I told him that, yes, in fact it would work. After this, I began to think of a way to make a script that will allow a help desk person, desktop support admin or a server admin to run the script and have it prompt for a machine, rather local or remote to make a connection to and then present a list of user profiles and the option to remove a specified profile.
Overall, it is a fairly simplistic script with with a couple Do/Until loops for the selection processes and some Try/Catch error checking (which in opinion, should always be included in any script that runs on PowerShell V2). I also make use of System.Management.Automation.Host.ChoiceDescription class to present a choice at the end of the script on whether the user wishes to quit the script or re-scan and delete another profile.
OS Compatibility
A big gotcha with this script is that while it can be ran from any machine with PowerShell v2, it can only be ran against a client using Vista and above or a server running Windows 2008 and above. Any other OS’s lower than this do not have the WMI class require for this to work and will fail.
Example
In this example, I have my profile (boe) on my laptop and another account (testuser) that I logged into to create the local profile folder.
I now call my script which asks for a computername, in which I type in the name and am then presented with 2 profiles, boe and testuser along with the option to quit the profile removal script. You will notice that it starts at 0, which is the beginning index of the array of user profiles.
I now select the testprofile to remove it. Since it is labeled 0, I type in 0 and proceed to remove the profile. After a few seconds (your time will vary depending on the size of the profile), I get a confirmation that the profile has been successfully deleted. There is then another prompt to either continue removing profiles or exit the script.
As you can see, the folder is now gone.
Really, that is all there is to it. This can be ran against a remote machine as well and it uses the Test-Connection cmdlet to verify the network access prior to making the WMI connection.
If you try to run this against a server that has an unsupported OS, then the script will throw an error and close.
Code
The script is available from the following locations:
<#
.SYNOPSIS
Interactive menu that allows a user to connect to a local or remote computer and remove a local profile.
.DESCRIPTION
Presents an interactive menu for user to first make a connection to a remote or local machine. After making connection to the machine,
the user is presented with all of the local profiles and then is asked to make a selection of which profile to delete. This is only valid
on Windows Vista OS and above for clients and Windows 2008 and above for server OS.
.NOTES
Name: Remove-LocalProfile
Author: Boe Prox
DateCreated: 26JAN2011
.LINK
https://boeprox.wordpress.com
http://msdn.microsoft.com/en-us/library/ee886409%28v=vs.85%29.aspx
.EXAMPLE
Remove-LocalProfile
Description
-----------
Presents a text based menu for the user to interactively remove a local profile on local or remote machine.
#>
#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)
