'How do you delete user profiles in powershell?

I am writing a powershell script to delete user profiles and I understand the method I am using is not the best. I was wondering what would be a better way to do it? I am still very much new to powershell but I am willing to learn

The code I already have:

$ErrorActionPreference= 'silentlycontinue'
$Users = Get-WmiObject -Class Win32_UserProfile
$IgnoreList = "helpdesk", "administrator", "Default"

:OuterLoop
foreach ($User in $Users) {
    foreach ($name in $IgnoreList) {
        if ($User.localpath -like "*\$name") {
            continue OuterLoop
        }
    }

    $User.Delete()
}


Solution 1:[1]

WHy script this when the enterprise approach is GPO.

How to Delete Old User Profiles Using GPO and PowerShell?

No reason to do this from scratch, leverage what others have provided...

Use PowerShell to remove local profiles

How to delete user profiles older than a specified number of days in Windows

...as well as the modules from the MS powershellgallery.com, as you look at whatever approach you decide use.

Find-Module -Name '*user*profile*' | Format-Table -AutoSize

<#
# Results

Version Name                               Repository Description
------- ----                               ---------- -----------
1.0     UserProfile                        PSGallery  This module manages user profiles on local and remote computers
0.1.1   Microsoft.Graph.Users.ProfilePhoto PSGallery  Microsoft Graph PowerShell Cmdlets
1.0.6   Get-UserProfile                    PSGallery  The Get-UserProfile module list or remove User Profiles from local
#>

Find-Module -Name '*userprofile*' | Format-List -Force

Update

Yet, you specifically said...

'I understand the method I am using is not the best. I was wondering what would be a better way to do it?

... and what we all have suggested, using GPO is the best way, the normal industry-accepted enterprise way to do this. Don't script, unless you have no other choice. Windows AD will do this for you.

Don't reinvent the wheel unless you know it's really a better wheel. In learning, of course, there is study, trial, and error, but learn and use from sources that have already done this. There are tons of examples all over the web for this use case. Just search for it. No reason to do this from scratch.

'powershell remove user profiles'

Which are showing what you are already doing... Example(s) - pre-built scripts for this use case via the Ms powershellgallery.com.

Use PowerShell delete a user profile (step-by-step guide)

Get-CimInstance -ComputerName SRV1,SRV2,SRV3 -Class Win32_UserProfile | 
Where-Object { $_.LocalPath.split('\')[-1] -eq 'UserA' } | 
Remove-CimInstance

Remove-UserProfile - Remove Local User Profiles and Clean C:\Users Directory

This script contains a function (Remove-UserProfile) which is used to remove user profiles, and additional contents of the C:\Users directory (if specified) on a local computer.

Download: Remove-UserProfile.ps1

Delete Unused user Profiles on local machine (PowerShell)

Script Delete user profiles over multiple servers v2

ANd using the modules that you see from the above commands, is not something to do later in life. Those are in / available from MS and in PowerShell directly for a reason. Everything you are using in PowerShell is coming from modules hosted on your machine and the ones you download and install from MS and other resources.

Again, use the built-in enterprise tools in Windows or other chosen OS as designed, and if they don't provide what you need, then look to other options, like scripting to an object-level that the enterprise tool is not exposing in its GUI.

Solution 2:[2]

I do a similar thing. With a lot of profiles, I've found I've had to wait for the cpu to calm down because of the appxsvc service spawning threads without limit. I used to delete per-user firewall rules, but that doesn't seem necessary anymore.

$excludedprofilelist = 'C:\Users\admin1','C:\users\admin2'

$myprofiles = $profiles | where { !$_.Special -and
  $excludedprofilelist -notcontains $_.LocalPath }

$sleepseconds = 1
$numcores = 4

foreach ($profile in $myprofiles) {
  $msg = "deleting profile " + $profile.LocalPath
  $profile | remove-wmiobject
  $msg = $msg + " $?"
  echo $msg   # the result

  # recycle bin
  if (test-path c:\`$recycle.bin\$($profile.sid)) {
    rm -r c:\`$recycle.bin\$($profile.sid) -force
  }

  # wait for appx cleanup, what if profile delete error?
  #while ( (get-appxpackage -user $profile.sid).count ) {
  #  sleep 1
  #}
  do {
    # make sure it's running
    $id = Get-WmiObject -Class Win32_Service -Filter "Name = 'appxsvc'" | 
      Select-Object -ExpandProperty ProcessId

    # $proc = get-process -id $id
    # access is denied
    # 4proc.priorityclass = 'belownormal'
  
    $cpu1 = (get-process -Id $id).cpu
    sleep $sleepseconds
    $cpu2 = (get-process -Id $id).cpu
    $cpu = [int](($cpu2 - $cpu1)/($numcores*$sleepseconds) * 100)
  } while ($cpu)
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2