Как создавать команды и функции в Powershell вызывать их и передавать параметры


12 октября 2019


Создание функций Powershell и команды с вызовом и передачей параметров

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

Создание

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

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

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

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

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

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

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

Get-DayLog

функции windows powershell

Учитывая, что нам может потребоваться получить данные не за последние 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

powershell вызов функции

При вызове функции мы передаем два обязательных параметра со значениями. Эти значения, внутри функции, будут доступны под названиями $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

powershell параметры функции

Мы должны всегда указывать ключ 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

powershell функции

Как видно на примере, если мы не указываем ключи 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 

powershell функции и процедуры

Мы не можем получить результат используя переменную $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

включения функции ввода команд в powershell

Я бы рекомендовал всегда возвращать значения через 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

powershell процедуры

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

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

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

создание скрипта powershell

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

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

командный файл powershell

Подробно о хэш таблицах в Powershell вы можете почитать в предыдущих статьях. Далее так же будет несколько примеров с ними.

Вы можете возвращать любой тип данных и в любом формате и последовательности. Каждый из них имеет своё преимущество.

Область видимости переменных

Все переменные объявленные до момента вызова функции могут быть ей использованы:

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

powershell написать скрипт

Такой подход не запрещает переопределить переменную внутри функции дав ей другое значение:

$Zarplata = 100000
function Get-Salary {
$Zarplata = 200000
$nalog = $Zarplata * $nalog
$zarplata_bez_nds = $Zarplata - $nalog
return @{"Налог"=$nalog;"Зарплата"=$zarplata_bez_nds;}
}
$nalog = 0.20
Get-Salary
$Zarplata

написание скрипта powershell

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

Такие переменные называются глобальными. Объявляются приставкой $global:

$Zarplata = 100000
function Get-Salary {
#Глобальная переменная
$global:Zarplata = 200000
$nalog = $Zarplata * $nalog
$zarplata_bez_nds = $Zarplata - $nalog
return @{"Налог"=$nalog;"Зарплата"=$zarplata_bez_nds;}
}
$nalog = 0.20
Get-Salary
$Zarplata

powershell передать параметры

Как вы видите, в отличие от предыдущего примера, переменная $zarplata изменила значение. Использование глобальных переменных является нежелательным так как может привести к ошибкам. Ваш скрипт может быть импортируемым модулем и об этой переменной может никто не знать, тем не менее она будет в области видимости.

 

Дополнительные возможности работы с параметрами

Строгие типы данных

Powershell автоматически преобразует типы данных. В отличие от других языков результат этого выражения будет число 3, а не "111":

3 * "1"

Такой подход может привести к ошибке. Мы можем исправить это объявляя типы:

function Get-Size ([int]$Num){
    $size = 18 * $Num
    return $size
}
Get-Size 5
Get-Size "str"

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

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

Таких типов данных в Powershell  всего 13:

  • [string] - строка;
  • [char] - 16-битовая строка Unicode;
  • [byte] - 8 битовый символ;
  • [int] - целое 32 битовое число;
  • [long] - целое 64 битовое число;
  • [bool] - булево значение True/False;
  • [decimal] - 128 битовое число с плавающей точкой;
  • [single] - 32 битовое число с плавающей точкой;
  • [double] - 64 битовое число с плавающей точкой;
  • [DateTime] - тип данных даты и времени;
  • [xml] - объект xml;
  • [array] - массив;
  • [hashtable] - хэш таблица.

Примеры работы с некоторыми типами данных вы увидите далее.

$args

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

function Get-Args {
    Write-Host "Пример с arg: " + $args[0] -BackgroundColor Red -ForegroundColor Black
    Write-Host "Пример с arg: " + $args[1] -BackgroundColor Black -ForegroundColor Red
}

Get-Args "Первый" "Второй"

функции windows powershell

Обратите внимание, что $args является массивом и значение получаются по индексу. Я не ставлю запятую при вызове функции так как в этом случае у меня был бы массив двойной вложенности.

Обязательные параметры Mandatory

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

function Get-ItemCreationTime ($item){
    Get-Item -Path $item | select LastWriteTime
}

Get-ItemCreationTime "C:\Windows\explorer.exe"
Get-ItemCreationTime

powershell вызов функции

Первый вызов функции прошел успешно, так как мы передали параметры. Во втором случае мы не передаем значения, а значит переменная $item равна $null (неопределенному/неизвестному значению). Во многих языках, в таких случаях, у нас появилась бы ошибка еще в момент вызова функции Get-ItemCreationTime, а не во время выполнения Get-Item.

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

