Puncte:0

Gestionați excepția cu căi lungi în Powershell

drapel in
ed7

Sunt nou aici și mă confrunt cu probleme cu scriptul meu Powershell cu căi lungi. Acest script își propune să obțină calea relativă și hash din fișiere/foldere și subfolderele sale. Funcționează cu unii cu alții, primesc următoarea eroare:

Get-ChildItem : Calea specificată, numele fișierului sau ambele sunt prea lungi. Numele de fișier complet calificat trebuie să aibă mai puțin de 260 de caractere, iar numele directorului trebuie să aibă mai puțin de 248 de caractere.

Aș dori să știu cum să rezolv acest lucru și să evit să-mi dau această eroare, vă rog.

Am activat căile lungi ale fișierelor în Windows Server 2012 unde rulez scriptul și încă nu funcționează.

Daca adaug asta \\?\ în variabila cale, nu reușește să spună că există caractere ilegale în cale chiar dacă adaug -LiteralPath.

Orice ajutor ar fi grozav

Acesta este scriptul mypowershell:

#Mesaj către utilizator
  Scriere-Ieșire „`nAcest script va colecta FilePathName, Name, RelativePath și Hash-ul fișierelor/directoarelor pe care le-ați ales.”
               „`nLa final, vă va spune cât timp a durat să rulați scriptul”   
  Read-Host -Prompt „`nApăsați ENTER pentru a continua sau CTRL+C pentru a ieși” 
        
  #Numărând timpul de la început
  $starttime = (Get-Date)
        
  #Variabile
  #Se pot adăuga doar 3 căi maxim. Dacă se adaugă mai mult de 3, se poate schimba calea relativă
  $root = "C:\mypath"
        
        
  #Variabilă pentru crearea fișierului CSV
  $report = "mycsvfile.csv"
        
        
  #Proces de generare a HASH-ului
  $hasher = [System.Security.Cryptography.SHA256]::Create()
  $AllFiles = @() 
        
  "`n"#line space
        
  Write-Host „Generarea hash-ului de la $root” 
        
        
        
  #Obținerea de informații din directoare
  foreach ($fișier în get-childitem $root -recurse | Select-Object FullName, Director, Nume, PSIContainer, Lungime)
  {
      $acl = get-acl $fișier.nume complet | select-object owner,accesstostring,group
      $obj = nou-obiect psObject
        
        
  #Generarea fișierului HASH
      if(!$file.PsIsContainer)
          {
          $relativePath = $file.FullName.Substring($root.Length)
          Write-Host "Debug $relativePath" -ForegroundColor Green
        
          $inputStream = Nou-Object IO.StreamReader $file.fullname
          $hashBytes = $hasher.ComputeHash($inputStream.BaseStream)
          $inputStream.Close()
        
          $builder = Obiect nou System.Text.StringBuilder
          $hashBytes | Foreach-Object { [void] $builder.Append($_.ToString("X2")) }
        
  #Adăugați informații în FIȘIERUL CSV
          $obj | Add-Member -membertype noteproperty -name FilePathandName -Value $file.FullName
          $obj | Add-Member -membertype noteproperty -name Nume -Valoare $fișier.Nume
          $obj | Add-Member -MemberType noteproperty -Nume RelativePath -Value $relativePath #-force
          $obj | Add-Member -MemberType noteproperty -Name Hash -Value $builder.ToString()
          #$obj | Add-Member -membertype noteproperty -name CreationTime -Value $file.CreationTime
          #$obj | Add-Member -MemberType noteproperty -Name LastAccessTime -Valoare $file.LastAccessTime
          #$obj | Add-Member -MemberType noteproperty -Nume LastWriteTime -Valoare $file.LastWriteTime
        
                
      #Variabilă pentru a trimite informații la CSV
      $ToateFișierele += $obj
      Clear-Variable relativePath
      }
  Eliminare-Variable obj
  }
        
  #$ToateFișierele += $obj
        
  #Generarea fișierului CSV
  $AllFiles |Export-Csv $raport âNoTypeInformation
        
  "`n"
  Write-Host „Fișierul $report a fost creat”
        
  "`n"
  Write-Host „Scriptul a luat:`n”
  $endTime = Get-Date
  New-TimeSpan -Start $startTime -End $endTime
drapel br
[1] dacă utilizați win10 sau win11, puteți seta sistemul de operare pentru a permite nume lungi. ///// [2] puteți folosi și prefixul unicode pentru a permite căi lungi doar pentru acel apel. ///// pentru informații despre ambele, uite... >>> Limitare maximă de lungime a căii - aplicații Win32 | Microsoft Docs â https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd
Puncte:1
drapel ru

Pentru ca cmdleturile Powershell să funcționeze corect folosind \\?\ Trebuie să instalați următoarele versiuni minime ale acestor componente (testate și validate pe Windows Server 2012 R2):

Apoi, trebuie doar să schimbați variabila cale rădăcină din scriptul dvs. după cum urmează și va funcționa exact așa cum vă așteptați:

  #Variabile
  #Se pot adăuga doar 3 căi maxim. Dacă se adaugă mai mult de 3, se poate schimba calea relativă
  $root = "\?\C:\mypath\"
        

Nu este nevoie să schimbați nicio cheie de registry pentru a activa suportul pentru căi lungi sau utilizarea parametrului -LiteralPath pentru orice cmdlet-uri.Am văzut aceste afirmații de mai multe ori în alte articole și forumuri, dar acest lucru nu este corect, cu excepția versiunilor foarte vechi de Windows.


Acum, dacă nu puteți instala aceste versiuni mai noi, va trebui să utilizați soluții alternative.

Rețineți că în scriptul dvs., următoarele funcții sunt afectate de această problemă:

  • Get-ChildItem
  • Get-Acl
  • Nou-Object IO.StreamReader

O soluție ar fi să înlocuiți o parte a căii ca unitate când devine prea lung și utilizați noua unitate ca folder rădăcină. Am încercat asta folosind SUBST comanda, dar ar trebui să funcționeze folosind Nou-PSDrive cmdlet. Acest lucru necesită să adăugați ceva logică în script-ul dvs., dar nu este prea mult efort și destul de ușor.

Acum, dacă doriți să obțineți o listă cu toate fișierele înainte de a efectua orice înlocuire (astfel încât să puteți verifica mai întâi toate căile și lungimile numelor de fișier), puteți utiliza următoarea soluție:

$root = "C:\mypath\" ;
$AllFiles = cmd /c dir $root /b /s /a-d ;

Aceasta vă va oferi lista de fișiere (nume complete).

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.