none
Нужна помощь с PowerShell RRS feed

  • Вопрос

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

    Проблема возникла там где я её не ожидал, поиск в инете результатов не дал, возникает ошибка при перемещении файлов из временного каталога во входящий каталог программы, конкретно это строка

     

    Move-Item -Path $sourcedir -Destination $destdir -Include $files[$i]
    

     

    Очевидно я не совсем правильно понимаю в каком виде передавать параметры этому командлету, по моему представлению параметры Path и Include в лице строковой переменной $files[$i] должны складываться в командлете и давать мне полный и правильный путь на файл который я хочу переместить, однако вместо этого возникает ошибка:

     

    Move-Item : Cannot move item because the item at 'C:\ABONENT\' does not exist.

    At C:\new8.ps1:22 char:10

    + Move-Item <<<<  -Path $sourcedir -Destination $destdir -Include $files[$i]

        + CategoryInfo          : InvalidOperation: (:) [Move-Item], PSInvalidOperationException

        + FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.MoveItemCommand

     

     

    Помогите пожалуйста разобраться, код целиком приведен ниже.

     

     

    $sourcedir = "c:\ABONENT\"
    $destdir = "c:\ABONENT\1\"
    $p = Get-Process -Name "7zg"
    $logname = "Load.log"
    if($p.Count>1)
    {
    "Кол-во запущенных процессов программы больше одного, что недопустимо, скрипт завершил работу." >> $logname
    exit
    }
    while($p.Responding)
    {
    $temp = $p.CPU
    sleep -Seconds 10
    $t = Get-Date -Format "MM-dd hh:mm:ss"
    $t.ToString()
    if($p.CPU-$temp -lt 5)
    {
    $files = Get-ChildItem -Name -Path $sourcedir -Recurse -Include "*.cer"
    $files = Sort-Object -InputObject $files
    for($i=0; $i -lt 50; $i++)
    {
    Move-Item -Path $sourcedir -Destination $destdir -Include $files[$i]
    }
    "$t >>> Загрузка ЦП меньше 50%, подброшена новая порция файлов" >> $logname
    }
    else
    {
    "$t >>> Загрузка ЦП в норме" >> $logname
    }
    }
    "Программа была закрыт, либо не отвечает на запрос." >> $logname
    "Выполнение скрипта остановлено." >> $logname
    exit
    


     


    15 июля 2011 г. 9:52

Ответы


  • if($p.CPU-$temp -lt 5)
    {
    	Get-ChildItem -Path $sourcedir "*.cer" -Recurce | Move-Item -Destination $destdir
    }
    



    Простите, немного не понял, мне нужно не все файлы переместить, а только первые 50 из сортированного массива..
    Get-ChildItem $sourcedir "*.cer" -Recurse | Sort | select -First 50 | Move-Item  -Destination $destdir

    Такой вариант работает, но оочень долго происходит получение и сортировка массива в конвеере, тем более что в данном случае я получаю не имена, а объекты целиком, если получать и сортировать массив в два приёма и только с именами, как написано у меня в первом сообщении - всё происходит раз в 10-15 быстрее, но при передаче полученных параметров в Move-Item powershell не может найти файлы, хотя по логике всё должно проходить успешно..

    $files[0..49] | Move-Item -Path {"$sourcedir\$_"} -Destination $destdir

    Или с циклом
    for($i=0; $i -lt 50; $i++) { Move-Item -Path "$sourcedir\$($files[$i])" -Destination $destdir }
    

    Ps. Если нужна скорость работы то лучше использовать dir и sort из cmd,в разы быстрее.
    15 июля 2011 г. 11:09
    Отвечающий

