Вышла третья ознакомительная версия PowerShell 2.0. Комментарий powershell


Включайте в сценарии PowerShell справочную информацию | Windows IT Pro/RE

Один из самых эффективных инструментов, которые помогают пользователям изучать механизмы оболочки PowerShell, — ее справочная система, и в первую очередь — команда Get-Help. Для изучающих среду PowerShell это одна из трех ключевых команд (остальные две — команды Get-Command и Get-Member). Если вам когда-либо доводилось работать с технологией PowerShell, вы, скорее всего, использовали команду Get-Help (или один из ее псевдонимов — help и man).

Справочная система загружается автоматически в ходе установки оболочки PowerShell, но если вы работаете с третьей или более новой версией этого продукта, не забудьте выполнить команду Update-Help при первом запуске PowerShell и регулярно запускать ее в дальнейшем. Дело в том, что Microsoft постоянно добавляет в справочную систему новые темы и исправляет ошибки в существующих темах, обнаруженные сотрудниками компании, а также другими пользователями. Предоставляя возможность выполнять команду Update-Help на вашей системе, Microsoft позволяет вам экономить значительную часть дискового пространства: ведь на вашу машину загружаются средства поддержки лишь того языка, который вы определили для своей системы, а не для всех языков, которые, возможно, указала система.

Сценарий PowerShell Get-Help

Однако помощь, получаемая вами от PowerShell, — это еще не все. Взяв за основу справочную функцию на базе комментариев, реализованную разработчиками во второй версии PowerShell, вы можете предоставить такую же помощь будущим пользователям написанных вами функций и сценариев. В этой версии добавлена возможность включения в сценарии многострочных комментариев. В качестве разделителей этих комментариев применяются пары символов ''. Используются они следующим образом:

# Любой однострочный комментарий

Сюда может быть включено любое число комментариев.

#>

Как применять справочную информацию

И как же использовать справочные данные в соответствии с вашим замыслом? В сущности все довольно просто. Достаточно определить в комментарии несколько ключевых слов и поместить комментарий в начало вашего сценария или в начало функции, и тогда каждый, кто будет пользоваться этим сценарием или функцией, сможет получить помощь точно таким же образом, каким вы получали нужные сведения с помощью команды Get-Help.

Ключевые слова, которые вы будете использовать, называются тегами. Я применяю такие базовые теги:. SYNOPSIS,. DESCRIPTION и. EXAMPLE. Тег. SYNOPSIS позволяет дать краткое определение задачи, выполняемой сценарием или функцией. Тег. DESCRIPTION дает возможность представить более детальные сведения, а тег. EXAMPLE позволяет привести примеры применения вашего сценария или функции с тем, чтобы пользователь понял, как следует должным образом их вызывать. Ниже помещается раздел комментариев из сценария, который я использую для того, чтобы присвоить владельцам всех баз данных имя 'sa'.

Вы также можете применять такие теги, как. PARAMETER для описания параметров, используемых в вашем коде,. INPUTS для описания типов объектов, которые могут быть переданы в ваш код по конвейеру, или. OUTPUTS для описания объектов, передаваемых на конвейер,. NOTES для передачи дополнительной информации,. LINK для передачи ссылок на дополнительные источники и т.д.

Сценарий PowerShell get-Help Set-Database

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

www.osp.ru

Вышла третья ознакомительная версия PowerShell 2.0

Корпорация Microsoft недавно выпустила третью ознакомительную версию PowerShell 2.0. Она значительно усовершенствована по сравнению с предыдущей и дает все основания надеяться, что PowerShell 2.0 в конечном итоге превратится в надежный инструмент системного администрирования, располагающий богатым набором функций уровня предприятия, которые так актуальны для многих организаций. В этой статье Скотт Лоу (Scott Lowe) рассказывает об основных особенностях новой версии.

Хотя версия 2.0 знаменитого языка сценариев Microsoft PowerShell не дошла еще даже до бета-тестирования, разработчики на днях выпустили уже третью ознакомительную версию оболочки. Хочу уточнить: ознакомительная версия – это ни в коем случае не бета. Она предназначена, как и следует из названия, только для ознакомления с новой технологией, а потому может существенно отличаться от окончательной версии по функциональности. Microsoft особо подчеркивает, что ознакомительные версии не предназначены для повседневного использования и могут иметь радиальные отличия от конечного продукта. Короче говоря, не стоит строить свои расчеты исходя из ознакомительной версии, а потом жаловаться, что расчеты не оправдались.

