Функции powershell: Функции — PowerShell | Microsoft Learn

Содержание

Функции — PowerShell | Microsoft Learn


  • Статья



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

По возможности я предпочитаю писать функции, потому что они больше ориентированы на работу со средствами. Я могу поместить функции в модуль сценария, отправить этот модуль в $env:PSModulePath и вызвать функции без необходимости физического определения их местонахождения. С помощью модуля PowerShellGet эти модули можно легко запрашивать в репозитории NuGet. PowerShellGet поставляется с PowerShell версии 5.0 и выше. Он доступен в виде отдельного скачиваемого файла для PowerShell версии 3.0 и более поздних версий.

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

Именование

При именовании функций в PowerShell используйте имя в Регистр Pascal с утвержденным глаголом и существительным в единственном числе. Кроме того, перед существительным рекомендуется добавить префикс. Например: <ApprovedVerb>-<Prefix><SingularNoun>.

В PowerShell есть конкретный список утвержденных глаголов, которые можно получить, выполнив Get-Verb.

Get-Verb | Sort-Object -Property Verb
Verb        Group
----        -----
Add         Common
Approve     Lifecycle
Assert      Lifecycle
Backup      Data
Block       Security
Checkpoint  Data
Clear       Common
Close       Common
Compare     Data
Complete    Lifecycle
Compress    Data
Confirm     Lifecycle
Connect     Communications
Convert     Data
ConvertFrom Data
ConvertTo   Data
Copy        Common
Debug       Diagnostic
Deny        Lifecycle
Disable     Lifecycle
Disconnect  Communications
Dismount    Data
Edit        Data
Enable      Lifecycle
Enter       Common
Exit        Common
Expand      Data
Export      Data
Find        Common
Format      Common
Get         Common
Grant       Security
Group       Data
Hide        Common
Import      Data
Initialize  Data
Install     Lifecycle
Invoke      Lifecycle
Join        Common
Limit       Data
Lock        Common
Measure     Diagnostic
Merge       Data
Mount       Data
Move        Common
New         Common
Open        Common
Optimize    Common
Out         Data
Ping        Diagnostic
Pop         Common
Protect     Security
Publish     Data
Push        Common
Read        Communications
Receive     Communications
Redo        Common
Register    Lifecycle
Remove      Common
Rename      Common
Repair      Diagnostic
Request     Lifecycle
Reset       Common
Resize      Common
Resolve     Diagnostic
Restart     Lifecycle
Restore     Data
Resume      Lifecycle
Revoke      Security
Save        Data
Search      Common
Select      Common
Send        Communications
Set         Common
Show        Common
Skip        Common
Split       Common
Start       Lifecycle
Step        Common
Stop        Lifecycle
Submit      Lifecycle
Suspend     Lifecycle
Switch      Common
Sync        Data
Test        Diagnostic
Trace       Diagnostic
Unblock     Security
Undo        Common
Uninstall   Lifecycle
Unlock      Common
Unprotect   Security
Unpublish   Data
Unregister  Lifecycle
Update      Data
Use         Other
Wait        Lifecycle
Watch       Common
Write       Communications

В предыдущем примере результаты отсортированы по столбцу Verb. Взглянув на столбец Group, вы получите представление о том, как эти глаголы используются. При добавлении функций в модуль важно выбрать утвержденную команду в PowerShell. Если будет выбран неутвержденный глагол, модуль создаст предупреждение во время загрузки. Из-за этого предупреждения ваши функции выглядят непрофессионально. Кроме того, неутвержденные глаголы ограничивают возможности обнаружения функций.

Простая функция

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

function Get-Version {
    $PSVersionTable.PSVersion
}

Показан простой пример функции, возвращающей версию PowerShell.

Get-Version
Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      14393  693

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

function Get-PSVersion {
    $PSVersionTable.PSVersion
}

Эта функция идентична предыдущей, за исключением имени.

Get-PSVersion
Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      14393  693

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

function Get-MrPSVersion {
    $PSVersionTable.PSVersion
}

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

Get-MrPSVersion
Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      14393  693

Функции, загруженные в память, можно увидеть на PSDrive Function.

Get-ChildItem -Path Function:\Get-*Version
CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Get-Version
Function        Get-PSVersion
Function        Get-MrPSVersion

Чтобы удалить эти функции из текущего сеанса, необходимо удалить их из PSDrive Function или закрыть и повторно открыть PowerShell.

Get-ChildItem -Path Function:\Get-*Version | Remove-Item

Убедитесь, что функции действительно удалены.

Get-ChildItem -Path Function:\Get-*Version

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

Remove-Module -Name <ModuleName>

Командлет Remove-Module удаляет модули из памяти в текущем сеансе PowerShell, но не удаляет их из системы или с диска.

Параметры

Не присваивайте значения статически! Используйте параметры и переменные. Когда дело доходит до именования параметров, по возможности используйте те же имена, что и у командлетов по умолчанию.

function Test-MrParameter {
    param (
        $ComputerName
    )
    Write-Output $ComputerName
}

Почему в качестве имени параметра я использовал ComputerName, а не Computer, ServerName или Host? Потому что я хотел, чтобы мои функции были стандартизированы как стандартные командлеты.

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

function Get-MrParameterCount {
    param (
        [string[]]$ParameterName
    )
    foreach ($Parameter in $ParameterName) {
        $Results = Get-Command -ParameterName $Parameter -ErrorAction SilentlyContinue
        [pscustomobject]@{
            ParameterName = $Parameter
            NumberOfCmdlets = $Results.Count
        }
    }
}

Как видно в приведенных ниже результатах, у 39 команд есть параметр ComputerName. Командлеты с такими параметрами, как Computer, ServerName, Host или Machine, не найдены.

Get-MrParameterCount -ParameterName ComputerName, Computer, ServerName, Host, Machine
ParameterName NumberOfCmdlets
------------- ---------------
ComputerName               39
Computer                    0
ServerName                  0
Host                        0
Machine                     0

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

Оператор param позволяет определить один или несколько параметров. Определения параметров разделяются запятой (,). Дополнительные сведения см. в разделе about_Functions_Advanced_Parameters.

Расширенные функции

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

Я начну с функции Test-MrParameter, которая использовалась в предыдущем разделе.

function Test-MrParameter {
    param (
        $ComputerName
    )
    Write-Output $ComputerName
}

Хочу обратить ваше внимание на то, что функция Test-MrParameter не имеет общих параметров. Существует несколько различных способов просмотра общих параметров. Один из них — просмотр синтаксиса с помощью Get-Command.

Get-Command -Name Test-MrParameter -Syntax
Test-MrParameter [[-ComputerName] <Object>]

Другой — детализация параметров с помощью Get-Command.

(Get-Command -Name Test-MrParameter).Parameters.Keys
ComputerName

Добавьте CmdletBinding, чтобы преобразовать функцию в расширенную.

function Test-MrCmdletBinding {
    [CmdletBinding()] #<<-- This turns a regular function into an advanced function
    param (
        $ComputerName
    )
    Write-Output $ComputerName
}

При добавлении CmdletBinding общие параметры добавляются автоматически. Для CmdletBinding требуется блок param, но блок param может быть пустым.

Get-Command -Name Test-MrCmdletBinding -Syntax
Test-MrCmdletBinding [[-ComputerName] <Object>] [<CommonParameters>]

Если выполнить детализацию параметров с помощью Get-Command, можно увидеть имена параметров, включая общие параметры.

(Get-Command -Name Test-MrCmdletBinding).Parameters.Keys
ComputerName
Verbose
Debug
ErrorAction
WarningAction
InformationAction
ErrorVariable
WarningVariable
InformationVariable
OutVariable
OutBuffer
PipelineVariable

SupportsShouldProcess

SupportsShouldProcess добавляет параметры WhatIf и Confirm. Они необходимы только для команд, которые вносят изменения.

