How to best handle Path Too Long error

This topic contains 4 replies, has 3 voices, and was last updated by Profile photo of JohnRock Bilodeau JohnRock Bilodeau 2 years, 2 months ago.

  • Author
    Posts
  • #19111
    Profile photo of JohnRock Bilodeau
    JohnRock Bilodeau
    Participant

    Hi,

    I'm trying to right a script that will recursively check a directory structure for broken inheritance, but I'm having issues with dreaded Path Too Long error.

    I've been reading quite a bit today to try and find a good solution, but have yet to find one.

    Some people suggested creating a PSDrive and access it from that point, which is fine if doing it on its own, but when going through a directory structure recursively you really have no idea how far down the path will go until you get there, which mean you never know at which point to begin using a psdrive to access it.

    I also read of a "unicode hack" where you can put \\?\ if front of the directory path, but that doesn't seem to work with Get-ChildItem

    Does anyone here have a suggestion on how best to deal with this...preferably within powershell itself.

    Here is an example of my code

    $UninheritedRights = @()
        
        Get-ChildItem -Path "E:\Data\HomeDirectories" -Directory | 
        Select -ExpandProperty Fullname |
        Get-ChildItem -Recurse |
        ForEach-Object{
    
            $path = $_.FullName 
            
            $UninheritedRights += $path | 
            Get-Acl | 
            Select -ExpandProperty Access | 
            Where -Property IsInherited -EQ $false | 
            Select -Property @{Name='Path';Expression={$path}},FileSystemRights,AccessControlType,IdentityReference,IsInherited
        }
    
        $UninheritedRights | Format-Table
  • #19123
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    There's not really a good way to handle this yet. There are several potential workarounds, and which one you use would depend on what functionality you need.

    In this case, it looks like you just need to be able to walk the directory tree and do something with ACLs. It so happens that Event 3 of the 2014 Winter Scripting Games involved that exact same task, so you could look through http://www.scriptinggames.org/events.php?game_id=4 for some ideas on different ways to tackle this problem.

    I can tell you that the only way you're going to get default cmdlets such as Get-ChildItem and Get-Acl to work is by mapping a drive part-way down the tree, effectively shortening the path. It complicates the code quite a bit; your single pipeline approach listed above won't work. Alternatively, you could stop using the default cmdlets and go with some other approach, such as navigating the file system with the https://www.nuget.org/packages/Microsoft.Experimental.IO/ assembly, and using something like Rohn Edwards' http://gallery.technet.microsoft.com/scriptcenter/PowerShellAccessControl-d3be7b83 module to handle the ACL interaction. (His 3.0 beta release notes say that it has support for long paths built-in.)

  • #19133
    Profile photo of Rohn Edwards
    Rohn Edwards
    Participant

    I just wanted to note that module Dave mentions is actually using the Microsoft.Experimental.IO assembly internally. You could combine that with the PAC module to come up with something like this:

    # Explicitly import module to make sure Microsoft.Experimental.IO assembly is loaded
    Import-Module PowerShellAccessControl
    
    # Define function that allows recursive directory listing:
    function Get-ChildItemLongPath {
        [CmdletBinding()]
        param(
            $Path = (Resolve-Path .),
            [switch] $Recurse
        )
    
        try {
            [Microsoft.Experimental.IO.LongPathDirectory]::EnumerateFileSystemEntries($Path) | ForEach-Object {
                $_
                if ($Recurse) {
                    Get-ChildItemLongPath -Path $_ -Recurse
                }
            }
        }
        catch { 
            # Put error handling here. As the function is currently designed, any file paths passed will throw
            # an error b/c EnumerateFileSystemEntries() is meant to take folder paths
            if ($_.Exception.Message -notmatch "The directory name is invalid") {
                Write-Error $_
            }
        }
    }
    
    # One liner that should give you the information you're after:
    Get-ChildItemLongPath C:\folder -Recurse | Get-AccessControlEntry -NotInherited
    

    The long path support hasn't gotten a lot of testing, so let me know if you try this and experience any problems.

  • #19134
    Profile photo of JohnRock Bilodeau
    JohnRock Bilodeau
    Participant

    Thanks Dave.

    I'll look into those

  • #19135
    Profile photo of JohnRock Bilodeau
    JohnRock Bilodeau
    Participant

    Thanks Rohn.

    I'm just wondering if creating that function to list long path would even be necessary, since the PowerShellAccessControl Module says that it supports long path starting in v 3, so i would assume that i can simply use it's equivalent to get-acl

    I might be wrong, but i'll try some stuff out and post back to let you guys know.

    I was basically writing this script to monitor permissions on our user home directories because we kept on seeing issues were inheritance would get broken even through users only had modify privileges, or users reporting that they didn't have access to certain folders or files.
    I think I might have found part of the issue. I'm still in the process of rewriting some old batch script that handled our user creation/modification/deletion process and i was using robocopy for file moves with the /MIR switch, but i didn't want it to copy securities. I simply wanted it to inherit the permission from the new folder that i created. I found a post from the guy that wrote robocopy that states that /MIR replicated the directory tree and securities, but the robocopy help and technet page say nothing about it replicating security so i was having issues were sometimes the securities would get messed up, like missing, or incorrectly ordered.

    ...so i guess now i need to fix that script and then reset the baseline for all folders permission before i can come back to working on this script which will be used to monitor that the issue is in fact fixed.

    Thanks again guys

You must be logged in to reply to this topic.