Что нам готовит PowerShell 2.0?

PowerShell 2.0 предлагает богатый набор новых функций, призванных сделать эту версию более мощной и простой в обращении, чем PowerShell 1.0. Ниже я расскажу об основных преимуществах новой версии.

ISE

Самое заметное отличие PowerShell 2.0 от предыдущей версии – наличие интегрированной среды построения сценариев Windows PowerShell (Integrated Scripting Environment, ISE). ISE – это утилита с графическим интерфейсом, которая делает процесс создания и изменения сценариев PowerShell намного проще и удобнее. Разумеется, для этого существуют и приложения сторонних производителей вроде PowerGUI от Quest, но все-таки приятно, что теперь и разработчики PowerShell взялись за дело.

Снимок PowerShell 2.0 ISE

Удаленная работа

В PowerShell 2.0 значительно расширены возможности применения сценариев PowerShell к удаленным системам. Если коротко, администратор получает возможность со своего собственного компьютера направлять команды PowerShell, которые выполняются на удаленных станциях и выводят результаты на экран администратора. Разумеется, для этого на удаленных системах тоже должен быть установлен PowerShell. Прелесть PowerShell 2.0 в том, что удаленные пользователи не видят визуальных признаков выполнения процессов PowerShell – они отражаются только в Диспетчере задач (Task Manager). Согласитесь, если бы посреди рабочего дня на компьютерах ничего не подозревающих удаленных пользователей вдруг ни с того, ни с сего начали бы выскакивать окна непонятных приложений, существование отдела технической поддержки превратилось бы в ад!

Фоновый режим

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

Транзакции

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

Многострочные комментарии

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

Новые командлеты, параметры, переменные и операторы

Поскольку PowerShell 2.0 – это новая полномасштабная версия языка, в нее включено множество новых командлетов, новых параметров для уже существующих командлетов, новых переменных и операторов. Например, операторы -Split и -Join позволяют при определенных условиях разбивать или объединять строки. Появились новые командлеты для обслуживания транзакций (Start-PSTransaction, Undo-PSTransaction) и задач, выполняемых в фоновом режиме (Start-PSJob, Stop-PSJob), а также для поддержки новых функций отладки PowerShell 2.0 (Set-PSBreakpoint, Get-PSBreakpoint). У старых командлетов, как я уже упоминал, появились новые параметры. Например, у Stop-Process — параметр -force, а у Export-Csv – параметр -Delimiter, позволяющий указать символы для применения. Большинство новых командлетов и параметров предназначено для обслуживания новых функций PowerShell, но многие из них были введены для того, чтобы сделать язык в целом более надежным.

Заключение

PowerShell 2.0 находится в разработке уже давно, и судя по третьей ознакомительной версии, этот замечательный язык сценариев движется в правильном направлении.

Автор: Scott LoweПеревод: SVET

Оцените статью: Голосов 0

www.winblog.ru

Сценарии в Windows PowerShell | вебисторий

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

Третьим типом команд в PowerShell являются сценарии. Сценарий это блок кода, хранящийся в отдельном файле с расширением .ps1. Это основное преимущество сценариев, так как можно сохранить код, избавив себя от необходимости набирать его каждый раз вручную.

Сценарии можно писать в любом текстовом редакторе, главное, сохранить написанное в файле с расширением .ps1. Сценарий можно написать и в консоли, скопировав затем текст в редактор и сохранив. Между тем, в PowerShell уже есть интегрированная среда сценариев, упрощающая написание.

Это важно!

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

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

Get-ExecutionPolicy

в PowerShell.

Проверка политики безопасности в Windows PowerShell

Если у Вас действует строгая политика безопасности уровня Restricted или AllSigned, то Вам придется сменить её командой

Set-ExecutionPolicy RemoteSigned

Теперь напишем наш первый сценарий. Для написания сценариев будем использовать Windows PowerShell ISE, окно с которым Вы уже видели на скриншоте выше. Наберем в верхнем окне какой-нибудь текст

И сохраним это через Файл → Сохранить как. Я, не мудрствуя лукаво, обозвал файл просто primer и поместил его в корень диска C.

Теперь запустим наш файл. Для этого перейдем в каталог с файлом командой

cd C:\

и запустим

.\primer

