Getting ACL info using PowerShell and Robocopy due to PathTooLongException

天涯浪子 提交于 2019-12-11 05:32:52

问题


I'm trying to get a listing of all permissions on some network folders using PowerShell. Unfortunately I'm encountering the dreaded PathTooLongException so I'm attempting to use Robocopy as a work around. However I'm a complete novice with PowerShell so was hoping for a little help. The easiest command I've come up with is

Get-Childitem "S:\StartingDir" -recurse | Get-Acl | Select-Object path,accestostring | Export-Csv "C:\export.csv"

That works and does what I want except the exception I'm getting. How would I insert Robocopy into this statement to bypass the exception? Any thoughts?


回答1:


First, create a batch file, such as getShortFilename.bat, with the following lines:

@ECHO OFF
echo %~s1

This will return the short filename of the long filename passed to it. The following script will use that to get the short filename when Get-Acl fails due to a long path. It will then use the short path with cacls to return the permissions.

$files = robocopy c:\temp NULL /L /S /NJH /NJS /NDL /NS /NC
remove-item "c:\temp\acls.txt" -ErrorAction SilentlyContinue

foreach($file in $files){

    $filename = $file.Trim()
    # Skip any blank lines
    if($filename -eq ""){ continue }

    Try{
        Get-Acl "$filename" -ErrorAction Stop| Select-Object path, accesstostring | Export-Csv "C:\temp\acls.txt" -Append
    }
    Catch{
        $shortName = &C:\temp\getShortFilename.bat "$filename"
        $acls = &cacls $shortName 
        $acls = $acls -split '[\r\n]'
        #create an object to hold the filename and ACLs so that export-csv will work with it
        $outObject = new-object PSObject
        [string]$aclString

        $firstPass = $true

        # Loop through the lines of the cacls.exe output
        foreach($acl in $acls){

        $trimmedAcl = $acl.Trim()

        # Skip any blank lines
        if($trimmedAcl -eq "" ){continue}

            #The first entry has the filename and an ACL, so requires extra processing
            if($firstPass -eq $true){
                $firstPass = $false

                # Add the long filename to the $exportArray
                $outObject | add-member -MemberType NoteProperty -name "path" -Value "$filename"

                #$acl
                # Add the first ACL to $aclString
                $firstSpace = $trimmedAcl.IndexOf(" ") + 1
                $aclString = $trimmedAcl.Substring($firstSpace, $trimmedAcl.Length - $firstSpace)

            } else {
                $aclString += " :: $trimmedAcl"
            }
        }

        $outObject | add-member -MemberType NoteProperty -name "accesstostring" -Value "$aclString"
        $outObject | Export-Csv "C:\temp\acls.txt" -Append
    }
}

Notes:

  • The string of ACLs that is created by Get-Acl is different from the on created by cacls, so whether that's an issue or not...

  • If you want the ACL string to be in the same format for all files, you could just use cacls on all files, not just the ones with long filenames. It wouldn't be very difficult to modify this script accordingly.

  • You may want to add extra error checking. Get-Acl could of course fail for any number of reasons, and you may or may not want to run the catch block if it fails for some reason other than the path too long.



来源:https://stackoverflow.com/questions/37755822/getting-acl-info-using-powershell-and-robocopy-due-to-pathtoolongexception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!