Using Powershell to clean up orphan Active Directory user profile folders

1.8k views Asked by At

The task seems trivial! A lot of users come and go in our environment. Every now and then I want to check for "orphan" roaming profile folders and get rid of them. My code works if the user name matches the folder name exactly but not for folders where Windows has added a .V2, .V3 etc. E.g. -eq works but not -like or -contains, or any of the ways I've tried to insert a wildcard. I tried a where-object construction and failed as well.

For example, if we have a user bob.smith, I want don't want my "orphan" list to include profile folders named bob.smith or bob.smith.V2.

Here's my code:

# Put profile folder names in array

$profilefolders = Get-ChildItem -Name "\\server\profiles$"



# Initialize arrays 

 $orphanprofiles = @()



foreach ($userprofile in $profilefolders)
    {
#  Do profile names match up with user accounts?
    If(Get-ADUser -Filter {SamAccountName -eq $userprofile})

        {
        # User account exists: no action
        }

    Else
        {
        # Profile is an orphan. Add to list.
        $orphanprofiles += $userprofile
                         }
                }




# put array values in a string variable with newline char for screen   output
$outputprofiles = $orphanprofiles -join "`n"

Write-Output "`n"
Write-Output "Orphan profiles: `n$outputprofiles"
Write-Output "  "
2

There are 2 answers

12
AudioBubble On

Change the first line to :

$profilefolders = Get-ChildItem -Name "\\server\profiles$"|where {$_ -notmach '.*\.V\d$'}

Came up with a better solution. It uses a RegEx to split the .V2 extension from the foldername and so checks the name without that ext. The intermediate $profilefolders isn't required.

# Initialize arrays 
$orphanprofiles = @()
$pattern = '^(.*?)(\.V\d)$'

Get-ChildItem -Name "\\server\profiles$"| 
    ForEach {
        If ($_ -match $pattern) {
            If (!(Get-ADUser -Filter {SamAccountName -eq $matches[1]}))
                {$orphanprofiles += $_} else {}
        } Else {
            If (!(Get-ADUser -Filter {SamAccountName -eq $_}))
                {$orphanprofiles += $_}
        }
    }


# put array values in a string variable with newline char for screen   output
$outputprofiles = $orphanprofiles -join "`n"
Write-Output "`n"
Write-Output "Orphan profiles: `n$outputprofiles"
Write-Output "  "
0
SKaye On

Many thanks to @LotPings. Here is my code now (with all the debug statements):

# Initialize array
$orphanprofiles = @()

# set regex pattern
$pattern = '^(.*?)(\.V\d)$'

Get-ChildItem -Name "\\server\profiles$"| 
    ForEach {
        Write-Host "Testfolder: " $_
        If ($_ -match $pattern) 
        {
          Write-Host "Loop 1 Foldername " $_
          Write-Host "Loop 1 Match " $matches[1]
          $Vnuser = $matches[1]

            If(Get-ADUser -Filter {SamAccountName -eq $Vnuser})
                {
             # match: do nothing
                }
               Else 
                {
                $orphanprofiles += $_
                Write-Host "Loop one inside If statement: " $_
                }


     }

      Else
        {
           Write-Host "Folders without .Vn: " $_
           If(Get-ADUser -Filter {SamAccountName -eq $_})
                {
                # match: do nothing
                }
            Else
                {
                $orphanprofiles += $_
                Write-Host "Loop 2 foldername: " $_
                }

   } 

   }



# put array values in a string variable with newline char for screen output
$outputprofiles = $orphanprofiles -join "`n"
Write-Output "`n"
Write-Output "Orphan profiles: `n$outputprofiles"
Write-Output "  "