Display and remove

Windows user profiles in Powershell
Posted by Miguel Mora on January 18, 2022

INDEX

1. Introduction
2. Prerrequisites
3. What are we going to do?
4. Steps
     4.1. Functions
          “ShowMenu" Function
          “ShowUsers" Function
          “RemoveUsers" Function
     4.2. Main Code
          Filtering Users
          Showing Menu
          Show Users
          Delete Users
5. Extras
     5.1. Run as Admin
     5.2. "Running scripts is disabled on this system" error
          Avoid it: “Bypass” Execution Policy Flag
          Set permissions
6. I want the code

 

1. Introduction

Working in a dynamic work environment makes "recycling" PCs that has been previously used for new users, a very common task.

We usually do not have that time to be able to completely reinstall the Operating System, install all the company applications and other necessary operations; that is why deleting user profiles from a computer is the most efficient task.

On this website we like to optimize our time, so we are going to show you how to show and delete user profiles for Windows computers using Powershell. Let's go for it!

 

 

 

2. Prerrequisites

For this lab we will need:

  • A PC with Windows Operating System
  • Admin permissions on that PC
  • At least Powershell 3.0 installed

 

3. What are we going to do?

These are the main steps to do :

  1. Show Main Menu
  2. Show Users
  3. Remove Users

 

This is the flow diagram that we're going to do.

 

 

4. Steps

4.1. Functions

For the repetitive tasks, we will create some functions that will be run in our Main code. The functions needed will be:

  • ShowMenu Function: Será el menú principal
  • ShowUsers Function: Display Users
  • RemoveUsers Function: Remove User Profiles

 

“ShowMenu” Function

This function will have the content of the main menu of our GUI (Graphical User Interface).

In this case we will create an ordered dictionary (or hash table).

 

What is a Dictionary or Hash Table?

A hash table is a data structure, like an array, except that each value (object) is associated with a key.

Our menu will be very simple, with only three values:

  • Show Users
  • Remove Users
  • Exit
function ShowMenu {
    $Menu = [ordered]@{
      1 = 'Show Users'
      5 = 'Remove Multiple Users'
      q = 'Exit'
      }
    return $Menu
}

 

“ShowUsers” Function

This functions receives a group of users as input, and it will allow to display them in an interactive way.

function ShowUsers {
    param (
        [Object[]]$User,
        [String]$Title
    )
    $ShowUsersTemp = $User | Out-GridView -PassThru -Title $Title
    return $ShowUsersTemp
}

 

param: It allows us to set the parameters that we receive. In this case, the title of our menu window, and a group of objects, where each of which will be a user.

ShowUsersTemp: This variable will use the group of objects and put them in our interactive window. We will use for that the “Out-GridView” command, which sends our output to a grid view window.

 

“RemoveUsers” Function

This function will receive a group of users as input, it will show them on the screen and will allow us to choose the ones we want to remove.

Once we have selected those users, a window will appear asking for confirmation.

 

function RemoveUsers {
    param (
        [Object[]]$User,
        [Object[]]$Userpath
    )

    $title    = 'Remove Users'
    $question1 = "The following profiles will be deleted:"
    $question2 = $Userpath -Join "`r"
    $question3 = "Are you sure you want to proceed?"

    $question = "$question1{0}$question2{0}$question3" -f [environment]::NewLine
    $choices  = '&Yes', '&No'

	$popup = New-Object -ComObject wscript.shell
	$decision = $popup.Popup("$question",0,"$title",64+1)

    if ($decision -eq 1) 
    {
        $User | Remove-WmiObject
    } else {
        Write-Host 'Cancelled'
    }
}

 

param: We define the input parameters of the function. In this case, our group of users, and the group of the location of the user profiles.

title, question1, question2, question3: We define what we are going to show in the confirmation window. In this case, we will show a list of all the profiles that are going to be deleted.

popup: We will define a popup window where it will let us confirm the deletion of user profiles. To do this we create a shortcut to a COM object called wscript.shell, and store it in the popup variable.

wscript.shell: It's an object that will let you interact with some features of the Windows Shell; in our case, we will use the popup method to display a popup window.

decision: We configure the wscript.shell object to define the title of the popup as well as what it should display. Specifically, the defined values ​​are:

 question: Text going to be displayed.

 0: Time that our window will be visible. In our case, it will not disappear.

 title: Title of the window

 64+1: Buttons and icons that will be shown. In this case, it shows us the “Information Mark” icon (64), as well as the “Accept” and “Cancel” buttons (1)

