powershell время выполнения скрипта
Секундомер для PowerShell скрипта
Класс StopWatch входит в пространство имен System.Diagnostics и у него есть статический метод StartNew. С помощью этого метода создадим новый экземпляр класса StopWatch, сохраним его в переменную и выведем свойства и методы нашего ″таймера″:
$watch = [System.Diagnostics.Stopwatch]::StartNew()
$watch | Get-Member
Здесь нас интересуют методы Start и Stop, отвечающие за запуск и остановку таймера и свойство Elapsed, показывающее прошедшее время.
Теперь создадим вот такой скрипт, который ищет в папке Windows все файлы с расширением txt и записывает полученный результат в файл:
Запустим его и посмотрим, что выдаст секундомер. Как видите, выполнение задачи заняло чуть больше 3 секунд (3,2).
Еще для измерения времени выполнения задачи в PowerShell есть командлет Measure-Command. Этот командлет берет команду\блок команд, указанную в фигурных скобках, выполняет ее внутри себя и в качестве результата выдает время, затраченное на выполнение. Вот так будет выглядеть наш скрипт с использованием Measure-Command:
Результат такой же, как и в предыдущем примере — 3,2 секунды.
Measure-Command выдает результат в не очень удобном виде. Для того, чтобы получить более наглядное представление, можно воспользоваться методом ToString:
В этом случае результат выводится в одну строку, в таком же виде, как и при использовании StopWatch.
В заключение напомню, что на скорость выполнения скрипта может влиять загруженность системы, скорость сетевого подключения и прочие внешние факторы. Для одной и той же команды, запущенной в разное время результат может заметно различаться. Поэтому для получения более-менее точного результата измерение стоит повторить 2-3 раза.
Время выполнения команды в PowerShell
Есть ли простой способ рассчитать время выполнения команды в PowerShell, например, команду time в Linux?
Я придумал это:
Но хотелось бы чего-нибудь попроще вроде
6 ответов
Вот написанная мной функция, которая работает аналогично команде Unix time :
Использование секундомера и форматирование прошедшего времени:
Несколько слов о том, как делать (неправильные) выводы из любой из команд измерения производительности, упомянутых в ответах. Существует ряд подводных камней, которые следует учитывать, помимо учета времени вызова (настраиваемой) функции или команды.
Sjoemelsoftware
Лично я считаю, что « Sjoemelsoftware » не всегда преднамеренно создается для обмана результатов тестирования, но может возникнуть из-за приспособления к практическим ситуациям, аналогичным тестовым примерам, показанным ниже.
В качестве примера, используя перечисленные команды измерения производительности, Language Integrated Query (LINQ) (1) часто квалифицируется как быстрый способ что-то сделать, и это часто бывает, но, конечно, не всегда! Любой, кто измеряет увеличение скорости в 40 или более раз по сравнению с собственными командами PowerShell, вероятно, неправильно измеряет или делает неверный вывод.
Также обратите внимание на другую ловушку: если вы сделаете это снова, некоторые шаги могут появиться намного быстрее, чем раньше, потому что некоторые выражения были кэшированы.
В итоге, если вы хотите сравнить производительность двух функций, вам нужно будет реализовать их в вашем используемом случае, начать с нового сеанса PowerShell и основывать свой вывод на фактической производительности полного решения.
Timing a command’s execution in PowerShell
Is there a simple way to time the execution of a command in PowerShell, like the ‘time’ command in Linux?
I came up with this:
But I would like something simpler like
8 Answers 8
Note that one minor downside of Measure-Command is that you see no stdout output.
[Update, thanks to @JasonMArcher] You can fix that by piping the command output to some commandlet that writes to the host, e.g. Out-Default so it becomes:
You may want to tweak the output
Here’s a function I wrote which works similarly to the Unix time command:
Using Stopwatch and formatting elapsed time:
All the answers so far fall short of the questioner’s (and my) desire to time a command by simply adding «time » to the start of the command line. Instead, they all require wrapping the command in brackets ( <> ) to make a block. Here is a short function that works more like time on Unix:
Just a word on drawing (incorrect) conclusions from any of the performance measurement commands referred to in the answers. There are a number of pitfalls that should taken in consideration aside from looking to the bare invocation time of a (custom) function or command.
Sjoemelsoftware
‘Sjoemelsoftware’ voted Dutch word of the year 2015
Sjoemelen means cheating, and the word sjoemelsoftware came into being due to the Volkswagen emissions scandal. The official definition is «software used to influence test results».
Personally, I think that «Sjoemelsoftware» is not always deliberately created to cheat test results but might originate from accommodating practical situation that are similar to test cases as shown below.
The result appears obvious, the later Linq command is a about 40 times faster than the first PowerShell command. Unfortunately, it is not that simple.
Let’s display the results:
Also notice an other pitfall that if you do it again, certain steps might appear a lot faster then before, this is because some of the expressions have been cached.
Bottom line, if you want to compare the performance between two functions, you will need to implement them in your used case, start with a fresh PowerShell session and base your conclusion on the actual performance of the complete solution.
(1) For more background and examples on PowerShell and LINQ, I recommend tihis site: High Performance PowerShell with LINQ
(2) I think there is a minor difference between the two concepts as with lazy evaluation the result is calculated when needed as apposed to deferred execution were the result is calculated when the system is idle
Запуск PowerShell скриптов по расписанию
В задачи практически любого системного администратора входит написание различных скриптов и их запуск. Запланировать запуск скрипта по расписанию с помощью Task Sheduler — задача несложная, но при использовании PowerShell есть некоторые нюансы, о которых я расскажу в этой статье.
Итак, предположим, у меня есть скрипт start.ps1, который мне необходимо запускать ежедневно в течении 10 дней. Есть два способа решить эту задачу.
Способ 1
Для запуска скрипта воспользуемся оснасткой Task Scheduler, он же планировщик заданий. Найти его можно в разделе Administrative Tools, либо нажав Win+R и введя команду taskschd.msc. Открываем планировщик и в разделе Actions выбираем пункт Create Task.
На вкладке General указываем имя и описание задания, а также (по необходимости) пользователя, от имени которого задание будет запускаться. Для того, чтобы задание выполнялось вне зависимости от того, залогинен ли пользователь в системе, выбираем опцию «Run whether user is logged on or not». Если для выполнения задания требуется повышение привилегий, то отмечаем опцию «Run with highest privileges».
Далее идем на вкладку Triggers и создаем новый триггер, в котором будет храниться расписание запуска нашего задания. В поле Start указываем дату и время запуска, а в поле Expire — дату и время завершения задания. Указываем выполнять задание ежедневно (Daily) и задаем период повтора (Recur every) 1 день.
Примечание. Если вы хотите запускать задание чаще, чем раз в день, то надо выбрать одноразовое выполнение (One time), а в разделе Advanced settings отметить пункт Repeat task every и указать время повторения, минимум 5 минут, максимум 1 час. Если этого недостаточно, то дополнительно в поле Delay task for up to можно указать временную задержку.
Также в поле аргументы можно указать:
Заполнив необходимые поля жмем ОК и сохраняем задание. Теперь скрипт будет запускаться по расписанию ежедневно в заданное время в течении 10 дней.
Способ 2
В PowerShell 3.0 появился новый функционал Sheduled Job, дающий возможность создавать запланированные задания прямо из консоли, не пользуясь оснасткой планировщика. Воспользуемся им для планового запуска нашего скрипта.
Сначала создаем расписание запуска (ежедневно в полпятого вечера, в течении 10 дней):
Затем сохраняем в переменной учетные данные:
$cred = Get-Credential contoso\administrator
В качестве опции указываем запуск задания с повышенными привилегиями:
И регистрируем задание с именем Start:
Чтобы убедится в том, что задание создано, можно открыть планировщик и найти наше задание в разделе Microsoft\Windows\PowerShell\SheduledJobs.
Примечание. Для каждого запланированного задания PowerShell в директории %systemdrive%\Users\%username%\AppData\Local\Microsoft\Windows\PowerShell\ScheduledJobs создается одноименная папка. В этой папке находится само задание в XML-файле и папка Output, в которой, в подпапках по времени выполнения, хранится история выполнения задания — результат выполнения (файлs Result.xml) и статус задания (Status.xml). Эти файлы могут пригодиться для отладки и диагностики в том случае, если задание не отрабатывает должным образом.
Execution Policy
• Restricted — блокируется выполнение любых скриптов. Значение по умолчанию;
• AllSigned — разрешено выполнение скриптов, имеющих цифровую подпись;
• RemoteSigned — скрипты, подготовленные на локальном компьютере, можно запускать без ограничений, скрипты, загруженные из Интернета — только при наличии цифровой подписи;
• Unrestricted — разрешено выполнение любых скриптов. При запуске неподписанного скрипта, который был загружен из Интернета, программа может потребовать подтверждение;
• Bypass — ничего не блокируется, никакие предупреждения и запросы не появляются.
Примечание. Если указанная в команде политика выполнения противоречит групповой политике, то параметр запишется в реестр, но действовать не будет.
Measure-Command
Measures the time it takes to run script blocks and cmdlets.
Syntax
Description
The Measure-Command cmdlet runs a script block or cmdlet internally, times the execution of the operation, and returns the execution time.
Script blocks run by Measure-Command run in the current scope, not a child scope.
Examples
Example 1: Measure a command
This example measures the time it takes to run a Get-EventLog command that gets the events in the Windows PowerShell event log.
Example 2: Compare two outputs from Measure-Command
The second command measures the time it takes to process a recursive Get-ChildItem command that uses the provider-specific ` parameter.
These commands show the value of using a provider-specific filter in PowerShell commands.
Example 3: Piping input to Measure-Command
Objects that are piped to Measure-Command are available to the script block that is passed to the Expression parameter. The script block is executed once for each object on the pipeline.
Example 4: Displaying output of measured command
Example 5: Measuring execution in a child scope
Measure-Command runs the script block in the current scope, so the script block can modify values in the current scope. To avoid changes to the current scope, you must wrap the script block in braces ( <> ) and use the invocation operator ( & ) to execute the block in a child scope.
For more information about the invocation operator, see about_Operators.
Parameters
Specifies the expression that is being timed. Enclose the expression in braces ( <> ).
Type: | ScriptBlock |
Position: | 0 |
Default value: | None |
Accept pipeline input: | False |
Accept wildcard characters: | False |
Type: | PSObject |
Position: | Named |
Default value: | None |
Accept pipeline input: | True |
Accept wildcard characters: | False |
Inputs
Outputs
Measure-Command returns a time span object that represents the result.