Detect Orphaned HomeDirectories and Roaming Profiles

Prerequisites: ActiveRoles Management Shell for Active Directory must be installed on the host running this script.

I was given the task to migrate data from one file server to the other. Some of the data were the homedirectories and profiles (both for Windows clients and Terminal Services) of all users in Active Directory. Even though this could be solved quite easily with e.g. DFS and file replication, it seemed like a good time to finally write that script I’ve always wanted to write. A script that helps me locate folders that weren’t deleted when a user had been deleted in Active Directory. This will also help me minimize wasted disk space in the future which shortens backup time and (maybe more important) restoration time in case of a server failure. So here we go…

First I want to load the snappin so I don’t have to open the ActiveRoles Management Shell everytime I want to run the script.

add-pssnapin -name Quest.ActiveRoles.ADManagement

As I don’t want to delete the orphaned folders right away I want to move them to a different location. By doing this I can easily restore the data in case of a mistake (of course I would back it up on tape before deleting it permanently after a few days and yes, Volume Shadow Copy could also be a good idea). Also I like the idea of moving the orphaned folders to the same folder so I can select properties of the top folder and see how much space I’ve saved this time. Therefore I declare 2 arrays with 3 paths each.

$paths         = "\\fileserver\e$\homedirectories\", "\\fileserver\e$\profiles\", "\\fileserver\e$\tsprofiles\"
$orphanedPaths = "\\fileserver\e$\orphaned\homedirectories\", "\\fileserver\e$\orphaned\profiles\", "\\fileserver\e$\orphaned\tsprofiles\"

I want to be able to run this script over the network so I’m using ‘e$’ in my paths. $paths contains the paths in which to look for orphaned folders. $orphanedPaths containts the paths to which I want to store the orphaned folders temporarily.

 Next I want to run through the subfolders of the different paths.

for( $i = 0; $i -lt $paths.length; $i++ )
{
    $directories = Get-ChildItem -Path $paths[$i]

    ...
}

By using the ‘Get-ChildItem’ cmdlet I get an array ‘$directories’ containing all the subfolders in the given path. I want to run through this array of folders and check if a user with a corresponding name exists in Active Directory. Obviously this would require you to use %username% in the path for homedirectories and romaing profiles when you create a user in Active Directory.

for( $j = 0; $j -lt $directories.Length; $j++ )
{
    $currentDirectory = $directories[$j]

    $index1 = $currentDirectory.Name.ToLower().IndexOf( ".mydomain" )
    $index2 = $currentDirectory.Name.ToLower().IndexOf( ".v2" ) # vista og win7 profiles

    $sAMAccountName = $currentDirectory.Name.ToLower()

    if( $index1 -gt 0 )
    {
        $sAMAccountName = $sAMAccountName.Remove( $index1 )
    }
    if( $index2 -gt 0 )
    {
        $sAMAccountName = $sAMAccountName.Remove( $index2 )
    }
    ...
}

In some cases the profile directories are suffixed with .v2 (for Windows Vista and Windows 7 profiles) or the NetBIOS name of your domain. I want to strip those suffixes from the folder name to get the sAMAccountName I wish to search for in Active Directory. Also I convert everything to lowercase for easier comparison. The last thing we need to do now is to search for an owner in Active Directory and move the current folder if the search fails.

$user = Get-QADUser -SamAccountName $sAMAccountName

if( $user -eq $null )
{
    $currentDirectory.MoveTo( $orphanedPaths[$i] + $currentDirectory.Name  )
}

That’s all there is to it.

Here’s the entire script: Detect Orphaned HomeDirectories and Roaming Profiles

  1. No comments yet.

  1. No trackbacks yet.