function Test-MrSupportsShouldProcess {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        $ComputerName
    )
    Write-Output $ComputerName
}

Обратите внимание, что теперь появились параметры WhatIf и Confirm.

Get-Command -Name Test-MrSupportsShouldProcess -Syntax
Test-MrSupportsShouldProcess [[-ComputerName] <Object>] [-WhatIf] [-Confirm] [<CommonParameters>]

Опять же: с помощью Get-Command можно получить список фактических имен параметров, включая общие параметры и WhatIf и Confirm.

(Get-Command -Name Test-MrSupportsShouldProcess).Parameters.Keys
ComputerName
Verbose
Debug
ErrorAction
WarningAction
InformationAction
ErrorVariable
WarningVariable
InformationVariable
OutVariable
OutBuffer
PipelineVariable
WhatIf
Confirm

Проверка параметров

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

Всегда вводите переменные, используемые для параметров (с указанием типа данных).

function Test-MrParameterValidation {
    [CmdletBinding()]
    param (
        [string]$ComputerName
    )
    Write-Output $ComputerName
}

В предыдущем примере в качестве типа данных для параметра ComputerName указано String. Это означает, что допускается только одно имя компьютера. Если задается несколько имен компьютеров в виде списка с разделителями-запятыми, возникает ошибка.

Test-MrParameterValidation -ComputerName Server01, Server02
Test-MrParameterValidation : Cannot process argument transformation on parameter
'ComputerName'. Cannot convert value to type System.String.
At line:1 char:42
+ Test-MrParameterValidation -ComputerName Server01, Server02
+
    + CategoryInfo          : InvalidData: (:) [Test-MrParameterValidation], ParameterBindingArg
     umentTransformationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Test-MrParameterValidation

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

function Test-MrParameterValidation {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [string]$ComputerName
    )
    Write-Output $ComputerName
}

В предыдущем примере используется синтаксис, совместимый с PowerShell версии 3.0 и более поздними.
Чтобы обеспечить совместимость функции с PowerShell версии 2.0 и более поздними, можно указать [Parameter(Mandatory=$true)]. Теперь, когда потребуется значение параметра ComputerName, которое пока не задано, функция выведет соответствующий запрос.

Test-MrParameterValidation
cmdlet Test-MrParameterValidation at command pipeline position 1
Supply values for the following parameters:
ComputerName:

Чтобы разрешить несколько значений для параметра ComputerName, используйте тип данных String, но добавьте к нему открывающие и закрывающие квадратные скобки, позволяющие использовать массив строк.

function Test-MrParameterValidation {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [string[]]$ComputerName
    )
    Write-Output $ComputerName
}

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

function Test-MrParameterValidation {
    [CmdletBinding()]
    param (
        [ValidateNotNullOrEmpty()]
        [string[]]$ComputerName = $env:COMPUTERNAME
    )
    Write-Output $ComputerName
}

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

Подробные выходные данные

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

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

function Test-MrVerboseOutput {
    [CmdletBinding()]
    param (
        [ValidateNotNullOrEmpty()]
        [string[]]$ComputerName = $env:COMPUTERNAME
    )
    foreach ($Computer in $ComputerName) {
        #Attempting to perform some action on $Computer <<-- Don't use
        #inline comments like this, use write verbose instead.
        Write-Output $Computer
    }
}

Лучшим вариантом является использование Write-Verbose вместо встроенных комментариев.

function Test-MrVerboseOutput {
    [CmdletBinding()]
    param (
        [ValidateNotNullOrEmpty()]
        [string[]]$ComputerName = $env:COMPUTERNAME
    )
    foreach ($Computer in $ComputerName) {
        Write-Verbose -Message "Attempting to perform some action on $Computer"
        Write-Output $Computer
    }
}

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

Test-MrVerboseOutput -ComputerName Server01, Server02

При вызове функции с параметром verbose будут выведены подробные выходные данные.

Test-MrVerboseOutput -ComputerName Server01, Server02 -Verbose

Входные данные конвейера

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

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

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

function Test-MrPipelineInput {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory,
                   ValueFromPipeline)]
        [string[]]$ComputerName
    )
    PROCESS {
        Write-Output $ComputerName
    }
}

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

function Test-MrPipelineInput {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory,
                   ValueFromPipelineByPropertyName)]
        [string[]]$ComputerName
    )
    PROCESS {
            Write-Output $ComputerName
    }
}

Блоки BEGIN и END являются необязательными. BEGIN указывается перед блоком PROCESS и используется для выполнения всех начальных задач до получения элементов из конвейера. Разобраться с этим очень важно. Переданные значения недоступны в блоке BEGIN. Блок END указывается после блока PROCESS и используется для очистки после обработки всех переданных элементов.

Обработка ошибок

Функция, показанная в следующем примере, создает необработанное исключение, если не удается связаться с компьютером.

function Test-MrErrorHandling {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory,
                   ValueFromPipeline,
                   ValueFromPipelineByPropertyName)]
        [string[]]$ComputerName
    )
    PROCESS {
        foreach ($Computer in $ComputerName) {
            Test-WSMan -ComputerName $Computer
        }
    }
}

В PowerShell существует несколько различных способов обработки ошибок. Более современным является Try/Catch.

function Test-MrErrorHandling {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory,
                   ValueFromPipeline,
                   ValueFromPipelineByPropertyName)]
        [string[]]$ComputerName
    )
    PROCESS {
        foreach ($Computer in $ComputerName) {
            try {
                Test-WSMan -ComputerName $Computer
            }
            catch {
                Write-Warning -Message "Unable to connect to Computer: $Computer"
            }
        }
    }
}

Хотя функция, показанная в предыдущем примере, использует обработку ошибок, она также выдает необработанное исключение, так как команда не создает неустранимую ошибку. Разобраться с этим очень важно! Перехватываются только устранимые ошибки. Чтобы преобразовать неустранимую ошибку в устранимую, укажите параметр ErrorAction со значением Stop.

function Test-MrErrorHandling {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory,
                   ValueFromPipeline,
                   ValueFromPipelineByPropertyName)]
        [string[]]$ComputerName
    )
    PROCESS {
        foreach ($Computer in $ComputerName) {
            try {
                Test-WSMan -ComputerName $Computer -ErrorAction Stop
            }
            catch {
                Write-Warning -Message "Unable to connect to Computer: $Computer"
            }
        }
    }
}

Не изменяйте глобальную переменную $ErrorActionPreference, если в этом нет крайней необходимости. Если вы используете нечто вроде .NET непосредственно в функции PowerShell, параметр ErrorAction невозможно указать в самой команде. В этом случае может потребоваться изменить глобальную переменную $ErrorActionPreference, но, если вы измените ее, верните ее к исходному виду сразу же после того, как попробуете запустить команду.

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

function Get-MrAutoStoppedService {
<#
.SYNOPSIS
    Returns a list of services that are set to start automatically, are not
    currently running, excluding the services that are set to delayed start.
.DESCRIPTION
    Get-MrAutoStoppedService is a function that returns a list of services from
    the specified remote computer(s) that are set to start automatically, are not
    currently running, and it excludes the services that are set to start automatically
    with a delayed startup.
.PARAMETER ComputerName
    The remote computer(s) to check the status of the services on.
.PARAMETER Credential
    Specifies a user account that has permission to perform this action.  The default
    is the current user.
.EXAMPLE
     Get-MrAutoStoppedService -ComputerName 'Server1', 'Server2'
.EXAMPLE
     'Server1', 'Server2' | Get-MrAutoStoppedService
.EXAMPLE
     Get-MrAutoStoppedService -ComputerName 'Server1' -Credential (Get-Credential)
.INPUTS
    String
.OUTPUTS
    PSCustomObject
.NOTES
    Author:  Mike F Robbins
    Website: http://mikefrobbins.com
    Twitter: @mikefrobbins
#>
    [CmdletBinding()]
    param (
    )
    #Function Body
}

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

