|
Вопрос по лекции 7, где рассматривается взаимодействие со сторонними программами, в том числе эмуляция нажатия кнопок клавиатуры WshShell.SendKeys. Вопрос в том что во время автоматизации может потребоваться не нажатие клавиатуры, а нажатие кнопок в сообщениях этих программ. Можно вытащить информацию о объекте (кнопке) скажем с помощью AutoIt Info, или ориентироваться скажем на текст на кнопке..., но как на эту кнопку нажать? (без обхода по клавиатуре) |
Конвейеризация и управление выводом команд Windows PowerShell
Конвейеризация и управление выводом команд Windows PowerShell
Ранее в "лекции 2" мы рассматривали понятие конвейеризации (или композиции) команд интерпретатора Cmd.exe, когда выходной поток одной команды перенаправлялся во входной поток другой, объединяя тем самым две команды вместе. Подобные конвейеры команд используются в большинстве оболочек командной строки и являются средством, позволяющим передавать информацию между разными процессами.
Механизм композиции команд представляет собой, вероятно, наиболее ценную концепцию, используемую в интерфейсах командной строки. Конвейеры не только снижают усилия, прилагаемые при вводе сложных команд, но и облегчают отслеживание потока работы в командах. Полезной чертой конвейеров является то, что они не зависят от числа передаваемых элементов, так как конвейер действует на каждый элемент отдельно. Кроме того, каждая команда в конвейере (называемая элементом конвейера) обычно передает свой вывод следующей команде в конвейере, элемент за элементом. Благодаря этому, как правило, снижается потребление ресурсов для сложных команд и возникает возможность получать выводимую информацию немедленно.
В оболочке PowerShell также очень широко используется механизм конвейеризации команд, однако здесь по конвейеру передается не поток текста, как во всех других оболочках, а объекты. При этом с элементами конвейера можно производить различные манипуляции: фильтровать объекты по определенному критерию, сортировать и группировать объекты, изменять их структуру (ниже мы подробнее рассмотрим операции фильтрации и сортировки элементов конвейера).
Конвейеризация объектов в PowerShell
Конвейер в PowerShell – это последовательность команд, разделенных между собой знаком | (вертикальная черта). Каждая команда в конвейере получает объект от предыдущей команды, выполняет определенные операции над ним и передает следующей команде в конвейере. С точки зрения пользователя, объекты упаковывают связанную информацию в форму, в которой информацией проще манипулировать как единым блоком и из которой при необходимости извлекаются определенные элементы.
Передача данных между командами в виде объектов имеет большое преимущество над обычным обменом информацией посредством потока текста. Ведь команда, принимающая поток текста от другой утилиты, должна его проанализировать, разобрать и выделить нужную ей информацию, а это может быть непросто, так как обычно вывод команды больше ориентирован на визуальное восприятие человеком (это естественно для интерактивного режима работы), а не на удобство последующего синтаксического разбора.
При передаче по конвейеру объектов этой проблемы не возникает, здесь нужная информация извлекается из элемента конвейера простым обращением к соответствующему свойству объекта. Однако теперь возникает новый вопрос: каким образом узнать, какие именно свойства есть у объектов, передаваемых по конвейеру? Ведь при выполнении того или иного командлета мы на экране видим только одну или несколько колонок отформатированного текста. Например, запустим командлет Get-Process, который выводит информацию о запущенных в системе процессах:
PS C:\> Get-Process
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
158 11 45644 22084 126 159.69 2072 AcroRd32
98 5 1104 284 32 0.10 256 alg
39 1 364 364 17 0.26 1632 ati2evxx
57 3 1028 328 30 0.38 804 atiptaxx
434 6 2548 3680 27 21.96 800 csrss
64 3 812 604 29 0.22 1056 ctfmon
364 11 14120 9544 69 11.82 456 explorer
24 2 1532 2040 29 5.34 2532 FarФактически на экране мы видим только сводную информацию (результат форматирования полученных данных), а не полное представление выходного объекта. Из этой информации не понятно, сколько точно свойств имеется у объектов, генерируемых командой Get-Process, и какие имена имеют эти свойства. Например, мы хотим найти все "зависшие" процессы, которые не отвечают на запросы системы. Можно ли это сделать с помощью командлета Get-Process, какое свойство нужно проверять у выводимых объектов?
Для ответа на подобные вопросы нужно, прежде всего, научиться исследовать структуру объектов PowerShell, узнавать, какие свойства и методы имеются у этих объектов.
Просмотр структуры объектов
Для анализа структуры объекта, возвращаемого определенной командой, проще всего направить этот объект по конвейеру на командлет Get-Member (псевдоним gm ), например:
PS C:\> Get-Process | Get-Member
TypeName: System.Diagnostics.Process
Name MemberType Definition
---- ---------- ----------
Handles AliasProperty Handles = Handlecount
Name AliasProperty Name = ProcessName
NPM AliasProperty NPM = NonpagedSystemMemorySize
PM AliasProperty PM = PagedMemorySize
VM AliasProperty VM = VirtualMemorySize
WS AliasProperty WS = WorkingSet
. . .
Responding Property System.Boolean Responding {get;}
. . .Здесь мы видим имя .NET-класса, экземпляры которого возвращаются в ходе работы исследуемого командлета (в нашем примере это класс System.Diagnostic.Process), а также полный список элементов объекта (в частности, интересующее нас свойство Responding, определяющего "зависшие" процессы). При этом на экран выводится очень много элементов, просматривать их неудобно. Командлет Get-Member позволяет перечислить только те элементы объекта, которые являются его свойствами. Для этого используется параметр MemberType со значением Properties:
PS C:\> Get-Process | Get-Member -MemberType Property
TypeName: System.Diagnostics.Process
Name MemberType Definition
---- ---------- ----------
BasePriority Property System.Int32 BasePriority {get;}
Container Property System.ComponentModel.IContainer...
EnableRaisingEvents Property System.Boolean EnableRaisingEvents...
ExitCode Property System.Int32 ExitCode {get;}
ExitTime Property System.DateTime ExitTime {get;}
Handle Property System.IntPtr Handle {get;}
HandleCount Property System.Int32 HandleCount {get;}
HasExited Property System.Boolean HasExited {get;}
Id Property System.Int32 Id {get;}
MachineName Property System.String MachineName {get;}
. . .
Responding Property System.Boolean Responding {get;}
. . .Как мы видим, процессам операционной системы соответствуют объекты, имеющие очень много свойств, на экран же при работе командлета Get-Process выводятся лишь несколько из них (способы отображения объектов различных типов задаются конфигурационными файлами в формате XML, находящимися в каталоге, где установлен файл powershell.exe).
Теперь, когда мы знаем, какие свойства имеют объекты, передаваемые по конвейеру, перейдем к рассмотрению наиболее часто используемых операций над элементами конвейера: фильтрации и сортировки.
Фильтрация объектов в конвейере
В PowerShell поддерживается возможность фильтрации объектов в конвейере, т.е. удаление из конвейера объектов, не удовлетворяющих определенному условию. Данную функциональность обеспечивает командлет Where-Object, позволяющий проверить каждый объект, находящийся в конвейере, и передать его дальше по конвейеру, только если объект удовлетворяет условиям проверки.
Например, для вывода информации о "зависших" процессах (объекты, возвращаемые командлетом Get-Process, у которых свойство Responding равно False ) можно использовать следующий конвейер:
Get-Process | Where-Object {-not $_.Responding}Другой пример – оставим в конвейере только те процессы, у которых значение идентификатора (свойство Id ) больше 1000:
Get-Process | Where-Object {$_.Id -gt 1000}В блоках сценариев командлета Where-Object для обращения к текущему объекту конвейера и извлечения нужных свойств этого объекта используется специальная переменная $_, которая создается оболочкой PowerShell автоматически. Данная переменная используется и в других командлетах, производящих обработку элементов конвейера.
Условие проверки в Where-Object задается в виде блока сценария – одной или нескольких команд PowerShell, заключенных в фигурные скобки {}. Результатом выполнения данного блока сценария должно быть значение логического типа: True (истина) или False (ложь). Как можно понять из примеров, в блоке сценария используются специальные операторы сравнения.
Замечание
В PowerShell для операторов сравнения не используются обычные символы > или <, так как в командной строке они обычно означают перенаправление ввода/вывода.
Основные операторы сравнения приведены в табл. 17.1.
| Оператор | Значение | Пример (возвращается значение True) |
|---|---|---|
| -eq | равно | 10 -eq 10 |
| -ne | не равно | 9 -ne 10 |
| -lt | меньше | 3 -lt 4 |
| -le | меньше или равно | 3 –le 4 |
| -gt | больше | 4 -gt 3 |
| -ge | больше или равно | 4 -ge 3 |
| -like | сравнение на совпадение с учетом подстановочного знака в тексте | "file.doc" –like "f*.doc" |
| -notlike | сравнение на несовпадение с учетом подстановочного знака в тексте | "file.doc" –notlike "f*.rtf" |
| -contains | содержит | 1,2,3 –contains 1 |
| -notcontains | не содержит | 1,2,3 –notcontains 4 |
Операторы сравнения можно соединять друг с другом с помощью логических операторов (см. табл. 17.2).
| Оператор | Значение | Пример (возвращается значение True) |
|---|---|---|
| -and | логическое И | (10 -eq 10) –and (1 –eq 1) |
| -or | логическое ИЛИ | (9 -ne 10) –or (3 –eq 4) |
| -not | логическое НЕ | -not (3 –gt 4) |
| ! | логическое НЕ | !(3 -gt 4) |
Сортировка объектов
Сортировка элементов конвейера – еще одна операция, которая часто применяется при конвейерной обработке объектов. Данную операцию осуществляет командлет Sort-Object: ему передаются имена свойств, по которым нужно произвести сортировку, а он возвращает данные, упорядоченные по значениям этих свойств.
Например, для вывода списка запущенных в системе процессов, упорядоченного по затраченному процессорному времени (свойство cpu ), можно воспользоваться следующим конвейером:
PS C:\> Get-Process | Sort-Object cpu
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
0 0 0 16 0 0 Idle
36 2 728 32 23 0.05 1792 klswd
98 5 1104 764 32 0.09 252 alg
21 1 164 60 4 0.09 748 smss
30 2 672 724 27 0.11 1700 WinCinemaMgr
39 1 364 464 17 0.12 1644 ati2evxx
163 6 1536 1404 35 0.12 1612 svchost
55 3 1088 852 27 0.14 1220 svchost
22 2 504 712 23 0.14 772 winampa
120 4 2364 1228 35 0.26 1876 svchost
170 5 4516 796 44 0.27 1260 GoogleToolbarNotifier
193 5 2916 1488 59 0.29 1040 svchost
64 3 812 1080 29 0.30 1252 ctfmon
140 5 3208 1220 41 0.32 1524 spoolsv
281 14 1764 1688 37 0.34 1120 svchost
57 3 1028 996 30 0.39 932 atiptaxx
503 52 7296 3596 51 2.47 836 winlogon
259 6 1432 1340 19 2.48 880 services
341 8 3572 1856 40 5.36 892 lsass
240 158 29536 10388 175 5.58 1780 outpost
149 4 2940 1108 41 9.29 1248 kav
398 5 36140 26408 137 9.97 1984 powershell
375 12 15020 10456 75 14.03 1116 explorer
376 0 0 36 2 14.97 4 System
409 6 2500 3192 26 20.10 812 csrss
1513 54 13528 9800 95 25.78 1156 svchost
717 75 37432 704 145 56.97 1748 kavsvc
152 4 2372 2716 38 58.09 2028 wmiprvse
307 13 10952 27080 173 9128.03 1200 WINWORD
17.1.
Для сортировки в обратном порядке используется параметр Descending:
PS C:\> Get-Process | Sort-Object cpu -Descending
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
307 13 10956 27040 173 9152.23 1200 WINWORD
152 4 2372 2716 38 59.19 2028 wmiprvse
717 75 37432 1220 145 57.15 1748 kavsvc
1524 54 13528 9800 95 26.13 1156 svchost
410 6 2508 3224 26 20.62 812 csrss
376 0 0 36 2 15.11 4 System
377 13 15020 10464 75 14.20 1116 explorer
374 5 36484 26828 137 10.53 1984 powershell
149 4 2940 1108 41 9.34 1248 kav
240 158 29536 10388 175 5.61 1780 outpost
344 8 3572 1856 40 5.40 892 lsass
512 53 7324 3608 51 2.51 836 winlogon
259 6 1432 1340 19 2.48 880 services
57 3 1028 996 30 0.39 932 atiptaxx
281 14 1764 1688 37 0.34 1120 svchost
140 5 3208 1220 41 0.32 1524 spoolsv
64 3 812 1080 29 0.30 1252 ctfmon
193 5 2916 1488 59 0.29 1040 svchost
170 5 4516 796 44 0.27 1260 GoogleToolbarNotifier
120 4 2364 1228 35 0.26 1876 svchost
22 2 504 712 23 0.15 772 winampa
55 3 1088 852 27 0.14 1220 svchost
39 1 364 464 17 0.13 1644 ati2evxx
163 6 1536 1404 35 0.12 1612 svchost
30 2 672 724 27 0.11 1700 WinCinemaMgr
21 1 164 60 4 0.09 748 smss
98 5 1104 764 32 0.09 252 alg
36 2 728 32 23 0.05 1792 klswd
0 0 0 16 0 0 Idle
17.2.
В рассмотренных нами примерах конвейеры состояли из двух командлетов. Это не обязательное условие, конвейер может объединять и большее количество команд, например:
Get-Process | Where-Object {$_.Id -gt 1000} | Sort-Object cpu -Descending
