Рейтинг:0

Обработка исключений с длинными путями в Powershell

флаг in
ed7

Я здесь новичок, и у меня возникли проблемы с моим скриптом powershell с длинными путями. Этот скрипт предназначен для получения относительного пути и хэша из файлов/папок и их подпапок. Это работает с некоторыми, с другими я получаю следующую ошибку:

Get-ChildItem : указанный путь, имя файла или оба слишком длинные. Полное имя файла должно быть меньше 260 символов, а имя каталога должно быть меньше 248 символов.

Я хотел бы знать, как справиться с этим и избежать этой ошибки, пожалуйста.

Я включил длинные пути к файлам в Windows Server 2012, где я запускаю скрипт, и он все еще не работает.

Если я добавлю это \\?\ в переменной пути он не говорит, что в пути есть недопустимые символы, даже если я добавляю -LiteralPath.

Любая помощь будет отличной

Это скрипт mypowershell:

#Сообщение пользователю
  Write-Output "`nThis script соберет FilePathName, Name, RelativePath и Hash файлов/папок, которые вы выбрали."
               "`nВ конце будет указано, сколько времени потребовалось для запуска скрипта"   
  Read-Host -Prompt «nНажмите ENTER, чтобы продолжить, или CTRL+C, чтобы выйти» 
        
  #Считаем время с начала
  $starttime = (дата получения)
        
  #Переменные
  #Можно добавить максимум 3 пути. Если добавлено более 3, это может изменить относительный путь
  $ root = "C:\мой путь"
        
        
  #Переменная для создания файла CSV
  $ отчет = "mycsvfile.csv"
        
        
  #Процесс генерации HASH
  $hasher = [Система.Безопасность.Криптография.SHA256]::Создать()
  $Все файлы = @() 
        
  "`n"#строчный пробел
        
  Write-Host "Создание хэша из $root" 
        
        
        
  #Получение информации из каталогов
  foreach ($file в get-childitem $root -recurse | Select-Object FullName, Directory, Name, PSIsContainer, Length)
  {
      $acl = get-acl $file.fullname | select-object owner,accesstostring,group
      $obj = новый объект psObject
        
        
  #Создание HASH-файла
      если(!$файл.PsIsContainer)
          {
          $relativePath = $file.FullName.Substring($root.Length)
          Write-Host "Debug $relativePath" -ForegroundColor Green
        
          $inputStream = New-Object IO.StreamReader $file.fullname
          $hashBytes = $hasher.ComputeHash($inputStream.BaseStream)
          $inputStream.Close()
        
          $builder = новый объект System.Text.StringBuilder
          $хэшбайт | Foreach-Object {[void] $builder.Append($_.ToString("X2")) }
        
  #Добавить информацию в CSV-ФАЙЛ
          $объект | Add-Member -membertype noteproperty -name FilePathandName -Value $file.FullName
          $объект | Add-Member -membertype noteproperty -name Name -Value $file.Name
          $объект | Add-Member -MemberType noteproperty -Name RelativePath -Value $relativePath #-force
          $объект | Add-Member -MemberType noteproperty -Name Hash -Value $builder.ToString()
          #$объект | Add-Member -membertype noteproperty -name CreationTime -Value $file.CreationTime
          #$объект | Add-Member -MemberType noteproperty -Name LastAccessTime -Value $file.LastAccessTime
          #$объект | Add-Member -MemberType noteproperty -Name LastWriteTime -Value $file.LastWriteTime
        
                
      #Переменная для отправки информации в CSV
      $Все файлы += $obj
      Относительный путь Clear-Variable
      }
  Удалить переменную obj
  }
        
  #$ВсеФайлы += $obj
        
  #Создание CSV-ФАЙЛА
  $AllFiles |Export-Csv $report âNoTypeInformation
        
  "н"
  Write-Host "Файл $report создан"
        
  "н"
  Write-Host "Сценарий взял:`n"
  $endTime = Get-Date
  New-TimeSpan -Начало $startTime -Конец $endTime
флаг br
[1] если вы используете Win10 или Win11, вы можете настроить ОС на разрешение длинных имен. ///// [2] вы также можете использовать префикс юникода, чтобы разрешить длинные пути только для одного вызова. ///// информацию об обоих, смотрите... >>> Ограничение максимальной длины пути — приложения Win32 | Документы Microsoft — https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd
Рейтинг:1
флаг ru

Чтобы командлеты Powershell работали правильно, используйте \\?\ Вам необходимо установить следующие минимальные версии этих компонентов (протестированы и проверены на Windows Server 2012 R2):

Затем вам просто нужно изменить переменную корневого пути в вашем скрипте, как показано ниже, и он будет работать так, как ожидалось:

  #Переменные
  #Можно добавить максимум 3 пути. Если добавлено более 3, это может изменить относительный путь
  $ root = "\?\C:\mypath\"
        

Нет необходимости изменять какие-либо разделы реестра, чтобы включить поддержку длинных путей или использовать параметр -LiteralPath для любых командлетов.Я неоднократно встречал подобные утверждения в других статьях и на форумах, но это неверно, за исключением очень старых версий Windows.


Теперь, если вы не можете установить эти более новые версии, вам придется использовать обходные пути.

Обратите внимание, что в вашем скрипте эта проблема затрагивает следующие функции:

  • Get-ChildItem
  • Get-Acl
  • Новый объект IO.StreamReader

Одним из решений было бы подставить часть пути как диск когда он станет слишком длинным, и используйте новый диск в качестве корневой папки. Я попробовал это, используя СУБСТ команда, но она должна работать с использованием New-PSDrive командлет. Это требует добавления некоторой логики в ваш скрипт, но это не слишком сложно и довольно просто.

В настоящее время, если вы хотите получить список всех файлов перед выполнением какой-либо замены (чтобы вы могли сначала проверить все длины путей и имен файлов), вы можете использовать следующий обходной путь:

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

Это даст вам список файлов (полные имена).

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.