Оптимизация Get-ChildItem в скрипте PowerShell

У меня есть сценарий Powershell, в котором мне нужно определить, были ли какие-либо файлы добавлены в папку за последние 60 минут. Если ответ да, то я беру эти файлы, копирую их в другой каталог и выполняю определенный код. Прямо сейчас в исходном каталоге ~ 10-20 тыс. файлов, и выполнение кода занимает много времени. Я попробовал метод оптимизации для gci, который нашел в Интернете (включая выходные данные конвейера), но ни один из них не сработал. Я также пытался выполнить пакетный файл с помощью c/dir, но получаю сообщение об ошибке, говорящее, что он не поддерживает пути UNC. Любые идеи?

Stop-Process -name excel
$PathMX1005 = "\\UNCsourcedir"
$numberoffilesMX1005 = Get-ChildItem $PathMX1005 -recurse -include *1Hz_1*.csv | Where { $_.CreationTime -ge [datetime]::Now.AddMinutes(-60) } | Measure-Object
If ($numberoffilesMX1005.Count -eq 0) {Exit-PSSession}
Else {   
$filesMX1005 = Get-ChildItem $PathMX1005 -recurse -include *1Hz_1*.csv | Where { $_.CreationTime -ge [datetime]::Now.AddMinutes(-60) } .... 

rest of code }

person Casousadc    schedule 01.06.2015    source источник
comment
Вы получаете список дважды. Это кажется неразумным. Просто сохраните возвращенный массив и используйте его свойство count/length и/или просто направьте его непосредственно в свой блок кода для запуска и полностью избегайте подсчета.   -  person Etan Reisner    schedule 01.06.2015
comment
Привет, у меня была проблема, аналогичная той, что у вас сейчас, я закончил тем, что отказался от метода get child, и вместо этого я создал наблюдатель за папкой в ​​Power Shell, поэтому в основном, когда файл добавляется в папку, он запускает и даже проверяет если это файл, который я ищу, а затем выполняет действие. Это было намного быстрее, но это может замедлить время создания файла/папки. В моем окружении я даже не мог сказать, что разница настолько мала, но приятно знать, что она может иметь влияние. Если вы хотите, чтобы я загрузил то, что я сделал в качестве ответа, дайте мне знать.   -  person justinf    schedule 01.06.2015
comment
В стороне: [DateTime]::Now содержит миллисекунды; Мне было интересно, будет ли предложение where пересчитывать Now.AddMinutes(-60) для каждого файла, и будет ли предварительный расчет быстрее. Таким образом я просканировал ~22k файлов через UNC. Это заняло 26,540 мс. Затем я снова запустил его с исходным расчетом внутри подхода с предложением where: 16,26 мс. Затем, чтобы попытаться учесть дисковые кеши, я повторил первую попытку с предварительным вычислением и получил 16,215 мс. Затем попытался распечатать расчет внутри предложения where. Я думаю, что он пересчитывается каждый раз, но общая разница незначительна для файлов размером 22 КБ в локальной сети.   -  person TessellatingHeckler    schedule 02.06.2015
comment
Большое спасибо за ваши ответы. @justinf, не могли бы вы загрузить то, что вы сделали, в качестве ответа, чтобы я мог на это взглянуть? Спасибо.   -  person Casousadc    schedule 05.06.2015
comment
Я откопаю код позже и опубликую его, если не найду, просто сделаю это быстро.   -  person justinf    schedule 06.06.2015


Ответы (2)


Пользователь -Filter предпочтительнее -Include, поскольку он передает параметры провайдеру, а не получает результаты синтаксического анализа PowerShell постфактум. Кроме того, как предложил Этан Рейснер, вы должны получить список каталогов только один раз, а затем получить его количество для своего оператора If и снова для обработки.

Stop-Process -name excel
$PathMX1005 = "\\UNCsourcedir"
$filesMX1005 = Get-ChildItem $PathMX1005 -recurse -filter "*1Hz_1*.csv" | Where { $_.CreationTime -ge [datetime]::Now.AddMinutes(-60) } 
If ($filesMX1005.Count -eq 0) {Exit-PSSession}
Else {   
    rest of code }
person TheMadTechnician    schedule 01.06.2015
comment
Вы действительно не хотите запускать список файлов в объект измерения, выбрасывать его и сохранять измерения в $filesMX1005, не так ли? - person TessellatingHeckler; 02.06.2015
comment
@TessellatingHeckler Вы правы, мне лень копировать/вставлять, а не перепроверять свою работу дважды. Обновлено! - person TheMadTechnician; 02.06.2015

У меня была проблема, аналогичная той, что у вас есть сейчас, я закончил тем, что отказался от метода get child, и вместо этого я создал наблюдатель за папкой в ​​Power Shell, поэтому в основном, когда файл добавляется в папку, он срабатывает, и событие даже проверяет, если файл - это тот, который я ищу, а затем выполняет действие. Это было намного быстрее, но это может замедлить время создания файла/папки.

Я пришел к этой идее после прочтения сообщения в блоге Scripting Guys, поэтому я просто дам ссылку на него. Если вам нужна помощь, спросите.

http://blogs.technet.com/b/heyscriptingguy/archive/2012/07/17/use-powershell-to-monitor-for-the-creation-of-new-files.aspx

person justinf    schedule 08.06.2015