Обратите внимание, точка важна, так как она показывает, что файл нужно запускать из текущего каталога.

Пример выполнения сценария в Windows PowerShell

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

Сценарий можно запустить и из обычной командной сроки Windows (не Windows PowerShell). Для этого перед путем к файлу сценария дописываем параметр powershell.exe. Например, в моем случае

powershell.exe C:\primer.ps1

Что касается кода, то сценарии, в общем-то, аналогичны функциям. Существенное отличие, которое нужно знать при написании сценариев, так это то, что формальные параметры нельзя задавать просто в круглых скобках. Для задания формальных параметров нужно воспользоваться специальной инструкцией Param. Эта инструкция должна располагаться на самом верху файла сценария (выше могут быть только пустые строки и комментарии).

Изменим наш файл primer так, как показано на рисунке ниже.

Формальные параметры в сценариях Windows PowerShell

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

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

# Это комментарий ############################################## # Это тоже комментарий # в сценарии Windows PowerShell ##############################################

Итак, как Вы уже могли убедиться Windows PowerShell обладает собственным скриптовым языком. В следующей статье поговорим о последнем типе команд.

webistore.ru

PowerShell скрипты - Get-PowerShell

Всем добрый день.

Речь пойдет о создании своих собственных скриптов на PowerShell. Прежде всего параметризованных скриптов.

Простые PowerShell скрипты

Но для начала разберемся с тем, что такое скрипт. Вот пример:

Get-ADComputer -Filter * | Where-Object -FilterScript {$_.DistinguishedName -like "*OU=Marketing,*"} | Select-Object -ExpandProperty Name | Out-File c:\test.txt

Get-ADComputer -Filter * | Where-Object -FilterScript {$_.DistinguishedName -like "*OU=Marketing,*"} | Select-Object -ExpandProperty Name | Out-File c:\test.txt

Данный код, если его запустить, запишет в файл c:\test.txt список компьютеров AD, находящихся в подразделении Marketing.

Вы можете написать свою команду или последовательность команд сохранить их в текстовом файле с расширением ps1. И этот файл и будет скриптом PowerShell или сценарием PowerShell. После этого в командной строке PowerShell вы можете выполнить данный скрипт и PowerShell выполнит команды, написанные в нем. Однако необходимо помнить про ExecutionPolicy.

Вернемся к нашему примеру, давайте я сохраню его в файле Get-Comp.ps1. Как вы думаете, как часто мне в таком виде придется запускать скрипт? Лично я думаю не часто. Причина простая — в этом коде нет универсальности. Т.е. если мне понадобиться вывести в другой файл компьютеры из другого подразделения, тогда увы я вынужден буду изменить данный скрипт. И поверьте мне эта процедура не так проста как кажется, во-первых, изменяемые данные могут находиться в любой части скрипта и найти их может быть не так просто, во-вторых,  обычно, для редактирования сложных скриптов используется специальный редактор PowerShell ISE, который запускается не так быстро как хотелось бы, в-третьих, вам, возможно, каждый раз придется подписывать ваш скрипт заново.

Поэтому вам необходимо выделить в вашем скрипте значения, которые могут изменяться при каждом запуске, и заменить их переменными. Например, так:

Get-ADComputer -Filter * | Where-Object -FilterScript {$_.DistinguishedName -like "*OU=$OrganizationalUnit,*"} | Select-Object -ExpandProperty Name | Out-File $File

Get-ADComputer -Filter * | Where-Object -FilterScript {$_.DistinguishedName -like "*OU=$OrganizationalUnit,*"} | Select-Object -ExpandProperty Name | Out-File $File

Конечно, после этого вы можете легко написать что-то вроде этого:

$OrganizationalUnit='Marketing' $File='c:\Test.txt' Get-ADComputer -Filter * | Where-Object -FilterScript {$_.DistinguishedName -like "*OU=$OrganizationalUnit,*"} | Select-Object -ExpandProperty Name | Out-File $File

$OrganizationalUnit='Marketing'

$File='c:\Test.txt'

Get-ADComputer -Filter * | Where-Object -FilterScript {$_.DistinguishedName -like "*OU=$OrganizationalUnit,*"} | Select-Object -ExpandProperty Name | Out-File $File

Однако, это совершенно не избавит вас от необходимости редактировать скрипт перед запуском. И я так делал. И поверьте, моя лень написать две лишних строчки стоила мне очень много времени, которые я потратил на десятки изменений файла. Поэтому, если вы начали так делать, доведите процесс до конца — напишите параметризированный скрипт.