Весь синтаксис написания функции в PowerShell может показаться слишком объемным и перегруженным, особенно для тех, кто только начинает работу с этой оболочкой. Часто, если я не могу вспомнить какой-то синтаксис, я открываю вторую копию ISE на отдельном мониторе, просматриваю фрагмент «Cmdlet (расширенная функция) — Complete» и одновременно ввожу код для функции. В интегрированной среде сценариев PowerShell доступ к фрагментам кода можно получить с помощью сочетания клавиш CTRL+J.

Сводка

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

Просмотр

  1. Как получить список утвержденных глаголов в PowerShell?
  2. Как преобразовать функцию PowerShell в расширенную функцию?
  3. Когда следует добавлять параметры WhatIf и Confirm в функции PowerShell?
  4. Как преобразовать неустранимую ошибку в устранимую?
  5. Для чего нужно добавлять справку на основе комментариев к функциям?

Рекомендуем прочесть

  • about_Functions
  • about_Functions_Advanced_Parameters
  • about_CommonParameters
  • about_Functions_CmdletBindingAttribute
  • about_Functions_Advanced
  • about_Try_Catch_Finally
  • about_Comment_Based_Help
  • Видео: создание инструментов PowerShell с помощью расширенных функций и модулей сценариев

о функциях — PowerShell | Microsoft Learn


  • Статья



Краткое описание

Описывает создание и использование функций в PowerShell.

Подробное описание

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

Функции могут быть простыми:

function Get-PowerShellProcess { Get-Process PowerShell }

Функция также может быть такой же сложной, как командлет или приложение.

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

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

Список инструкций функции может содержать различные типы списков операторов с ключевыми словами begin, process, endи clean. Эти списки операторов обрабатывают входные данные из конвейера по-разному.

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

Функции также могут действовать как командлеты. Вы можете создать функцию, которая работает так же, как командлет, без использования C# программирования. Дополнительные сведения см. в разделе about_Functions_Advanced.

Важно!

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

Синтаксис

Ниже приведен синтаксис функции.

function [<scope:>]<name> [([type]$parameter1[,[type]$parameter2])]
{
  begin {<statement list>}
  process {<statement list>}
  end {<statement list>}
  clean {<statement list>}
}
function [<scope:>]<name>
{
  param([type]$parameter1 [,[type]$parameter2])
  dynamicparam {<statement list>}
  begin {<statement list>}
  process {<statement list>}
  end {<statement list>}
  clean {<statement list>}
}

Функция включает следующие элементы:

  • Ключевое слово A function
  • Область (необязательно)
  • Выбранное имя
  • Любое количество именованных параметров (необязательно)
  • Одна или несколько команд PowerShell, заключенных в фигурные скобки {}

Дополнительные сведения о ключевом слове Dynamicparam и динамических параметрах в функциях см. в разделе about_Functions_Advanced_Parameters.

Простые функции

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

function <function-name> {statements}

Например, следующая функция запускает PowerShell с параметром Запуск от имени администратора .

function Start-PSAdmin {Start-Process PowerShell -Verb RunAs}

Чтобы использовать функцию , введите: Start-PSAdmin

Чтобы добавить операторы в функцию, введите каждый оператор в отдельной строке или используйте точку с запятой ; для разделения операторов.

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

function Get-NewPix
{
  $start = Get-Date -Month 1 -Day 1 -Year 2010
  $allpix = Get-ChildItem -Path $env:UserProfile\*.jpg -Recurse
  $allpix | Where-Object {$_.LastWriteTime -gt $Start}
}

Вы можете создать панель элементов полезных небольших функций. Добавьте эти функции в профиль PowerShell, как описано в about_Profiles и далее в этом разделе.

Имена функций

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

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

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

Дополнительные сведения о стандартных командах PowerShell см. в разделе Утвержденные команды.

Функции с параметрами

С функциями можно использовать параметры, включая именованные параметры, позиционные параметры, параметры switch и динамические параметры. Дополнительные сведения о динамических параметрах в функциях см. в разделе about_Functions_Advanced_Parameters.

именованных параметров

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

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

function <name> {
  param ([type]$parameter1 [,[type]$parameter2])
  <statement list>
}

Кроме того, можно определить параметры за пределами фигурных скобок без ключевого Param слова , как показано в следующем примере синтаксиса:

function <name> [([type]$parameter1[,[type]$parameter2])] {
  <statement list>
}

Ниже приведен пример этого альтернативного синтаксиса.

function Add-Numbers([int]$one, [int]$two) {
    $one + $two
}

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

При запуске функции значение, указываемое для параметра, присваивается переменной, содержащей имя параметра. Значение этой переменной можно использовать в функции .

В следующем примере показана функция с именем Get-SmallFiles. Эта функция имеет $Size параметр . Функция отображает все файлы, которые меньше значения $Size параметра, и исключает каталоги:

function Get-SmallFiles {
  Param($Size)
  Get-ChildItem $HOME | Where-Object {
    $_.Length -lt $Size -and !$_.PSIsContainer
  }
}

В функции можно использовать $Size переменную , которая является именем, определенным для параметра .

Чтобы использовать эту функцию, введите следующую команду:

Get-SmallFiles -Size 50

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

Get-SmallFiles 50

Чтобы определить значение по умолчанию для параметра, введите знак равенства и значение после имени параметра, как показано в следующем варианте Get-SmallFiles примера:

function Get-SmallFiles ($Size = 100) {
  Get-ChildItem $HOME | Where-Object {
    $_. Length -lt $Size -and !$_.PSIsContainer
  }
}

При вводе Get-SmallFiles без значения функция присваивает значение 100 $size. Если указать значение, функция использует это значение.

При необходимости можно предоставить краткую строку справки, описывающую значение параметра по умолчанию, добавив атрибут PSDefaultValue в описание параметра и указав свойство Helpпараметра PSDefaultValue. Чтобы предоставить строку справки, описывающую значение по умолчанию (100) параметра Size в Get-SmallFiles функции, добавьте атрибут PSDefaultValue , как показано в следующем примере.

function Get-SmallFiles {
  param (
      [PSDefaultValue(Help = '100')]
      $Size = 100
  )
}

Дополнительные сведения о классе атрибутов PSDefaultValue см. в разделе Элементы атрибута PSDefaultValue.

Позиционные параметры

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

При использовании позиционных параметров введите одно или несколько значений после имени функции. Значения позиционных параметров назначаются переменной массива $args .
Значение, следующее за именем функции, назначается первой позиции в массиве $args , $args[0].

Следующая Get-Extension функция добавляет .txt расширение имени файла в указанное имя файла:

function Get-Extension {
  $name = $args[0] + ".txt"
  $name
}
Get-Extension myTextFile
myTextFile.txt

Переключение параметров

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

Чтобы определить параметр switch, укажите тип [switch] перед именем параметра, как показано в следующем примере:

function Switch-Item {
  param ([switch]$on)
  if ($on) { "Switch on" }
  else { "Switch off" }
}

При вводе On параметра switch после имени функции функция отображает . Switch on Без параметра switch отображается Switch off.

Switch-Item -on
Switch on
Switch-Item
Switch off

При запуске функции можно также назначить логическое значение параметру, как показано в следующем примере:

Switch-Item -on:$true
Switch on
Switch-Item -on:$false
Switch off

Использование splatting для представления параметров команды

Для представления параметров команды можно использовать сплаттинг. Эта функция появилась в Windows PowerShell 3.0.

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

Следующий пример функции вызывает Get-Command командлет . Команда использует @Args для представления параметров .Get-Command

function Get-MyCommand { Get-Command @Args }

При вызове Get-MyCommand функции можно использовать все параметры Get-Command . Параметры и значения параметров передаются команде с помощью @Args.

