Главная » Компьютер, железо » Вывод информации об успешном выполнении команды powershell. Out-Null или подавление вывода информации в Windows PowerShell. Кодирование с помощью PowerShell

Вывод информации об успешном выполнении команды powershell. Out-Null или подавление вывода информации в Windows PowerShell. Кодирование с помощью PowerShell

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

Создание

Представим, что каждое утро вы проверяете 50 последних логов за 14 часов журнала Application с помощью этой команды:

Get-EventLog -LogName Application -Newest 50 | where TimeWritten -ge (Get-Date).AddHours(-14)

Команда не очень сложная, но в скором времени ее надоест писать. Для сокращения этой работы ее можно выделить в отдельную функцию:

Function Get-DayLog { Get-EventLog -LogName Application -Newest 50 | where TimeWritten -ge (Get-Date).AddHours(-14) }

Любая функция обязательно должна состоять из трех вещей:

  • function - объявляет и говорит что после нее будет название;
  • имя функции - название, по которому мы будем ее вызывать. В нашем случае имя Get-DayLog;
  • скобки - обозначают начало и конец выражения.

После написания функции она вызывается по имени:

Get-DayLog

Учитывая, что нам может потребоваться получить данные не за последние 14 часов и более чем за 50 дней нам может потребуется изменить ее передав параметры.

Именование

Не обязательно использовать имя такого же плана, как принято в Powershell, то есть вместо "Get-DayLog" можно писать "daylog". Такой подход рекомендуем и является распространенной практикой, который поможет отличить запуск сторонней программы от функции.

Функции в Powershell всегда именуются по следующему признаку. Первое слово это глаголы типа:

  • Get - получить;
  • Set - изменить;
  • Install - установить;
  • New - создать.

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

Передача параметров

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

Function Get-DayLog ($param1,$param2) { Get-EventLog -LogName Application -Newest $param1 | where TimeWritten -ge (Get-Date).AddHours($param2) }

Параметры функции обозначаются в круглые скобки и пишутся после названия функции и до выражения.

Теперь, для вызова функции, требуется передавать два параметра:

Get-DayLog -param1 50 -param2 -14

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

Установка значений по умолчанию

В нашей задаче, чаще всего, мы получаем только 50 последних логов и нам не хочется указывать их каждый раз. Если мы не будем указывать этот параметр в существующей функции, то получим ошибку. Что бы этого избежать нужно указать значение по умолчанию. На примере ниже я присвоил $param1 значение 50. Оно будет использоваться только в том случае, если мы не используем этот параметр при вызове:

Function Get-DayLog ($param1=50,$param2) { Get-EventLog -LogName Application -Newest $param1 | where TimeWritten -ge (Get-Date).AddHours($param2) } Get-DayLog -param2 -7

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

Function Get-DayLog ($param2,$param1=50) { Get-EventLog -LogName Application -Newest $param1 | where TimeWritten -ge (Get-Date).AddHours($param2) } Get-DayLog -7 1 Get-DayLog -7

Как видно на примере, если мы не указываем ключи param1 и param2 важна последовательность, так как именно в такой последовательности они будут присвоены переменным внутри функций.

Возвращение значений

В отличие от других языков, если мы присвоим переменной $result результат функции Get-DayLog, то она будет содержать значения:

$result = Get-DayLog -7 1

Это будет работать до тех пор, пока мы не решим изменить функцию присвоив переменные:

Function Get-DayLog ($param2,$param1=50) { $events = Get-EventLog -LogName Application -Newest $param1 | where TimeWritten -ge (Get-Date).AddHours($param2) } $result = Get-DayLog -7 $result $events

Мы не можем получить результат используя переменную $result, так как функция не выводит информацию, а хранит ее в переменной $events. Вызывая $events мы тоже не получаем информацию, так как тут работает понятие "область видимости переменных".

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

Function Get-DayLog ($param2,$param1=50) { $events = Get-EventLog -LogName Application -Newest $param1 | where TimeWritten -ge (Get-Date).AddHours($param2) return $events } $result = Get-DayLog -7 $result

Я бы рекомендовал всегда возвращать значения через return, а не использовать вывод используя команды типа Write-Output внутри функции. Использование return останавливает работу функции и возвращает значение, а это значит что его не стоит ставить по середине логики если так не планировалось.

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

Function Get-Salary ($Zarplata) { $nalog = $Zarplata * 0.13 $zarplata_bez_nds = $Zarplata - $nalog return $nalog,$zarplata_bez_nds } Get-Salary -Zarplata 100000

Я вернул оба значения разделив их запятой. По умолчанию всегда возвращается массив. это набор не именованных параметров. Более подробно о них мы уже писали.

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

$result = Get-Salary -Zarplata 100000 # Определяем тип данных $result.GetType() Write-Host "это зарплата" $result Write-Host "это налог" $result

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

Function Get-Salary ($Zarplata) { $nalog = $Zarplata * 0.13 $zarplata_bez_nds = $Zarplata - $nalog return @{"Налог"=$nalog;"Зарплата"=$zarplata_bez_nds;} } Get-Salary -Zarplata 100000

Использование массивов

Передача массивов в виде параметров

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

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