Параметризированный скрипт

Все что нам понадобится это дописать ключевое слово param и поставить запятые между объявлением переменных:

Param ( $OrganizationalUnit='Marketing', $File='c:\Test.txt' ) Get-ADComputer -Filter * | Where-Object -FilterScript {$_.DistinguishedName -like "*OU=$OrganizationalUnit,*"} | Select-Object -ExpandProperty Name | Out-File $File

Param

(

  $OrganizationalUnit='Marketing',

  $File='c:\Test.txt'

)

Get-ADComputer -Filter * | Where-Object -FilterScript {$_.DistinguishedName -like "*OU=$OrganizationalUnit,*"} | Select-Object -ExpandProperty Name | Out-File $File

После этого в командной строке я могу выполнить данный скрипт следующим образом:

PS E:\> .\Get-Comp.ps1 PS E:\> .\Get-Comp.ps1 -File 'E:\Test.txt' PS E:\> .\Get-Comp.ps1 -OrganizationalUnit 'Sales' PS E:\> .\Get-Comp.ps1 -OrganizationalUnit 'Sales' -File 'E:\Test.txt'

PS E:\> .\Get-Comp.ps1

PS E:\> .\Get-Comp.ps1 -File 'E:\Test.txt'

PS E:\> .\Get-Comp.ps1 -OrganizationalUnit 'Sales'

PS E:\> .\Get-Comp.ps1 -OrganizationalUnit 'Sales' -File 'E:\Test.txt'

Первая строчка запишет список компьютеров в подразделении Marketing в файл c:\test.txt. Вторая строчка запишет список компьютеров в подразделении Marketing в файл e:\test.txt. Третья строчка запишет список компьютеров в подразделении Sales в файл c:\test.txt. Четвертая строчка запишет список компьютеров в подразделении Sales в файл e:\test.txt. Другими словами, если параметр не указан, его значение возьмется из указанных в файле.

Проблема в том, что можно и так:

PS E:\> .\Get-Comp.ps1 -OU 'Sales' -TextFile 'E:\Test.txt'

PS E:\> .\Get-Comp.ps1 -OU 'Sales' -TextFile 'E:\Test.txt'

В этом случае PowerShell не обнаружит ни каких ошибок, данные параметры проигнорирует, а значения параметров возьмет из файла. Как долго ваш коллега будет думать почему не создался файл e:\test.txt?

Чтобы обеспечить проверку параметров, возможность использовать общие параметры (-Verbose, -ErrorAction) и другие дополнительные возможности по работе с параметрами, необходимо в начало нашего скрипта поставить [CmdletBinding()]

[CmdletBinding()] Param ( $OrganizationalUnit='Marketing', $File='c:\Test.txt' ) Get-ADComputer -Filter * | Where-Object -FilterScript {$_.DistinguishedName -like "*OU=$OrganizationalUnit,*"} | Select-Object -ExpandProperty Name | Out-File $File

[CmdletBinding()]

Param

(

  $OrganizationalUnit='Marketing',

  $File='c:\Test.txt'

)

Get-ADComputer -Filter * | Where-Object -FilterScript {$_.DistinguishedName -like "*OU=$OrganizationalUnit,*"} | Select-Object -ExpandProperty Name | Out-File $File

Теперь пример с неверным указанием параметров не сработает и вернет ошибку.

В общем-то на этом все. Если вы будете использовать функционал описанный выше ваш скрипт можно назвать параметризованным.

Ниже я приведу несколько советов, особо не описывая их.

Несколько полезных советов

1. Указание типа значения параметра. Полезно для контроля ввода:

Param ( [string]$OrganizationalUnit='Marketing', [string]$File='c:\Test.txt', [int]$count=8 )

Param (

  [string]$OrganizationalUnit='Marketing',

  [string]$File='c:\Test.txt',

  [int]$count=8

)

2. Указание какие параметры являются обязательными (нужно их указывать при запуске или нет). По умолчанию все параметры являются опциональными, т.е. их можно не указывать. Если вы указали, что параметр является обязательным, то его значение по умолчанию можно не указывать.

Param ( [parameter(Mandatory=$true)] [string]$OrganizationalUnit, [string]$File='c:\Test.txt', [parameter(Mandatory=$true)] [int]$Сount=8 )

