2016-06-10 5 views
1

PowerShell을 사용하여 일부 네트워크 폴더에 대한 모든 사용 권한 목록을 가져 오려고합니다. 불행히도 나는 두려운 PathTooLongException을 만날 것이므로 Robocopy를 사용하려고 시도하고있다. 그러나 저는 PowerShell의 초보자이기 때문에 약간의 도움이 필요합니다. 내가 함께 왔어요 가장 쉬운 명령은 내가지고있어 예외를 제외하고 작동하고 내가 원하는 것을PathTooLongException으로 인해 PowerShell 및 Robocopy를 사용하여 ACL 정보 가져 오기

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

입니다. 예외를 무시하려면이 문에 Robocopy를 어떻게 삽입합니까? 이견있는 사람?

+1

'Get-ChildItem "\\? \ S : \ StartingDir"'을 사용해 보셨습니까? PowerShell이 ​​긴 경로에서 작동하는지 여부는 알 수 없지만 시도해 볼만한 가치가 있습니다. –

+0

전에 "\\? \"절을 보았습니다. 그러나 시도하는 것은 전혀 작동하지 않는 것 같습니다. 스크립트를 추가 할 때 실행되지 않습니다. – cardician

+1

나는 이것을 가지고 놀았고'$ files = robocopy c : \ temp NULL/L/S/NJH/NJS/NDL/NS/NC'라는 이름으로 Robocopy로 긴 파일 이름을 얻을 수있다. 'foreach ($ file in $ files) {'. 그러나'Get-Acl'은 긴 이름을 처리하지 못하기 때문에 여전히 작동하지 않습니다. 또한 cacls.exe를 시도했는데 긴 경로에서는 작동하지 않습니다. http://stackoverflow.com/questions/27805419/get-folder-ntfs-acl-on-long-path-name에서 메서드를 사용하여 PSDrive를 매핑했지만 Get-ACL을 사용하여 작동하지 못했습니다. 어느 한 쪽. 이 상황이 발생하는 장소를 관리 할 수있는 곳이 있다면 공유를 사용할 수 있습니다. –

답변

1

먼저 다음 라인 등 getShortFilename.bat 같은 배치 파일을 만들 :

@ECHO OFF 
echo %~s1 

이 전달 된 긴 파일 이름의 짧은 파일 이름을 반환합니다. 다음 스크립트는 긴 경로로 인해 Get-Acl이 실패 할 때 짧은 파일 이름을 가져 오는 데이 파일을 사용합니다. 그런 다음 cacls와 함께 짧은 경로를 사용하여 권한을 반환합니다.

$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 블록을 실행하려고 할 수도 있고 원치 않을 수도 있습니다.

+0

해결책을 제안 해 주셔서 대단히 감사합니다. 매우 감사. – cardician

+0

도와 드리겠습니다! 나는 어제 그것을 단념했다. 그러나 명백하게 단지 그것에 잠할 필요가 있었다. –