none
Последовательный подсчет размеров дочерних каталогов RRS feed

  • Вопрос

  • Добрый день, господа!

    Стоит задача: ежесуточно собирать данные о размерах вложенных папок (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