Powershell - IO.Directory - поиск типов файлов во всех подкаталогах

Я наткнулся на этот код в другом посте, который почти делает то, что мне нужно, но можетt выяснить, как изменить его, чтобы искать файлы определенного типа, т.е. * .bak,.txt и т. д. Яя использую Powershell с [System.IO.DirectoryInfo], потому что, как уже говорили другие, использование Get-ChildItem слишком медленное в сети. Я думал, что это будет что-то вроде $ fileEntries = [IO.Directory] :: GetFiles ("C: \ ",".bak»), но он по-прежнему возвращает каждый файл в каждом каталоге. --PS / .NET новичок

try
{
       $fileEntries = [IO.Directory]::GetFiles("C:\")
       [System.IO.DirectoryInfo]$directInf = New-Object IO.DirectoryInfo("C:\")
       $folders = $directInf.GetDirectories()
}
catch [Exception]
{
       $_.Exception.Message
       $folders = @()
 }

foreach($fileName in $fileEntries) 
{

      #[Console]::WriteLine($fileName); 

}

Remove-Variable -ErrorAction SilentlyContinue -Name fileEntries 

foreach($folder in $folders)
{
    recurse("C:\" + $folder + "\")
}

Ответы на вопрос(3)

4.0 Framework:

try{
    $path = "\\$Server\$($drive.replace(':','))"
    foreach ($filepath in [System.IO.Directory]::EnumerateFiles($path,"*.bak","AllDirectories"))
       {
          $file = New-Object System.IO.FileInfo($filepath)
          write-host $file
          # insert file into database table
       }
  }
catch [UnauthorizedAccessException]
  {
     $exception = $_.Exception.Message #I don't need to write/insert exception
  }

Простой скрипт PowerShell для перемещения многих файлов из каталога в структурированный каталог по году, месяцу и дню. Это очень быстро, у меня было более 500К файлов.

$listofFiles =   System.IO.Directory]::EnumerateFiles("D:\LotsOfFiles","*.*","TopDirectoryOnly")

$listofFiles |% {
   $file = New-Object System.IO.FileInfo($_)    
   $date = Get-Date ($file.CreationTime)
   $filepath = ("{0}\{1:00}\{2:00}-{3}\{4:00}\" -f "D:\LotsOfFiles", $date.year, 
   $date.month, $date.toString("MMM"), $date.day)
   Write-Output ("Move: {0} to {1}" -f $file.Fullname, $filepath)

   if (! (Test-Path $filepath)) {       
      new-item -type Directory -path $filepath      
   }

   move-item $file $filepath
}   

Это, вероятно, можно улучшить, но это работает.

ища все файлы в корневом каталоге и подкаталогах. Убедитесь, что у вас есть правильные привилегии для всех каталогов, особенно когда вызапускается из C: \ как корень.

$Extensions = @(".bak",".csv",".txt")

Foreach ( $Extension in $Extensions )
{
   [System.IO.Directory]::EnumerateFiles("C:\","*$Extension","AllDirectories")
}

Этот метод будет работать только с Powershell под управлением .Net 4.0 или выше. Чтобы проверить и обновить версию .Net:

$PSVersionTable

Name                           Value
----                           -----
CLRVersion                     2.0.50727.4971
BuildVersion                   6.1.7600.16385
PSVersion                      2.0
WSManStackVersion              2.0
PSCompatibleVersions           {1.0, 2.0}
SerializationVersion           1.1.0.1
PSRemotingProtocolVersion      2.1

Значение CLRVersion - это версия .net.

Обновите файл конфигурации следующим образом:

$Config = @"
<!--?xml version="1.0"?-->
<configuration>
    <startup uselegacyv2runtimeactivationpolicy="true">
        <supportedruntime version="v4.0.30319">
        <supportedruntime version="v2.0.50727">
    </supportedruntime></supportedruntime></startup>
</configuration>
"@

$Config > $PSHOME\Powershell.exe.config

Перезапустите сеанс Powershell и проверьте значение CLRVersion в переменной $ PSVersionTable.

 user208928720 февр. 2013 г., 23:51
Облом. Я неВозможность установки 3.0 пока отсутствует.
 user208928723 февр. 2013 г., 00:17
Это извлекает файлы и перехватывает исключение в сообщении об ошибке в одну строку, но теперь похоже, что я столкнулся с другой проблемой невозможности фильтрации по дате, потому что [IO.DirectoryInfo], НЕ [IO.Directory], имеет свойства FileObject как .CreationTime? Серьезно, уже, кто написал этот материал, Хауди Дуди? :)
 user208928721 февр. 2013 г., 23:34
Метод :: EnumerateFiles теперь работает, но есть ли способ избежать этого »Доступ закрыт" я столкнулся с использованием :: GetFiles? Кроме того, как мне захватить / отобразить только имя файла против всего пути + имя файла? Использование $ file.fullname или $ file.name показывает процесс, выполняемый / прокручиваемый, но значение для каждой строки не отображается.
 user208928721 февр. 2013 г., 19:01
Я создал файл powershell.exe.config и powershell_ise.exe.config для .NET 4.0, но все еще сталкиваюсь с ошибками вызова метода. Не уверен, что я настроил это неправильно. Для "Доступ закрыт" ошибка, я попробовал фильтр как| где {$ _. name -ne "Информация о томе системы "}", Папка существует на каждом диске, который яm сканирует и запрещает доступ администратора. Я не' хотите изменить некоторые атрибуты этого на 50+ серверах, чтобы "исправить» Это. Я'Придется найти способ обойти это с помощью catch [Exception] и т. д.
 Musaab Al-Okaidi21 февр. 2013 г., 20:01
Чтобы убедиться, что изменения конфигурации вступили в силу, проверьте переменную $ PSVersionTable, она имеет "CLRVersion» и значение должно переключиться на 4.xxxx, если конфигурации были применены правильно. Фильтр where не будет работать, потому что, как я объяснил ранее, GetFiles извлечет весь список файлов перед выполнением операции над файлами, поэтомувсегда будет терпеть неудачу в этом случае.
 Musaab Al-Okaidi22 февр. 2013 г., 09:25
посмотрите на это обсуждение, у него есть решение, позволяющее избежать ошибки Access Denied от остановки рекурсии, это 'немного сложнее, хотя.stackoverflow.com/questions/4986293/...  Чтобы вернуть имя файла только вамнам придется немного поработать со строками, поскольку возвращаемые результаты - это строки, а не файловые объекты.
 user208928723 февр. 2013 г., 00:18
попробуй {$ path = "\\ $ MyServer \ $ \ ($ drive.replace ( ':', '$70$#39;))»       $ files = [IO.Directory] :: EnumerateFiles ($ path, "* .bak ","AllDirectories») foreach ($ file in $ files) {# do processing}} catch [UnauthorizedAccessException] {write-host $ _. Exception.Message}
 Musaab Al-Okaidi21 февр. 2013 г., 09:59
Если ты'Если вы собираетесь сделать это в корне драйвера C: \, то вам потребуется полный доступ ко всем каталогам, в противном случае вы 'обязательно получить доступ запрещен. GetFiles и EnumerateFiles выполняют одну и ту же функцию, за исключением того, что EnumerateFiles работает быстрее, поскольку работает с файлами по порядку, тогда как GetFiles сначала возвращает полный список файлов, а затем начинает работу с ними. Чтобы использовать EnumerateFiles, вы можете придерживаться Powershell 2.0, но вам нужно изменить конфигурационный файл Powershell для использования .Net 4.0 или выше.
 user208928721 февр. 2013 г., 22:58
Я успешно сохранил файл конфигурации на своем компьютере, поэтому теперь у меня есть немного работы. Надеюсь, яскоро смогу опубликовать решение.
 user208928721 февр. 2013 г., 19:02
Исходный опубликованный код повторяется во всех подпапках без проблем, но находитвсе файлы вместо указанных. Я подумал, что где-то внутри одного из этих циклов или :: GetFiles я могу добавить фильтр для типа файла.
 Musaab Al-Okaidi20 февр. 2013 г., 22:47
У меня была та же ошибка с Powrshell 2.0, но она работает на Powershell 3.0
 user208928723 февр. 2013 г., 00:24
Использование [IO.DirectoryInfo]. $ Dir = New-Object IO.DirectoryInfo ($ path) $ files = $ dir.EnumerateFiles ($ path, "* .bak ","AllDirectories») возвращает ошибку: свойство 'Документы и настройки' не может быть найдено на этом объекте  Может кто-нибудь сказать мне, если / где явводишь что-то неправильно?
 user208928720 февр. 2013 г., 22:30
Благодарю. Есть ли у меня проблема с синтаксисом в Powershell? Я получил "Ошибка вызова метода, потому что [systemRuntimeType] не 'не содержит метод с именем 'EnumerateDirectories' ошибка.
 user208928725 февр. 2013 г., 20:02
Хорошо, я думаюмы получили его, используя [IO.Directory] :: EnumerateFiles и IO.FileInfo. Последнее, что яМне бы хотелось исключить системные или скрытые файлы - это можно сделать, просто сравнив некоторый атрибут в объекте FileInfo, т.е. $ file.System -ne "правда" или "0"?
 user208928725 февр. 2013 г., 18:33
Я сталкиваюсь с ошибками при попытке использовать IO.DirectoryInfo. Я'Я также пробую New-Object System.IO.FileInfo ($ file) в моей итерации foreach ($ file in $ files), но это также приводит к ошибке: "Новый объект: конструктор не найден. Не удается найти подходящий конструктор для типа System.IO.FileInfo. "  Мне просто нужен способ использования IO.Directory + что-то еще или IO.DirectoryInfo для сортировки / фильтрации по дате файла.
 user208928721 февр. 2013 г., 22:33
Хорошо яЯ угадал этоВероятно, это не проблема синтаксиса, а еще один тип препятствий с политикой corp. тьфу.
 user208928721 февр. 2013 г., 00:52
Есть ли способ сделать это без метода EnumerateFiles? Я также пробовал GetFiles с [IO.SearchOption] :: AllDirectories, но столкнулся с "Доступ закрыт" ошибка противИнформация о томе системы " каталог.
 user208928721 февр. 2013 г., 20:30
ХОРОШО. Спасибо за информацию. Похоже, что я, возможно, сделал что-то неправильно с конфигурационными файлами. Значение CLRVersion все еще показывает 2.0.50727.3643. Haven»пока не нашел решения, но выложу как только я. Я думаю, что enumeratefiles может быть таким, если метод работает после исправления версии .NET.
 Musaab Al-Okaidi21 февр. 2013 г., 20:02
Пожалуйста, опубликуйте решение, если выЕсли он окажется полезным для других, я дополню свой ответ инструкциями по установке версии .Net.
 user208928721 февр. 2013 г., 21:56
Извините за беспокойство, но я получаю сообщение об ошибке с Powershell после обновления файла конфигурации. "Система не может выполнить указанную программу " или (ISE): "Это приложение не удалось запустить из-за неправильной конфигурации приложения. Переустановка приложения может решить проблему."

Ваш ответ на вопрос