Все ответы

  • if($p.CPU-$temp -lt 5)
    {
    	Get-ChildItem -Path $sourcedir "*.cer" -Recurce | Move-Item -Destination $destdir
    }
    

    И свойство CPU отображает не загрузку процессора,для этого лучше использовать счетчик производительность(Get-Counter или WMi).
    • Изменено KazunEditor 15 июля 2011 г. 10:20
    15 июля 2011 г. 10:01
    Отвечающий
  • if($p.CPU-$temp -lt 5)
    {
    	Get-ChildItem -Path $sourcedir "*.cer" -Recurce | Move-Item -Destination $destdir
    }
    



    Простите, немного не понял, мне нужно не все файлы переместить, а только первые 50 из сортированного массива..
    15 июля 2011 г. 10:15
  • if($p.CPU-$temp -lt 5)
    {
    	Get-ChildItem -Path $sourcedir "*.cer" -Recurce | Move-Item -Destination $destdir
    }
    



    Простите, немного не понял, мне нужно не все файлы переместить, а только первые 50 из сортированного массива..
    Get-ChildItem $sourcedir "*.cer" -Recurse | Sort | select -First 50 | Move-Item  -Destination $destdir
    15 июля 2011 г. 10:23
    Отвечающий
  • if($p.CPU-$temp -lt 5)
    {
    	Get-ChildItem -Path $sourcedir "*.cer" -Recurce | Move-Item -Destination $destdir
    }
    



    Простите, немного не понял, мне нужно не все файлы переместить, а только первые 50 из сортированного массива..
    Get-ChildItem $sourcedir "*.cer" -Recurse | Sort | select -First 50 | Move-Item  -Destination $destdir

    Такой вариант работает, но оочень долго происходит получение и сортировка массива в конвеере, тем более что в данном случае я получаю не имена, а объекты целиком, если получать и сортировать массив в два приёма и только с именами, как написано у меня в первом сообщении - всё происходит раз в 10-15 быстрее, но при передаче полученных параметров в Move-Item powershell не может найти файлы, хотя по логике всё должно проходить успешно..

    15 июля 2011 г. 11:00

  • if($p.CPU-$temp -lt 5)
    {
    	Get-ChildItem -Path $sourcedir "*.cer" -Recurce | Move-Item -Destination $destdir
    }
    



    Простите, немного не понял, мне нужно не все файлы переместить, а только первые 50 из сортированного массива..
    Get-ChildItem $sourcedir "*.cer" -Recurse | Sort | select -First 50 | Move-Item  -Destination $destdir

    Такой вариант работает, но оочень долго происходит получение и сортировка массива в конвеере, тем более что в данном случае я получаю не имена, а объекты целиком, если получать и сортировать массив в два приёма и только с именами, как написано у меня в первом сообщении - всё происходит раз в 10-15 быстрее, но при передаче полученных параметров в Move-Item powershell не может найти файлы, хотя по логике всё должно проходить успешно..

    $files[0..49] | Move-Item -Path {"$sourcedir\$_"} -Destination $destdir

    Или с циклом
    for($i=0; $i -lt 50; $i++) { Move-Item -Path "$sourcedir\$($files[$i])" -Destination $destdir }
    

    Ps. Если нужна скорость работы то лучше использовать dir и sort из cmd,в разы быстрее.
    15 июля 2011 г. 11:09
    Отвечающий
  • По поводу быстродействия,тоже результат ваши совсем не оправдались.Ваш у меня самый медленный.

     

    PS 1 > Measure-Command {
    >>   1..10 | %{
    >>     Get-ChildItem C:\Windows "*.ini" -Recurse -ea silentlycontinue | sort
    >>     }
    >> }
    >>
    
    
    Days       : 0
    Hours       : 0
    Minutes      : 2
    Seconds      : 12
    Milliseconds   : 955
    Ticks       : 1329558912
    TotalDays     : 0.00153884133333333
    TotalHours    : 0.036932192
    TotalMinutes   : 2.21593152
    TotalSeconds   : 132.9558912
    TotalMilliseconds : 132955.8912
    
    
    
    PS 2 > Measure-Command {
    >>   1..10 | % {
    >>     $files = Get-ChildItem -Name -Path C:\Windows "*.ini" -Recurse
    >>     $files = Sort-Object -InputObject $files
    >>   }
    >> }
    >>
    
    
    Days       : 0
    Hours       : 0
    Minutes      : 3
    Seconds      : 19
    Milliseconds   : 460
    Ticks       : 1994602991
    TotalDays     : 0.00230856827662037
    TotalHours    : 0.0554056386388889
    TotalMinutes   : 3.32433831833333
    TotalSeconds   : 199.4602991
    TotalMilliseconds : 199460.2991
    
    
    
    PS 3 > Measure-Command {
    >>   1..10 | %{
    >>     cmd /c dir C:\Windows\*.ini /s /b | sort
    >>     }
    >> }
    >>
    
    
    Days       : 0
    Hours       : 0
    Minutes      : 0
    Seconds      : 59
    Milliseconds   : 908
    Ticks       : 599082648
    TotalDays     : 0.000693382694444444
    TotalHours    : 0.0166411846666667
    TotalMinutes   : 0.99847108
    TotalSeconds   : 59.9082648
    TotalMilliseconds : 59908.2648
    
    


    15 июля 2011 г. 11:43
    Отвечающий
  • Спасибо большое, Ваш вариант с циклом работает, если не сложно не могли бы пояснить почему не работал мой изначальный?

    По поводу скорости у меня результаты с Measure были обратные, получение и сортировка в конвеере почти минута, а тот вариант который в исходном скрипте - получение ок. 3-4ёх секунд, сортировка 0.2-0.3сек, вечером попробую ещё раз провести замеры в своём окружении.

    15 июля 2011 г. 12:30