Param (

  [parameter(Mandatory=$true)]

  [string]$OrganizationalUnit,

  [string]$File='c:\Test.txt',

  [parameter(Mandatory=$true)]

  [int]$Сount=8

)

3. Указания сообщения для ввода. Если не указать обязательный параметр при запуске скрипта, то PowerShell предложит его ввести. Можно указать текст приглашения для ввода данного параметра.

Param ( [parameter(Mandatory=$true,HelpMessage="Enter name of organizational unit")] [string]$OrganizationalUnit, [string]$File='c:\Test.txt', [parameter(Mandatory=$true,HelpMessage="Enter computers count")] [int]$Сount=8 )

Param (

  [parameter(Mandatory=$true,HelpMessage="Enter name of organizational unit")]

  [string]$OrganizationalUnit,

  [string]$File='c:\Test.txt',

  [parameter(Mandatory=$true,HelpMessage="Enter computers count")]

  [int]$Сount=8

)

4. Отключение позиционных параметров. По умолчанию все параметры позиционные, т.е. вы можете не указывать при запуске имя параметра, а просто указать его значение. При этом PowerShell будет определять к какому параметру соотносится каждый аргумент по порядковому номеру аргумента. Например, так:

PS E:\> .\Get-Comp.ps1 'Sales' 'E:\Test.txt'

PS E:\> .\Get-Comp.ps1 'Sales' 'E:\Test.txt'

Однако лучше эту возможность выключить и «ручками» указать какие параметры должны быть позиционными и на каком месте должен стоять аргумент для данного параметра.

[CmdletBinding(PositionalBinding=$false)] Param ( [parameter(Mandatory=$true,Position=0)] [string]$OrganizationalUnit, [string]$File='c:\Test.txt', [parameter(Position=1)] [int]$Сount=8 )

[CmdletBinding(PositionalBinding=$false)]

Param (

  [parameter(Mandatory=$true,Position=0)]

  [string]$OrganizationalUnit,

  [string]$File='c:\Test.txt',

  [parameter(Position=1)]

  [int]$Сount=8

)

5. Переключатели. Если вам необходимо использовать параметры типа boolean, то лучше вместо них использовать переключатели. Если параметр указан, то его значение истина, если опущен тогда ложь.

Param ( [parameter(Mandatory=$true)] [string]$OrganizationalUnit, [string]$File='c:\Test.txt', [parameter(Mandatory=$false)] [Switch]$OnlyEnabled )

Param (

  [parameter(Mandatory=$true)]

  [string]$OrganizationalUnit,

  [string]$File='c:\Test.txt',

  [parameter(Mandatory=$false)]

  [Switch]$OnlyEnabled

)

6. Ввод значений с конвейера. Реализовать ввод значений с конвейера (PipeLine) можно двумя путями через значение (ValueFromPipeline=$true) или через имя свойства (ValueFromPipelineByPropertyName=$true).

Param ( [parameter(Mandatory=$true,ValueFromPipeline=$true)] [string]$OrganizationalUnit, [string]$File='c:\Test.txt' )

Param (

  [parameter(Mandatory=$true,ValueFromPipeline=$true)]

  [string]$OrganizationalUnit,

  [string]$File='c:\Test.txt'

)

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

Param ( [parameter(Mandatory=$true)] [ValidateRange(0,10)] [Int]$Сount )

Param (

  [parameter(Mandatory=$true)]

  [ValidateRange(0,10)]

  [Int]$Сount

)

Дополнительно почитать

1. Get-Help about_Functions_Advanced_Parameters -Online2. Get-Help about_Functions_CmdletBindingAttribute -Online

get-powershell.ru

Try или обработка ошибок PowerShell

Вообще я редко вижу смысл в том чтобы отлавливать ошибки в скриптах, но недавно ко мне попалась задача, где необходимо было обработать ошибки в скрипте PowerShell. Дело в том что данный скрипт использовался как часть работы System Center Orchestrator. Для этого я использовал Try/Catch/Finaly . Но все по порядку.

Немного про ошибки

Ошибки можно условно разделить на две больших категории.

  1. Прерывающие
  2. Не прерывающие

Первые завершают выполнение конвейера с ошибкой. Т.е. дальнейшие команды в конвейере не выполняются. Например, вы не правильно указали имя команды. Вторая категория лишь генерирует ошибку, но конвейер продолжает выполняться далее. Например, вы запросили содержимое не существующего каталога.

