Updated Function to Remove Long Files and Directories

I had a post last month ( or year for that matter) on Hey, Scripting Guy! where I talked about using PInvoke and PowerShell to create a function that allowed you to remove files which were nested too deep in a folder path causing a long path issue meaning that the file could not be removed.

The problem with this function is that it could only remove a file by using the DeleteFile function. While this is great, it could really use some extra features such as being able to remove directories which includes deleting the child files/folders…similar to what you would have with Remove-Item.

In order to do this, I need to look at working with RemoveDirectory to actually delete the folder. The next issue is that I first need to remove all of the child objects under the directory which includes other files and folders and continue to recursively go through each sub-folder until I reach the end and at that point I can remove the folder.

The result is my function called Remove-Item2 which performs like Remove-Item with the exception of the only parameter that you have is –Path.

For those interested, here is the code that I put together for the recursive folder and file deletion.

If ($Handle -ne -1) {
    While ($Found) {
        If ($findData.cFileName -notmatch '^(\.){1,2}$') {
            $IsDirectory =  [bool]($findData.dwFileAttributes -BAND 16) 
            Write-Debug "$(Get-PSCallStack | Out-String)" 
            If ((Get-PSCallStack).Count -eq 2) {
                $_FullName = "$($Path)"
            } Else {                   
                $_FullName = "$($Path)\$($findData.cFileName)"
            }
            If ($IsDirectory) {                        
                #Dive deeper
                $PSBoundParameters.Fullname = "$_FullName\*"                  
                Remove-Item2 @PSBoundParameters
                If ($PSCmdlet.ShouldProcess($_FullName.TrimStart('\\?\'), 'Remove Directory')) {
                    #Remove file
                    $Return = [poshfile]::RemoveDirectory($_FullName)
                    If (-NOT $Return) {
                        Write-Warning "Unable to remove $_FullName"
                    }
                }
            } Else {
                If ($PSCmdlet.ShouldProcess($_FullName.TrimStart('\\?\'), 'Remove File')) {
                    #Remove file
                    $Return = [poshfile]::DeleteFile($_FullName)
                    If (-NOT $Return) {
                        Write-Warning "Unable to remove $_FullName"
                    }
                }
            }
        }
        $Found = [poshfile]::FindNextFile($Handle,[ref]$findData)
    }
    [void][PoshFile]::FindClose($Handle)
}

I used Get-PSCallStack to help me determine where I am at in the folder path as each call to the function would increase the callstack which helped me to actually delete the top level folder that I was looking to remove. I tried a few other approaches like a counter or setting another variable, but they had less than desirable results.

The result is a function that you can use to clear out files and folders which are normally unreachable using Remove-Item as shown below:

image

The function is available below from the Script Center Repository to use. Give it a run and let me know how you like it!

Download Remove-Item2

https://gallery.technet.microsoft.com/scriptcenter/Remove-LongPathFile-7a4db495

This entry was posted in powershell and tagged , , . Bookmark the permalink.

2 Responses to Updated Function to Remove Long Files and Directories

  1. Tim Green says:

    Thanks for making this available. I’ve run into a similar problem just trying to search files with a long directory path. I love PS, but MS should be embarrassed that it’s file functions fail with long paths.

Leave a comment