由于 PathTooLongException,使用 PowerShell 和 Robocopy 获取 ACL 信息
Getting ACL info using PowerShell and Robocopy due to PathTooLongException
我正在尝试使用 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
这将return 将长文件名的短文件名传递给它。当 Get-Acl 由于路径较长而失败时,以下脚本将使用它来获取短文件名。然后它将使用带有 cacls 的短路径来 return 权限。
$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
}
}
备注:
Get-Acl 创建的 ACL 字符串与 cacls 创建的不同,所以这是否是一个问题...
如果您希望所有文件的 ACL 字符串采用相同的格式,您可以只对所有文件使用 cacls,而不仅仅是那些具有长文件名的文件。相应地修改这个脚本不会很难。
您可能想要添加额外的错误检查。 Get-Acl 当然可能由于多种原因而失败,如果它由于路径太长以外的其他原因而失败,您可能希望也可能不希望 运行 catch 块。
我正在尝试使用 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
这将return 将长文件名的短文件名传递给它。当 Get-Acl 由于路径较长而失败时,以下脚本将使用它来获取短文件名。然后它将使用带有 cacls 的短路径来 return 权限。
$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
}
}
备注:
Get-Acl 创建的 ACL 字符串与 cacls 创建的不同,所以这是否是一个问题...
如果您希望所有文件的 ACL 字符串采用相同的格式,您可以只对所有文件使用 cacls,而不仅仅是那些具有长文件名的文件。相应地修改这个脚本不会很难。
您可能想要添加额外的错误检查。 Get-Acl 当然可能由于多种原因而失败,如果它由于路径太长以外的其他原因而失败,您可能希望也可能不希望 运行 catch 块。