В любом случае всю информацию о всех ошибках можно поглядеть в переменной $error. Последняя ошибка идет с индексом 0, т.е. $error[0] — покажет последнюю ошибку. А $error[0].Exception описание последней ошибки.

PS C:\> Get-Command NoCommand,Dir Get-Command : Имя "NoCommand" не распознано как имя командлета, функции, файла сценария или выполняемой программы. Пров ерьте правильность написания имени, а также наличие и правильность пути, после чего повторите попытку. строка:1 знак:1 + Get-Command NoCommand,Dir + ~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (NoCommand:String) [Get-Command], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand CommandType Name ModuleName ----------- ---- ---------- Alias dir -> Get-ChildItem PS C:\> $error[0] Get-Command : Имя "NoCommand" не распознано как имя командлета, функции, файла сценария или выполняемой программы. Пров ерьте правильность написания имени, а также наличие и правильность пути, после чего повторите попытку. строка:1 знак:1 + Get-Command NoCommand,Dir + ~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (NoCommand:String) [Get-Command], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand PS C:\> $error[0].Exception Имя "NoCommand" не распознано как имя командлета, функции, файла сценария или выполняемой программы. Проверьте правильн ость написания имени, а также наличие и правильность пути, после чего повторите попытку.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

PS C:\> Get-Command NoCommand,Dir

Get-Command : Имя "NoCommand" не распознано как имя командлета, функции, файла сценария или выполняемой программы. Пров

ерьте правильность написания имени, а также наличие и правильность пути, после чего повторите попытку.

строка:1 знак:1

+ Get-Command NoCommand,Dir

+ ~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : ObjectNotFound: (NoCommand:String) [Get-Command], CommandNotFoundException

    + FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand

 

 

CommandType     Name                                               ModuleName

-----------     ----                                               ----------

Alias           dir -> Get-ChildItem

 

 

PS C:\> $error[0]

Get-Command : Имя "NoCommand" не распознано как имя командлета, функции, файла сценария или выполняемой программы. Пров

ерьте правильность написания имени, а также наличие и правильность пути, после чего повторите попытку.

строка:1 знак:1

+ Get-Command NoCommand,Dir

+ ~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : ObjectNotFound: (NoCommand:String) [Get-Command], CommandNotFoundException

    + FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand

 

PS C:\> $error[0].Exception

Имя "NoCommand" не распознано как имя командлета, функции, файла сценария или выполняемой программы. Проверьте правильн

ость написания имени, а также наличие и правильность пути, после чего повторите попытку.

Этот же пример, но в виде рисунка для наглядности.

Используем Try в PowerShell

Для того чтобы выяснить была ли в какой-то части кода ошибка необходимо использовать Try. Это помогает избавиться от неожиданного и некорректного завершение вашего скрипта. Позволяя так же корректно завершить его работу.

Синтаксис выглядит в общем случае так.

Try { часть кода в которой ищем ошибку } Catch { [тип ошибки, которую ищем] код, который будет выполнен когда ошибка будет найдена } Finally { код, который будет выполнен в любом случае }

Try

{

  часть кода в которой ищем ошибку

}

Catch

{

[тип ошибки, которую ищем] код,

     который будет выполнен когда ошибка будет найдена

}

Finally

{

код, который будет выполнен в любом случае

}

Однако использование Finally и определение типа ошибки — опционально и может не использоваться.

Для проверки напишем вот такой код где используем Try в PowerShell для того чтобы обработать ошибку деления на ноль и вывести информацию об ошибке.

try { [float](4/0) } catch { Write-Host "Error!!!" Write-Host $error[0].Exception }

try

{

[float](4/0)

}

catch

{

  Write-Host "Error!!!"

  Write-Host $error[0].Exception

}

Как видно я произвожу деление на ноль в блоке try, т.е. совершаю прерывающую ошибку. Только прерывающие ошибку будут отловлены. А далее в блоке catch произвожу уже необходимые отладочные действия, т.е. произвожу обработку ошибки.. В моей исходной задаче я в данном блоке заносил информацию об ошибках в специальный лог файл, но давайте попробуем запустить мой данный пример.

PS C:\> .\test.ps1 Error!!! System.Management.Automation.RuntimeException: Попытка деления на нуль. ---> System.DivideByZeroException: Попытка делен ия на нуль. --- Конец трассировки внутреннего стека исключений --- в System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exce ption) в System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame) в System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame) в System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)