Remove-WmiObject: In case of we are agree with the removal, we will remove the selected users.

 

4.2. Main Code

Once we have defined the functions, we will explain our main code step by step.

 

Filtering Users

We will first extract the local users along with their properties from our system, and filter the information of every user.

 

accounts: We will extract the user profiles from the system. To do this, we use the “Get-WmiObject” command. We will exclude those users that belong to the system itself (such as NETWORK SERVICE or LOCAL SERVICE).

$accounts = Get-WmiObject -Class Win32_UserProfile | Where-Object {$_.Special -ne 'Special'}

 

selection: Run our "ShowMenu" function, and displays the main menu on the screen with the data extracted from the previous function.

$selection = ShowMenu | Out-GridView -PassThru  -Title 'STT User Profile Manager - [by SalvaTuTiempo]'

 

allusers: Using the filtered users in the "accounts" variable, we will extract only the following fields:

  • Username: The username
  • LocalPath: The location of the profile
  • Loaded: If it is active (that is, if your session is in use)
  • SID: It is the identifier of said profile
  • LastUsed: Last time that profile was used

 

$allusers = $accounts | Select-Object @{Name='UserName';Expression={Split-Path $_.LocalPath -Leaf}}, LocalPath, Loaded, SID, @{Name='LastUsed';Expression={$_.ConvertToDateTime($_.LastUseTime)}}

 

Selecting Menu

In this section we will deal with the selection of the main menu. To do this, we will control with the “switch” instruction the value chosen in said menu, stored in the “selection” variable.

switch ($selection)
{

}

 

The rest of code will be inside this switch.

 

Show Users

In case of  "selection" variable is "1" (selecting the "Show Users" option), it will display the local user profiles. To do this, we will run the “ShowUsers” function and send the filtered users through the “User” field

{$Selection.Name -eq 1} 
{        
     ShowUsers -User $allusers -Title "Show User Profiles"
}

 

Remove Useres

In case of the "selection" variable is “5” (selecting “Remove Users” option), it will display the local user profiles. In this case, it will also let us select the users to be removed, and will be stored in “_SelectUser” variable.

$_Selectuser = ShowUsers -User $allusers -Title "Remove Users"

 

Once the users to be deleted have been selected, we will delete their profiles.

rmvuser: We will filter the user profiles with those that have been selected in the menu. To do this, we will filter by their SID identifier.

RemoveUsers: We will run “RemoveUsers” function and will send as parameters:

  • User: User profiles filtered through the variable “rmvuser”
  • Userpath: Location of those profiles

 

if ($_Selectuser) 
{
     $rmvuser = $accounts | Where-Object {$_.SID -in $_Selectuser.SID}
     RemoveUsers -User $rmvuser -Userpath $_SelectUser.LocalPath
} 

 

5. Extras

5.1. Run as Admin

Once we have finished our code, in order to delete user profiles it will be necessary to run our code as Administrator.

To do this, we can launch the "Run" window by pressing CTRL+R

 

And we need to write the following code inside:

powershell -Command "Start-Process PowerShell -Verb RunAs"

 

This will open a Powershell shell as Administrator.

Once we are inside the Shell, we will run our code

PS C:\WINDOWS\system32> & "D:\salvatutiempo\stt_winprofile_manager.ps1"

 

5.2. "Running scripts is disabled on this system" error

We might find the the following error when running our script: "Running scripts is disabled on this system".

 

This error is because scripting needs to be enabled on our system in order to run our code. We have two alternatives to fix this: avoid it or set permissions.

 

Avoid it: “Bypass” Execution Policy Flag

In order to avoid that error, we can use "Bypass" flag. This flag allows us to bypass the execution policy when executing scripts from a file. When we use this flag, we set that "Nothing is blocked and there are no warnings"

In order to run it, once we are in Powershell shell, we will run our code with the following command line:

PS C:\WINDOWS\system32> powershell.exe -ExecutionPolicy Bypass -File D:\Users\Miguel\Documents\salvatutiempo\stt_winprofile_manager.ps1

 

Set permissions

The other solution we have is to set the needed permissions.

For that, once we are in Powershell shell, we need run this command first:

C:\WINDOWS\system32> Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

 

Once permissions have been applied, we can run our code 

PS C:\WINDOWS\system32> & "D:\salvatutiempo\stt_winprofile_manager.ps1"

 

6. I want the code

You can find the whole code in the following repository:

Code

¿Te ha gustado?

Si te ha gustado y quieres aportar tu granito de arena para que esta comunidad crezca: