Лучший отвечающий
Последовательный подсчет размеров дочерних каталогов

Вопрос
-
Добрый день, господа!
Стоит задача: ежесуточно собирать данные о размерах вложенных папок (1 уровня) в конкретном каталоге R:\.
Я решил написать скрипт на одну папку, и зациклить его для всех объектов в каталоге. Выглядит это так:
# Определяем текущую дату $Date = get-date -uformat "%Y%m%d" # Выбираем дочерний каталог $Name = "FolderOne" # Команда подсчета размера каталога в МБ $FolderSize = (Get-ChildItem R:\$Name -recurse -Force | Measure-Object -Property Length -Sum).Sum / 1Mb # Округляем получившийся размер $Size = [math]::round($FolderSize,2) # Пишем итог в файл "$Name`t$Size" >> C:\1\1\$Date.txt
Так всё работает, но только для одной папки. Чтобы посчитать размер всех папок, скрипт нужно скопипастить, последовательно меняя переменную $Name. Это несерьёзно, и я решил реализовать цикл через ForEach. Попытка зацикливания выглядит так:
Foreach ($Name in $DList) { (Get-ChildItem $Name -recurse -Force | Measure-Object -Property Length -Sum).Sum / 1Mb }
Данная команда моментально возвращает строки, количество которых равно количеству дочерних каталогов, а в каждой строке - 0. Если изменить команду, и привести к виду:
Foreach ($Name in $DList) { (Get-ChildItem R:\$Name -recurse -Force | Measure-Object -Property Length -Sum).Sum / 1Mb }
, то скрипт выполняется нереально долгое время безрезультатно (после ~ 2-3 часов я так и не дождался окончания отработки). Нормальное время сканирования размеров всех папок в PS ~40 минут. В данном случае, складывается впечатление, что скрипт зациклился.
Очевидно, проблема кроется в реализации ForEach, но чтение документации и изучение примеров реализации к сожалению не дало необходимого понимания.
15 октября 2014 г. 9:23
Ответы
-
Get-ChildItem R:\ -Force | Foreach { $FolderSize = (Get-ChildItem $_.FullName -recurse -Force | Measure-Object -Property Length -Sum).Sum / 1Mb $Size = [math]::round($FolderSize,2) # Пишем итог в файл "$($_.Name)`t$Size" >> C:\1\1\$Date.txt }
- Предложено в качестве ответа tatiana_spb 17 октября 2014 г. 10:57
- Помечено в качестве ответа Desolato 20 октября 2014 г. 7:33
15 октября 2014 г. 9:33Отвечающий
Все ответы
-
Get-ChildItem R:\ -Force | Foreach { $FolderSize = (Get-ChildItem $_.FullName -recurse -Force | Measure-Object -Property Length -Sum).Sum / 1Mb $Size = [math]::round($FolderSize,2) # Пишем итог в файл "$($_.Name)`t$Size" >> C:\1\1\$Date.txt }
- Предложено в качестве ответа tatiana_spb 17 октября 2014 г. 10:57
- Помечено в качестве ответа Desolato 20 октября 2014 г. 7:33
15 октября 2014 г. 9:33Отвечающий -
Большое спасибо! В конечном итоге скрипт заработал, как надо!
Конечный вариант (вдруг кому понадобится):
# Определяем время запуска скрипта $ScriptStartDate=(GET-DATE) # Определяем дату в нужном формате $Date = get-date -uformat "%Y%m%d" # Получаем список каталогов Get-ChildItem R: -Force | ?{ $_.PSIsContainer } | Foreach { # Замеряем время подсчета размера каждого каталога $StopWatch = [Diagnostics.Stopwatch]::StartNew() # Считаем размер и округляем $FolderSize = (Get-ChildItem $_.FullName -recurse -Force | Measure-Object -Property Length -Sum).Sum / 1Mb $Size = [math]::round($FolderSize,2) # Вычисляем время прогона и пишем результат в файл $StopWatch.Stop() "$($_.Name)`t$Size" >> С:\1\$Date.txt echo "Counting size of $_ catalog is finished" echo "Run time:" "$($StopWatch.Elapsed)" echo "------------------------------" } # Определяем время окончания скрипта $ScriptEndDate=(GET-DATE) echo "Total time:" "$(NEW-TIMESPAN -Start $ScriptStartDate -End $ScriptEndDate)"
- Изменено Desolato 28 октября 2014 г. 13:31
20 октября 2014 г. 7:43