PS C:\> .\test.ps1

Error!!!

System.Management.Automation.RuntimeException: Попытка деления на нуль. ---> System.DivideByZeroException: Попытка делен

ия на нуль.

   --- Конец трассировки внутреннего стека исключений ---

   в System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exce

ption)

   в System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)

   в System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)

   в System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)

Увы в блоке try в PowerShell должна присутствовать прерывающая ошибка.

Преобразуем не прерывающую ошибку в прерывающую

Существует общий параметр для всех командлетов в PowerShell -ErrorAction. Данный параметр может принимать четыре значения

  • Continue — выводит ошибку и продолжает выполнение
  • SilentlyContinue — не выводит ошибку и продолжает выполнение
  • Stop — завершает выполнение
  • Inquire — спрашивает у пользователя как поступить

В нашем случае подходит действие stop. Если использовать параметр со значением -ErrorAction Stop, то при возникновении ошибки при выполнении команды, данная ошибка прерывает выполнение команды. Ниже пример скрипта, использующего -ErrorAction Stop.

try { Dir NoFolder -ErrorAction Stop } catch { Write-Host "Error!!!" Write-Host $error[0].Exception }

try

{

  Dir NoFolder -ErrorAction Stop

}

catch

{

  Write-Host "Error!!!"

  Write-Host $error[0].Exception

}

Ниже результат выполнения данного скрипта

PS C:\> .\test.ps1 Error!!! System.Management.Automation.ItemNotFoundException: Не удается найти путь "C:\NoFolder", так как он не существует. в System.Management.Automation.SessionStateInternal.GetChildItems(String path, Boolean recurse, C mdletProviderContext context) в Microsoft.PowerShell.Commands.GetChildItemCommand.ProcessRecord()

PS C:\> .\test.ps1

Error!!!

System.Management.Automation.ItemNotFoundException: Не удается найти путь "C:\NoFolder",

так как он не существует.

   в System.Management.Automation.SessionStateInternal.GetChildItems(String path, Boolean recurse, C

mdletProviderContext context)

   в Microsoft.PowerShell.Commands.GetChildItemCommand.ProcessRecord()

В моей исходной задаче try в PowerShell необходимо было использовать для всех команд в скрипте. Поскольку обработка ошибки была общей для любой ошибки в скрипте весь скрипт можно поместить в один Try, конечно это не совсем правильно, но зато просто. Чтобы каждый раз не писать -ErrorAction Stop. Можно воспользоваться переменной $ErrorActionPreference, которая имеет те же значения и сходна по действию, однако распространяет свое действие на все командлеты в скрипте.

$ErrorActionPreference = "stop" try { Dir Folder Get-Process -ComputerName TestPC } catch { Write-Host "Error!!!" Write-Host $error[0].Exception }

$ErrorActionPreference = "stop"

try

{

  Dir Folder

  Get-Process -ComputerName TestPC

}

catch

{

  Write-Host "Error!!!"

  Write-Host $error[0].Exception

}

Вместо заключения

Конечно, по началу вы мало будете задумываться об поиске ошибок, используя множество условных конструкций вы их минимизируете. Однако использование try в PowerShell позволит минимизировать случаи неожиданного завершения скрипта.

 

get-powershell.ru

Переменные в Windows PowerShell, часть 1

В своем изучении PowerShell мы уже имели дело с переменными. Настало время поговорить о них подробнее.

Переменные в Windows PowerShell всегда начинаются со знака доллара ($). Переменные создаются в момент присваивания им первого значения, так что отдельно это делать не надо.

Переменные в PowerShell делятся на переменные оболочки (имеет в виду оболочка PowerShell), пользовательские переменные и переменные среды (или окружения, т.е. операционной системы Windows).

Переменные оболочки PowerShell

Это будет первый тип переменных, который мы разберем. Данные переменные присутствуют в каждом сеансе PowerShell и доступны всем командам, сценариям и приложениям. Существуют два вида переменных оболочки:

  • Автоматические переменные — в них хранятся параметры состояния оболочки PowerShell. Данные переменные используются системой и их значения не должны меняться пользователем.
  • Переменные настроек — в них хранятся настройки текущего пользователя. Эти переменные также создаются оболочной PowerShell и доступны для изменения пользователям.

Ниже приведены часто использующиеся переменные оболочки.