function Get-ItemCreationTime ([parameter(Mandatory=$true)]$item){
    Get-Item -Path $item | select LastWriteTime
}

Get-ItemCreationTime "C:\Windows\explorer.exe"
Get-ItemCreationTime

powershell параметры функции

Атрибут Mandatory обязывает указывать значение. Если оно будет проигнорировано, то мы получим ошибку еще до момента выполнения функции.

Param()

Вы могли видеть функции, которые имеют значение Param(). Это значение так же объявляет параметры. На предыдущем примере это значение использовалось бы так:

function Get-ItemCreationTime {

	param (
		[parameter(Mandatory=$true)]$item
		)

    Get-Item -Path $item | select LastWriteTime
	}

Get-ItemCreationTime "C:\Windows\explorer.exe"
Get-ItemCreationTime

Microsoft Рекомендует использовать именно такой синтаксис написания функции, но не обязывает его использовать. Такой синтаксис говорит, что это не просто функция, а командлет.

Создадим скрипт, в котором будет происходить умножение, где добавим несколько обязательных параметров используя синтаксис с Param:

function Get-PlusPlus {
	param (
		[parameter(Mandatory=$true, Position=0)]
		[int]
		$item1,
        [parameter(Position=1)]
        [int]
        $item2,
        [parameter(Position=2)]
        [string]
        $item3
        )

    $summ = $item1 + $item2
    Write-Output $item3 $summ
	}

Get-PlusPlus 2 5 "Summ"

powershell функции

Position говорит под каким номером передается значение.

Одно из преимуществ работы с param() в том, что у нас становятся доступны ключи типа -Confirm и -Verbose. 

CmdletBinding()

Использование этого атрибута позволяет расширять возможность по созданию командлетов. Microsoft пишет, что использование CmdletBinding или Parameter расширяет возможность функций в Powershell, но по моему опыту не всегда все срабатывает и нужно ставить оба атрибута.

На примере ниже я установил ограничение на длину строк с 1 по 13 символов с помощью ValidateLength(1,13). Position=1 говорит об индексе элемента в массиве:

function Get-LenStr {
    [CmdletBinding()]
	param (        
		[parameter(Mandatory=$true,
                        Position=1
                        )]        
        [ValidateLength(1,13)]
		[string]
		$len1,
		[parameter(Mandatory=$true, 
                        Position=0
                        )]
		[string]
		$len2
        )
    Write-Host $len2 $len1
	}

Get-LenStr "Это строка 1" "Это строка 2"

Таких дополнительных аргументов для команд достаточно много. Для примера еще несколько атрибутов, которые можно добавить в блок parameter:

  • HelpMessage = "Текст"  - подсказка по использованию переменной. Это пояснение можно увидеть при запросе справки через Get-Help;
  • ParameterSetName="Computer" - указывает к какой переменной относятся параметры;

Отдельные блоки типа [ValidateLength]:

  • [Alias('t')] - устанавливает алиас для этого параметра в виде буквы t;
  • [PSDefaultValue(Test='Test')] - устанавливает значение по умолчанию переменной Test;
  • [string[]] - такое использование говорит, что значение принимает массив строк
  • [AllowNull()] - позволяет обязательным параметрам быть $null
  • [AllowEmptyString()] - позволяет обязательным параметрам быть пустой строкой
  • [AllowEmptyCollection()] - обязательный параметр с пустым массивом
  • [ValidateCount(1,5)] - минимальное и максимальное количество значений.
  • [ValidatePattern("[0-9]")] - проверка на шаблон используя регулярного выражения

Больше примеров и аргументов на сайте Microsoft.

 

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

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

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

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

function Get-ServiceStopped ([array]$Computers){
    $services = Get-Service -ComputerName $Computers | where Status -eq Stopped
    return $services
}

Get-ServiceStopped '127.0.0.1','localhost'

powershell функции и процедуры

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

function Get-ServiceStopped ([array]$Computers){
    $services = Get-Service -ComputerName $Computers[0,-2] | where Status -eq $Computers[-1]
    return $services
}

Get-ServiceStopped '127.0.0.1','localhost','Stopped'

Хэш таблицы

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

