Перейти на главную страничку сайта (список статей, файлы для скачивания)

ФОРУМ (здесь можно обсудить эту статью, а также любые проблемы программирования на различных макроязыках и в скриптовых средах)

Обзор Windows Monad Shell (часть 2)

Данная статья является продолжением обзора Windows Monad Shell.

Monad Shell поддерживает понятие объектов и их методов:

MSH> $a = "a is for apple"
MSH> $a.SubString(2,2)

Доступ к статическим методам и свойствам:

MSH> [DateTime]::Now

Есть много методов строк (по умолчанию они работают с учётом регистра). Вот несколько примеров:

MSH> [String]::Concat("abcd", "efgh", "ijkl")

MSH> $a = "abcdabcdabcdabcd"
MSH> $a.Replace("ab","XY")

MSH> $a = "abcd abcd abcd abcd"
MSH> $a.Split(" ")

MSH> $a = "MnOP"
MSH> $a.ToUpper()

MSH> $a = "xxxxabcdxxx"
MSH> $a.Trim("x")
MSH> $a.TrimStart("x")
MSH> $a.TrimEnd("x")

Можно создавать объекты через команд-лет new-object:

new-object System.DateTime
new-object DateTime 2000,1,1,0,0,0

Подобным образом могут быть созданы и COM-объекты:

MSH> $ie = new-object -com internetexplorer.application
MSH> $ie.navigate2("http://www.msn.com/")
MSH> $ie.visible = $true

Однако, не все COM-объекты поддерживаются. Например, Collaboration Data Objects (CDO) не поддерживаются в данном релизе.

Пример использования .NET для создания графического интерфейса:

