2016-06-10 14 views
1

Ich versuche, mithilfe von PowerShell eine Liste aller Berechtigungen für einige Netzwerkordner zu erhalten. Leider stoße ich auf die gefürchtete PathTooLongException, also versuche ich Robocopy als Workaround zu benutzen. Ich bin jedoch ein absoluter Neuling mit PowerShell und hoffe auf ein wenig Hilfe. Der einfachste Befehl, den ich mir ausgedacht habe, istAbrufen von ACL-Informationen mithilfe von PowerShell und Robocopy aufgrund von PathTooLongException

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

Das funktioniert und macht was ich will außer die Ausnahme, die ich bekomme. Wie würde ich Robocopy in diese Anweisung einfügen, um die Ausnahme zu umgehen? Irgendwelche Gedanken?

+1

Haben Sie versucht, Get-ChildItem "\\? \ S: \ StartingDir" '? Ich weiß nicht, ob PowerShell mit langen Pfaden arbeiten wird, aber es wäre einen Versuch wert. –

+0

Ich hatte diese "\\" -Klausel schon einmal gefunden, aber es scheint überhaupt nicht zu funktionieren. Das Skript wird nicht einmal ausgeführt, wenn ich es hinzufüge. – cardician

+1

Ich habe damit gespielt, und Sie können die langen Dateinamen mit Robocopy mit '$ files = Robocopy c: \ Temp NULL/L/S/NJH/NJS/NDL/NS/NC 'bekommen, dann durchlaufen Sie sie mit 'foreach ($ Datei in $ Dateien) {'. Get-Acl behandelt jedoch nicht die langen Namen, so dass es immer noch nicht funktioniert. Auch versucht cacls.exe - funktioniert auch nicht mit langen Pfaden. Ich versuchte die Methode an http://stackoverflow.com/questions/27805419/get-folder-ntfs-acl-on-long-path-name, um ein PSDrive abzubilden, aber ich konnte das nicht bekommen, um mit Get-ACL zu arbeiten entweder. Wenn Sie über eine überschaubare Anzahl von Stellen verfügen, an denen dies auftritt, können Sie Freigaben verwenden. –

Antwort

1

Erstellen Sie zunächst eine Batch-Datei, wie getShortFilename.bat, mit den folgenden Zeilen:

@ECHO OFF 
echo %~s1 

Dies wird den kurzen Dateinamen des langen Dateinamen zurückgeben an sie übergeben. Das folgende Skript wird das verwenden, um den kurzen Dateinamen abzurufen, wenn Get-Acl aufgrund eines langen Pfads fehlschlägt. Es wird dann den kurzen Pfad mit cacls verwenden, um die Berechtigungen zurückzugeben.

$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 
    } 
} 

Hinweise:

  • Die Kette von ACLs, die von Get-Acl erstellt wird, unterscheidet sich von der auf von cacls erstellt, also, ob das ein Problem ist oder nicht ...

  • Wenn Sie möchten, dass die ACL-Zeichenfolge für alle Dateien dasselbe Format hat, können Sie nur CACLs für alle Dateien verwenden, nicht nur für Dateien mit langen Dateinamen. Es wäre nicht sehr schwierig, dieses Skript entsprechend zu modifizieren.

  • Sie können eine zusätzliche Fehlerprüfung hinzufügen. Get-Acl könnte natürlich aus verschiedenen Gründen fehlschlagen und Sie könnten den catch-Block ausführen oder nicht, wenn er aus einem anderen Grund als dem Pfad zu lange ausfällt.

+0

Vielen Dank, dass Sie eine Lösung gefunden haben. Sehr geschätzt. – cardician

+0

Gut zu helfen! Ich habe gestern aufgegeben, aber anscheinend musste ich nur darauf schlafen. –