2016-06-10 1 views
1

J'essaie d'obtenir une liste de toutes les autorisations sur certains dossiers réseau à l'aide de PowerShell. Malheureusement, je suis confronté à la redoutable PathTooLongException, alors j'essaie d'utiliser Robocopy comme un travail. Cependant, je suis un novice complet avec PowerShell alors j'espérais un peu d'aide. La meilleure commande que je suis venu avec estObtention d'informations ACL à l'aide de PowerShell et Robocopy en raison de PathTooLongException

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

qui fonctionne et fait ce que je veux, sauf l'exception que je reçois. Comment est-ce que j'insérerais Robocopy dans cette déclaration pour contourner l'exception? Des pensées?

+1

Avez-vous essayé 'Get-ChildItem" \\? \ S: \ StartingDir "'? Je ne sais pas si PowerShell fonctionnera avec de longs chemins, mais ça vaudrait la peine d'essayer. –

+0

J'avais déjà rencontré cette clause "\\?" Mais essayer ne semble pas marcher du tout. Le script ne fonctionne même pas lorsque je l'ajoute. – cardician

+1

J'ai joué avec cela, et vous pouvez obtenir les noms de fichiers longs avec Robocopy avec '$ files = robocopy c: \ temp NULL/L/S/NJH/NJS/NDL/NS/NC», puis bouclez-les avec 'foreach ($ file dans les fichiers $) {'. Cependant, 'Get-Acl' ne gère pas les noms longs, cela ne fonctionne toujours pas. Aussi essayé cacls.exe - ne fonctionne pas non plus avec de longs chemins. J'ai essayé la méthode à http://stackoverflow.com/questions/27805419/get-folder-ntfs-acl-on-long-path-name pour mapper un PSDrive, mais je n'ai pas réussi à le faire fonctionner avec Get-ACL non plus. Si vous disposez d'un nombre gérable d'emplacements, vous pouvez utiliser des partages. –

Répondre

1

d'abord, créez un fichier de commandes, telles que getShortFilename.bat, avec les lignes suivantes:

@ECHO OFF 
echo %~s1 

Ceci renvoie le nom de fichier court du long nom de fichier qui lui est passé. Le script suivant l'utilisera pour obtenir le nom de fichier court lorsque Get-Acl échoue en raison d'un long chemin. Il utilisera ensuite le chemin court avec cacls pour retourner les 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 
    } 
} 

Notes:

  • La chaîne de ACLs créée par Get-Acl est différent de celui créé par le cacls, de sorte que ce soit un problème ou non ...

  • Si vous voulez que la chaîne ACL soit dans le même format pour tous les fichiers, vous pouvez simplement utiliser cacls sur tous les fichiers, pas seulement ceux avec des noms de fichiers longs. Il ne serait pas très difficile de modifier ce script en conséquence.

  • Vous pouvez ajouter une vérification d'erreur supplémentaire. Get-Acl peut bien sûr échouer pour un certain nombre de raisons, et vous pouvez ou non vouloir exécuter le bloc catch si cela échoue pour une raison autre que le chemin trop long.

+0

Merci beaucoup d'avoir trouvé une solution. Très appréciée. – cardician

+0

Content de vous aider! J'ai abandonné hier mais apparemment j'avais juste besoin de dormir dessus. –