Get-MyCommand -Name Get-ChildItem
CommandType     Name                ModuleName
-----------     ----                ----------
Cmdlet          Get-ChildItem       Microsoft.PowerShell.Management

Функция @Args использует $Args параметр automatic, который представляет необъявленные параметры командлета и значения из оставшихся аргументов.

Дополнительные сведения см. в разделе about_Splatting.

Передача объектов в функции

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

function <name> {
  begin {<statement list>}
  process {<statement list>}
  end {<statement list>}
  clean {<statement list>}
}

Важно!

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

Список begin инструкций выполняется только один раз в начале функции.

Список process инструкций выполняется один раз для каждого объекта в конвейере.
process Во время выполнения блока каждый объект конвейера назначается автоматической $_ переменной по одному объекту конвейера за раз.

После того как функция получит все объекты в конвейере, список инструкций end выполняется один раз.

Следующая функция использует ключевое process слово . Функция отображает значения из конвейера:

function Get-Pipeline
{
  process {"The value is: $_"}
}
1,2,4 | Get-Pipeline
The value is: 1
The value is: 2
The value is: 4

При использовании функции в конвейере объекты, переданные в функцию, назначаются автоматической переменной $input . Функция выполняет инструкции с ключевым словом , begin прежде чем какие-либо объекты поступают из конвейера. Функция выполняет инструкции с ключевым словом после end получения всех объектов из конвейера.

В следующем примере показана автоматическая $input переменная с begin ключевыми словами и end .

function Get-PipelineBeginEnd
{
    begin {"Begin: The input is $input"}
    end   {"End:   The input is $input" }
}

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

1,2,4 | Get-PipelineBeginEnd
Begin: The input is
End:   The input is 1 2 4

При выполнении инструкции begin функция не имеет входных данных из конвейера. Инструкция end выполняется после того, как функция имеет значения.

Если функция имеет ключевое process слово , каждый объект в $input удаляется из $input и назначается $_. В следующем примере содержится список инструкций process :

function Get-PipelineInput
{
    process {"Processing:  $_ " }
    end     {"End:   The input is: $input" }
}

В этом примере каждый объект, передаваемый в функцию, отправляется в список инструкций process . Инструкции process выполняются для каждого объекта по одному объекту за раз. Автоматическая $input переменная пуста, когда функция достигает ключевого end слова .

1,2,4 | Get-PipelineInput
Processing:  1
Processing:  2
Processing:  4
End:   The input is:

Дополнительные сведения см. в разделе Использование перечислителей.

PowerShell 7.3 добавил блок clean . Блок clean — это удобный способ очистки ресурсов, созданных и используемых в блоках begin, processи end . Семантически он похож на блок finally, охватывающий все другие именованные блоки функции скрипта или командлета скрипта. Очистка ресурсов применяется в следующих сценариях:

  1. Когда выполнение конвейера завершается нормально без неустранимой ошибки.
  2. Когда выполнение конвейера прерывается из-за неустранимой ошибки.
  3. Если конвейер остановлен с помощью Select-Object -First.
  4. при остановке конвейера с помощью клавиш CTRL+C или StopProcessing()

Внимание!

Добавление блока clean является критическим изменением. Поскольку clean анализируется как ключевое слово, пользователи не могут напрямую вызвать команду clean в качестве первой инструкции в блоке скрипта. Однако это вряд ли будет проблемой. Команду по-прежнему можно вызвать с помощью оператора вызова (& clean).

Фильтры

Фильтр — это тип функции, которая выполняется для каждого объекта в конвейере. Фильтр напоминает функцию со всеми ее операторами в блоке process .

Синтаксис фильтра выглядит следующим образом:

filter [<scope:>]<name> {<statement list>}

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

filter Get-ErrorLog ([switch]$Message)
{
  if ($Message) { Out-Host -InputObject $_. Message }
  else { $_ }
}

Эта функция используется следующим образом.

Get-WinEvent -LogName System -MaxEvents 100 | Get-ErrorLog -Message

Область функции

Функция существует в области, в которой она создана.

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

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

function global:Get-DependentSvs {
  Get-Service | Where-Object {$_.DependentServices}
}

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

Функции создают новую область. Элементы, созданные в функции, например переменные, существуют только в области функции.

Дополнительные сведения см. в разделе about_Scopes.

Поиск функций и управление ими с помощью функции: диск

Все функции и фильтры в PowerShell автоматически сохраняются на Function: диске. Этот диск предоставляется поставщиком функций PowerShell.

При обращении к диску Function: введите двоеточие после функции так же, как и при ссылке C на диск или D компьютера.

Следующая команда отображает все функции в текущем сеансе PowerShell:

Get-ChildItem function:

Команды в функции хранятся в виде блока скрипта в свойстве definition функции. Например, чтобы отобразить команды в функции Help, которая поставляется с PowerShell, введите:

(Get-ChildItem function:help).Definition

Можно также использовать следующий синтаксис.

$function:help

Дополнительные сведения о диске см. в Function: разделе справки для поставщика функций . Введите Get-Help Function.

Повторное использовать функции в новых сеансах

При вводе функции в командной строке PowerShell она становится частью текущего сеанса. Функция доступна до завершения сеанса.

Чтобы использовать функцию во всех сеансах PowerShell, добавьте функцию в профиль PowerShell. Дополнительные сведения о профилях см. в разделе about_Profiles.

Вы также можете сохранить функцию в файле скрипта PowerShell. Введите функцию в текстовый файл, а затем сохраните файл с расширением .ps1 filename.

Справка по написанию функций

Командлет Get-Help получает справку для функций, а также для командлетов, поставщиков и скриптов. Чтобы получить справку по функции, введите Get-Help ее имя.

Например, чтобы получить справку по функции, введите Get-MyDisks :

Get-Help Get-MyDisks

Справку для функции можно написать с помощью двух следующих методов:

  • Comment-Based справка по функциям

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

  • XML-Based справка по функциям

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

    Чтобы связать функцию с разделом справки на основе XML, используйте ключевое слово справки .EXTERNALHELP на основе комментариев. Без этого ключевого слова Get-Help не удается найти раздел справки функции, и вызовы Get-Help функции возвращают только автоматически созданную справку.

    Дополнительные сведения о ключевом слове см. в .EXTERNALHELPразделе about_Comment_Based_Help. Дополнительные сведения о справке на основе XML см. в разделе Практическое руководство по написанию командлетов.

См. также раздел

  • about_Automatic_Variables
  • about_Comment_Based_Help
  • about_Function_Provider
  • about_Functions_Advanced
  • about_Functions_Advanced_Methods
  • about_Functions_Advanced_Parameters
  • about_Functions_CmdletBindingAttribute
  • about_Functions_OutputTypeAttribute
  • about_Parameters
  • about_Profiles
  • about_Scopes
  • about_Script_Blocks

функций — PowerShell | Microsoft Learn

  • Статья

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

Когда это возможно, я предпочитаю писать функции, потому что они больше ориентированы на инструменты. я могу поставить
функции в модуле сценария, поместите этот модуль в $env:PSModulePath и вызовите функции
без необходимости физически определять, где они сохранены. Используя модуль PowerShellGet, легко
чтобы поделиться этими модулями в репозитории NuGet. PowerShellGet поставляется с PowerShell версии 5.0 и
выше. Он доступен для отдельной загрузки для PowerShell версии 3.0 и выше.

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

Именование

При именовании функций в PowerShell используйте регистровое имя Pascal с одобренным глаголом и
существительное в единственном числе. Я также рекомендую ставить префикс существительного. Например:
- .

В PowerShell есть определенный список утвержденных команд, которые можно получить, запустив Get-Verb .

 Get-глагол | Sort-Object -Глагол свойства
 
 Глагольная группа
