In recent times I had another challenging task.
In the current infrastructure we have a domain, where the user’s roaming user profile is directed to a user share. The share grown too much, so it was decided that we need to remove old profiles, belonging to users who left the company. The challenge here was that, the folders were owned by default by the user account, and they were the only ones with rights on it, so the admin accounts could not modify them.

Enter PowerShell, with some help of his friends,icacls.exe and takeown.exe.

I wrote a lengthy script – after some trial and error – which is still being developed – but the current state is as follows:

Firstly I wrote a helper script. This can take ownership of a folder – for the person running it and reset the ACL of the folder, so that the admin account has full rights.

Next, I added the importing of this script along with the Active Directory module to the script.

Added a few parameters to the script.
$path: location of the share
$days: I decided to leave only 60 days worth of files

I started output the logs – for latter analysis – to the log files. I then calculated the current – 60 days old files, as I am only interested in the old items. (assuming user folders are constantly being use, most of the files should have recent time stamp)

Now comes something that specific in our environment. We usually add a prefix to the leavers, and another suffix was on all folders, added by the GPO creating them.
So first I captured the full folder name – so that I can work with it latter – and re-created the SAMAccountName from the short name of the folder, then compared this to AD, if the user still exists – to distinguish them from the leavers.

First I dealt with the folders with still present users.
– first I did reset their ACL – just for good measures, so that Admin group has rights
– next I have given the users full access to the folder and it’s child objects
– finally I set the ownership of the folder back to the user

Secondly I dealt with the folders, whom had no apparent owners.
– taking over the ownership of the folder first
– deleting all the child items within this folder
– deleting the folder itself

Before finishing, I have sent the errors to the error log (oh and set the $ErrorActionPreference of the system back to how it was)

Finally ending the transcript.

Full code (might add Github, currently this is in a private repo):

    #Function load
Import-Module C:\SCHEDULED\FolderCleanup\TakeOwnFolder_all_subfolders.ps1
Import-Module ActiveDirectory

#region Parameters #location of the folder, age of doccuments pre-filtered, log file locations
$path = "\\pemkfile03\E$\Profiles"
$days = "60" # adjust this to match to your needs
$today = Get-Date -format "yyyyMMdd"
$log = "C:\SCHEDULED\FolderCleanup\Logs\" + $today + "_logs.txt"
$errorlog = "C:\SCHEDULED\FolderCleanup\Errors\" + $today + "_errors.txt"
    #endregion Parameters

#region Take ownership, reset ACL
#endregion Take ownership

#Start transcript
Start-Transcript -Path $log -NoClobber -IncludeInvocationHeader -Force

#region Remove Folders

    ## Find folders older then the date given (current date - $days)
    $age = (Get-Date).AddDays(-$days)
    $olditems = Get-ChildItem -Directory -Path $path | Where-Object {$_.CreationTime -le $age} | select *

    ## Filter out orphaned folders (folders where "Foldername" != any SAMAccountName in AD)
    foreach ($f in $olditems)
        #Find the owner - build the user's SAM from the foldername, by replacing the "xx" (indicating user left) and the ".PROTOEDU.V2" tags
        $fold = $f.FullName
        $SAM =  $f.Name -replace "xx","" 
        $SAM = $SAM -replace ".PROTOEDU.V2",""
        $usermatch = Get-ADUser -Filter * | Where-Object {$_.SAMAccountName -like $SAM} -ErrorAction SilentlyContinue -Verbose | select Name,SAMAccountName

            # Folders with owners will not be removed.
            If ($usermatch -notlike $null)
            Write-Host -ForegroundColor Green "$fold folder belongs to user: $SAM"

                #Ensure rights given back to the user, since the user is still existing.

                    #reset access rights on the folder

                    Write-Host -ForegroundColor Yellow "Reseting ACL on [$fold]"
                    icacls.exe $fold /T /Q /C /RESET

                    # give full access to the user

                    $user = "PROTOEDU\" + $SAM
                    Write-Host -ForegroundColor Yellow "Granting full access on [$fold] for user [$user]"
                    $userF = $user + ":(OI)(CI)F"
                    icacls.exe $fold /T /Q /C /GRANT $userF

                    #give ownership to the user

                    Write-Host -ForegroundColor Yellow "Granting ownership rights on [$fold] for user [$user]"
                    icacls.exe $fold /T /Q /C /setowner $user


            # Folders without owners will be removed
                $ErrorActionPreference = "STOP";
                #Take ownership of the user folder in order to be able to process
                Write-Host -ForegroundColor Cyan "Taking ownership of folder $fold"

                #Remove all child items in the orphaned folder
                Get-ChildItem $fold -Recurse -Force | Remove-Item -Recurse -Force # -WhatIf

                #Remove orphaned folder itself 
                Remove-Item $fold  -Force -Recurse # -WhatIf 
                Write-Host -ForegroundColor Magenta "$SAM user no longer present - removing folder $fold ";

                #Dealing with errors
                    IF($_.Exception.Message -notlike $null)
                    $ErrorDetails = $_.Exception.Message
                    "Could not delete folder: $fold`nError: $ErrorDetails" >> $errorlog
                $ErrorActionPreference = "CONTINUE";

#endregion Remove Folders

##Stop transcript