Important Notice: On February 29th, this community was put into read-only mode. All existing posts will remain but customers are unable to add new posts or comment on existing. Please feel to join our Community Discord for any questions and discussions.

Identifying orphaned local user profiles (either no username matching SID or path no longer exists)

I'm using the following PowerShell scanner in PDQ Inventory to identify orphaned local user profiles (note that I use text "True"/"False" instead of $true/$false since it seems newly-added Boolean variables test as $false before a scan populates the field with a value instead of $null, text fields do not have that issue):

if(Test-ComputerSecureChannel){
    Get-CimInstance -Class Win32_UserProfile | select -Property SID, LocalPath, @{Name='Username';expression={((New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList $_.SID).Translate([System.Security.Principal.NTAccount])).Value}}, @{Name='PathExists';expression={if(Test-Path -Path $_.LocalPath -ErrorAction SilentlyContinue){ "True" } else { "False" }}}
}

To cut down on false positives I wrap the code in Test-ComputerSecureChannel (to confirm the secure channel between the local computer and the domain isn't broken).  If that fails nothing is returned (safer to return nothing than false positives).

PowerShell code for package in PDQ Deploy to remove orphaned local user profiles (using exit code 777 as error):

if(Test-ComputerSecureChannel){
    $orphans = Get-CimInstance -Class Win32_UserProfile | select -Property SID, LocalPath, @{Name='Username';expression={((New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList $_.SID).Translate([System.Security.Principal.NTAccount])).Value}}, @{Name='PathExists';expression={if(Test-Path -Path $_.LocalPath -ErrorAction SilentlyContinue){ "True" } else { "False" }}} | Where-Object { ($_.Username -eq $null) -or ($_.PathExists -eq "False") }
    foreach ($orphan in $orphans) {
     $error.clear()
     try {
         $vCim = $null
         $vCim = Get-CimInstance -Class Win32_UserProfile -ErrorAction Stop| Where-Object { $_.SID -eq $orphan.SID }
         if ($vCim.GetType().Name -eq "CimInstance"){
            $vCim | Remove-CimInstance -ErrorAction Stop
            $vCim = $null
         } 
     } catch {
         "Failed to remove $orphan"
         $_.Exception
         exit 777
     }
     if (!$error) { "Successfully removed $orphan" }
    }
} else {
    Test-ComputerSecureChannel -Verbose
}

 

 

0

Comments

0 comments