---- -----
Добавить общий
Утвердить жизненный цикл
Утвердить жизненный цикл
Резервные данные
Блокировать безопасность
Данные контрольной точки
Очистить общий
Закрыть Общие
Сравнить данные
Полный жизненный цикл
Сжать данные
Подтвердить жизненный цикл
Подключить связь
Преобразование данных
Преобразовать из данных
Преобразовать в данные
Копировать общий
Диагностика отладки
Запретить жизненный цикл
Отключить жизненный цикл
Отключить связь
Размонтировать данные
Изменить данные
Включить жизненный цикл
Введите общий
Выход Общий
Развернуть данные
Экспорт данных
Найдите общее
Общий формат
Получить общий
Грант безопасности
Групповые данные
Скрыть общее
Импорт данных
Инициализировать данные
Установить жизненный цикл
Вызвать жизненный цикл
Присоединяйтесь к общему
Ограничить данные
Общий замок
Измерение диагностики
Объединить данные
Данные монтирования
Переместить общий
Новый общий
Открытый общий
Оптимизировать общее
Выходные данные
Пинг-диагностика
Поп-музыка
Защита безопасности
Опубликовать данные
Нажмите Общий
Читать сообщения
Получать сообщения
Повторить общий
Зарегистрировать жизненный цикл
Удалить общий
Переименовать общее
Диагностика ремонта
Жизненный цикл запроса
Сброс общего
Изменить размер Общий
Разрешить диагностику
Перезапустить жизненный цикл
Восстановить данные
Возобновить жизненный цикл
Отменить безопасность
Сохранить данные
Поиск Общий
Выберите общий
Отправить сообщения
Установить общий
Показать общее
Пропустить общий
Разделить общий
Начать жизненный цикл
Общий шаг
Остановить жизненный цикл
Отправить жизненный цикл
Приостановить жизненный цикл
Общий переключатель
Синхронизировать данные
Тестовая диагностика
Диагностика трассировки
Разблокировать безопасность
Отменить Общие
Удалить жизненный цикл
Разблокировать общий
Снять защиту безопасности
Отменить публикацию данных
Отменить регистрацию жизненного цикла
Обновить данные
Использовать другое
Жизненный цикл ожидания
Смотреть Общие
Пишите сообщения
 

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

Простая функция

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

 функция Get-Version {
    $PSVersionTable.PSVersion
}
 

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

 Get-версия
 
 Основная незначительная версия сборки
----- ----- ----- --------
5 1 14393 693
 

Существует большая вероятность конфликта имен с функциями с именами вроде Get-Version и default
команды в PowerShell или команды, которые могут написать другие. Вот почему я рекомендую ставить префикс существительного
часть ваших функций, чтобы помочь предотвратить конфликты имен. В следующем примере я буду использовать
префикс «ПС».

 функция Get-PSVersion {
    $PSVersionTable.PSVersion
}
 

За исключением названия, эта функция идентична предыдущей.

 Get-PSVersion
 
 Основная незначительная версия сборки
----- ----- ----- --------
5 1 14393 693
 

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

 функция Get-MrPSVersion {
    $PSVersionTable.PSVersion
}
 

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

 Get-MrPSVersion
 
 Основная незначительная версия сборки
----- ----- ----- --------
5 1 14393 693
 

После загрузки в память вы можете увидеть функции на Function PSDrive.

 Get-ChildItem -Path Функция:\Get-*Version
 
 CommandType Имя Версия Источник
----------- ---- ------- ------
Функция Get-Version
Функция Get-PSVersion
Функция Get-MrPSVersion
 

Если вы хотите удалить эти функции из текущего сеанса, вам придется удалить их из
Функция PSDrive или закройте и снова откройте PowerShell.

 Get-ChildItem -Path Функция:\Get-*Version | Убрать предмет
 

Убедитесь, что функции действительно удалены.

 Get-ChildItem -Path Функция:\Get-*Version
 

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

 Remove-Module -Name 
 

Командлет Remove-Module удаляет модули из памяти в текущем сеансе PowerShell.
не удаляет их из вашей системы или с диска.

Параметры

Не присваивать значения статически! Используйте параметры и переменные. Когда дело доходит до именования вашего
параметров, используйте то же имя, что и командлеты по умолчанию для имен ваших параметров, когда это возможно.

 функция Test-MrParameter {
    параметр (
        $ИмяКомпьютера
    )
    Запись-вывод $ComputerName
}
 

Почему я использовал ComputerName , а не Computer , ServerName или Host для моего параметра
имя? Это потому, что я хотел, чтобы моя функция была стандартизирована, как командлеты по умолчанию.

Я создам функцию для запроса всех команд в системе и возврата их количества, которое
имеют определенные имена параметров.

 функция Get-MrParameterCount {
    параметр (
        [строка[]]$имя_параметра
    )
    foreach ($Parameter в $ParameterName) {
        $Results = Get-Command -ParameterName $Parameter -ErrorAction SilentlyContinue
        [pscustomobject]@{
            ИмяПараметра = $Параметр
            NumberOfCmdlets = $Результаты.Количество
        }
    }
}
 

Как видно из приведенных ниже результатов, 39 команд имеют параметр ComputerName . Там
нет командлетов с такими параметрами, как Computer , ServerName , Host или
Машина .

 Get-MrParameterCount -ParameterName ComputerName, Computer, ServerName, Host, Machine
 
 ParameterName NumberOfCmdlets
------------- ---------------
имя_компьютера 39
Компьютер 0
ИмяСервера 0
Хост 0
Машина 0
 

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

Оператор param позволяет определить один или несколько параметров. Определения параметров
разделенные запятой ( , ). Дополнительные сведения см. в разделе about_Functions_Advanced_Parameters.

Расширенные функции

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

Я начну с функции Test-MrParameter , которая использовалась в предыдущем разделе.

 функция Test-MrParameter {
    параметр (
        $ИмяКомпьютера
    )
    Запись-вывод $ComputerName
}
 

Я хочу, чтобы вы заметили, что функция Test-MrParameter не имеет общих
параметры. Существует несколько различных способов просмотра общих параметров. Один из них — просмотр
синтаксис с использованием Get-Command .

 Get-Command -Name Test-MrParameter -Syntax
 
 Test-MrParameter [[-ComputerName] ]
 

Еще один способ — детализировать параметры с помощью Get-команда .

 (Get-Command -Name Test-MrParameter). Параметры.Ключи
 
 ИмяКомпьютера
 

Добавьте CmdletBinding , чтобы превратить функцию в расширенную.

 функция Test-MrCmdletBinding {
    [CmdletBinding()] #<<-- Превращает обычную функцию в расширенную.
    параметр (
        $ИмяКомпьютера
    )
    Запись-вывод $ComputerName
}
 

Добавление CmdletBinding автоматически добавляет общие параметры. CmdletBinding требуется параметр
блок, но блок param может быть пустым.

 Get-Command -Name Test-MrCmdletBinding -Syntax
 
 Test-MrCmdletBinding [[-ComputerName] ] []
 

Детализация параметров с помощью Get-Command показывает фактические имена параметров, включая
общие.

 (Get-Command -Name Test-MrCmdletBinding).Параметры.Ключи
 
 ИмяКомпьютера
Подробный
Отлаживать
ErrorAction
ПредупреждениеДействие
ИнформацияДействие
ErrorVariable
ПредупреждениеПеременная
ИнформацияПеременная
OutVariable
OutBuffer
PipelineVariable
 

SupportsShouldProcess

SupportsShouldProcess добавляет WhatIf и Подтверждение параметров. Они нужны только для
команды, которые вносят изменения.

 функция Test-MrSupportsShouldProcess {
    [CmdletBinding (SupportsShouldProcess)]
    параметр (
        $ИмяКомпьютера
    )
    Запись-вывод $ComputerName
}
 