Function Get-ServiceStopped ($Computers){ $services = Get-Service -ComputerName $Computers | where Status -eq Stopped return $services } Get-ServiceStopped "127.0.0.1","localhost"

Массивы так же работают по индексам, что позволяет передавать больше параметров. Такой способ не релевантный, но может когда-то пригодиться.

Function Get-ServiceStopped ($Computers){ $services = Get-Service -ComputerName $Computers | where Status -eq $Computers[-1] return $services } Get-ServiceStopped "127.0.0.1","localhost","Stopped"

Хэш таблицы

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

Function Get-ServiceStopped ($Params){ $services = Get-Service @Params | where Status -eq Stopped $services = Start-Service $services return $services } Get-ServiceStopped @{Name="WinRM";ComputerName=@("127.0.0.1","localhost")}

Знак @ в команде объявляет, что данные хэш таблицы будут использоваться как параметры команды. Важно, чтобы их имена соответствовали настоящим параметрам.

Условия

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

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

Function Get-SiteResponse { # Начало отсчета $start_time = Get-Date # Выполнение запроса $request = Invoke-WebRequest -Uri "https://сайт" # Фиксирование окончания выполнения $end_time = Get-Date # Высчитываем разницу во времени $result = $end_time - $start_time # Проверка и возвращение результата if ($result.Milliseconds -lt 76) { return "Скорость ответа нормальная " + $result.Milliseconds} else{ return "Сайт отвечает долго " + $result.Milliseconds } } Get-SiteResponse

Switch

Мы уже говорили про в предыдущих статьях. Если коротко, то это более удобные условия. Используя предыдущий пример, но со Switch, это будет выглядеть так:

Function Get-SiteResponse { # Начало отсчета $start_time = Get-Date # Выполнение запроса $request = Invoke-WebRequest -Uri "https://сайт" # Фиксирование окончания выполнения $end_time = Get-Date # Высчитываем разницу во времени $result = $end_time - $start_time # Проверка и возвращение результата switch($result.Milliseconds) { {$PSItem -le 76} { return "Скорость ответа нормальная " + $result.Milliseconds} default { return "Сайт отвечает долго " + $result.Milliseconds } } } Get-SiteResponse

Другой пример Switch это вызов функции в зависимости от переданных параметров. На примере ниже я вызываю функцию, в которой находится Switch. В эту функцию я передаю имя компьютера, которое проверяется на упоминание указанных фраз и вызывает соответствующую функцию. Каждая функция, которая устанавливает обновления, возвращает значение в Switch, а затем происходит return внутри нее:

Function Install-SQLUpdates { # делаем установку return "Установка обновлений на SQL сервер прошла успешно" } function Install-ADUpdates { # делаем установку return "Установка обновлений на сервер AD прошла успешно" } function Install-FileServerUpdates { # делаем установку return "Установка обновлений на файловый сервер прошла успешно" } function Make-Switch ($computer) { # Проверка имени компьютера $result = switch($computer){ {$computer -like "SQL*"} {Install-SqlUpdates} {$computer -like "AD*"} {Install-ADUpdates} {$computer -like "FileServer*"} {Install-FileServerUpdates} default {"Такого типа компьютеров нет"} } return $result } Make-Switch "AD1"

Со switch так же удобно передавать булевы значения. В примере ниже если указан ключ -On сервис включится, а если его нет выключится:

Function Switch-ServiceTest ($on) { if ($on) {Write-Output "Сервис включен"} else {"Сервис выключен"} } Switch-ServiceTest -On Switch-ServiceTest

Передача через конвейер или Pipeline

Вы наверняка работали через команды Powershell, которые позволяли использовать конвейер следующим образом:

Get-Process -Name *TestProc* | Stop-Process

Если мы захотим использовать подход описанный выше, создав новые команды в виде функций, то конвейер не будет работать:

Function Get-SomeNum { # Генерация числа $num = Get-Random -Minimum 5 -Maximum 10 return $num } function Plus-SomeNum ($num) { Write-Host "Прибавление числа " $num $num += $num return $num } Get-SomeNum Plus-SomeNum 5 Get-SomeNum | Plus-SomeNum

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

Get-Help Stop-Process -Parameter Name

Таких атрибутов всего два:

  • ValueFromPipelineByPropertyName - получение значения из конвейера по имени;
  • ValueFromPipeline - получение через конвейер только значения.

Кроме этого, внутри нашей функции, мы должны добавить специальный блок Process. Наш скрипт в итоге будет выглядеть так:

Function Get-SomeNum { $num = Get-Random -Minimum 5 -Maximum 10 return $num } function Plus-SomeNum { Param ( $num) process { Write-Host "Прибавление числа " $num $num += $num return $num } } 1..5 | Plus-SomeNum Get-SomeNum | Plus-SomeNum

Атрибут расширения функции, который добавляет некоторые возможности в функции позволяя им работать как команду.

Если бы мы не указали блок Process функция бы вернула только последней результат из массива 1..5:

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

Function Get-SomeNum { $num = Get-Random -Minimum 5 -Maximum 10 $object = @{num=$num} return $object } function Plus-SomeNum { Param ( $num) process { Write-Host "Прибавление числа " $num $num += $num return $num } } Get-SomeNum | Plus-SomeNum @{num=5} | Plus-SomeNum @{bad=5} | Plus-SomeNum

Как уже писалось ValueFromPipelineByPropertyName принимает только именованные параметры и в случае с именем "bad" мы получаем ошибку:

  • Не удается привязать объект ввода к любым параметрам команды, так как команда не принимает входные данные конвейера
  • The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.

Причем передавать именованные параметры через хэш таблицы мы не можем, только через pscustomobject.

Вы можете указывать сразу два атрибута таким образом:

Это позволит использовать и значение с именем, если оно указано либо без него. Это не спасет вас от ситуации, если вы передаете параметр с другим именем:

Передача через конвейер нескольких значений

Для примера рассмотрим ситуацию, где нам нужно передать через конвейер два значения. Если Get-SomeNum будет возвращать массив, то через конвейер у нас будет проходить каждое число по отдельности. Это еще один повод использовать именованные параметры:

Function Get-SomeNum { $number1 = Get-Random -Minimum 5 -Maximum 10 $number2 = Get-Random -Minimum 1 -Maximum 5 $object = @{num1=$number1;num2=$number2} return $object } function Plus-SomeNum { Param ( $num1, $num2) begin {$num1 += $num1 $num2 = $num2 * $num2} process { return @{"Результат сложения"=$num1; "Результат умножения"=$num2} } } Get-SomeNum | Plus-SomeNum

Закончим работу с выводом данных.

В том случае, если нам не нужен вывод информации на экран консоли (допустим, она просто для нас лишняя, и нам просто нужно, чтобы определенные команды отработали без вывода результатов на экран), мы можем воспользоваться командлетом Out-Null .

Что будет, если к хорошо известному командлету Get-Process добавить Out-Null ?

Get-Process | Out-Null
Пример действия Out-Null в PowerShell

Как видим, не произошло ровным счетом ничего. А, точнее будет сказать, ничего видимого для наших глаз. Командлет Get-Process отработал, но мы не захотели ознакомиться с результатами его работы. Конечно, данное действие было бессмысленным.

Можно привести пример более осмысленного действия. Перейдем в корень диска C и создадим там каталог primer.

cd c:\ mkdir primer

Как видим, PowerShell вывел нам содержимое только что созданного каталога. Если нам это не нужно, можно использовать Out-Null .

mkdir primer | Out-Null

Итак, Out-Null это полезный инструмент для совершения тех действий, которые должны выполняться что называется «под капотом».

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

Самый простой способ вывести окошко с произвольным тестом через подсистему сценариев Windows – Wscript.

Следующий код выведет обычное текстовое окно с необходимым текстом и кнопкой OK.

$wshell = New-Object -ComObject Wscript.Shell
$Output = $wshell.Popup("Скрипт формирования отчета выполнен")

С помощью различных свойств метода Popup вы можете настроить вид модального окна сообщения. В том числе можно вернуть в скрипт результаты ответа пользователя на вопрос (Да / Нет).

$Output = $wshell.Popup("Скрипт формирования отчета завершен! Хотите вывести его на экран?",0,"Отчет готов",4+32)

Общий синтаксис и параметры метода Popup:

Popup(,,,<Type>) </b></p><p>Параметры:</p><ul><li><Text> — строка, текст сообщения.</li><li><SecondsToWait> — необязательный, число. Количество секунд, по истечении которого окно будет автоматически закрыто.</li><li><Title> — необязательный, строка. Текст заголовка окна сообщения.</li><li><Type> — необязательный, число. Комбинация флагов, определяет тип кнопок и значка. Возможные значения флагов:<ul><li>0 — кнопка ОК.</li><li>1 — кнопки ОК и Отмена.</li><li>2 — кнопки Стоп, Повтор, Пропустить.</li><li>3 — кнопки Да, Нет, Отмена.</li><li>4 — кнопки Да и Нет.</li><li>5 — кнопки Повтор и Отмена.</li><li>16 — значок Stop.</li><li>32 — значок Question.</li><li>48 — значок Exclamation.</li><li>64 — значок Information.</li> </ul></li> </ul><p>Описание: возвращает целое значение, с помощью которого можно узнать, какая кнопка была нажата пользователем. Возможные значения:</p><ul><li>-1 — таймаут.</li><li>1 — кнопка ОК.</li><li>2 — кнопка Отмена.</li><li>3 — кнопка Стоп.</li><li>4 — кнопка Повтор.</li><li>5 — кнопка Пропустить.</li><li>6 — кнопка Да.</li><li>7 — кнопка Нет.</li> </ul><p>Более привлекательные и приятные взгляду всплывающие сообщения (ballons) можно вывести в Windows 7, 8.1 и 10 через API Windows Forms. Следующий PowerShell код выведет всплывающее сообщение рядом с панелью уведомлений Windows 10, которое автоматически исчезнет через 10 секунд.</p><p>Add-Type -AssemblyName System.Windows.Forms<br>$global:balmsg = New-Object System.Windows.Forms.NotifyIcon<br>$path = (Get-Process -id $pid).Path<br>$balmsg.Icon = ::ExtractAssociatedIcon($path)<br>$balmsg.BalloonTipIcon = ::Warning<br>$balmsg.BalloonTipText = "Это текст всплывающего сообщения для пользователя Windows 10"<br>$balmsg.BalloonTipTitle = "Внимание $Env:USERNAME"<br>$balmsg.Visible = $true<br>$balmsg.ShowBalloonTip(10000)</p><p><img src='https://i0.wp.com/winitpro.ru/wp-content/uploads/2018/10/vsplyvayushee-uvedomlenie-v-powershell.png' width="100%" loading=lazy></p><p>Кроме того для создания красочных всплывающих сообщений в Windows 10 (PowerShell 5.0+)можно использовать отдельный PowerShell модуль BurntToast из галереи PowerShell.</p><p>Модуль устанавливается из онлайн репозитория с помощью :<br> Install-Module -Name BurntToast</p><p>Теперь, например, в ранее рассматриваемый можно добавить красочное уведомление:</p><p>New-BurntToastNotification -Text "Отключение от Wi-Fi сети", "Вы были отключены от Wi-Fi сети, т.к. Вше устройство было подключено к скоростному Ethernet подключению." -AppLogo C:\PS\changenetwork.png</p><p>Итак, теперь вы знаете как вывести уведомление пользователя через PowerShell. Если у пользователя есть динамики, можно даже сыграть ему мелодию:</p><p>::beep(440,500)<br>::beep(440,500)<br>::beep(440,500)<br>::beep(349,350)<br>::beep(523,150)<br>::beep(440,500)<br>::beep(349,350)<br>::beep(523,150)<br>::beep(440,1000)<br>::beep(659,500)<br>::beep(659,500)<br>::beep(659,500)<br>::beep(698,350)<br>::beep(523,150)<br>::beep(415,500)<br>::beep(349,350)<br>::beep(523,150)<br>::beep(440,1000)<br>::beep(880,500)<br>::beep(440,350)<br>::beep(440,150)<br>::beep(880,500)<br>::beep(830,250)<br>::beep(784,250)<br>::beep(740,125)<br>::beep(698,125)<br>::beep(740,250)<br>::beep(455,250)<br>::beep(622,500)<br>::beep(587,250)<br>::beep(554,250)<br>::beep(523,125)<br>::beep(466,125)<br>::beep(523,250)<br>::beep(349,125)<br>::beep(415,500)<br>::beep(349,375)<br>::beep(440,125)<br>::beep(523,500)<br>::beep(440,375)<br>::beep(523,125)<br>::beep(659,1000)<br>::beep(880,500)<br>::beep(440,350)<br>::beep(440,150)<br>::beep(880,500)<br>::beep(830,250)<br>::beep(784,250)<br>::beep(740,125)<br>::beep(698,125)<br>::beep(740,250)<br>::beep(455,250)<br>::beep(622,500)<br>::beep(587,250)<br>::beep(554,250)<br>::beep(523,125)<br>::beep(466,125)<br>::beep(523,250)<br>::beep(349,250)<br>::beep(415,500)<br>::beep(349,375)<br>::beep(523,125)<br>::beep(440,500)<br>::beep(349,375)<br>::beep(261,125)<br>::beep(440,1000)</p> <p>Работая в оболочке PowerShell, мы пока не задумывались, каким образом система формирует строки текста, которые выводятся на экран в результате выполнения той или иной команды (напомним, что командлеты PowerShell возвращают.NET-объекты, которые, как правило, не знают, каким образом отображать себя на экране).</p><p>На самом деле в PowerShell имеется база данных (набор XML-файлов), содержащая модули форматирования по умолчанию для различных типов.NET-объектов. Эти модули определяют, какие свойства объекта отображаются при выводе и в каком формате: списка или таблицы. Когда объект достигает конца конвейера, PowerShell определяет его тип и ищет его в списке объектов, для которых определено правило форматирования. Если данный тип в списке обнаружен, то к объекту применяется соответствующий модуль форматирования; если нет, то PowerShell просто отображает свойства этого.NET-объекта.</p><p>Также в PowerShell можно явно задавать правила форматирования данных, выводимых командлетами, и подобно командному интерпретатору Cmd.exe перенаправлять эти данные в файл, на принтер или в пустое устройство.</p> <h5>Форматирование выводимой информации</h5><p>В традиционных оболочках команды и утилиты сами форматируют выводимые данные. Некоторые команды (например, dir в интерпретаторе Cmd.exe) позволяют настраивать формат вывода с помощью специальных параметров.</p><p>В оболочке PowerShell вывод форматируют только четыре специальных командлета Format (табл. 17.3). Это упрощает изучение, так как не нужно запоминать средства и параметры форматирования для других команд (остальные командлеты вывод не форматируют).</p><table border="0" class="xml_table" cellpadding="2" cellspacing="1"> Таблица 17.3. Командлеты PowerShell для форматирования вывода <tr><th bgcolor="#d8d8d8">Командлет </th> <th bgcolor="#d8d8d8">Описание </th> </tr><tr><td bgcolor="#eaeaea" valign="top">Format-Table </td> <td bgcolor="#eaeaea" valign="top">Форматирует вывод команды в виде таблицы, столбцы которой содержат свойства объекта (также могут быть добавлены вычисляемые столбцы). Поддерживается возможность группировки выводимых данных </td> </tr><tr><td bgcolor="#eaeaea" valign="top">Format-List </td> <td bgcolor="#eaeaea" valign="top">Вывод форматируется как список свойств, в котором каждое свойство отображается на новой строке. Поддерживается возможность группировки выводимых данных </td> </tr><tr><td bgcolor="#eaeaea" valign="top">Format-Custom </td> <td bgcolor="#eaeaea" valign="top">Для форматирования вывода используется пользовательское представление (view) </td> </tr><tr><td bgcolor="#eaeaea" valign="top">Format-Wide </td> <td bgcolor="#eaeaea" valign="top">Форматирует объекты в виде широкой таблицы, в которой отображается только одно свойство каждого объекта </td> </tr></table><p>Как уже отмечалось выше, если ни один из командлетов Format явно не указан, то используется модуль форматирования по умолчанию, который определяется по типу отображаемых данных. Например, при выполнении командлета Get-Service данные по умолчанию выводятся как таблица с тремя столбцами (Status, Name и DisplayName):</p><p>PS C:\> Get-Service Status Name DisplayName ------ ---- ----------- Stopped Alerter Оповещатель Running ALG Служба шлюза уровня приложения Stopped AppMgmt Управление приложениями Stopped aspnet_state ASP.NET State Service Running Ati HotKey Poller Ati HotKey Poller Running AudioSrv Windows Audio Running BITS Фоновая интеллектуальная служба пер... Running Browser Обозреватель компьютеров Stopped cisvc Служба индексирования Stopped ClipSrv Сервер папки обмена Stopped clr_optimizatio... .NET Runtime Optimization Service v... Stopped COMSysApp Системное приложение COM+ Running CryptSvc Службы криптографии Running DcomLaunch Запуск серверных процессов DCOM Running Dhcp DHCP-клиент...</p><p>Для изменения формата выводимых данных нужно направить их по конвейеру соответствующему командлету Format . Например, следующая команда выведет список служб с помощью командлета Format-List :</p><p>PS C:\> Get-Service | Format-List Name: Alerter DisplayName: Оповещатель Status: Stopped DependentServices: {} ServicesDependedOn: {LanmanWorkstation} CanPauseAndContinue: False CanShutdown: False CanStop: False ServiceType: Win32ShareProcess Name: ALG DisplayName: Служба шлюза уровня приложения Status: Running DependentServices: {} ServicesDependedOn: {} CanPauseAndContinue: False CanShutdown: False CanStop: True ServiceType: Win32OwnProcess . . .</p><p>Как мы видим, при использовании формата списка выводится больше сведений о каждой службе, чем в формате таблицы (вместо трех столбцов данных о каждой службе в формате списка выводятся девять строк данных). Однако это вовсе не означает, что командлет Format-List извлекает дополнительные сведения о службах. Эти данные содержатся в объектах, возвращаемых командлетом Get-Service , однако командлет Format-Table , используемый по умолчанию, отбрасывает их, потому что не может вывести на экран более трех столбцов.</p><p>При форматировании вывода с помощью командлетов Format-List и Format-Table можно указывать имена свойства объекта, которые должны быть отображены (напомним, что просмотреть список свойств, имеющихся у объекта, позволяет рассмотренный ранее командлет Get-Member ). Например:</p><p>PS C:\> Get-Service | Format-List Name, Status, CanStop Name: Alerter Status: Stopped CanStop: False Name: ALG Status: Running CanStop: True Name: AppMgmt Status: Stopped CanStop: False . . .</p><p>Вывести все имеющиеся у объектов свойства можно с помощью параметра * , например:</p><p>PS C:\> Get-Service | Format-table *</p> <h5>Перенаправление выводимой информации</h5><p>В оболочке PowerShell имеются несколько командлетов, с помощью которых можно управлять выводом данных. Эти командлеты начинаются со слова Out , их список можно увидеть следующим образом:</p><p>PS C:\> Get-Command out-* | Format-Table Name Name ---- Out-Default Out-File Out-Host Out-Null Out-Printer Out-String</p><p>По умолчанию выводимая информация передается командлету Out-Default , который, в свою очередь, делегирует всю работу по выводу строк на экран командлету Out-Host . Для понимания данного механизма нужно учитывать, что архитектура PowerShell подразумевает различие между собственно ядром оболочки (интерпретатором команд) и главным приложением (host), которое использует это ядро. В принципе, в качестве главного может выступать любое приложение, в котором реализован ряд специальных интерфейсов, позволяющих корректно интерпретировать получаемую от PowerShell информацию. В нашем случае главным приложением является консольное окно, в котором мы работаем с оболочкой, и командлет Out-Host передает выводимую информацию в это консольное окно.</p><p>Параметр Paging командлета Out-Host , подобно команде more интерпретатора Cmd.exe, позволяет организовать постраничный вывод информации, например:</p><p>Get-Help Get-Process –Full | Out-Host -Paging</p> <h6>Сохранение данных в файл</h6><p>Командлет Out-File позволяет направить выводимые данные вместо окна консоли в текстовый файл. Аналогичную задачу решает оператор перенаправления (>), однако командлет Out-File имеет несколько дополнительных параметров, с помощью которых можно более гибко управлять выводом: задавать тип кодировки файла (параметр Encoding ), задавать длину выводимых строк в знаках (параметр Width ), выбирать режим перезаписи файла (параметры Append , noClobber ). Например, следующая команда направит информацию о зарегистрированных на компьютере службах в файл C:\service.txt, причем данный файл будет записан в формате ASCII.</p> Данная статья представляет собой текстовую версию урока из нашего бесплатного видеокурса PowerShell и Основы Active Directory (для получения полного доступа используйте секретное слово «blog»).<p>Данный видеокурс оказался необычайно популярным по всему миру и он проведет вас по всем ступеням для создания полного набора инструментов по управлению службой каталогов Active Directory начиная с самых азов.</p><h3>Кодирование с помощью PowerShell</h3> Вначале это может показаться сложной задачей начать работать с PowerShell, особенно если с годами вы уже привыкли работать с командной строкой cmd.exe и так называемыми «батниками» (файли с расширениями.bat и.cmd). В этой статье, написанной по материалам 2-го урока нашего видеокурса, мы расскажем, как и почему вам стоит обновить свои навыки работы с PowerShell, а также разберем основы запуска редактора PowerShell, освоим авто-завершение команд и как в любой затруднительной ситуации получить актуальную помощь и примеры.<h3>Выполнение Команд</h3><p>Консоль PowerShell – это интерактивная среда, которая позволяет запускать различные команды в реальном времени. Здесь не нужно сперва редактировать скрипт в блокноте и лишь затем запускать его в командной строке, что также значительно съэкономит ваше время.</p><p>Если вы сейчас работаете в какой-либо организации, которая при этом существует не один день, то у вас уже наверняка есть несколько маленьких скриптов на каждый день, которые вы запускаете из командной строки cmd.exe. И это отличная новость! Значит вы так же легко сможете выполнять все это и из PowerShell. Это было поистине мудрое дизайнерское решение со стороны Microsoft, так они сделали переход на новое решение более легким для администораторов.</p><p>По внешнему виду, редактор PowerShell выглядит и функционирует точно также, как и окружение командной строки cmd.exe. Приемы и навыки, которыми вы уже владеете, будут работать без изменений и в PowerShell. А если вы к тому же хотите повысить свою квалификацию и работаете над переходом от выполнения одноразовых задач, к тому чтобы обеспечивать более автоматизированное администрирование, то привычка запускать PowerShell, а не командную строку является отличным способом для начала.</p><p>Все ваши часто используемые утилиты, такие как ping, ipconfig, nslookup, и т. п. будут работать именно так, как вы ожидаете.</p><h3>Как найти команды PowerShell</h3> Люди любят PowerShell, потому что это так, ну, мощно! Но эта сила исходит от совершенно безумного количества встроенных возможностей. Это просто не возможно, да наверное и не практично, чтобы кто-то запомнил всевозможные команды, командлеты, флаги, фильтры и другие способы сказать PowerShell что и как сделать.<p>К счастью, прямо в редакторе встроено несколько инструментов, чтобы помочь вам справиться с этим.</p><p><u>Авто-завершение команд по нажатию Tab </u></p><p>Нет необходимости запоминать различные команды или точное написание команды. Наберите</p><p>Get-c <br> Теперь нажимая на клавишу Tab – вы сможете перебрать все доступные команды, начинающиеся с тех символов, что вы уже ввели. Причем это работает в любой части тела команды, на которую вы пытаетесь сослаться: в именах и флагах команд и даже при автозавершении полных путей на файловой системе.</p><p><b>Команда Get-Command </b></p><p>Несмотря на то, что автодополнение по Tab работает превосходно, что произойдет, если Вы не знаете правильное имя команды, которая вам нужна? В этом случае можно использовать команду чтобы найти другие доступные команды: Get-Command.</p><p>В поиске имени команды, важно иметь в виду, что есть синтаксис для них: Глагол-Существительное. Как правило, Глаголы такие как – Get (Получить), Set (Установить), Add (Добавить), Clear (Очистить), Read (Читать) и Write (Писать) и Существительные – файлы, серверы или другими сущности в вашей сети и приложениях.</p><p><u>Get-Command </u>– это инструмент для поиска и изучения команд, доступных на вашем компьютере.</p><h3>Синтаксис команд в PowerShell</h3> Кто-то когда-то описал язык скриптов Perl, как “шум из исполняемых строк кода” (ориг. “executable line noise”) – невероятно полезный инструмент, с дико непрозрачным синтаксисом и соответственно с высоким порогом входа для его изучения.<p>Хотя если разобраться то и традиционная командная строка в Windows не так уж далеко от этого ушла. Рассмотрим общую задачу как найти все файлы в каталоге, имена которых начинаются с ‘foo’.</p><p>CMD: FOR /D /R %G IN (“Foo*”) DO @ECHO %G <br> FOR и DO указывают на то, что это цикл.<br> Флаг /D указывает, что это цикл по всем папкам<br> Флаг /R указывает, что нужно включать все файлы и папки, включая подкаталоги<br> Шаблон поиска, который определяет интересующий нас набор файлов, обозначается с помощью “IN”<br>ECHO указывает, что сценарий должен вывести на экран результат каждого цикла и, наконец,<br> %G – это “вынужденный параметр” и выбран потому, что ранее программисты Microsoft уже использовали при разработке буквы A, D, F, N, P, S, T, и X. Поэтому, начинать с G, является хорошим тоном, т.к. это дает вам самый большой набор неиспользованных букв для форматов путей возвращенных переменных (G, H, I, J, K, L, M) – другими словами, это лайфхак.</p><p>Сравните теперь эквивалент на PowerShell:</p><p>PowerShell: Get-ChildItem -Path C:\ -Filter ‘Foo*’ <br> Результат – тот же, но даже на таком достаточно тривиальном примере, будет намного легче понять, что происходит. Сразу становится очевидно, что делает каждый элемент в команде и как можно их изменить. Ну разве что подстановочный знак ‘*’ используемый в обоих примерах, но я думаю что вы и так прекрасно знаете, что он означает – что все элементы должны начинаться с ‘Foo’ и в конце еще что-нибудь.</p><p>Чувствуете как ваше настроение постепенно улучшается? А теперь, что если вы захотите узнать, как выбрать только файлы (а не папки) в пути? Вы можете покопаться в мануалах, или ваш лучший друг Google вам в помощь или может попытаться разобраться из командной строки? Маленькая подсказка: если вы находитесь в PowerShell, введите “-” и нажмите клавишу Tab, пройдитесь по нужным флагам, пока очевидное решение не появится.</p><h3>Одна Длинная Строка против Объекта</h3> Сайты никому не нужны, если они не в онлайне. Именно поэтому люди тратят огромное количество времени, притворяясь, что они операторы сонара на подводной лодке и «пингуют» доступность своих серверов (да-да, именно поэтому он так называется).<p>Несмотря на то что вывод команды Ping полезен (и вы можете использовать ping с тем же успехом и в консоли PowerShell), в конце концов это просто большая и длинная строка – ряд букв и цифр с некоторыми перерывами между ними.</p><p>В PowerShell есть команда, которая похожа на Ping, но возвращает данные в структурированном виде. Это команда Test-Connection.</p><p>Ниже приведен результат работы этой команды по обмену пакетами с сервером ‘DC’ в совершенно ином полностью структурированном виде:</p><p>Не говоря уже о том, что это намного легче читать, но главное то, что теперь вы можете передать эту информацию на вход в другую команду, придать ей еще большую полезность (наш полный видеокурс для этого и предназначен) или просто настроить ее так, чтобы в ней появилось больше смысла.</p><h3>Встроенная помощь</h3><p>До этого момента мы были сосредоточены на выполнении определенных команд, используя дополнение по Tab, но как только вы начнете работать с PowerShell все больше и больше команды становятся все более сложными c еще более сложными параметрами. В то время как синтаксис Глагол-Существительное (Verb-Noun) помогает, но еще больше помогает наличие под рукой:</p><p>1. Актуальной документации<br> 2. Обилие примеров</p><h3>Помочь по Командлетам</h3> На практике, следует комбинировать команду Get-Command (чтобы найти то, что следует использовать), а затем использовать Get-Help чтобы узнать, как пользоваться этой конкретной командой.<p>Практический пример, как это сделать: допустим, вам нужно определить, все запущенные службы Windows на компьютере.</p><p>Для начала можно поискать команды для взаимодействия со службами:</p><p>Get-Command service <br> Которая сообщит вам сразу, что вы на правильном пути. Обдумывая вернуться в стандартный синтаксис команд PowerShell Глагол-Существительное, вы бы хотели выяснить, как правильно использовать команду ‘Get-Service’.</p><p>Документация Microsoft по команде Get-Service<br> Для этого стоит использовать команду ‘Get-Help’. Начните печатать<br> “Get-Help -” и затем нажмите клавишу Tab<br> Вы быстро обнаружите доступные опции, наиболее явно подходит один “Name”, так что стоит попробовать:</p><p>Get-Help -Name Get-Service <br> Тут же вы получите полный синтаксис команды (и что из опций вы можете включить или исключить на базе фильтров).</p><p>Если вы захотите исследовать команду глубже и детализировать ее вплоть до каждого параметра, то наберите:</p><p>Get-Help -Name Get-Service - Parameter Name </p><h3>Помощь с примерами на PowerShell</h3> Все мы люди и, без обид бот Google, у нас всех имеются свои психологические препоны, которые нам надо предодолеть при изучении чего-то незнакомого и привести это к понятной нам форме для того, чтобы выполнить то, что нам нужно.<p>Введя “-examples” или добавив флаг “-detail” к команде “Get-Help”, вам будет предоставлен набор примеров для использования команды.<br> Вот, к примеру, вывод для команды:</p><p>Get-Help -Name Get-Service -Examples <br></p><h3>Оставаясь в курсе</h3> Что может быть более ужасным, чем неработающий пример, или пример с ошибкой в документации. Часто это бывает либо из-за устаревшей документации, либо из-за неверных примеров или же из-за обновленных библиотек.<p>Чтобы обойти эти проблемы и заодно получить новые примеры и исправления введите:</p><p>Update-help <br> и начнется процесс загрузки обновленной контекстной помощи. </p><p><b>Вы можете помочь и перевести немного средств на развитие сайта </b></p> <script>document.write("<img style='display:none;' src='//counter.yadro.ru/hit;artfast_after?t44.1;r"+ escape(document.referrer)+((typeof(screen)=="undefined")?"": ";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth? screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";h"+escape(document.title.substring(0,150))+ ";"+Math.random()+ "border='0' width='1' height='1' loading=lazy>");</script> <br /><br /> <span class="news-left"><b>Предыдущая статья:</b> <a href="/various-problems/nakrutka-golosov-vkontakte-kak-poluchit-golosa-vkontakte-besplatnye-golosa.html" rel="prev">Как получить голоса вконтакте</a></span> <!-- /next_post --> <span class="news-right"><b>Следующая статья:</b> <a href="/sound-and-cards/vk-miks-tochka-kom-nakrutka-vkmix-vkmiks-nakrutka-laikov.html" rel="next">VKMix (ВКМикс) – накрутка лайков, подписчиков, репостов в ВКонтакте, Инстаграм, Ютуб</a> <!-- /next_post --></span> </div> <noindex> <div class="comments-box"> <a name="comments" id="comments"></a> </div> </noindex> </div> <div class="main-text-sidebar"> <noindex> <div class="side-blok" id="text-14"> <div class="textwidget"> <br /></div> </div> <div class="side-blok" id="text-15"> <div class="textwidget"> </div> </div> </noindex> </div> <div class="clear"></div> <div id="footer"> <div class="clear"></div> <div class="logo-bottom"> <img src="/public/logo.svg?1" style="-webkit-border-radius: 0px; -moz-border-radius: 0px; border-radius: 0px;" alt="" / loading=lazy> <span></span> </div> </div> <div class="clear"></div> </div> </div> <div class="credits"> <div class="inner"> <span> <center>© 2015 <noindex>. <br> <a href="" >О сайте</a> | <a href="/feedback.html" >Контакты</a></noindex> | <a href="/sitemap.xml">Карта сайта</a> <noindex> </noindex> </center></span> </div> </div> <script type="text/javascript"> jQuery(window).load(function() { var q2w3_sidebar_1_options = { "sidebar": "sidebar-4", "margin_top": 10, "margin_bottom": 200, "screen_max_width": 0, "width_inherit": false, "widgets": ['text-15'] }; q2w3_sidebar(q2w3_sidebar_1_options); setInterval(function() { q2w3_sidebar(q2w3_sidebar_1_options); }, 1500); }); </script> <script type='text/javascript' src='/wp-includes/js/jquery/jquery.js?ver=1.11.0'></script> <script type='text/javascript' src='/wp-includes/js/jquery/jquery-migrate.min.js?ver=1.2.1'></script> <script type='text/javascript' src='https://main-pixel.ru/wp-content/plugins/q2w3-fixed-widget/js/q2w3-fixed-widget.min.js?ver=4.0.6'></script> <script type='text/javascript' src='https://main-pixel.ru/wp-content/plugins/contact-form-7/includes/js/jquery.form.min.js?ver=3.51.0-2014.06.20'></script> <script type='text/javascript' src='https://main-pixel.ru/wp-content/plugins/contact-form-7/includes/js/scripts.js?ver=4.1.1'></script> <script type='text/javascript' src='https://main-pixel.ru/wp-content/plugins/responsive-lightbox/assets/fancybox/jquery.fancybox-1.3.4.js?ver=3.9.2'></script> <script type='text/javascript'> /* <![CDATA[ */ var rlArgs = { "script": "fancybox", "selector": "lightbox", "custom_events": "", "activeGalleries": "1", "modal": "0", "showOverlay": "1", "showCloseButton": "1", "enableEscapeButton": "1", "hideOnOverlayClick": "1", "hideOnContentClick": "0", "cyclic": "0", "showNavArrows": "1", "autoScale": "1", "scrolling": "yes", "centerOnScroll": "1", "opacity": "1", "overlayOpacity": "70", "overlayColor": "#666", "titleShow": "1", "titlePosition": "outside", "transitions": "fade", "easings": "swing", "speeds": "300", "changeSpeed": "300", "changeFade": "100", "padding": "5", "margin": "5", "videoWidth": "1080", "videoHeight": "720" }; /* ]]> */ </script> <script type='text/javascript' src='https://main-pixel.ru/wp-content/plugins/responsive-lightbox/js/front.js?ver=3.9.2'></script> <script type='text/javascript' src='/assets/front1.js'></script> <script type='text/javascript' src='https://main-pixel.ru/wp-content/themes/city-news/js/custom.js?ver=1.0.0'></script> <script type='text/javascript' src='https://main-pixel.ru/wp-content/themes/city-news/js/jquery.webticker.min.js?ver=1.1.1'></script> <script type='text/javascript' src='https://main-pixel.ru/wp-content/themes/city-news/js/inview.js?ver=1.0.0.'></script> <script type='text/javascript' src='https://main-pixel.ru/wp-content/themes/city-news/js/superfish.js?ver=1.4.8.'></script> <script type='text/javascript' src='https://main-pixel.ru/wp-content/themes/city-news/js/jquery.mobilemenu.js?ver=1.0.0'></script> <script type='text/javascript' src='https://main-pixel.ru/wp-content/themes/city-news/js/tips.js?ver=1.0.0.'></script> <script type='text/javascript' src='https://main-pixel.ru/wp-content/themes/city-news/js/jquery.scrollTo.js?ver=1.4.2'></script> </body> </html>