Главная

Tuesday, 13 September 2016

Эффективное программирование в Windows PowerShell.

Всем привет.

Чтение умной книжки "Keith Hill, Эффективное программирование в Windows PowerShell. 2009" завершено. Советую всем! Неординарный материал по PowerShell. А я, как и обещал, покажу вам самое интересное из этой книги.

Три кита получения информации о командах PowerShell.

Get-Command показывает команды с совпадающими именами в том порядке, в котором PowerShell их будет выполнять. Если Get-Help не сможет обнаружить название раздела справочной системы с заданным именем, он выведет список разделов, в которых обнаружит заданное слово. Get-Member больше не выводит по умолчанию методы, генерируемые компилятором (наподобие get_Name/set_Name). Если вам необходимо вывести эти методы, используйте параметр –Force. 

Консоль PowerShell создаёт иллюзию, что вы работаете с текстом - на самом деле вы имеете дело с .NET-объектами, даже если они представлены текстом. Вы часто имеете дело с объектами, содержащими больше информации, чем System.String и часто эти объекты содержат необходимую вам информацию в виде свойств. Можно извлекать эту информацию, не прибегая к помощи синтаксического разбора текста.

Журналирование вывода PowerShell через Start-Transcript.

Имейте ввиду что не весь вывод PowerShell может быть захвачен через Start-Transcript.
Вот список типов вывода, которые не могут быть захвачены, кроме как используя Start-Transcript:

1.Прямой вывод на экран с использованием Write-Host & Out-Host.
2.Вывод отладочной информации в консоль с помощью Write-Debug или параметра -Debug командлета.
3.Вывод предупреждающих сообщений с помощью Write-Warning.
4.Вывод дополнительных подробных сведений, которые могут осуществлять многие командлеты при указании параметра -Verbose.
5.Потоки stdout или stderr непосредственно исполняемого файла.

Просто всегда помните о том, что операторы и выражения участвуют в выводе функций в PowerShell. Вы должны всегда проверять, что вывод происходит именно так, как вы планировали. 


Удобный онлайн фильтр для определения типа объекта.

Выглядит он вот так.
PS> filter Get-TypeName {if ($_ -eq $null) {'<null>'} else {$_.GetType().Fullname }}

А так используется.
PS> Get-Date | Get-TypeName
System.DateTime

Он требует подключения PowerShell Community Extensions (version 3.2.0.0) в вашем профиле.
>Import-Module Pscx -arg ~\Pscx.UserPreferences.ps1

Т.е. при отладке передачи объектов по конвейеру, используйте Get-Member, чтобы узнать свойства и методы, доступные для этих объектов. Используйте Format-List *, чтобы узнать значения свойств объектов. И используйте наш небольшой, но полезный фильтр, показывающий тип каждого объекта, проходящего через элемент конвейера в том порядке, в каком увидит их следующий командлет. 

Лучший метод форматирования для исследования вывода PowerShell. 

Вы наверняка заметили, что содержание некоторых колонок при стандартном выводе обрезается. Если необходимо вывести их полное содержание, используйте командлет Format-List. Этот командлет выводит различные значения свойств в отдельных строках, так что данные редко сокращаются. Например: 

PS> Get-Date | Get-Member -Name DateTime | Format-List
TypeName : System.DateTime
Name : DateTime
MemberType : ScriptProperty
Definition : System.Object DateTime {get=if ($this.DisplayHint -ieq "Date") 
"{0}" -f $this.ToLongDateString() 
elseif ($this.DisplayHint -ieq "Time") 
"{0}" -f $this.ToLongTimeString() 
else 
"{0} {1}" -f $this.ToLongDateString(), $this.ToLongTimeString() 
};}

Теперь мы видим полное определение свойств DateTime. Замечание: часто PowerShell выводит сокращённый набор значений свойств с помощью командлета Format-List. Это делается для того, чтобы отсекать обычно ненужную информацию. Однако, если вам необходим самый подробный вывод всех деталей, используйте этот командлет так: "format-list *". 

Запуск других приложений из PowerShell.

PS> & 'C:\Program Files\Windows NT\Accessories\wordpad.exe'

Внимание: пример выше показывает, что PowerShell анализирует первый не пустой символ в строке для определения, в каком режиме строка будет обработана. Любой из нижеприведённых символов переводит PowerShell в режим команд:
[_aA-zZ]
&
.
\
У этого правила есть одно исключение - если строка начинается с ключевого слова (if, do, while, foreach и т. д.), PowerShell переходит в режим выражений и будет ожидать оставшуюся часть выражения, связанную с этим ключевым словом.

Преимущества командного режима:
•Строка не нуждается в обрамлении кавычками, если она не содержит пробелы
•Числа обрабатываются как числа, все другие аргументы - как строки, за исключением тех, которые начинаются с @, $, (, ' или ". Числа интерпретируются как Int32, Int64, Double или Decimal в зависимости от их написания и величины, необходимой для хранения числа, например, 12, 30GB, 1E-3, 100.01d.

Ну, как я уже говорил, необходимо иметь возможность оценки выражений, таких, как это:
PS> 64-2
62

Не удивительно, что некоторые оболочки могут интерпретировать это выражение, например, попытавшись выполнить команду с именем '64-2'. Как же PowerShell определяет, что строку необходимо анализировать в режиме выражений? Если строка начинается с цифры, или одного из этих знаков - @, $, (, ' или " - строка разбирается в режиме выражений. Преимущества этого режима: 
•Устранение возможности неверного толкования команд как строк, например, del -recurse * - это команда, а "del -recurse *" - это строка.
•Прямое указание арифметических операций и сопоставления выражений, например 64-2 (62) и $array.count -gt 100. В режиме команд -gt интерпретировалось бы как параметр, если предыдущая лексема соответствует верной команде.

Чем различаются выражения группировки (), подвыражения $() и подвыражения массива @()? Выражение группировки может содержать лишь простое выражение или простой конвейер. Подвыражение может содержать несколько операторов, разделённых точкой с запятой. Вывод каждого оператора передаётся на вывод подвыражения, который может быть скаляром, коллекцией или пустым множеством. Массив подвыражений ведет себя точно так же, как подвыражение, за исключением того, что он гарантирует, что выводом будет массив. Два случая, имеющих различия:
1.Когда массив не имеет вывода, подвыражение вернёт пустой массив.
2.Если результатом является скалярное значение, будет выведен массив с одним элементом, содержащим скалярную величину.

И будет не лишним использование Trace-Command для жесткого контроля корректности набора команд в PowerShell.

Разумеется в книге еще много интересного!

Успехов вам.

No comments:

Post a Comment

А что вы думаете по этому поводу?