Обратите внимание, что теперь есть параметры WhatIf и Confirm .

 Get-Command -Name Test-MrSupportsShouldProcess -Syntax
 
 Test-MrSupportsShouldProcess [[-ComputerName] ] [-WhatIf] [-Confirm] []
 

Еще раз, вы также можете использовать Get-Command для возврата списка фактических имен параметров, включая
общие вместе с WhatIf и Confirm.

 (Get-Command -Name Test-MrSupportsShouldProcess).Параметры.Ключи
 
 ИмяКомпьютера
Подробный
Отлаживать
ErrorAction
ПредупреждениеДействие
ИнформацияДействие
ErrorVariable
ПредупреждениеПеременная
ИнформацияПеременная
OutVariable
OutBuffer
PipelineVariable
Что, если
Подтверждать
 

Проверка параметров

Проверка ввода на ранней стадии. Зачем позволять вашему коду продолжать путь, если это невозможно
запустить без действительного ввода?

Всегда вводите переменные, которые используются для ваших параметров (укажите тип данных).

 функция Test-MrParameterValidation {
    [Привязка командлета()]
    параметр (
        [строка]$имя_компьютера
    )
    Запись-вывод $ComputerName
}
 

В предыдущем примере я указал String в качестве типа данных для Имя_компьютера
параметр. Это приводит к тому, что разрешается указывать только одно имя компьютера. Если более одного
имя компьютера указывается через запятую, выдается ошибка.

 Test-MrParameterValidation-ComputerName Server01, Server02
 
 Test-MrParameterValidation: невозможно обработать преобразование аргумента для параметра
'Имя компьютера'. Не удается преобразовать значение в тип System.String.
В строке:1 символ:42
+ Test-MrParameterValidation -ComputerName Server01, Server02
+
    + CategoryInfo: InvalidData: (:) [Test-MrParameterValidation], ParameterBindingArg
     менттрансформатионисцептион
    + FullyQualifiedErrorId: ParameterArgumentTransformationError, Test-MrParameterValidation
 

Проблема с текущим определением заключается в том, что допустимо опускать значение ComputerName
параметр, но для успешного завершения функции требуется значение. Вот где
Обязательный атрибут параметра пригодится.

 функция Test-MrParameterValidation {
    [Привязка командлета()]
    параметр (
        [Параметр (обязательный)]
        [строка]$имя_компьютера
    )
    Запись-вывод $ComputerName
}
 

Синтаксис, использованный в предыдущем примере, совместим с PowerShell версии 3.0 и выше.
[Параметр(обязательный=$true)] можно указать вместо этого, чтобы сделать функцию совместимой с
PowerShell версии 2.0 и выше. Теперь, когда требуется ComputerName , если его нет
указано, функция запросит один.

 Тест-MrParameterValidation
 
 командлет Test-MrParameterValidation в позиции 1 конвейера команд
Укажите значения для следующих параметров:
Имя компьютера:
 

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

 функция Test-MrParameterValidation {
    [Привязка командлета()]
    параметр (
        [Параметр (обязательный)]
        [строка[]]$имя_компьютера
    )
    Запись-вывод $ComputerName
}
 

Возможно, вы хотите указать значение по умолчанию для параметра ComputerName , если оно не указано.
Проблема в том, что значения по умолчанию нельзя использовать с обязательными параметрами. Вместо этого вам нужно будет
использовать ValidateNotNullOrEmpty Атрибут проверки параметра со значением по умолчанию.

 функция Test-MrParameterValidation {
    [Привязка командлета()]
    параметр (
        [Подтвердить ненулевой или пустой ()]
        [строка[]]$имя_компьютера = $env:ИМЯ_КОМПЬЮТЕРА
    )
    Запись-вывод $ComputerName
}
 

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

Подробный вывод

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

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

 функция Test-MrVerboseOutput {
    [Привязка командлета()]
    параметр (
        [Подтвердить ненулевой или пустой ()]
        [строка[]]$имя_компьютера = $env:ИМЯ_КОМПЬЮТЕРА
    )
    foreach ($Computer в $ComputerName) {
        #Попытка выполнить какое-либо действие на $Computer <<-- Не используйте
        #встроенные комментарии, подобные этому, вместо этого используйте подробную запись.
        Запись-вывод $Computer
    }
}
 

Лучше использовать Write-Verbose вместо встроенных комментариев.

 функция Test-MrVerboseOutput {
    [Привязка командлета()]
    параметр (
        [Подтвердить ненулевой или пустой ()]
        [строка[]]$имя_компьютера = $env:ИМЯ_КОМПЬЮТЕРА
    )
    foreach ($Computer в $ComputerName) {
        Write-Verbose -Message "Попытка выполнить какое-то действие на $Computer"
        Запись-вывод $Computer
    }
}
 

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

 Test-MrVerboseOutput-ComputerName Server01, Server02
 

При вызове с параметром Verbose будет отображаться подробный вывод.

 Test-MrVerboseOutput-ComputerName Server01, Server02-Verbose
 

Конвейерный ввод

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

Чтобы принять вход конвейера по значению , укажите атрибут параметра ValueFromPipeline для
именно этот параметр. Имейте в виду, что вы можете принимать вход конвейера только по значению из
по одному каждому типу данных. Например, если у вас есть два параметра, принимающих строковый ввод, только один из них
те, которые могут принимать входные данные конвейера по значению , потому что если вы указали его для обеих строк
параметры, ввод конвейера не будет знать, к какому из них привязываться. Это еще одна причина, по которой я звоню
этот тип ввода конвейера по типу вместо по значению .

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

 функция Test-MrPipelineInput {
    [Привязка командлета()]
    параметр (
        [Параметр(Обязательный,
                   Значение из конвейера)]
        [строка[]]$имя_компьютера
    )
    ПРОЦЕСС {
        Запись-вывод $ComputerName
    }
}
 

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

 функция Test-MrPipelineInput {
    [Привязка командлета()]
    параметр (
        [Параметр(Обязательный,
                   Значение из пайпелина по имени свойства)]
        [строка[]]$имя_компьютера
    )
    ПРОЦЕСС {
            Запись-вывод $ComputerName
    }
}
 

Блоки BEGIN и END являются необязательными. BEGIN должен быть указан перед блоком PROCESS и
используется для выполнения любой начальной работы до получения элементов из конвейера. Это
важно понять. Значения, переданные по конвейеру, недоступны в НАЧАЛО блока. КОНЕЦ
блок будет указан после блока PROCESS и будет использоваться для очистки после того, как все элементы
которые переданы по каналу, были обработаны.

Обработка ошибок

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

 функция Test-MrErrorHandling {
    [Привязка командлета()]
    параметр (
        [Параметр(Обязательный,
                   значение из трубопровода,
                   Значение из пайпелина по имени свойства)]
        [строка[]]$имя_компьютера
    )
    ПРОЦЕСС {
        foreach ($Computer в $ComputerName) {
            Test-WSMan - имя_компьютера $Computer
        }
    }
}
 

Существует несколько способов обработки ошибок в PowerShell. Try/Catch более современный
способ обработки ошибок.

 функция Test-MrErrorHandling {
    [Привязка командлета()]
    параметр (
        [Параметр(Обязательный,
                   значение из трубопровода,
                   Значение из пайпелина по имени свойства)]
        [строка[]]$имя_компьютера
    )
    ПРОЦЕСС {
        foreach ($Computer в $ComputerName) {
            пытаться {
                Test-WSMan - имя_компьютера $Computer
            }
            ловить {
                Write-Warning-Message "Невозможно подключиться к компьютеру: $Computer"
            }
        }
    }
}
 

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

 функция Test-MrErrorHandling {
    [Привязка командлета()]
    параметр (
        [Параметр(Обязательный,
                   значение из трубопровода,
                   Значение из пайпелина по имени свойства)]
        [строка[]]$имя_компьютера
    )
    ПРОЦЕСС {
        foreach ($Computer в $ComputerName) {
            пытаться {
                Test-WSMan -ComputerName $Computer -ErrorAction Stop
            }
            ловить {
                Write-Warning-Message "Невозможно подключиться к компьютеру: $Computer"
            }
        }
    }
}
 

