由于 PathTooLongException,使用 PowerShell 和 Robocopy 获取 ACL 信息



我正在尝试使用PowerShell获取某些网络文件夹的所有权限的列表。不幸的是,我遇到了可怕的PathTooLongException,所以我试图使用Robocopy作为解决方法。但是,我是PowerShell的新手,所以希望得到一点帮助。我想出的最简单的命令是

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

这有效并且可以做我想要的,除了我得到的例外。我将如何在此语句中插入 Robocopy 以绕过异常?有什么想法吗?

首先,使用以下行创建一个批处理文件,例如 getShortFilename.bat:

@ECHO OFF
echo %~s1

这将返回传递给它的长文件名的短文件名。 以下脚本将使用它来获取短文件名,当 Get-Acl 由于路径较长而失败时。 然后,它将使用带有 cacls 的短路径来返回权限。

$files = robocopy c:temp NULL /L /S /NJH /NJS /NDL /NS /NC
remove-item "c:tempacls.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:tempacls.txt" -Append
    }
    Catch{
        $shortName = &C:tempgetShortFilename.bat "$filename"
        $acls = &cacls $shortName 
        $acls = $acls -split '[rn]'
        #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:tempacls.txt" -Append
    }
}

笔记:

  • 由 Get-Acl 创建的 ACL 字符串与 cacls 创建的 on 不同,所以这是否是一个问题......

  • 如果您希望所有文件的 ACL 字符串采用相同的格式,则可以对所有文件使用 cacls,而不仅仅是文件名较长的文件。 相应地修改此脚本并不困难。

  • 您可能需要添加额外的错误检查。 Get-Acl 当然可能由于多种原因而失败,如果由于路径太长以外的某种原因而失败,您可能希望也可能不希望运行 catch 块。

最新更新