MSH> [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
MSH> $form = new-object system.windows.forms.form
MSH> $form.topmost = $true
MSH> $button = new-object system.windows.forms.button
MSH> $button.Dock = "Fill"
MSH> $button.Text = get-date
MSH> $button.Add_Click({$button.Text = get-date})
MSH> $form.Controls.add($button)
MSH> $form.showdialog()

Пример вызова функции Win32 API при помощи динамической генерации кода VB.NET:

$provider = new-object Microsoft.VisualBasic.VBCodeProvider
$params = new-object System.CodeDom.Compiler.CompilerParameters
$params.GenerateInMemory = $True
$refs = "System.dll", "Microsoft.VisualBasic.dll"
$params.ReferencedAssemblies.AddRange($refs)
$txtCode = '
Class Test
    Declare Auto Function MyMessageBox Lib "user32.dll" Alias _
    "MessageBox" (ByVal hWnd as Integer, ByVal msg as String, _
    ByVal Caption as String, ByVal Tpe as Integer) As Integer
    Sub Main()
        MyMessageBox(0, "Текст окна", "Заголовок окна", 0)
    End Sub
End Class
'
$results = $provider.CompileAssemblyFromSource($params, $txtCode)
$mAssembly = $results.CompiledAssembly
$i = $mAssembly.CreateInstance("Test")
$r = $i.main()

Блок сценария - совокупность инструкций или выражений, которые могут использоваться как отдельный модуль. Блоки сценария могут использоваться, например, чтобы создать произвольный код в середине конвейера. Обратите внимание, что вы должны использовать оператор вызова &, чтобы выполнить блок сценария:

MSH> Get-Process | &{ foreach ( $p in $input ) { $p.Id } }

Блоки сценария могут также быть присвоены переменной и затем выполнены:

MSH> $getid = { foreach ( $p in $input ) { $p.Id } }
MSH> Get-Process | &$getid

Рассмотрим работу с конвейерами. Например, если мы хотим разыскать все процессы, где handlecount больше, чем 400, можем написать следующее:

MSH> Get-Process | where { $_.handlecount -gt 400 } | Format-List

В этом примере команд-лет Get-Process передаёт объекты команд-лету Where-Object, который выбирает объекты со значением свойства handlecount большим, чем 400. Затем команд-лет Where-Object посылает найденные объекты команд-лету Format-List, чтобы они были отображены.

Если вы желаете создать строковую переменную, которая является названием команд-лета, и затем вычислить/выполнить команду, должны использоваться операторы "&" или "." (точка):

MSH> $cmd = "Get-Date"
MSH> $cmd
Get-Date
MSH> &$cmd
23 февраля 2006 г. 14:48:33
MSH> .$cmd
23 февраля 2006 г. 14:48:39

Объявление и вызов функций:

MSH> function add2numbers { [int]$args[0] + [int]$args[1] }
MSH> add2numbers 3 5
8

Параметры функции, если они не были явно объявлены, связаны c динамической локальной переменной $args. Ещё один пример функции:

MSH> function addnums
>> {
>> $local:result = 0
>> foreach ( $local:a in $args )
>> {
>> $result += $a
>> }
>> $result
>> }
>>
MSH> addnums 2 3 1
6

Параметры функции могут быть объявлены двумя способами: список переменных через запятую, заключенный в круглые скобки после имени функции, или с помощью ключевого слова param, которое должно быть первой инструкцией в функции.

MSH> function add2numbers
>> ([int]$x, [int]$y )
>> {
>>    $x + $y
>> }
>>
MSH> add2numbers 20 25
45
MSH> function add2numbers
>> {
>>     Param ([int]$x, [int]$y )
>>     $x + $y
>> }
>>
MSH> add2numbers 100 2
102

Чтобы просмотреть содержание функции или удалить функцию, используется диск function:

MSH> get-content function:add2numbers
MSH> remove-item function:add2numbers

Объявление параметров функции может не только гарантировать надлежащий тип, но и обеспечивать значения по умолчанию:

MSH> function add2numbers
>> {
>>     Param ( [int]$x = 0, [int]$y = 0 )
>>     $x + $y
>> }
>>
MSH> Add2numbers
0
MSH> Add2numbers 7
7

Один из самых полезных команд-летов - Get-Command. Этот команд-лет позволяет получить список всех доступных команд-летов. Учитываются подстановочные знаки, фильтры по глаголам или существительным. Например, вы можете напечатать такие команды:

Get-Command Get-*
Get-Command -Verb get
Get-Command -Noun process

Естественно, для получения информации по конкретному команд-лету вы можете использовать его полное название:

Get-Command Get-Location

Информация, возвращаемая Get-Command, является структурированными данными и может быть отображена в виде форматированного списка:

Get-Command Get-Location | Format-List *

Часть информации в этом выводе очень полезна; например, свойство Definition объекта содержит синтаксис вызова команд-лета:

(Get-Command Get-Process).Definition

Другой полезный команд-лет - Get-Member. Этот команд-лет позволяет вам получать свойства объектов, которые возвращены другим команд-летом. Например, чтобы получить свойства файла, используйте Get-ChildItem и передайте его вывод Get-Member:

Get-ChildItem | Get-Member -MemberType property

Флаг -MemberType указывает фильтр по типу члена. Например, получение методов объекта:

Get-ChildItem | Get-Member -MemberType method

Встроенные переменные

Оболочкой автоматически создаётся множество переменных:


$^ Содержит первую лексему последней введённой строки в оболочку.
$$ Содержит последнюю лексему последней введённой строки в оболочку.
$_ Текущий объект; используется в блоках сценария, фильтрах, операторах функций, в конструкциях where, foreach и switch.
$? Содержит состояние успеха/сбоя последней инструкции.
$Args Содержит параметры функции.
$Error Содержание произошедших ошибок.
$foreach Ссылка на итератор в цикле foreach.
$HOME Содержит каталог пользователя; аналог %HOMEDRIVE%\%HOMEPATH%.
$Input Конвейерный ввод к функции или блоку кода.
$Match Хеш-таблица, состоящая из элементов, найденных match-оператором.
$MyInvocation Информация о выполняющемся в настоящее время сценарии или командной строке.
$MshHome Каталог установки MSH.
$Host Информация о текущем хосте.
$LastExitCode Код завершения последнего приложения.
$true Булево TRUE.
$false Булево FALSE.
$null Объект NULL.
$OFS Разделитель, используемый при преобразовании массива к строке. По умолчанию - пробел.
$ShellID Идентификатор оболочки. Это значение используется оболочкой, чтобы определить ExecutionPolicy и профили, выполняемые при запуске.
$StackTrace Содержит детальный стек, прослеживающий информацию о последней ошибке.
$DebugPreference Определяет поведение при отладке. "SilentlyContinue", "NotifyContinue", "NotifyStop" или "Inquire".
$ErrorActionPreference Определяет поведение при ошибке. "SilentlyContinue", "NotifyContinue", "NotifyStop" или "Inquire".
$MaximumAliasCount Максимальное количество псевдонимов.
$MaximumDriveCount Максимальное количество дисков.
$MaximumErrorCount Максимальное количество ошибок в $Error.
$MaximumFunctionCount Максимальное количество функций, которое может быть создано.
$MaximumVariableCount Максимальное количество переменных, которое может быть создано.
$MaximumHistoryCount Максимальное количество команд, сохраняемых в истории команд.
$ReportErrorShowExceptionClass Истина указывает, что будет показано имя класса исключения. Значение по умолчанию - ложь.
$ReportErrorShowInnerException Истина указывает, что нужно показать цепочку внутренних исключений. Значение по умолчанию - ложь.
$ReportErrorShowSource Истина указывает, что будет показана сборка (assembly), породившая исключение. Значение по умолчанию - истина.
$ReportErrorShowStackTrace Истина указывает, что будет осуществлена трассировка стека исключения. Значение по умолчанию - ложь.
$ShouldProcessPreference Определяет поведение при использовании ShouldProcess в команд-лете. "SilentlyContinue", "NotifyContinue", "NotifyStop" или "Inquire".
$ProcessReturnPreference ShouldProcess возвратит эту установку.
$ProgressPreference Определяет поведение при использовании Write-Progress. "SilentlyContinue", "NotifyContinue", "NotifyStop" или "Inquire".
$VerbosePreference Определяет поведение при использовании Write-Verbose. "SilentlyContinue", "NotifyContinue", "NotifyStop" или "Inquire".

Безопасность оболочки и скриптов

MSH Shell обеспечивает возможность в цифровой форме подписать сценарии, чтобы гарантировать, что сценарий не был изменен со времени его подписания. Через конфигурацию оболочки возможно выполнять только сценарии, имеющие цифровую подпись. MSH Shell обеспечивает диск сертификатов, где хранятся цифровые удостоверения. Можно сделать запрос и получить сертификат, который может использоваться, чтобы подписать код. Если файл был изменен, сценарий больше не будет выполняться.

get-childitem cert: -recurse -codesigning

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

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSH\1\ShellIds\Microsoft.Management.Automation.msh\ExecutionPolicy

Возможные значения ключа:

Пример запуска msh-скрипта:

MSH C:\Documents and Settings\USER1> ./Test.msh

Параметры -WhatIf и -Confirm позволяют получить информацию о том, что произойдёт в случае выполнения какой-либо команды, и потребовать дополнительного подтверждения соответственно. Примеры:

get-process c* | stop-process –whatif
get-process c* | stop-process -confirm

Команды-утилиты

Where-Object обеспечивает способ выбрать объекты на основании их свойств и значений. Этот команд-лет берёт как параметр выражение и использует его, чтобы фильтровать объектный поток. Например, чтобы отобрать только те процессы в системе, которые имеют подстроку "cs" в их именах, используйте следующий конвейер:

Get-Process | where { $_.processname -like "*cs*" }

Sort-Object обеспечивает мультиключевую сортировку, где каждый ключ может быть отсортирован по возрастанию или убыванию:

Get-ChildItem | Sort-Object @{ e = { $_.extension }; asc = $false }, @{ e = { $_.length }; asc = $true }

Group-Object преобразовывает поток объектов в поток групп. Каждая группа имеет свойство COUNT, которое определяет, сколько объектов находится в этой группе, свойство GROUP, содержащее все объекты в той группе, строку NAME с представлением значения свойства и коллекцию значений VALUES:

Get-Process | Group-Object { $_.mainmodule.fileversioninfo.companyname }

Select-Object обеспечивает способ выбрать специфические свойства потока объектов и развернуть коллекции:

Get-Process | Select-Object ProcessName –Expand modules | Format-Table Processname, FileName

Foreach-Object обеспечивает способ управлять отдельными объектами в потоке. Подобно Where-Object, переменная $_ привязана к текущему объекту. Например, определить сумму специфического свойства в потоке объектов можно следующим образом:

Get-Process | foreach-object {$t=0} {$t += $_.Handlecount} {"Total is $t"}

Measure-Object обеспечивает способ вычислить сумму или другую статистическую информацию свойства:

Get-Process | Measure-Object –property handlecount,workingset

Людоговский Александр

Перейти на главную страничку сайта (список статей, файлы для скачивания)

© 2007 http://www.script-coding.com При любом использовании материалов сайта обязательна ссылка на него как на источник информации, а также сохранение целостности и авторства материалов.