Переменная Описание
$$ Содержит последнее слово (или знак) последней полученной оболочкой строки
$? Показывает, успешно ли завершилась последняя операция
$^ Первое слово (или знак) последней полученной оболочной строки
$_ При использовании в блоках сценариев, фильтрах и инструкции Where содержит текущий объект конвейера
$Args Содержит массив параметров, передаваемых в функцию
$DebugPreference Указывает действие, которое необходимо выполнить при записи данных с помощью командлета Write-Debug
$Error Содержит объекты, для которых возникла ошибка при обработке в командлете
$ErrorActionPreference Указывает действие, которое необходимо выполнить при записи данных с помощью командлета Write-Error
$ForEach Обращается к итератору в цикле ForEach
$Home Указывает домашний каталог пользователя
$Input Используется в блоках сценариев, находящихся в конвейере
$LASTEXITCODE Содержит код завершения последнего выполнения исполнимого файла Win32
$MaximumAliasCount Максимальное число псевдонимов, доступных сеансу
$MaximumDriveCount Максимальное число доступных дисков, кроме предоставляемых операционной системой
$MaximumFunctionCount Максимальное число функций, доступных сеансу
$MaximumHistoryCount Максимальное число записей, сохраненных в истории команд
$MaximumVariableCount Максимальное число переменных, доступных сеансу
$PSHome Показывает имя каталога, в который установлен Windows PowerShell
$Host Содержит сведения о текущем узле
$OFS Используется в качестве разделителя при преобразовании массива в строку, по умолчанию имеет значение пробела
$ReportErrorShowExceptionClass Если значение переменной $True, показывает имена класса выведенных исключений
$ReportErrorShowInnerException Если значение переменной $True, показывает цепочку внутренних исключений
$ReportErrorShowSource Если значение переменной $True, показывает имена сборок выведенных исключений
$ReportErrorShowStackTrace Если значение переменной $True, происходит трассировка стека исключений
$StackTrace Содержит подробные сведения трассировки стека на момент последней ошибки
$VerbosePreference Указывает действие, которое нужно выполнить, если данные записываются с помощью командлета Write-Verbose
$WarningPreference Указывает действие, которое нужно выполнить при записи данных с помощью командлета Write-Warning в сценарии

В следующей части поговорим о пользовательских переменных и переменных среды Windows.

Продолжение следует…

webistore.ru

Как создать свой объект в PowerShell

Пост чтоб ссылаться на него, а то часто спрашивают

Самый красивый и правильный способ – использовать командлеты New-Object, и Add-Member:

$obj = New-Object psobject $obj | Add-Member -type noteproperty -name Prop1 -Value "Abc" $obj | Add-Member -type noteproperty -name Prop2 -Value 123

К сожалению этот способ относительно громоздкий, и при написании “ad-hoc” скриптов, или в интерактивной консоли, часто используют командлет Select-Object. Он оставляет от переданного ему объекта только указанные свойства. Причем свойства можно указывать даже отсутствующие у объекта раньше А вместо имён свойств можно использовать специальные хеш-таблицы в которых еще и указывать их значения

$o = 0 | Select-Object @{name="Prop1";expression={"Abc"}}, @{n="Prop2";e={123}}

Мы передаём на Select-Object объект 0 (ноль), впрочем можно использовать и любой другой, например «» (пустую строку). Ни одно из свойств исходного объекта мы не указываем и они удаляются. Зато добавляем пару новых

Ну и до кучи – хэш-таблицы (hashtable). Это не объекты, но ведут себя в некоторых случаях довольно похоже.

$h = @{prop1="Abc";prop2=123} $h["prop3"]=456 $h.prop1 = "Def"

Обратите внимание на такую фичу – к свойствам хеш-таблиц можно обращаться как к массивам по индексу – $h[«свойство»], так и как к объектам: $h.свойство.

Upd: Спасибо Вадиму за напоминание, в PowerShell 2.0 можно еще вот так легко создать свой класс с помощью кода C#, и затем его экземпляр:

Add-Type @' public class MyClass { public string prop1 = "blabla"; public bool prop2 = true; } '@ $Object = New-Object MyClass

Аналогично можно сделать и в 1.0, но там вызывать C# код уже несколько сложнее.

Источник

P.S.Так же рекомендую для просмотра — Создание объектов в PowerShell

Забрать к себе:

angelkeeper.wordpress.com