PowerShell и другие скрипты

29.4.2008

AD Domains

Рубрика: Learn, PowerShell, Practice, Scripting, Tips — Xaegr @ 15:42

Продолжая тему Active Directory и PowerShell, приведу несколько команд (точнее методов .Net), которые бывают полезны в скриптах.

Серьезный, “продакшн” скрипт, не должен требовать указывать ему имя домена, а использовать по умолчанию домен того компьютера на котором он запущен. А как его определить? Вызвать статический метод GetCurrentDomain() класса System.DirectoryServices.ActiveDirectory.Domain:

(далее&hellip ;)

28.4.2008

Set-AdProperty

Рубрика: Learn, PowerShell, Practice, Scripting, Tips — Xaegr @ 15:44

Сегодня из общения с Пашей Дугаевым “узнал” что людям “иногда” бывает нужно задать из PowerShell атрибут какого нибудь объекта в Active Directory :) . Процесс не сложный, но в PowerShell 1.0 не очень “красивый”. Поэтому для удобного использования стоит завернуть его в такую вот функцию:

(далее&hellip ;)

24.4.2008

Option Explicit

Рубрика: Learn, PowerShell, Scripting, Tips — Xaegr @ 8:08

Скриптерам и программерам на Visual Basic наверняка знакома эта “ключевая фраза”. Дело в том что по умолчанию, если использовать не объявленную заранее переменную, то ошибки не произойдет ни в Visual Basic ни в PowerShell. Просто вместо несуществующей переменной будет подставлено пустое значение. Обычно это является нормальным поведением, но иногда может привести и к логическим ошибкам. Ведь достаточно ошибится на одну букву в имени переменной, и логика скрипта может сильно изменится. Для таких случаев и был сделан Option Explit. При объявлении в начале скрипта этой директивы, при обращении к несуществующей переменной выдается ошибка. Аналог разумеется есть и в PowerShell - команда Set-PsDebug с ключем -Strict

(далее&hellip ;)

23.4.2008

Try/Catch/Finally в PowerShell

Рубрика: Learn, PowerShell, Scripting, Tips — Xaegr @ 8:19

PowerShell очень классный язык, но тем не менее очень молодой. И по этой причине в нём зачастую нет того чего хочется. Пока нет.

Но так как он всё же очень классный - то чего нет можно дописать ;) Вот к примеру если кому то не хватает привычной конструкции Try/Catch/Finally то Adam Weigert её написал :) За что ему большое спасибо :) (и ajax76 спасибо что напомнил :) )

(далее&hellip ;)

11.4.2008

-ErrorVariable

Рубрика: Learn, PowerShell, Scripting, Tips — Xaegr @ 8:24

Продолжаем “работу над ошибками” :) В прошлый раз я рассказал о параметре командлетов -ErrorAction, а сегодня займёмся его соседом -ErrorVariable. Как можно догадаться из названия, он указывает переменную в которую будет помещён объект ошибки (да, в PowerShell даже ошибки являются объектами ;) ). Но тут возникает одна популярная ошибка. Обычно все (в том числе и я ;) ) пробуют указать в качестве аргумента этой команде переменную ;)

[PS <24> C:\Root] Get-Process -id 1234 -ErrorVariable $MyError
Get-Process : Cannot find a process with the process identifier 1234.
At line:1 char:12
+ Get-Process <<<<  -id 1234 -ErrorVariable $MyError

Казалось бы всё правильно, произошла ошибка, и соответствующий объект был помещен в переменную $MyError? Ан нет, такой переменной даже не существует. В чём же дело? А в том что парсер PowerShell’а, разбирая эту строчку увидел символ $ и понял что следом за ним идет переменная, которую надо преобразовать в её значение перед передачей команде (логично ведь? ;) ). А так как такой переменной не существует, PowerShell поступил так же как он обычно поступает с неназначенными переменными - передал вместо неё … ничего. То есть параметр -ErrorVariable не получил названия переменной в которую ему следовало поместить ошибку. Думаю уже понятно что для того чтобы этого не произошло, надо указывать просто название переменной, без символа $:

[PS <25> C:\Root] Get-Process -id 1234 -ErrorVariable MyError
Get-Process : Cannot find a process with the process identifier 1234.
At line:1 char:12
+ Get-Process <<<<  -id 1234 -ErrorVariable MyError
[PS <26> C:\Root] $MyError
Get-Process : Cannot find a process with the process identifier 1234.
At line:1 char:12
+ Get-Process <<<<  -id 1234 -ErrorVariable MyError

Итак объект с ошибкой у нас есть, что же с ним можно делать дальше?

Нет! Ни в коем случае не парсить! Хотя это и можно сделать - это было бы в корне неправильно. У нас в руках полноценный объект, с очень полезными свойстами к которым можно обращаться без всяких заморочек с разбором текста (который кстати может отличатся не только у разных ошибок, но и при использовании разных языков).

И тут возникает вторая тонкость. При попытке посмотреть свойства ошибки перенаправив её на команду Format-List * нас ждёт жестокий облом:

[PS <27> C:\Root] $MyError | Format-List *
Get-Process : Cannot find a process with the process identifier 1234.
At line:1 char:12
+ Get-Process <<<<  -id 1234 -ErrorVariable MyError

На выходе получился не ожидаемый список всех свойств, а тот же самый текст. Чтобы этого не случилось, надо добавить к Format-List параметр -Force:

[PS <28> C:\Root] $MyError | Format-List * -Force

Exception             : Microsoft.PowerShell.Commands.ProcessCommandException: Cannot find a process with the process identifier 1234.
TargetObject          : 1234
CategoryInfo          : ObjectNotFound: (1234:Int32) [Get-Process], ProcessCommandException
FullyQualifiedErrorId : NoProcessFoundForGivenId,Microsoft.PowerShell.Commands.GetProcessCommand
ErrorDetails          :
InvocationInfo        : System.Management.Automation.InvocationInfo

Еще стоит обратить внимание на то что $MyError является массивом. В случае если при выполнении команды произойдет несколько ошибок - все они будут помещены в переменную, и ни одна не потеряется. И поэтому если мы хотим посмотреть например свойство InvocationInfo то следует указать индекс элемента:

[PS <29> C:\Root] $MyError[0].InvocationInfo

MyCommand             : Get-Process
CommandLineParameters : {[Id, System.Int32[]]}
ScriptLineNumber      : 1
OffsetInLine          : 12
ScriptName            :
Line                  : Get-Process -id 1234 -ErrorVariable MyError
PositionMessage       :
                        At line:1 char:12
                        + Get-Process <<<<  -id 1234 -ErrorVariable MyError
InvocationName        : Get-Process
PipelineLength        : 1
PipelinePosition      : 1
ExpectingInput        : False
CommandOrigin         : Runspace

Ну и конечно можно получить только значение конкретного свойства. И без всякого парсинга ;) Например позицию в строке на которой произошла ошибка:

[PS <30> C:\Root] $MyError[0].InvocationInfo.OffsetInLine
12

Это разумеется еще не всё про ошибки, ждите продолжений ;)

Older Posts »

Заведите блог на WordPress.com.