问题描述
我正在尝试使用PowerShell列出某些网络文件夹上的所有权限。不幸的是,我遇到了可怕的PathTooLongException,因此我尝试使用Robocopy来解决。但是,我是PowerShell的新手,因此希望能有所帮助。我想出的最简单的命令是
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"
这可以工作,并且可以做我想要的,除了我得到的例外。如何将Robocopy插入此语句以绕过异常?有什么想法吗?
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?
推荐答案
首先,创建带有以下行的批处理文件,例如getShortFilename.bat:
First, create a batch file, such as getShortFilename.bat, with the following lines:
@ECHO OFF
echo %~s1
这将返回传递给它的长文件名的短文件名。当由于长路径而导致Get-Acl失败时,以下脚本将使用该脚本来获取短文件名。然后它将使用带有cacls的短路径来返回权限。
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
}
}
注意:
-
Get-Acl创建的ACL字符串与on创建的ACL字符串不同通过cacls,所以这是否是一个问题...
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...
如果您希望所有文件的ACL字符串都采用相同格式,则可以在所有文件上使用cacls,而不仅仅是文件名较长的文件。相应地修改该脚本并不是很困难。
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.
您可能想添加额外的错误检查。当然,Get-Acl可能由于多种原因而失败,并且,如果它由于某种原因(而不是路径太长)而失败,则您可能会或可能不希望运行catch块。
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.
这篇关于由于PathTooLongException而使用PowerShell和Robocopy获取ACL信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!