Не изменяйте глобальную переменную $ErrorActionPreference без крайней необходимости. Если вы
используя что-то вроде .NET непосредственно из вашей функции PowerShell, вы не можете указать
ErrorAction для самой команды. В этом случае вам может потребоваться изменить глобальный
Переменная $ErrorActionPreference , но если вы измените ее, измените ее обратно сразу после попытки
команда.

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

 функция Get-MrAutoStoppedService {
<#
.СИНОПСИС
    Возвращает список служб, которые настроены на автоматический запуск, но не
    запущены в данный момент, за исключением служб, для которых настроен отложенный запуск.
.ОПИСАНИЕ
    Get-MrAutoStoppedService — это функция, которая возвращает список сервисов из
    указанные удаленные компьютеры, настроенные на автоматический запуск, не
    работает в данный момент, и исключает службы, которые настроены на автоматический запуск
    с отложенным запуском.
.ПАРАМЕТР Имя_компьютера
    Удаленный компьютер (ы), на котором нужно проверить состояние служб.
.ПАРАМЕТР Учетные данные
    Указывает учетную запись пользователя, у которой есть разрешение на выполнение этого действия.  По умолчанию
    является текущим пользователем.
.ПРИМЕР
     Get-MrAutoStoppedService — имя_компьютера «Server1», «Server2»
.ПРИМЕР
     «Сервер1», «Сервер2» | Get — мраутостоппедсервице
.ПРИМЕР
     Get-MrAutoStoppedService -ComputerName 'Server1' -Credential (Get-Credential)
.ВХОДЫ
    Нить
.ВЫХОДЫ
    PSCustomObject
.ПРИМЕЧАНИЯ
    Автор: Майк Ф. Роббинс.
    Сайт: http://mikefrobbins.com
    Твиттер: @mikefrobbins
#>
    [Привязка командлета()]
    параметр (
    )
    # Тело функции
}
 

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

Весь синтаксис для написания функции в PowerShell может показаться слишком сложным, особенно для кого-то
кто только начинает. Часто, если я не могу вспомнить синтаксис чего-то, я открываю
вторую копию ISE на отдельном мониторе и просмотреть "Командлет (расширенная функция) - Завершить"
фрагмент при вводе кода для моей функции. Доступ к сниппетам можно получить в PowerShell ISE.
используя Ctrl + J Комбинация клавиш.

Резюме

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

Обзор

  1. Как получить список утвержденных команд в PowerShell?
  2. Как превратить функцию PowerShell в расширенную функцию?
  3. Когда следует добавить параметры WhatIf и Confirm в ваши функции PowerShell?
  4. Как превратить непрерывающую ошибку в завершающую?
  5. Почему вы должны добавлять к своим функциям справку на основе комментариев?

Рекомендуемое чтение

  • about_Functions
  • about_Functions_Advanced_Parameters
  • about_CommonParameters
  • about_Functions_CmdletBindingAttribute
  • about_Functions_Advanced
  • about_Try_Catch_Finally
  • about_Comment_Based_Help
  • Видео: создание инструментов PowerShell с расширенными функциями и модулями сценариев

о функциях - PowerShell | Microsoft Learn

  • Статья

Краткое описание

Описывает создание и использование функций в PowerShell.

Подробное описание

Функция — это список инструкций PowerShell, которым назначено имя.
Когда вы запускаете функцию, вы вводите имя функции. Заявления в списке
запустите, как если бы вы набрали их в командной строке.

Функции могут быть такими простыми, как:

 function Get-PowerShellProcess { Get-Process PowerShell }
 

Функция также может быть такой же сложной, как командлет или приложение.

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

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

Список операторов функции может содержать различные типы списков операторов
с ключевыми словами begin , process , end и clean . Эти списки утверждений
обрабатывать входные данные из конвейера по-разному.

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

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

Важно

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

Синтаксис

Ниже приведен синтаксис функции:

 function [] [([type]$parameter1[[type]$parameter2])]
{
  begin {<список операторов>}
  процесс {<список операторов>}
  конец {<список операторов>}
  очистить {<список операторов>}
}
 
 функция [<область:>]<имя>
{
  параметр([тип]$параметр1 [[тип]$параметр2])
  dynamicparam {<список операторов>}
  begin {<список операторов>}
  процесс {<список операторов>}
  конец {<список операторов>}
  очистить {<список операторов>}
}
 

Функция включает следующие элементы:

  • Функция ключевое слово
  • Прицел (дополнительно)
  • Имя, которое вы выбираете
  • Любое количество именованных параметров (необязательно)
  • Одна или несколько команд PowerShell, заключенных в фигурные скобки {}

Для получения дополнительной информации о ключевом слове Dynamicparam и динамических параметрах в
функций, см. about_Functions_Advanced_Parameters.

Простые функции

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

 function <имя-функции> {операторы}
 

Например, следующая функция запускает PowerShell с кодом Запуск от имени
Опция администратора
.

 функция Start-PSAdmin {Start-Process PowerShell -Глагол RunAs}
 

Чтобы использовать эту функцию, введите: Start-PSAdmin

Чтобы добавить операторы в функцию, введите каждый оператор в отдельной строке или
используйте точку с запятой ; для разделения операторов.

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

 функция Get-NewPix
{
  $start = Get-Date -Месяц 1 -День 1 -Год 2010
  $allpix = Get-ChildItem -Path $env:UserProfile\*.jpg -Recurse
  $allpix | Где-Объект {$_.LastWriteTime -gt $Start}
}
 

Вы можете создать набор полезных небольших функций. Добавьте эти функции в свой
Профиль PowerShell, как описано в about_Profiles и далее в этом
тема.

Имена функций

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

Имена функций должны состоять из пары глагол-существительное, где глагол определяет
действие, которое выполняет функция, а существительное определяет элемент, на котором
командлет выполняет свое действие.

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

Дополнительные сведения о стандартных командах PowerShell см.
Утвержденные глаголы.

Функции с параметрами

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

Именованные параметры

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

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

 function <имя> {
  параметр ([тип]$параметр1 [[тип]$параметр2])
  <список операторов>
}
 

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

 function  [([type]$parameter1[[type]$parameter2])] {
  <список операторов>
}
 

Ниже приведен пример этого альтернативного синтаксиса.

 function Add-Numbers([int]$one, [int]$two) {
    $ один + $ два
}
 

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

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

В следующем примере показана функция с именем Get-SmallFiles . Эта функция имеет
параметр $Size . Функция отображает все файлы, размер которых меньше
стоимость Параметр $Size , и он исключает каталоги:

 function Get-SmallFiles {
  Параметр($Размер)
  Get-ChildItem $HOME | Где-Объект {
    $_.Length -lt $Size -и !$_.PSIsContainer
  }
}
 

В функции можно использовать переменную $Size , имя которой определено для
параметр.

Чтобы использовать эту функцию, введите следующую команду:

 Get-SmallFiles -Size 50
 

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

 Get-SmallFiles 50
 

Чтобы определить значение по умолчанию для параметра, введите знак равенства и значение
после имени параметра, как показано в следующем варианте
Get-SmallFiles пример:

 функция Get-SmallFiles ($Size = 100) {
  Get-ChildItem $HOME | Где-Объект {
    $_. Length -lt $Size -и !$_.PSIsContainer
  }
}
 

Если ввести Get-SmallFiles без значения, функция присвоит 100
$размер . Если вы предоставляете значение, функция использует это значение.