function Get-ServiceStopped ([hashtable]$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')}

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

 

Условия

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

IF

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

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

Get-SiteResponse

включения функции ввода команд в powershell

Switch

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

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

Get-SiteResponse

powershell процедурыДругой пример 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"

создание скрипта powershell

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

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


Switch-ServiceTest -On
Switch-ServiceTest

командный файл powershell

 

Передача через конвейер или 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

powershell написать скрипт

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

Get-Help Stop-Process -Parameter Name

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

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

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

function Get-SomeNum { 
        $num = Get-Random -Minimum 5 -Maximum 10
        return $num
}

function Plus-SomeNum {
    [cmdletbinding()]
    Param (
            [parameter(ValueFromPipeline=$True)]
            [int]
            $num
        )
    process {  
    Write-Host "Прибавление числа " $num 
    $num += $num
    return $num
    }
}

1..5 | Plus-SomeNum
Get-SomeNum | Plus-SomeNum

написание скрипта powershell

[cmdletbinding()] - атрибут расширения функции, который добавляет некоторые возможности в функции позволяя им работать как команду.

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

powershell передать параметры

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

function Get-SomeNum { 
    $num = Get-Random -Minimum 5 -Maximum 10
    $object = [pscustomobject]@{num=$num}
    return $object
}

function Plus-SomeNum {
    [cmdletbinding()]
    Param (
            [parameter(ValueFromPipelineByPropertyName=$True)]
            [int]
            $num
        )
    process {  
    Write-Host "Прибавление числа " $num 
    $num += $num
    return $num
    }
}

Get-SomeNum | Plus-SomeNum
[pscustomobject]@{num=5} | Plus-SomeNum
[pscustomobject]@{bad=5} | Plus-SomeNum

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

Как уже писалось 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.

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

[parameter(ValueFromPipelineByPropertyName,ValueFromPipeline)]

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

функции windows powershell

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

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

function Get-SomeNum { 
    $number1 = Get-Random -Minimum 5 -Maximum 10
    $number2 = Get-Random -Minimum 1 -Maximum 5
    $object = [pscustomobject]@{num1=$number1;num2=$number2}
    return $object
}

function Plus-SomeNum {
    [cmdletbinding()]
    Param (
            [parameter(ValueFromPipelineByPropertyName=$true,
                        ValueFromPipeline=$true,
                        Mandatory=$true)]
            [int]
            $num1,
            [parameter(ValueFromPipelineByPropertyName=$true,
                        ValueFromPipeline=$true,
                        Mandatory=$true)]
            [int]
            $num2
        )
    begin {$num1 += $num1
           $num2 = $num2 * $num2}
    process {  
    return @{"Результат сложения"=$num1; "Результат умножения"=$num2}
    }
}

Get-SomeNum | Plus-SomeNum

powershell вызов функции

 

Комментарии, описание и synopsis 

При вызове справки на любой командлет мы получим такую информацию:

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

function Get-SomeNum { 
  <#
  .SYNOPSIS
  (короткое описание) Получение случайного числа
  .DESCRIPTION
  (полное описание) Получение случайного числа от 1 до 3
  .EXAMPLE
  (пример) Get-Random
  .EXAMPLE
  (второй)
  .PARAMETER num
  (описание параметра) Параметр ни на что не влияет
  .PARAMETER num2
  (описание второго)
  #>
    [CmdletBinding()]
    param (
           [int]
           $num
    )
    $num = Get-Random -min 1 -Max 3
    return $num
}

Get-SomeNum

powershell параметры функции

Некоторые виды описаний, например Examples, можно использовать несколько раз.

 

Сохранение, загрузка и импорт

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

Импорт на множество компьютеров

Если это командлет, который будет использоваться на множестве компьютеров или вы его планируете использовать короткое время, то скрипт можно сохранить в файл с расширением ".ps1". Загрузка такой функции будет выполняться так:

Import-Module C:\funct.ps1 -Force

После выполнения этой команды мы сможем использовать нашу функцию.

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

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

Загрузка как модуля

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

Первое что нужно сделать это получить пути окружения Powershell:

$env:PSModulePath

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

C:\Users\%username%\Documents\WindowsPowerShell\Modules

В указанной папке Modules вам нужно создать папку и файл с одинаковыми именами. Файлу добавляете расширение ".psm1" и помещаете в него свой скрипт.

В моём случае путь выглядит так:

C:\Users\%username%\Documents\WindowsPowerShell\Modules\Test\Test.psm1

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

Get-Module -ListAvailable -Name "*Часть имени папки*"

 

...

Теги: #powershell


Популярные тэги
Каналы
О блоге
Этот блог представляет собой конспекты выученного материала, преобретенного опыта и лучшие практики в системном администрировании и программировании.