none
Рекурсивный поиск файлов

    Вопрос

  • Требуется рекурсивно обойти все каталоги и найти файлы, которые соответствуют ряду признаков (дата создания, владелец файла и так далее). Проблемы начинаются когда много вложенных каталогов и длинные путь. 

    Пытался разными способами (для примера 2 последних, каждая строка - разная попытка):

    $files = @(ls -File -Recurse  -Path $path) # вообще все файлы в одну переменную а потом уже через if сортировка
    $files = ls -Recurse -Path $path |?{$_.CreationTime -lt $(get-date).AddDays(-90)}  # добавляем в переменную лишь старые файлы, а уже после отбираем по владельцу
    

    Соответственно потом по алгоритму через 

    foreach ($file in $files)
    Проверяю каждый файл на ряд признаков (как писал выше, дату создания, владельца, наличие владельца в AD и так далее).

    В итоге на "больших каталогах" (где много папок и подпапок с длинными именами) все заканчивается ошибкой:

    ls : The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.

    Какие решить данную задачу? 

    21 января 2019 г. 13:32

Ответы

Все ответы

  • пробуйте использовать unc пути по типу "\\server\c$\donotdelete\New folder\New folder (1)\"

    The opinion expressed by me is not an official position of Microsoft

    21 января 2019 г. 14:04
    Модератор
  • Точно такая же ошибка. 
    21 января 2019 г. 14:59
  • Добрый день,

    Может эта ссылка поможет?

    https://stackoverflow.com/questions/46308030/handling-path-too-long-exception-with-new-psdrive/46309524

    • Помечено в качестве ответа KazunEditor 25 января 2019 г. 5:48
    21 января 2019 г. 15:14
  • PS C:\Windows\system32> get-childitem -LiteralPath "\\?\E:\Documents\" -Recurse
    get-childitem : Illegal characters in path.
    At line:1 char:1
    + get-childitem -LiteralPath "\\?\E:\Documents\" -Recurse
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [Get-ChildItem], ArgumentException
        + FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.GetChildItemCommand
    Править реестр боязно, много сервисов завязано на сервер. 
    22 января 2019 г. 7:00
  • поппробуйте одинарные кавычки как в примере

    The opinion expressed by me is not an official position of Microsoft

    22 января 2019 г. 7:06
    Модератор
  • PS C:\Windows\system32> get-childitem -LiteralPath "\\?\E:\Documents\" -Recurse
    get-childitem : Illegal characters in path.
    At line:1 char:1
    + get-childitem -LiteralPath "\\?\E:\Documents\" -Recurse
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [Get-ChildItem], ArgumentException
        + FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.GetChildItemCommand
    Править реестр боязно, много сервисов завязано на сервер. 

    Префикс пути '\\?\' доступен к использованию в версии с Powershell 5.1.

    Какая у вас версия Powershell? Можно посмотреть при помощи переменной $host

    23 января 2019 г. 8:18
  • PS C:\Windows\system32> get-childitem -LiteralPath "\\?\E:\Documents\" -Recurse
    get-childitem : Illegal characters in path.
    At line:1 char:1
    + get-childitem -LiteralPath "\\?\E:\Documents\" -Recurse
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [Get-ChildItem], ArgumentException
        + FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.GetChildItemCommand
    Править реестр боязно, много сервисов завязано на сервер. 

    Префикс пути '\\?\' доступен к использованию в версии с Powershell 5.1.

    Какая у вас версия Powershell? Можно посмотреть при помощи переменной $host

    Для работы с Long Path версия системы должна быть Windows 10 Anniversary Update 1607/Windows Server 2016 и выше. Подробнее - https://blogs.msdn.microsoft.com/jeremykuhne/2016/07/30/net-4-6-2-and-long-paths-on-windows-10/

    $host - Это версия хоста, а не PowerShell. Для определения версии -  $PSVersionTable.

    PS > $host
    Name             : Visual Studio Code Host
    Version          : 1.10.2

    PS:

    Если Windows 10/Windows Server 2016 - нет, то используйте модуль NTFSSecurity для обхода ограничений: Get-ChildItem2


    • Изменено KazunEditor 23 января 2019 г. 8:36
    23 января 2019 г. 8:26
    Отвечающий
  • https://social.technet.microsoft.com/Forums/ru-RU/832b9bd4-82d1-4120-890e-7f4443e6a8e4/ps-getchilditem?forum=scrlangru

    Вопрос 2: почему программа не может переместить папки (247,248 символов), но при этом вручную переместить их можно. http://www.cyberforum.ru/csharp-beginners/thread1797338.html

    Потому что .NET (до версии 4.6.2) умеет работать только с короткими путями. Windows же поддерживает пути длиной до 32 Кб и поэтому ручное копирование срабатывает. Если есть возможность перейти на .NET 4.6.2, то лучше это сделать. Если нет, то нужно использовать функции Windows API или взять библиотеку AlphaFS, которая повторяет функциональность System.IO, но при этом поддерживает длинные пути.

    23 января 2019 г. 8:39