При желании вы можете предоставить краткую справочную строку, описывающую
значение вашего параметра, добавив атрибут PSDefaultValue в
описание вашего параметра и указание свойства Help
PSDefaultValue . Чтобы предоставить строку справки, описывающую значение по умолчанию
(100) параметра Size в функции Get-SmallFiles добавьте
Атрибут PSDefaultValue , как показано в следующем примере.

 функция Get-SmallFiles {
  параметр (
      [PSDefaultValue (Справка = '100')]
      Размер $ = 100
  )
}
 

Дополнительные сведения о классе атрибута PSDefaultValue см.
Члены атрибута PSDefaultValue.

Позиционные параметры

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

При использовании позиционных параметров введите одно или несколько значений после функции
имя. Значения позиционных параметров присваиваются переменной массива $args .
Значение, следующее за именем функции, присваивается первой позиции в
массив $args , $args[0] .

Следующая функция Get-Extension добавляет расширение имени файла .txt к
имя файла, которое вы указываете:

 function Get-Extension {
  $имя = $args[0] + ".txt"
  $имя
}
 
 Get-Extension myTextFile
 
 myTextFile.txt
 

Параметры переключателя

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

Чтобы определить параметр переключателя, укажите тип [переключатель] перед параметром
имя, как показано в следующем примере:

 function Switch-Item {
  параметр ([переключатель]$on)
  если ($on) { "Включить" }
  иначе { "Выключить" }
}
 

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

 Элемент включения
 
 Включить
 
 Элемент переключения
 
 Выключить
 

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

 Switch-Item -on:$true
 
 Включить
 
 Элемент включения: $false
 
 Выключить
 

Использование разбрызгивания для представления параметров команды

Вы можете использовать разбрызгивание для представления параметров команды. Эта функция
представлен в Windows PowerShell 3.0.

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

В следующем примере функция вызывает Командлет Get-Command . Команда использует
@Args для представления параметров Get-Command .

 функция Get-MyCommand { Get-Command @Args }
 

Вы можете использовать все параметры Get-Command при вызове
Функция Get-MyCommand . Параметры и значения параметров передаются в
команда с использованием @Args .

 Get-MyCommand -Name Get-ChildItem
 
 Имя CommandType Имя модуля
----------- ---- ----------
Командлет Get-ChildItem Microsoft.PowerShell.Management
 

Функция @Args использует автоматический параметр $Args , который представляет
необъявленные параметры командлета и значения из оставшихся аргументов.

Для получения дополнительной информации см. about_Splatting.

Конвейер объектов к функциям

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

 функция <имя> {
  begin {<список операторов>}
  процесс {<список операторов>}
  конец {<список операторов>}
  очистить {<список операторов>}
}
 

Важно

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

begin Список операторов запускается только один раз, в начале
функция.

Список операторов процесса выполняется один раз для каждого объекта в конвейере.
Пока блок
процесса работает, каждый объект конвейера назначается
$_ автоматическая переменная, по одному объекту конвейера за раз.

После того, как функция получит все объекты в конвейере, конец
список операторов запускается один раз.

Следующая функция использует процесс ключевое слово. Функция отображает
значения из конвейера:

 функция Get-Pipeline
{
  процесс {"Значение: $_"}
}
1,2,4 | Get-Pipeline
 
 Значение: 1
Значение: 2
Значение: 4
 

При использовании функции в конвейере объекты, переданные в функцию,
присваивается автоматической переменной $input . Функция запускает операторы с
ключевое слово begin до поступления каких-либо объектов из конвейера. Функция
запускает операторы с end ключевое слово после получения всех объектов
из трубопровода.

В следующем примере показана автоматическая переменная $input с begin и
конечных ключевых слов.

 функция Get-PipelineBeginEnd
{
    begin {"Начало: ввод $input"}
    end {"Конец: ввод $input" }
}
 

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

 1,2,4 | Get-PipelineBeginEnd
 
 Начало: ввод
Конец: ввод 1 2 4
 

Когда запускается оператор begin , функция не имеет входных данных из
трубопровод. Оператор end запускается после того, как функция получит значения.

Если функция имеет ключевое слово process , каждый объект в $input удаляется.
из $введите и присвойте $_ . В следующем примере есть процесс
список операторов:

 функция Get-PipelineInput
{
    процесс {"Обработка: $_ " }
    end {"Конец: ввод: $input" }
}
 

В этом примере каждый объект, передаваемый функции, отправляется в
процесс список операторов. Операторы процесса выполняются для каждого объекта, по одному
объект за раз. Автоматическая переменная $input пуста, когда функция
достигает ключевого слова end .

 1,2,4 | Get-PipelineInput
 
 Обработка: 1
Обработка: 2
Обработка: 4
Конец: Вход:
 

Дополнительные сведения см. в разделе Использование перечислителей

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

  1. , когда выполнение конвейера завершается нормально без ошибки завершения
  2. , когда выполнение конвейера прерывается из-за ошибки завершения
  3. , когда конвейер остановлен Select-Object -First
  4. , когда конвейер останавливается с помощью Ctrl+C или
    Остановить обработку()

Осторожно

Добавление блока clean является критическим изменением. Поскольку чистый анализируется как
ключевое слово, оно не позволяет пользователям напрямую вызывать команду с именем clean как
первый оператор в блоке скрипта. Однако вряд ли это будет
проблема. Команду по-прежнему можно вызвать с помощью оператора вызова
( и очистить ).

Фильтры

Фильтр — это тип функции, которая выполняется для каждого объекта в конвейере. А
filter напоминает функцию со всеми ее операторами в блоке процесса .

Синтаксис фильтра следующий:

 filter [<область:>]<имя> {<список операторов>}
 

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

 фильтр Get-ErrorLog ([switch]$Message)
{
  if ($Message) { Out-Host -InputObject $_.Message}
  иначе {$_}
}
 

Его можно использовать следующим образом:

 Get-WinEvent -LogName System -MaxEvents 100 | Get-ErrorLog-Сообщение
 

Область действия функции

Функция существует в области действия, в которой она создана.

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

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

 function global:Get-DependentSvs {
  Получить-Сервис | Где-объект {$_.DependentServices}
}
 

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

Функции создают новую область. Элементы, созданные в функции, например
переменные существуют только в области видимости функции.

Дополнительные сведения см. в разделе about_Scopes.

Поиск функций и управление ими с помощью функции: Диск

Все функции и фильтры в PowerShell автоматически сохраняются в
Функция: диск. Этот диск предоставляется функцией PowerShell .
провайдер.

При обращении к диску Функция: введите двоеточие после Функция , просто
как если бы вы ссылались на диск C или D компьютера.

Следующая команда отображает все функции в текущем сеансе
PowerShell:

 Функция Get-ChildItem:
 

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

 (функция Get-ChildItem:help). Определение
 

Вы также можете использовать следующий синтаксис.

 $функция:помощь
 

Для получения дополнительной информации о Функция: диск , см. раздел справки для
Функция провайдера. Введите Функция получения справки .

Повторное использование функций в новых сеансах

Когда вы вводите функцию в командной строке PowerShell, она становится
часть текущего сеанса. Функция доступна до завершения сеанса.

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

Вы также можете сохранить свою функцию в файле сценария PowerShell. Введите свою функцию
в текстовом файле, а затем сохраните файл с расширением имени файла .ps1 .

Написание справки для функций

Командлет Get-Help получает справку по функциям, а также по командлетам,
провайдеры и скрипты. Чтобы получить справку по функции, введите Get-Help , а затем
имя функции.

Например, чтобы получить справку по функции Get-MyDisks , введите:

 Get-Help Get-MyDisks
 

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

  • Справка по функциям на основе комментариев

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

  • XML-справка по функциям

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

    Чтобы связать функцию с разделом справки на основе XML, используйте
    .EXTERNALHELP ключевое слово справки на основе комментариев.

    Imacros | Все права защищены © 2021