Функции — PowerShell | Microsoft Docs
- Чтение занимает 13 мин
В этой статье
Если вы пишете однострочные коды и сценарии PowerShell, которые часто приходится изменять для применения в различных ситуациях, возможно, их стоит преобразовать в многократно используемую функцию.
По возможности я предпочитаю писать функции, потому что они больше ориентированы на работу со средствами. Я могу поместить функции в модуль сценария, отправить этот модуль в $env:PSModulePath
и вызвать функции без необходимости физического определения их местонахождения. С помощью модуля PowerShellGet эти модули можно легко запрашивать в репозитории NuGet.
Не нужно ничего усложнять. Будьте проще и выбирайте самый прямой путь для решения задач. Избегайте псевдонимов и позиционных параметров в любом многократно используемом коде. Отформатируйте код, чтобы сделать его удобочитаемым. Не указывайте значения прямо в коде — используйте параметры и переменные. Не пишите лишний код, даже если это ничему не повредит. Он усложнит ситуацию. При написании кода PowerShell очень важно обращать внимание на детали.
Именование
При именовании функций в PowerShell используйте имя в Регистр Pascal с утвержденным глаголом и существительным в единственном числе. Кроме того, перед существительным рекомендуется добавить префикс. Например:
.
В 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
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, такими как проверка параметров, вывод подробных данных, входные данные конвейера, обработка ошибок и справка на основе комментариев.
Просмотр
- Как получить список утвержденных глаголов в PowerShell?
- Как преобразовать функцию PowerShell в расширенную функцию?
- Когда следует добавлять параметры WhatIf и Confirm в функции PowerShell?
- Как преобразовать неустранимую ошибку в устранимую?
- Для чего нужно добавлять справку на основе комментариев к функциям?
Рекомендуем прочесть
о функциях — PowerShell | Microsoft Docs
- 000Z» data-article-date-source=»ms.date»>2/27/2019
- Чтение занимает 10 мин
В этой статье
Краткое описание
Описание создания и использования функций в PowerShell.
Подробное описание
Функция — это список операторов PowerShell с назначенным именем. При запуске функции необходимо ввести имя функции. Инструкции в списке выполняются так, как если бы вы вводили их в командной строке.
Функции могут быть простыми:
function Get-PowerShellProcess { Get-Process PowerShell }
Функция также может быть сложной в качестве командлета или программы приложения.
Как и командлеты, функции могут иметь параметры. Параметры могут быть именованными, позиционированными, переключателями или динамическими параметрами. Параметры функции можно считывать из командной строки или из конвейера.
Функции могут возвращать значения, которые могут быть отображены, назначены переменным или переданы другим функциям или командлетам. Также можно указать возвращаемое значение с помощью return
ключевого слова. return
Ключевое слово не влияет или не подавляет другие выходные данные, возвращаемые функцией. Однако return
ключевое слово завершает функцию в этой строке. Дополнительные сведения см. в разделе about_Return.
Список операторов функции может содержать различные типы списков операторов с ключевыми словами Begin
, Process
и End
. Эти списки инструкций обработают входные данные из конвейера по-разному.
Фильтр — это специальный тип функции, который использует Filter
ключевое слово.
Функции также могут действовать как командлеты. Можно создать функцию, которая работает так же, как командлет, без использования C#
программирования. Дополнительные сведения см. в разделе about_Functions_Advanced.
Синтаксис
Ниже приведен синтаксис функции.
function [<scope:>]<name> [([type]$parameter1[,[type]$parameter2])]
{
param([type]$parameter1 [,[type]$parameter2])
dynamicparam {<statement list>}
begin {<statement list>}
process {<statement list>}
end {<statement list>}
}
Функция включает следующие элементы:
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 см. в разделе утвержденные команды в документация Майкрософт.
Функции с параметрами
Параметры можно использовать с функциями, в том числе с именованными параметрами, параметрами, параметрами и динамическими параметрами. Дополнительные сведения о динамических параметрах в функциях см. в разделе 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($one, $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
. Если указать значение, то функция использует это значение.
При необходимости можно указать краткую строку справки, описывающую значение параметра по умолчанию, добавив атрибут псдефаултвалуе в описание параметра и указав свойство Help объекта псдефаултвалуе. Чтобы предоставить строку справки, описывающую значение по умолчанию (100) параметра size в Get-SmallFiles
функции, добавьте атрибут псдефаултвалуе , как показано в следующем примере.
function Get-SmallFiles {
param (
[PSDefaultValue(Help = '100')]
$Size = 100
)
}
Дополнительные сведения о классе атрибута псдефаултвалуе см. в разделе псдефаултвалуе Attribute Members.
Параметры позиционирования
Параметр с заданной позицией — это параметр без имени параметра. PowerShell использует порядок значений параметра, чтобы связать каждое значение параметра с параметром в функции.
При использовании позиционированных параметров введите одно или несколько значений после имени функции. Значения позиционированных параметров присваиваются $args
переменной массива.
Значение, следующее за именем функции, присваивается первой положению в $args
массиве, $args[0]
.
Следующая Get-Extension
функция добавляет .txt
расширение имени файла к указанному имени файла:
function Get-Extension {
$name = $args[0] + ".txt"
$name
}
Get-Extension myTextFile
myTextFile.txt
Параметры переключателя
Переключатель — это параметр, который не требует значения. Вместо этого введите имя функции, за которым следует имя параметра переключателя.
Чтобы определить параметр переключателя, укажите тип [switch]
перед именем параметра, как показано в следующем примере:
function Switch-Item {
param ([switch]$on)
if ($on) { "Switch on" }
else { "Switch off" }
}
При вводе On
параметра Switch после имени функции функция отображает параметр on. Без параметра Switch отображается значение «Отключить выключение».
Switch-Item -on
Switch on
Switch-Item
Switch off
При выполнении функции можно также присвоить логическое значение параметру, как показано в следующем примере:
Switch-Item -on:$true
Switch on
Switch-Item -on:$false
Switch off
Использование Сплаттинг для представления параметров команды
Сплаттинг можно использовать для представления параметров команды. Эта функция появилась в Windows PowerShell 3,0.
Используйте этот метод в функциях, вызывающих команды в сеансе. Вам не нужно объявлять или перечислять параметры команды или изменять функцию при изменении параметров команды.
Следующий пример функции вызывает Get-Command
командлет. Команда использует @Args
для представления параметров Get-Command
.
function Get-MyCommand { Get-Command @Args }
Get-Command
При вызове функции можно использовать все параметры Get-MyCommand
. Параметры и значения параметров передаются в команду с помощью команды @Args
.
Get-MyCommand -Name Get-ChildItem
CommandType Name ModuleName
----------- ---- ----------
Cmdlet Get-ChildItem Microsoft.PowerShell.Management
Эта @Args
функция использует $Args
Автоматический параметр, представляющий необъявленные параметры и значения командлета из оставшихся аргументов.
Дополнительные сведения о Сплаттинг см. в разделе about_Splatting.
Передача объектов в функции
Любая функция может принимать входные данные из конвейера. Можно контролировать, как функция обрабатывает входные данные из конвейера с помощью Begin
Process
End
ключевых слов, и. В следующем образце синтаксиса показаны три ключевых слова:
function <name> {
begin {<statement list>}
process {<statement list>}
end {<statement list>}
}
Begin
Список инструкций выполняется только один раз в начале функции.
Важно!
Если функция определяет Begin
блок, то Process
End
весь код должен находиться внутри этих блоков. Код не будет располагаться за пределами блоков, если определены какие либо блоки.
Process
Список инструкций выполняется один раз для каждого объекта в конвейере.
Во время Process
выполнения блока каждый объект конвейера назначается $_
автоматической переменной, по одному объекту конвейера за раз.
После того как функция получит все объекты в конвейере, End
список инструкций будет выполняться один раз. Если не Begin
Process
End
используются ключевые слова, или, все инструкции рассматриваются как 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:
Дополнительные сведения см. в разделе Использование перечислителей .
Фильтры
Фильтр — это тип функции, которая выполняется для каждого объекта в конвейере. Фильтр напоминает функцию со всеми ее операторами в Process
блоке.
Синтаксис фильтра выглядит следующим образом:
filter [<scope:>]<name> {<statement list>}
Следующий фильтр принимает записи журнала из конвейера, а затем отображает всю запись или только часть сообщения в записи:
filter Get-ErrorLog ([switch]$message)
{
if ($message) { Out-Host -InputObject $_.Message }
else { $_ }
}
Область действия функции
Функция существует в области, в которой она была создана.
Если функция является частью скрипта, функция доступна для инструкций внутри этого скрипта. По умолчанию функция в скрипте недоступна в командной строке.
Можно указать область функции. Например, функция добавляется в глобальную область в следующем примере:
function global:Get-DependentSvs {
Get-Service | Where-Object {$_.DependentServices}
}
Если функция находится в глобальной области, ее можно использовать в скриптах, функциях и в командной строке.
Обычно функции создают область. Элементы, созданные в функции, такие как переменные, существуют только в области видимости функции.
Дополнительные сведения об области действия в PowerShell см. в разделе about_Scopes.
Поиск функций и управление ими с помощью диска Function:
Все функции и фильтры в PowerShell автоматически сохраняются на Function:
диске. Этот диск предоставляется поставщиком функций PowerShell.
При обращении к Function:
диску введите двоеточие после функции, как при обращении к C
диску или на D
диске компьютера.
Следующая команда отображает все функции в текущем сеансе PowerShell:
Get-ChildItem function:
Команды в функции хранятся в виде блока скрипта в свойстве определения функции. Например, чтобы отобразить команды в функции справки, поставляемой с PowerShell, введите:
(Get-ChildItem function:help).Definition
Можно также использовать следующий синтаксис.
$function:help
Дополнительные сведения о Function:
диске см. в разделе справки по поставщику функций . Введите Get-Help Function
.
Повторное использование функций в новых сеансах
При вводе функции в командной строке PowerShell функция станет частью текущего сеанса. Он доступен до завершения сеанса.
Чтобы использовать функцию во всех сеансах PowerShell, добавьте функцию в профиль PowerShell. Дополнительные сведения о профилях см. в разделе about_Profiles.
Можно также сохранить функцию в файле сценария PowerShell. Введите функцию в текстовом файле, а затем сохраните файл с .ps1
расширением имени файла.
Написание справки для функций
Get-Help
Командлет возвращает справку по функциям, а также к командлетам, поставщикам и скриптам. Чтобы получить справку по функции, введите, Get-Help
за которым следует имя функции.
Например, чтобы получить справку по Get-MyDisks
функции, введите:
Get-Help Get-MyDisks
Вы можете написать справку для функции с помощью любого из двух следующих методов:
Comment-Based справки по функциям
Создайте раздел справки, используя специальные ключевые слова в комментариях. Чтобы создать справку на основе комментариев для функции, комментарии должны располагаться в начале или в конце тела функции или в строках, предшествующих ключевому слову Function. Дополнительные сведения о справке на основе комментариев см. в разделе 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_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
about_Function_provider
PowerShell. Пользовательские функции для пользователей / Хабр
Привет! Довольно часто в своей работе приходиться пользоваться самостоятельно написанными функциями и таскать куски кода между разными скриптами. На Хабре уже есть довольно хорошая статья про
Повторное использование кодаот
Mroff, но была необходимость пойти немного дальше, задокументировать и как-то описать свои функции. Как оказалось, поиск выдавал довольно сухую информацию в основном по общей структуре функции и не более того. Упорство было вознаграждено, и я решил поделиться полученной информацией. Добро пожаловать под кат, где мы научимся вносить в свои функции информацию для потомков и коллег.
Давайте для начала разберем стандартную структуру функции в PowerShell. Выглядит она следующим образом
Function TestPath ([String]$Path)
{
Return(Test-Path $Path)
}
В общем то ничего сложного, как и в других языках задали имя TestPath, в круглых скобках через запятую скормили переменные $Path, выполнили в теле функции необходимые действия и при необходимости вернули Return() значение. А как быть, когда нужно работать с несколькими переменными? Выходов всегда больше одного – постоянно давать мнемонические коды или делать описание переменной, давайте рассмотрим, как это делается:
Function TestPath
{
PARAM (
[PARAMETER(Mandatory=$True,Position=0,HelpMessage = "Путь до проверяемого ресурса",ParameterSetName='Path')]$Path
)
Return(Test-Path $Path)
}
Сложности никакой нет, но появились дополнительные параметры, которые нам упрощают жизнь:
Mandatory – Принимает два значения True обязательный для заполнения и False необязательный;
HelpMessage – Справка по переменной;
ParameterSetName – Имя переменной к которой относятся данные параметры;
Position – Позиция переменной при вызове функции;
Вроде бы все хорошо теперь у нас есть переменная, у которой есть описание, но для того что бы его узнать необходимо выполнить следующий код:
((Get-Command TestPath).ParameterSets.Parameters | Where-Object Name -eq Path).HelpMessage
PowerShell ответит нам одной строкой в которой будет написано: Путь до проверяемого ресурса.
В какой-то степени удобно, но если мы привыкли работать с PowerShell, то знаем команду Get-Help которая выводит подробную информацию о функции с примерами ее использования и переменными, которые необходимо передавать.
Немного усложним задачу и подготовим функцию информация о которой по запросу Get-Help будет выводиться в полном объеме:
Function WriteToLog {
<#
.SYNOPSIS
Вывод сообщения в консоль и в файл лога.
.DESCRIPTION
Данная функция выводит переданную строку в лог файл и в консоль PowerShell
.EXAMPLE
#WriteToLog -Str "Данное сообщение будет выведено в консоль красным цветом и в файл C:\Log\log.txt" -FileName 'C:\Log\log.txt' -Color Red
.EXAMPLE
#WriteToLog -Str "Данное сообщение будет выведено в консоль цветом по умолчанию (White) и в файл C:\Log\log.txt" -FileName 'C:\Log\log.txt'
.PARAMETER Str
Строка, которую необходимо вывести (обязательный параметр)
.PARAMETER FileName
Имя файла лога (обязательный параметр)
.PARAMETER Color
Цвет текста сообщения в консоли PowerShell (По умолчанию цвет текста белый (White))
#>
param (
[PARAMETER(Mandatory=$True,Position=0)][String]$Str,
[PARAMETER(Mandatory=$True,Position=1)][String]$FileName,
[PARAMETER(Mandatory=$False,Position=2)][String]$Color='White'
)
Write-Host $Str -ForegroundColor $Color
If ((Test-Path $FileName) -eq $True)
{
Add-Content -Path $FileName -Value $Str
}
Else
{
Set-Content -Path $FileName -Value $Str
}
}
После выполнения данного кода команда Get-Help ‘WriteToLog’ -ShowWindow выведет нам следующее окно.
Давайте разберем что же мы такого написали:
<##> – В данном блоке написаны параметры для справки PowerShell.
.SYNOPSIS – блок для краткого описание функции
.DESCRIPTION – блок для полного описание функции
.EXAMPLE – блок для примера использования функции, может быть несколько
.PARAMETR Имя параметра – блок для описания переменной, для каждой переменной свой блок.
Как вы могли заметить текстовый комментарий начинается со следующей строки после ключевого названия раздела и может быть многострочным. Окончанием комментария считается закрывающий тег #> или следующий блок.
param () – блок для описания переменных, в котором мы указали их порядок и необходимость передачи параметров при вызове функции. Для переменной $Color мы присвоили значение по умолчанию’White’.
Теперь все пользовательские функции можно использовать централизованно и вам не придется вспоминать какой параметр за что отвечает, а также какой тип данных использует та или иная переменная.
Спасибо что дочитали до конца.
Использование функций
Помимо командлетов, в Windows PowerShell можно запускать функции. Windows PowerShell поставляется с набором встроенных функций, помимо которых можно добавлять функции, полученные от других пользователей, и создавать собственные функции.
Функции — это тип команд в Windows PowerShell. Для запуска функции введите ее имя, точно так же, как и для командлета. Как и командлеты, функции могут иметь параметры. Как и командлеты, функции могут использовать объекты .NET в качестве источника ввода и выводить объекты .NET. Фактически функции обладают теми же возможностями, что и командлеты.
Лучше всего в функциях то, что их очень легко создавать. В отличие от командлетов, которые пишутся на языке C#, функции представляют собой просто именованные наборы команд и выражений Windows PowerShell. Создавать функции так же просто, как и вводить команды в Windows PowerShell.
Функции являются командами, и поэтому для поиска функций используйте командлет Get-Command.
Например, чтобы найти все функции текущего сеанса, введите команду:
get-command -CommandType function
Кроме того, в Windows PowerShell имеется диск Function:, содержащий все функции текущего сеанса. Для просмотра диска Function: используйте те же методы, что и для просмотра дисков файловой системы.
Чтобы открыть диск функций, введите:
Чтобы вывести функции с диска функций, введите:
Для запуска функции нужно просто ввести ее имя. Например, для запуска функции Clear-Host введите следующую команду:
В консоли Windows PowerShell функция Clear-Host служит для удаления всего текста из окна консоли. В других приложениях эта функция может иметь другое действие или не иметь никакого действия.
Чтобы использовать параметры функции, введите имя параметра с дефисом перед ним и значением после него, точно так же, как и при вводе параметров командлета.
Например, функция Help, выводящая разделы справки постранично, имеет те же параметры, что и командлет Get-Help. Чтобы использовать функцию Help для вывода только примеров из раздела справки для командлета Get-Service, введите следующую команду:
help -name get-service -examples
Для функций могут существовать разделы справки. Чтобы найти раздел справки для функции, используйте командлет Get-Help. Это тот же командлет, что используется для получения справки по командлетам.
Например, для получения справки по функции Disable-PSRemoting, введите следующую команду:
get-help Disable-PSRemoting
Для получения справки по функциям можно использовать любые параметры командлета Get-Help. Например, чтобы получить примеры из раздела справки для функции Disable-PSRemoting, введите следующую команду:
get-help Disable-PSRemoting -example
Функция представляет собой именованную группу команд или выражений. Чтобы написать простую функцию, используйте следующий формат.
function <name> { <commands> }
Введите ключевое слово function и имя функции и заключите команды в фигурные скобки ({ }).
Например, если какая-то команда, например,
get-help get-member -examples
, используется часто, для
экономии времени можно написать функцию, исполняющую эту команду.
Следующая функция с именем GMEX исполняет эту команду.
function GMEX {get-help get-member -examples}
После ввода в командной строке Windows PowerShell (или после копирования и вставки из этого раздела) и нажатия клавиши ENTER эту функцию можно будет использовать в текущем сеансе. Для исполнения функции введите команду GMEX.
Эта функция простая, но добавив еще несколько строк, можно включить в нее обязательные или необязательные параметры, добавить пользовательские сообщения или создать для нее раздел справки. После ознакомления с возможностями Windows PowerShell можно научиться писать сложные функции со всеми характеристиками командлетов.
Дополнительные сведения о написании функций см. в разделах about_Functions, about_Comment_Based_Help и about_Functions_Advanced.
При запуске Windows PowerShell открывается ее сеанс. Сеанс длится, пока не закрывается окно Windows PowerShell (или пока сеанс не завершается с помощью команды Exit). Элементы, созданные во время сеанса, удаляются при его закрытии, если они не сохранены в файле на диске или в реестре.
Для использования функций в будущих сеансах Windows PowerShell нужно создать профиль Windows PowerShell и сохранить эти функции в нем.
Дополнительную информацию см. в разделе about_Profiles.
Функции в Windows PowerShell | вебисторий
В предыдущей статье мы говорили о командлетах в Windows PowerShell. Теперь поговорим о следующем типе команд — функциях.
Функции — это блоки кода на языке PowerShell, имеющие название и находящиеся в памяти до завершения текущего сеанса командной оболочки. Функции в PowerShell это не совсем то же самое, что функции в языках программирования.
Создадим простейшую функцию Primer, которая просто выводит сообщение. Для этого введем в PowerShell
Function Primer{"Это пример функции."}
Таким образом мы задали имя функции и выполняемое действие. Теперь, для того, чтобы исполнить функцию, нам достаточно написать её имя.
Функции способны работать с аргументами, которые передаются им при запуске. Сделать это можно с помощью переменной $Args, которая представляет собою массив с аргументами, или при помощи формальных параметров.
Изменим нашу функцию Primer, добавив в неё переменную $Args.
Function Primer{"Это пример $Args."}
Тогда при вызове функции нам необходимо будет прописать аргумент или аргументы. Внимательно посмотрите на скриншот ниже.
Пример функции с аргументами в PowerShellВ данном случае «функции», «с» и «аргументами» — три элемента массива $Args. Как видим, они выводятся через пробел. Для того, чтобы убедиться, что это именно три отдельных элемента, введем разделитель в виде точки с помощью специальной переменной $OFS.
Function Primer{ >> $OFS="." >> "Это пример $Args."} >>
Смотрим результат.
Использование переменной $OFSВторой способ обработки аргументов функций в Windows PowerShell это использование формальных параметров. Формальные параметры указываются в круглых скобках после имени функции.
Продолжим наш пример с выводом сообщения. Снова изменим функцию Primer, приведя её к следующему виду
Function Primer ($a, $b, $c) {"Это пример $a $b $c."}
Результат будет тем же самым.
Использование формальных параметровВ данном случае каждый параметр принял значение определенного слова. Но это могут быть и числа, с которыми мы можем производить математические операции.
Создадим функцию Summa, которая складывала бы значения двух аргументов.
Function Summa ($a, $b) {$a+$b}
Мы можем задать значения параметров сразу. Если все значения уже заданы, функции не нужны дополнительные аргументы. Мы также вольны называть параметры по собственному усмотрению.
Видоизменим функцию Summa.
Function Summa ($chislo1=15,$chislo2=20) {$chislo1+$chislo2}
Мы обозначили параметры как $chislo1 и $chislo2, задав им значения соответственно 15 и 20. Поскольку значения всех параметров здесь указаны, аргументы нам не нужны. Но, если мы всё-таки запустим эту функцию с дополнительным аргументом, то он заменит собой значение $chislo1, а $chislo2 останется без изменений.
PowerShell также позволяет указывать тип параметра функции. Например, тип [int] это целые числа, [string] — текст, а [boolean] — логический тип данных.
Вот следующий пример.
Использование типов данных в Windows PowerShellКак видим, в результате деления $a на $b должно было получиться 1,15. Но, поскольку мы указали интерпретатору воспринимать все параметры функции как целые числа, дробные значения были округлены до целых. Обратите внимание на округления, которые представлены ниже.
Они не совсем соответствуют тем законам математики, к которым мы привыкли.
Среди типов параметров есть так называемые «параметры-переключатели» обозначающиеся типом [Switch]. Их смысл состоит в логическом выборе, а сами параметры могут принимать только значения $True или $False.
Создадим функцию с таким переключателем.
Function Vybor ([Switch] $a) { >> if ($a) { >> "Это первый вариант." >> } >> else { "Это второй вариант." >> } >> } >>
В данном случае, если мы запустим функцию Vybor с параметром -a (аналогично, как мы запускали dir с параметрами -recurse и -filter в прошлой статье), то нам выйдет одно сообщение, а если без параметра, то другое.
Использование переключателя Switch в Windows PowerShellНа этом с функциями пока всё. Далее мы продолжим изучать типы команд в Windows PowerShell.
Переменные и функции
Security Controls поддерживает использование ряда переменных и функций PowerShell для выполнения каждого сценария. Все имена переменных начинаются с «ST_». Все имена функций начинаются с «ST-«. Вы можете использовать эти переменные и функции в своих сценариях.
Переменные PowerShell могут иметь другие области действия:
•Global: Доступна в текущем сеансе PowerShell.
•Script: Используется в сценарии (вне функций) и локально для этого сценария.
•Закрытая: Используется в функции и локально для этой функции.
•Local: Текущая область действия, которая может быть глобальной, сценарием или закрытой.
Переменные, используемые с Security Controls, имеют общую область действия. Так как каждый целевой компьютер выполняет собственный сеанс PowerShell, это равносильно использованию области действия сценария.
Переменные выполнения
В следующей таблице перечислены переменные для каждого выполнения. Для всех компьютеров будет отображаться одно и то же значение этих переменных. Не изменяйте значения переменных, отмеченных как [Только чтение].
ST_OutputDirectory | Полный путь к базовому каталогу вывода. Для выполнения будет создан подкаталог. [Только чтение] |
ST_RunDirectory | Полный путь к каталогу выполнения вывода. [Только чтение] |
ST_RunErrorFile | Полный путь к файлу ошибок выполнения вывода. В этом файле должны быть представлены ошибки, не относящиеся к конкретному компьютеру. Этот файл также будет содержать сообщения о компьютерах, для которых не удалось определить IP-адрес, и о компьютерах, на которых не будут созданы соответствующие им вложенные папки. [Только чтение] |
ST_RunName | Имя выполнения, указанное в пользовательском интерфейсе во время запуска вручную или по расписанию с добавленным временем выполнения. По умолчанию используется имя сценария или шаблона. [Только чтение] |
ST_RunOnConsole | Установите значение $false, если в сценарии используется удаленное подключение PowerShell, а в противном случае — $true. [Только чтение] |
ST_RunOutputFile | Полный путь к стандартному файлу вывода выполнения вывода. В этом файле будут присутствовать все данные вывода, отображаемые на консоли во время запуска из командной строки. [Только чтение] |
ST_RunResult | Это краткий результат выполнения, отображаемый в Мониторе операций. Он ограничен 100 символами. Если вы не введете эту переменную явно в своем сценарии, она будет установлена для указания количества компьютеров, на которых были обнаружены ошибки, и количество ошибок обнаружения компьютеров. |
Переменные компьютера
В следующей таблице перечислены переменные для каждого компьютера. Значения этих переменных могут отличаться для каждого целевого компьютера. Не изменяйте значения переменных, отмеченных как [Только чтение].
ST_ComputerName | Имя целевого компьютера. [Только чтение] |
ST_Credential | Объект PSCredential, содержащий имя пользователя и пароль SecureString, используемые для подключения к целевому компьютеру. Эту переменную можно передать в любую команду, которая поддерживает параметр Credential. [Только чтение] |
ST_DomainName | Имя домена или рабочей группы целевого компьютера. [Только чтение] |
ST_MachineDirectory | Полный путь к каталогу компьютера. Обычно это имя компьютера, однако, если имя компьютера содержит символы, недопустимые в именах папок, эти символы будут заменены символами подчеркивания. [Только чтение] |
ST_MachineError | Логическое значение, указывающее, что во время выполнения этого сценария на конкретном компьютере, обнаружена одна или несколько ошибок. |
ST_MachineErrorFile | Полный путь к файлу ошибок компьютера. Если во время выполнения сценария будут обнаружены ошибки, они будут записаны в этот файл. [Только чтение] |
ST_MachineOutputFile | Полный путь к файлу вывода компьютера. В этом файле будут представлены данные вывода, созданные сценарием для стандартного вывода. |
ST_MachineResult | Это краткий результат для компьютера, отображаемый в Мониторе операций. Он ограничен 100 символами. Если вы не укажете эту переменную явно в своем сценарии, для нее будет установлено значение «Успешно» в случае отсутствия ошибок на компьютере, или сообщение первой ошибки, обнаруженной для этого компьютера. Используйте функцию ST-SetMachineResult для явной установки значения этой переменной. |
ST_MachineResultSet | Логическое значение, указывающее, что сценарий установил переменную ST_MachineResult. Используйте функцию ST-SetMachineResult для явной установки значения ST_MachineResult и этой переменной. |
Функции
Security Controls содержит набор функций, доступных для каждого создаваемого вами сценария. Они перечислены в следующей таблице.
ST-GetTargetOS | Эта функция выполняет попытку подключения к целевой системе, опрашивая WMI и получая объект Win32_OperatingSystem. |
ST-SetMachineResult | Эта функция использует строковый параметр. Она устанавливает переменную ST_MachineResult для передачи строки и устанавливает для переменной ST_MachineResultSet значение $true. |
ST-SetMachineError | Эта функция использует строковый аргумент в качестве параметра. Она устанавливает переменную ST_MachineResult для передачи строки. Она также устанавливает для переменных ST_MachineResultSet и ST_MachineError значение $true. |
ST-SendMessage | Эта функция использует строковый параметр. Эта строка будет отображаться в Мониторе операций. Используйте эту функцию для отслеживания выполнения долговременных сценариев. После выполнения сценария строка в ST_MachineResult будет отображена в Мониторе операций. За исключением процесса отладки вы должны избегать вызова этого метода в быстро выполняемых сценариях. Строка будет усечена до 100 символов, если будет передана строка длиннее этого значения. |
ST-CreateMachineDirectory | Обычно каталог компьютера не создается до записи выводных данных. Если ваш сценарий создает файлы в каталоге компьютера, перед записью в каталоге вы должны вызвать эту функцию для создания каталога. Вызов этой функции более одного раза не имеет отрицательного эффекта. |
ST-CreateRunDirectory | Обычно каталог выполнения не создается до тех пор, пока во время выполнения не будут записаны любые выходные данные. Если ваш сценарий создает файлы в каталоге выполнения, перед записью в каталоге вы должны вызвать эту функцию для создания каталога. Вызов этой функции более одного раза не имеет отрицательного эффекта. |
ST-ComputerAndCredential | Эта функция возвращает для целевого компьютера соответствующие значения для использования в параметрах ComputerName и Credential. Для получения информации см. раздел Использование параметров ComputerName и Credential. |
ST-SubCC | Эта функция принимает строковый параметр, который является допустимым для команд PowerShell. Эта функция заменяет параметр «$ST_CC» в этой командной строке соответствующими значениями для использования параметров ComputerName и Credential. Затем она выполняет полученную команду и возвращает результаты выполнения. Для получения информации см. раздел Использование параметров ComputerName и Credential. |
powershell — Как передать несколько параметров в функцию в PowerShell?
Здесь есть несколько хороших ответов, но я хотел бы отметить пару других вещей. Параметры функций — это место, где светит PowerShell. Например, вы можете иметь именованные или позиционные параметры в расширенных функциях, например:
function Get-Something
{
Param
(
[Parameter(Mandatory=$true, Position=0)]
[string] $Name,
[Parameter(Mandatory=$true, Position=1)]
[int] $Id
)
}
Затем вы можете либо вызвать его, указав имя параметра, либо просто использовать позиционные параметры, поскольку вы явно их определили. Так что любой из них будет работать:
Get-Something -Id 34 -Name "Blah"
Get-Something "Blah" 34
Первый пример работает, хотя имя предоставляется вторым, потому что мы явно использовали имя параметра. Второй пример работает на основе позиции, поэтому имя должно быть первым. Когда это возможно, я всегда стараюсь определить позиции, чтобы оба варианта были доступны.
PowerShell также имеет возможность определять наборы параметров. Это использует это вместо перегрузки метода, и снова довольно полезно:
function Get-Something
{
[CmdletBinding(DefaultParameterSetName='Name')]
Param
(
[Parameter(Mandatory=$true, Position=0, ParameterSetName='Name')]
[string] $Name,
[Parameter(Mandatory=$true, Position=0, ParameterSetName='Id')]
[int] $Id
)
}
Теперь функция будет либо принимать имя, либо идентификатор, но не оба. Вы можете использовать их по месту или по имени. Так как они другого типа, PowerShell поймет это.Some.*’)] [string] $Name, [Parameter(Mandatory=$true, Position=1)] [ValidateRange(10,100)] [int] $Id ) }
В первом примере ValidatePattern принимает регулярное выражение, которое гарантирует, что предоставленный параметр соответствует ожидаемому. Если это не так, выдается интуитивно понятное исключение, которое говорит вам, что именно не так. Таким образом, в этом примере «Something» будет работать нормально, но «Summer» не пройдет проверку.
ValidateRange гарантирует, что значение параметра находится в диапазоне, который вы ожидаете для целого числа. Таким образом, 10 или 99 сработают, но 101 сгенерирует исключение.
Еще одним полезным является ValidateSet, который позволяет явно определять массив допустимых значений. Если будет введено что-то еще, будет сгенерировано исключение. Есть и другие, но, вероятно, самый полезный один из них — ValidateScript. Это берет блок скрипта, который должен иметь значение $ true, поэтому пределом является небо. Например:
function Get-Something
{
Param
(
[Parameter(Mandatory=$true, Position=0)]
[ValidateScript({ Test-Path $_ -PathType 'Leaf' })]
[ValidateScript({ (Get-Item $_ | select -Expand Extension) -eq ".csv" })]
[string] $Path
)
}
В этом примере мы уверены, что не только $ Path существует, но и что это файл (в отличие от каталога) и имеет расширение .csv. ($ _ относится к параметру, находящемуся внутри вашего скриптового блока.) Вы также можете передать гораздо большие многострочные скриптовые блоки, если требуется этот уровень, или использовать несколько скриптовых блоков, как я сделал здесь. Это чрезвычайно полезно, и делает для Nice чистые функции и интуитивно понятные исключения.
функций — PowerShell | Документы Microsoft
- 14 минут на чтение
В этой статье
Если вы пишете однострочники или сценарии PowerShell и вам часто приходится изменять их для различные сценарии, есть большая вероятность, что это хороший кандидат на превращение в функцию которые можно использовать повторно.
По возможности, я предпочитаю писать функции, потому что они больше ориентированы на инструменты. Я могу поставить
функции в модуле сценария, поместите этот модуль в $ env: PSModulePath
и вызовите функции
без необходимости физически определять, где они сохранены. Используя модуль PowerShellGet, это просто
для совместного использования этих модулей в репозитории NuGet. PowerShellGet поставляется с PowerShell версии 5.0 и
выше. Он доступен для отдельной загрузки для PowerShell версии 3.0 и выше.
Не усложняйте слишком много. Сохраняйте простоту и используйте самый простой способ достичь задача. Избегайте псевдонимов и позиционных параметров в любом коде, который вы повторно используете. Отформатируйте свой код для читаемость. Не кодируйте значения жестко; использовать параметры и переменные. Не пишите ненужный код даже если это ничего не повредит. Это добавляет ненужной сложности. Внимание к деталям идет долго способ при написании любого кода PowerShell.
Именование
При именовании ваших функций в PowerShell используйте регистр Pascal с утвержденным глаголом и
существительное в единственном числе.Я также рекомендую ставить перед существительным префикс. Например:
.
В PowerShell есть специальный список утвержденных глаголов, который можно получить, запустив Get-Verb
.
Get-Verb | Sort-Object -Property Глагол
Verb Group
---- -----
Добавить общий
Утвердить жизненный цикл
Жизненный цикл утверждения
Резервные данные
Блокировать безопасность
Данные контрольной точки
Очистить общий
Закрыть общий
Сравнить данные
Полный жизненный цикл
Сжать данные
Подтвердить жизненный цикл
Подключить коммуникации
Конвертировать данные
Конвертировать из данных
Преобразовать в данные
Копировать Common
Диагностика отладки
Запретить жизненный цикл
Отключить жизненный цикл
Отключить связь
Снять данные
Редактировать данные
Включить жизненный цикл
Введите общий
Выход из общего
Развернуть данные
Экспорт данных
Найти общий
Формат Общий
Общайся
Обеспечение безопасности
Групповые данные
Скрыть общее
Импортировать данные
Инициализировать данные
Установить жизненный цикл
Вызов жизненного цикла
Присоединяйтесь к Common
Ограничить данные
Замок Общий
Измерение диагностики
Объединить данные
Смонтировать данные
Переместить общий
Новый Common
Открытый общий
Оптимизировать Общие
Выходные данные
Ping Diagnostic
Поп-Коммон
Защитить безопасность
Опубликовать данные
Нажмите Common
Читать сообщения
Получать сообщения
Повторить Common
Жизненный цикл регистрации
Удалить общие
Переименовать общий
Диагностика ремонта
Жизненный цикл запроса
Сбросить общий
Изменить размер общего
Разрешить диагностику
Перезапустить жизненный цикл
Восстановить данные
Продолжить жизненный цикл
Отменить безопасность
Сохранять данные
Общий поиск
Выберите Common
Отправить сообщения
Установить общий
Показать общие
Пропустить Common
Разделить общий
Начать жизненный цикл
Шаг Общий
Остановить жизненный цикл
Отправить жизненный цикл
Приостановить жизненный цикл
Коммутатор Общий
Синхронизировать данные
Диагностический тест
Диагностика трассировки
Разблокировать безопасность
Отменить общее
Жизненный цикл удаления
Разблокировать Common
Снять защиту безопасности
Отменить публикацию данных
Отменить регистрацию жизненного цикла
Обновить данные
Использовать другое
Ждать жизненный цикл
Смотреть общие
Написать сообщение
В предыдущем примере я отсортировал результаты по столбцу Verb .Столбец Группа дает вы имеете представление о том, как используются эти глаголы. Важно выбрать утвержденный глагол в PowerShell. когда функции добавляются в модуль. Модуль генерирует предупреждающее сообщение во время загрузки, если вы выберите неподтвержденный глагол. Это предупреждающее сообщение заставляет ваши функции выглядеть непрофессионально. Не одобрено глаголы также ограничивают обнаружение ваших функций.
Простая функция
Функция в PowerShell объявляется с ключевым словом function, за которым следует имя функции и затем открывающая и закрывающая фигурная скобка.Код, который будет выполнять функция, содержится в эти фигурные скобки.
function Get-Version {
$ PSVersionTable.PSVersion
}
Показанная функция представляет собой простой пример, возвращающий версию PowerShell.
Get-версия
Major Minor Build Revision
----- ----- ----- --------
5 1 14393 693
Существует большая вероятность конфликта имен с функциями, названными чем-то вроде Get-Version
и default.
команды в 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
После загрузки в память вы можете видеть функции на Function PSDrive.
Get-ChildItem -Path Функция: \ Get- * Версия
CommandType Имя Версия Источник
----------- ---- ------- ------
Функция Get-Version
Функция Get-PSVersion
Функция Get-MrPSVersion
Если вы хотите удалить эти функции из текущего сеанса, вам придется удалить их из Функция PSDrive или закрыть и снова открыть PowerShell.
Get-ChildItem -Path Функция: \ Get- * Version | Убрать предмет
Убедитесь, что функции действительно были удалены.
Get-ChildItem -Path Функция: \ Get- * Версия
Если функции были загружены как часть модуля, модуль можно выгрузить, чтобы удалить их.
Remove-Module -Name
Командлет Remove-Module
удаляет модули из памяти в текущем сеансе PowerShell.
не удаляет их из вашей системы или с диска.
Параметры
Не присваивать значения статически! Используйте параметры и переменные. Когда дело доходит до наименования вашего параметры, по возможности используйте то же имя, что и командлеты по умолчанию для имен параметров.
function Test-MrParameter {
парам (
$ ComputerName
)
Запись-вывод $ ComputerName
}
Почему я использовал ComputerName , а не Computer , ServerName или Host для моего параметра название? Это потому, что я хотел, чтобы моя функция была стандартизирована, как командлеты по умолчанию.
Я создам функцию для запроса всех команд в системе и возврата количества из них, которые иметь определенные имена параметров.
function Get-MrParameterCount {
парам (
[строка []] $ ParameterName
)
foreach ($ Parameter в $ ParameterName) {
$ Results = Get-Command -ParameterName $ Parameter -ErrorAction SilentlyContinue
[pscustomobject] @ {
ParameterName = $ Parameter
NumberOfCmdlets = $ Results.Count
}
}
}
Как видно из результатов, показанных ниже, 39 команд имеют параметр ComputerName .Там нет командлетов с такими параметрами, как Computer , ServerName , Host или Станок .
Get-MrParameterCount -ParameterName ComputerName, Computer, ServerName, Host, Machine
ParameterName NumberOfCmdlets
------------- ---------------
ComputerName 39
Компьютер 0
ServerName 0
Хост 0
Машина 0
Я также рекомендую использовать тот же регистр для имен параметров, что и для командлетов по умолчанию.Использовать Имя компьютера
, а не имя компьютера
. Это заставляет ваши функции выглядеть и чувствовать себя как по умолчанию
командлеты. Люди, которые уже знакомы с PowerShell, будут чувствовать себя как дома.
Оператор param
позволяет определить один или несколько параметров. Определения параметров:
через запятую (,
). Для получения дополнительной информации см. About_Functions_Advanced_Parameters.
Расширенные функции
Превратить функцию в PowerShell в расширенную функцию действительно просто.Одно из отличий между функцией и расширенной функцией заключается в том, что расширенные функции имеют ряд общих параметры, которые добавляются к функции автоматически. Эти общие параметры включают параметры например Verbose и Debug .
Я начну с функции Test-MrParameter
, которая использовалась в предыдущем разделе.
function Test-MrParameter {
парам (
$ ComputerName
)
Запись-вывод $ ComputerName
}
Я хочу, чтобы вы заметили, что функция Test-MrParameter
не имеет общего
параметры.Есть несколько разных способов увидеть общие параметры. Один из них — просмотр
синтаксис с использованием Get-Command
.
Get-Command -Name Test-MrParameter -Syntax
Test-MrParameter [[-ComputerName]
Другой способ — развернуть параметры с помощью команды Get-Command
.
(Get-Command -Name Test-MrParameter) .Parameters.Keys
Имя компьютера
Добавьте CmdletBinding
, чтобы превратить функцию в расширенную функцию.
function Test-MrCmdletBinding {
[CmdletBinding ()] # << - превращает обычную функцию в расширенную.
парам (
$ ComputerName
)
Запись-вывод $ ComputerName
}
Добавление CmdletBinding
автоматически добавляет общие параметры. CmdletBinding
требует параметра
блок, но блок param
может быть пустым.
Get-Command -Name Test-MrCmdletBinding -Syntax
Test-MrCmdletBinding [[-ComputerName]
Детализация параметров с помощью команды Get-Command
показывает фактические имена параметров, включая
общие.
(Get-Command -Name Test-MrCmdletBinding) .Parameters.Keys
Имя компьютера
Подробный
Отлаживать
ErrorAction
ПредупреждениеДействие
ИнформацияДействие
ErrorVariable
ПредупреждениеПеременная
ИнформацияПеременная
OutVariable
OutBuffer
PipelineVariable
Поддерживает процесс
SupportsShouldProcess
добавляет WhatIf и Подтвердите параметры . Они нужны только для
команды, которые вносят изменения.
function Test-MrSupportsShouldProcess {
[CmdletBinding (SupportsShouldProcess)]
парам (
$ ComputerName
)
Запись-вывод $ ComputerName
}
Обратите внимание, что теперь есть параметры WhatIf и Confirm .
Get-Command -Name Test-MrSupportsShouldProcess -Syntax
Test-MrSupportsShouldProcess [[-ComputerName]
Еще раз, вы также можете использовать Get-Command
для возврата списка фактических имен параметров, включая
общие вместе с WhatIf и Confirm.
(Get-Command -Name Test-MrSupportsShouldProcess) .Parameters.Keys
Имя компьютера
Подробный
Отлаживать
ErrorAction
ПредупреждениеДействие
ИнформацияДействие
ErrorVariable
ПредупреждениеПеременная
ИнформацияПеременная
OutVariable
OutBuffer
PipelineVariable
Что если
Подтверждать
Проверка параметров
Проверить ввод на ранней стадии.Зачем позволять вашему коду продолжать путь, если это невозможно запустить без правильного ввода?
Всегда вводите переменные, которые используются для ваших параметров (укажите тип данных).
function Test-MrParameterValidation {
[CmdletBinding ()]
парам (
[строка] $ ComputerName
)
Запись-вывод $ ComputerName
}
В предыдущем примере я указал String в качестве типа данных для ComputerName параметр.Это приводит к тому, что он позволяет указать только одно имя компьютера. Если более одного имя компьютера указывается через список, разделенный запятыми, генерируется ошибка.
Test-MrParameterValidation -ComputerName Server01, Server02
Test-MrParameterValidation: невозможно обработать преобразование аргумента для параметра
'Имя компьютера'. Невозможно преобразовать значение в тип System.String.
В строке: 1 символ: 42
+ Test-MrParameterValidation -ComputerName Server01, Server02
+
+ CategoryInfo: InvalidData: (:) [Test-MrParameterValidation], ParameterBindingArg
umentTransformationException
+ FullyQualifiedErrorId: ParameterArgumentTransformationError, Test-MrParameterValidation
Проблема с текущим определением заключается в том, что можно опустить значение ComputerName параметр, но для успешного выполнения функции требуется значение.Вот где Обязательный атрибут
параметра пригодится.
function Test-MrParameterValidation {
[CmdletBinding ()]
парам (
[Параметр (обязательный)]
[строка] $ ComputerName
)
Запись-вывод $ ComputerName
}
Синтаксис, использованный в предыдущем примере, совместим с PowerShell версии 3.0 и выше. [Параметр (Обязательный = $ true)] Вместо этого можно указать
, чтобы функция была совместима с
PowerShell версии 2.0 и выше. Теперь, когда требуется ComputerName , если он не
указано, функция запросит один.
Test-MrParameterValidation
командлет Test-MrParameterValidation в позиции 1 командного конвейера
Задайте значения для следующих параметров:
Имя компьютера:
Если вы хотите разрешить более одного значения для параметра ComputerName , используйте String тип данных, но добавьте открытые и закрытые квадратные скобки к типу данных, чтобы учесть массив строк.
function Test-MrParameterValidation {
[CmdletBinding ()]
парам (
[Параметр (обязательный)]
[строка []] $ ComputerName
)
Запись-вывод $ ComputerName
}
Может быть, вы хотите указать значение по умолчанию для параметра ComputerName , если оно не указано.
Проблема в том, что значения по умолчанию нельзя использовать с обязательными параметрами. Вместо этого вам нужно
используйте атрибут проверки параметра ValidateNotNullOrEmpty
со значением по умолчанию.
function Test-MrParameterValidation {
[CmdletBinding ()]
парам (
[ValidateNotNullOrEmpty ()]
[строка []] $ ComputerName = $ env: COMPUTERNAME
)
Запись-вывод $ ComputerName
}
Даже при установке значения по умолчанию старайтесь не использовать статические значения. В предыдущем примере $ env: COMPUTERNAME
используется как значение по умолчанию, которое автоматически переводится в локальный
имя компьютера, если значение не указано.
Подробный вывод
Хотя встроенные комментарии полезны, особенно если вы пишете сложный код, они никогда не получат увидят пользователи, если они не заглянут в сам код.
Функция, показанная в следующем примере, имеет встроенный комментарий в цикле foreach
. Пока это
конкретный комментарий может быть не так уж сложно найти, представьте, если бы функция включала сотни
строки кода.
function Test-MrVerboseOutput {
[CmdletBinding ()]
парам (
[ValidateNotNullOrEmpty ()]
[строка []] $ ComputerName = $ env: COMPUTERNAME
)
foreach ($ Computer в $ ComputerName) {
# Попытка выполнить какое-либо действие на $ Computer << - Не используйте
# встраивайте такие комментарии, используйте вместо этого подробный текст.Запись-Вывод $ Компьютер
}
}
Лучше использовать Write-Verbose
вместо встроенных комментариев.
function Test-MrVerboseOutput {
[CmdletBinding ()]
парам (
[ValidateNotNullOrEmpty ()]
[строка []] $ ComputerName = $ env: COMPUTERNAME
)
foreach ($ Computer в $ ComputerName) {
Write-Verbose -Message «Попытка выполнить какое-либо действие на $ Computer»
Запись-Вывод $ Компьютер
}
}
Когда функция вызывается без параметра Verbose , подробный вывод не будет отображается.
Test-MrVerboseOutput -ComputerName Server01, Server02
Когда он вызывается с параметром Verbose , выводится подробный вывод.
Test-MrVerboseOutput -ComputerName Server01, Server02 -Verbose
Вход трубопровода
Если вы хотите, чтобы ваша функция принимала ввод конвейера, необходимо дополнительное кодирование. В виде упоминалось ранее в этой книге, команды могут принимать конвейерный ввод по значению (по типу) или по значению название собственности .Вы можете писать свои функции так же, как собственные команды, чтобы они принимали один или оба этих типа ввода.
Чтобы принять ввод конвейера по значению , укажите атрибут параметра ValueFromPipeline
для
этот конкретный параметр. Имейте в виду, что вы можете принимать входные данные конвейера по значению только из
по одному каждого типа данных. Например, если у вас есть два параметра, которые принимают строковый ввод, только один из
они могут принимать ввод конвейера по значению , потому что если вы указали его для обеих строк
параметры, вход конвейера не знает, к какому из них привязаться.Это еще одна причина, по которой я звоню
этот тип конвейера вводит по типу вместо по значению .
Ввод в конвейер поступает по одному элементу за раз, аналогично тому, как элементы обрабатываются в цикле foreach
.
Как минимум, для обработки каждого из этих элементов требуется блок процесса
, если вы принимаете
массив в качестве входных данных. Если вы принимаете в качестве входных данных только одно значение, блок процесса
не нужен,
но я все же рекомендую указать его для единообразия.
function Test-MrPipelineInput {
[CmdletBinding ()]
парам (
[Параметр (обязательный,
ValueFromPipeline)]
[строка []] $ ComputerName
)
ПРОЦЕСС {
Запись-вывод $ ComputerName
}
}
Прием ввода конвейера по имени свойства аналогичен, за исключением того, что он указан с помощью ValueFromPipelineByPropertyName
атрибут параметра, и его можно указать для любого количества
параметры независимо от типа данных.Ключ в том, что вывод команды, которая передается по конвейеру
должно иметь имя свойства, которое соответствует имени параметра или псевдониму параметра вашего
функция.
function Test-MrPipelineInput {
[CmdletBinding ()]
парам (
[Параметр (обязательный,
ValueFromPipelineByPropertyName)]
[строка []] $ ComputerName
)
ПРОЦЕСС {
Запись-вывод $ ComputerName
}
}
Блоки BEGIN
и END
являются необязательными. BEGIN
должен быть указан перед блоком PROCESS
и
используется для выполнения любой начальной работы до получения элементов из конвейера. Это
важно понять. Введенные значения недоступны в блоке BEGIN
. КОНЕЦ
блок будет указан после блока PROCESS
и используется для очистки после того, как все элементы
, которые подаются по трубопроводу, были обработаны.
Обработка ошибок
Функция, показанная в следующем примере, генерирует необработанное исключение, когда компьютер не может связаться.
function Test-MrErrorHandling {
[CmdletBinding ()]
парам (
[Параметр (обязательный,
ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[строка []] $ ComputerName
)
ПРОЦЕСС {
foreach ($ Computer в $ ComputerName) {
Test-WSMan -ComputerName $ Компьютер
}
}
}
Есть несколько различных способов обработки ошибок в PowerShell. Try / Catch
более современный
способ обработки ошибок.
function Test-MrErrorHandling {
[CmdletBinding ()]
парам (
[Параметр (обязательный,
ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[строка []] $ ComputerName
)
ПРОЦЕСС {
foreach ($ Computer в $ ComputerName) {
пытаться {
Test-WSMan -ComputerName $ Компьютер
}
поймать {
Предупреждение о записи - сообщение «Невозможно подключиться к компьютеру: $ Computer»
}
}
}
}
Хотя функция, показанная в предыдущем примере, использует обработку ошибок, она также генерирует необработанное исключение, потому что команда не генерирует завершающую ошибку.Это тоже важно понять. Выявляются только завершающие ошибки. Задайте параметр ErrorAction с помощью Остановить как значение для превращения непрекращающейся ошибки в прерывающуюся.
function Test-MrErrorHandling {
[CmdletBinding ()]
парам (
[Параметр (обязательный,
ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[строка []] $ ComputerName
)
ПРОЦЕСС {
foreach ($ Computer в $ ComputerName) {
пытаться {
Test-WSMan -ComputerName $ Computer -ErrorAction Stop
}
поймать {
Предупреждение о записи - сообщение «Невозможно подключиться к компьютеру: $ Computer»
}
}
}
}
Не изменяйте глобальную переменную $ ErrorActionPreference
без крайней необходимости.Если ты
используя что-то вроде .NET непосредственно из вашей функции PowerShell, вы не можете указать ErrorAction на самой команде. В этом случае вам может потребоваться изменить глобальный $ ErrorActionPreference
, но если вы измените ее, верните ее сразу после попытки
команда.
Лучшей практикой считается добавление справки на основе комментариев к вашим функциям, чтобы люди вы делитесь ими, и будете знать, как их использовать.
function Get-MrAutoStoppedService {
<#
.ОБЗОР
Возвращает список служб, которые настроены на автоматический запуск, но не
в настоящее время работает, за исключением служб, для которых настроен отложенный запуск.
.ОПИСАНИЕ
Get-MrAutoStoppedService - это функция, которая возвращает список служб из
указанные удаленные компьютеры, которые настроены на автоматический запуск, не
в настоящее время работает, и исключает службы, которые настроены на автоматический запуск
с отложенным запуском.
.PARAMETER имя_компьютера
Удаленный компьютер (ы), на которых нужно проверить статус служб..PARAMETER Учетные данные
Задает учетную запись пользователя, у которой есть разрешение на выполнение этого действия. По умолчанию
текущий пользователь.
.ПРИМЕР
Get-MrAutoStoppedService -ComputerName 'Server1', 'Server2'
.ПРИМЕР
«Сервер1», «Сервер2» | Get-MrAutoStoppedService
.ПРИМЕР
Get-MrAutoStoppedService -ComputerName 'Server1' -Credential (Get-Credential)
.ВХОДЫ
Нить
ВЫХОДЫ
PSCustomObject
.ПРИМЕЧАНИЯ
Автор: Майк Ф. Роббинс
Сайт: http://mikefrobbins.com
Twitter: @mikefrobbins
#>
[CmdletBinding ()]
парам (
)
#Function Body
}
Когда вы добавляете справку на основе комментариев к своим функциям, справку для них можно получить так же, как встроенные команды по умолчанию.
Весь синтаксис для написания функции в PowerShell может показаться ошеломляющим, особенно для кого-то. кто только начинает. Часто, если я не могу вспомнить синтаксис для чего-либо, я открываю второй экземпляр ISE на отдельном мониторе и просмотр «Командлет (расширенная функция) - Завершено» фрагмент кода при вводе кода для моей функции. Доступ к фрагментам можно получить в среде PowerShell ISE. используя комбинацию клавиш Ctrl + J .
Сводка
В этой главе вы узнали основы написания функций в PowerShell, чтобы включить функцию в расширенную функцию и некоторые из наиболее важных элементов, которые вам следует учитывать при написании функций PowerShell, таких как проверка параметров, подробный вывод, конвейер ввод, обработка ошибок и помощь на основе комментариев.
Обзор
- Как получить список утвержденных глаголов в PowerShell?
- Как превратить функцию PowerShell в расширенную функцию?
- Когда нужно добавить WhatIf и Confirm в ваши функции PowerShell параметры ?
- Как превратить непрекращающуюся ошибку в прерывающуюся?
- Почему вы должны добавлять справку на основе комментариев к своим функциям?
Рекомендуемая литература
функций - PowerShell - SS64.com
Функции - PowerShell - SS64.com Блок кода может содержаться в функции для удобного повторного использования.
Чтобы создать функцию, вызовите ключевое слово function , за которым следует имя функции, а затем включите свой код в пару фигурных скобок.
функция Сложение чисел {
$ args [0] + $ args [1]
}
PS C: \> Добавить номера 5 10
15
Аналогичная функция с именованными параметрами:
функция Выходной налог с продаж {
param ( [int] $ Цена, [int] $ Tax )
$ Цена + $ НДС
}
PS C: \> Output-SalesTax -price 1000 -tax 38
1038
Для отображения определения функции можно использовать несколько методов:
функция cat: добавочные номера
или
$ {function: Add-Numbers}
или
(Get-команда Добавить номера).определение
Чтобы вывести список всех функций в текущем сеансе: get-command -CommandType function
Обратите внимание: в блоке кода вам нужно определить функцию до того, как вы ее вызовете.
Не добавляйте скобки к параметрам функции:
$ result = Сложить числа (5, 10) - Неверно!
$ результат = Сложение 5 10 - Право
Функция автоматически принимает позиционные параметры в том порядке, в котором они объявлены, или вы можете передавать именованные параметры в любом порядке.Это также работает при вызове через псевдоним.
Как запустить функцию
Наиболее распространенный способ использования функции - включить ее в сценарий PowerShell. Функция должна быть определена до любых ее вызовов, так что это допустимый сценарий:
Добавочные номера функции{
$ args [0] + $ args [1]
}
Добавочные номера 5 10Для небольших функций и / или при тестировании также можно ввести (или скопировать и вставить) всю функцию в командной строке PowerShell.Это не совсем практично для более длинных скриптов, потому что это заполняет большую часть вашей истории команд.
PowerShell по умолчанию не сохраняет функции или фильтры постоянно. Поэтому, если вы закроете и снова откроете PowerShell, функция / фильтр больше не будут доступны. Чтобы сделать функцию постоянно доступной, добавьте ее в свой PowerShell $ Profile, после чего она будет загружаться для каждого нового сеанса PowerShell и может вызываться из нескольких разных сценариев без необходимости явного включения.
Точечный источник скрипта очень похож на использование PowerShell $ Profile, но вместо всегда загружаемого $ Profile вы сохраняете функцию в скрипте по вашему выбору, а затем загружаете его (с помощью точечного источника) только тогда, когда это необходимо:
. C: \ Scripts \ Tools.ps1
Добавочные номера 5 10Другой способ сделать функцию доступной для нескольких сценариев / сеансов - включить ее как часть модуля PowerShell . При сохранении в папке системного модуля или в папке пользовательского модуля автоматическое обнаружение командлетов (в PowerShell v3 и выше) гарантирует доступность этих функций.
Когда вы вызываете имя функции, код внутри функции запускается. Функция может принимать импортированные значения либо в качестве аргументов, либо через конвейер. Если функция возвращает какие-либо значения, их можно присвоить переменным или передать другим функциям или командлетам.
Выберите хорошее имя функции
Встроенные псевдонимы PowerShell будут иметь приоритет над функцией (или скриптом) с тем же именем. Чтобы избежать конфликтов, всегда проверяйте, используется ли уже имя с помощью name .Выбор хорошего описательного имени для вашей функции поможет с этим
Лучше всего использовать имя в формате Глагол-Существительное , поскольку оно содержит символ «-», это не будет конфликтовать с любыми встроенными псевдонимами. Вы можете создать список утвержденных команд PowerShell, запустив командлет Get-Verb
.
Определение функции или фильтра:
функция [ scope_type :] имя { [param ( param_list )] script_block }фильтр [ scope_type :] имя { [param ( param_list )] script_block }
Разница между функцией фильтра и обычной функцией заключается в том, как они обрабатывают элементы, проходящие через конвейер:
В случае обычной функции объекты конвейера привязываются к автоматической переменной $ input, и выполнение блокируется до тех пор, пока не будет получен весь ввод.Затем функция начинает обработку данных.
С функцией фильтрации данные обрабатываются во время их получения, не дожидаясь ввода всех данных. Фильтр получает каждый объект из конвейера через автоматическую переменную $ _, и блок скрипта обрабатывается для каждого объекта.
param_list - это необязательный список имен параметров, разделенных запятыми, им также могут предшествовать их типы данных в скобках. Это делает функцию более читаемой, чем использование $ args, а также дает вам возможность указать значения по умолчанию.
Расширенная функция
Функция Advanced PowerShell содержит атрибут [cmdletbinding ()] (или атрибут Parameter). Это добавляет несколько возможностей, таких как дополнительная проверка параметров и возможность простого использования Write-Verbose.
Функция с cmdletbinding выдаст ошибку, если в командной строке появятся необработанные значения параметров.Расширенные функции PowerShell обычно включают блоки Begin..Process..End для обработки входных данных, документации и автопомощи, включая параметры.
Диапазон изменения
По умолчанию все переменные, созданные в функциях, являются локальными, они существуют только внутри функции, хотя они все еще видны, если вы вызываете вторую функцию из первой.
Чтобы сохранить переменную, чтобы функция могла вызываться многократно, а переменная сохраняла свое последнее значение, добавьте $ script: к имени переменной, например $ script: myvar
Чтобы сделать переменную global, добавьте $ global: к имени переменной, e.г. $ global: myvar
Примеры функций
Функция для поиска всех файлов на диске C:, принадлежащих определенному пользователю:
функция Get-ByOwner { Get-ChildItem -recurse C: \ | get-acl | где {$ _. Owner -match $ args [0]} }
PS C: \> Get-ByOwner JackFrost
Функция для отображения справки PowerShell на SS64.com, при этом будет запущен веб-браузер по умолчанию:
функция Get-Help2 {
параметр ([строка] $ команда) Start-process -filepath "https: // ss64.com / ps / $ command.html " }
Затем вы можете сделать:
PS C: \> Get-Help2 -command set-acl
или потому что есть только один параметр:
PS C: \> Get-Help2 set-acl
Фильтр для отображения только файлов меньше заданного размера:
фильтр FileSizeBelow ($ size) { if ($ _. Length -le $ size) {$ _} }
PS C: \> gci \\ server64 \ workgroups -filter | FileSizeBelow 200kb
PS C: \> gci -recurse \\ server64 \ workgroups | ? {! $ _.PSIsContainer} | Размер файла ниже 100 МБ
Функция со значениями по умолчанию:
функция цена записи { параметр ( [строка] $ description = "unknown", [int] $ price = 100 ) Запись-вывод "$ описание ..... $ цена" } PS C: \> написать-цена -цена 250 -описание Hammer
Hammer ..... 250
Фильтр для поиска файлов, принадлежащих определенному пользователю:
фильтр ownbyme { если ($ _.Владелец -матч "JackFrost") {$ _} } PS C: \> gci -recurse C: \ | Get-Acl | где {$ _ | ownbyme }
«Функция воображения состоит не в том, чтобы уладить странные вещи, а в том, чтобы сделать их странными» ~ Г. К. Честертон
Связанные командлеты PowerShell:
Расширенные функции - включают функции командлетов, общие параметры -verbose, -whatif, -confirm и т. Д.
Утверждения - Использование фильтра для утверждения определенных предварительных условий.
New-Alias - Создайте новый (короткий) псевдоним для вашей функции.
Begin..Process..End - Обработка ввода функции.
Scriptblock - набор операторов.
Ref vars - Передача ссылочной переменной функции.
Авторские права © 1999-2021 SS64.com
Некоторые права защищены.
Функции PowerShell - Технические мысли
В этом выпуске серии «Изучение PowerShell» мы рассмотрим функции PowerShell. В последнем выпуске мы рассмотрели сценарии PowerShell, в которых мы начали создавать решения и решать проблемы с помощью PowerShell.Сценарии PowerShell великолепны, и многие люди тратят на этом этапе довольно много времени при изучении PowerShell. Сценарии позволяют упростить работу и помогают быстро автоматизировать задачи. По мере того, как вы поправитесь и начнете писать больше PowerShell, вам нужно будет заняться созданием функций PowerShell!
Видео
Если вы предпочитаете формат видео, а не письменную документацию, я обсуждаю эту тему в следующем видео TechThoughts:
Когда следует писать функцию PowerShell
В конце концов, сценарий PowerShell - это набор кода, который выполняет задачу.То же самое и с функцией PowerShell! Итак, почему вы решили написать функцию вместо скрипта? Ниже мы рассмотрим несколько причин. Вообще говоря, сценарий - это что-то для , для вас . Когда вы хотите начать делиться своим кодом или попросить товарищей по команде задействовать его, вы захотите задействовать некоторые возможности, которые предоставляют функции. Нет твердой линии. Для быстрой задачи, которая будет запускаться на вашей рабочей станции один раз, может иметь смысл сценарий. Если вы пишете оболочку PowerShell, которую могут использовать другие или которую вы можете использовать более одного раза, функция, скорее всего, будет работать лучше.
- Одноцелевое - функция обычно используется для выполнения узкой задачи и «делать одно, и делать это хорошо». Это делает функции очень удобными для повторного использования . Например, если вы пишете функцию ведения журнала, вы можете использовать эту функцию ведения журнала PowerShell с другими функциями или сценариями.
- Справка - функции поддерживают комментарии на основе справки. Это позволяет вашим пользователям делать такие вещи, как вводить Get-Help и выяснять, как использовать вашу функцию.
- Параметры - поддержка простых и расширенных объявлений параметров и управления позволяет вашей функции быть динамической и принимать различные формы пользовательского ввода.
- Testable - функции можно тестировать и имитировать, что значительно улучшает качество кода.
Анатомия функции PowerShell
Вот базовая структура и порядок функции PowerShell. Мы подробно рассмотрим каждый из этих разделов ниже.
# function help - (необязательно, но настоятельно рекомендуется) # имя функции # CmdletBinding - (необязательно) # параметры - (необязательно) # функциональная логика (необязательно Begin / Process / End) # return - (необязательно) function Verb-Noun { [CmdletBinding ()] парам ( ) начинать { } процесс { } конец { } }
Справка по функциям
Когда вы включаете справку в верхней части вашей функции, она будет отображаться, когда Get-Help запускается для вашей функции. Это мощная возможность, когда другие изучают ваш код.Потратьте время на то, чтобы конкретизировать хороший Синопсис и Описание в сочетании с убедительными примерами, чтобы помочь другим понять, для чего предназначена ваша функция и как ее использовать.
Все поля справки необязательны, и вы можете добавлять или удалять их по своему усмотрению. Я рекомендую вам включить как минимум поля ниже.
<# .СИНОПСИС Краткое описание .ОПИСАНИЕ Длинное описание .ПРИМЕР C: \ PS> Пример использования этого командлета .ПРИМЕР C: \ PS> Еще один пример использования этого командлета .ПАРАМЕТР InputObject Задает обрабатываемый объект. Вы также можете передать объекты по конвейеру этой команде. ВЫХОДЫ Выходные данные этого командлета (если есть) .ПРИМЕЧАНИЯ Главные примечания .КОМПОНЕНТ Компонент, которому принадлежит этот командлет #>
CmdletBinding
Когда вы пишете отличную функцию и даете ей имя, например, Get-AllFileInformation , она выглядит и будет действовать как командлет . Но важным отличием является то, что функция PowerShell не является командлетом .Командлеты написаны и скомпилированы на C #, а ваша функция PowerShell написана на PowerShell.
CmdletBinding - это атрибут функций, который включает возможности, которые заставляют их работать как скомпилированные командлеты. Добавление этого в начало вашей функции даст вашей функции множество дополнительных возможностей, таких как:
- Write-Verbose - разрешите пользователям использовать переключатель -Verbose, чтобы узнать, что делает ваша функция, пока она ее выполняет.
- ShouldProcess - если ваша функция внесет изменения в систему с высоким риском, вы можете захотеть, чтобы пользователь подтвердил действие.
- PositionalBinding - позволяет запускать вашу функцию без явного указания имени каждого параметра. Значения могут быть выведены по порядку, в котором они предоставляются вашей функции
параметры
параметр ( [Параметр ( Позиция = 0, Обязательно = $ false )] [нить] $ Город, [Параметр (позиция = 1)] [ValidateSet ('Метрика', 'USCS')] [нить] $ Units = 'USCS', [Параметр (Позиция = 2)] [ValidateSet ('ar', 'af', 'be', 'ca', 'da', 'de', 'el', 'en', 'et', 'fr', 'fa', 'hu' , 'ia', 'id', 'it', 'nb', 'nl', 'pl', 'pt-br', 'ro', 'ru', 'tr', 'th', 'uk' , 'vi', 'zh-cn', 'zh-tw')] [нить] $ Language = 'ru', [Параметр (Позиция = 3)] [выключатель] $ Короткие )
Параметры служат для того, чтобы предоставить пользователю способ динамического взаимодействия с вашей функцией.Вы можете принимать различные формы ввода и выполнять широкий спектр проверок и подтверждений, чтобы убедиться, что вы получаете нужную информацию.
Вы можете оставаться очень простым и объявлять только имена своих параметров. В качестве альтернативы вы можете уточнить, что требуется для ваших параметров:
- Обязательный ли параметр
- Положение параметра (порядок)
- Тип параметра (строка / int / bool / и т. Д.)
- Установка значений по умолчанию
- Проверка ввода
- Наборы параметров
- Намного больше
Этот пост не может охватить все возможные конфигурации параметров.Даже после многих лет написания PowerShell мне трудно запомнить все настройки параметров и синтаксис. Знайте, что объявления параметров - это ваш способ ввода данных в вашу функцию. Вы можете предоставить им много деталей и элементов управления или просто сделать их простыми в зависимости от ваших потребностей. Добавьте в закладки ссылки на параметры внизу этого сообщения. Даже сегодня я часто бываю у них!
Начало процесса Конец
Эти три ключевых слова представляют собой этапы, которые вы можете объявить в своей функции.
- Начало инициализирует некоторые шаги в начале
- Процесс будет обрабатывать каждый полученный объект
- Конец может выполнить очистку.
Это особенно полезно, если вы хотите, чтобы ваша функция поддерживала обработку входных данных из конвейера.
Это может быть трудно понять в теории, поэтому вот пример, демонстрирующий его использование.
function Get-PipelineBeginEnd { парам ( [строка] $ SomeInput ) начинать { "Начало: вход $ SomeInput" } процесс { "Значение: $ _" } конец { "Конец: вход $ SomeInput" } } # Get-PipelineBeginEnd 1, 2, 3 | Get-PipelineBeginEnd -SomeInput 'Test'
Когда вы запускаете приведенный выше код, обратите внимание, что Begin запускается один раз, как и End . Процесс запускается для каждого переданного в него элемента, и Процесс имеет доступ к текущему объекту в конвейере.
Функциональная логика
Логика, содержащаяся в функции PowerShell, не отличается от логики сценария. Здесь вы напишете основную логику, которая выполняет задачу, для которой предназначена ваша функция. Об этом рассказывалось в эпизодах 1-10 этого курса. Вы также можете увидеть полный живой пример в эпизоде PowerShell Scripts.
Возврат функции
Не все функции возвращают что-то при запуске.Если ваша функция что-то вернет, вы можете при желании использовать return. Имейте в виду, что при использовании return все дальнейшие действия в функции будут остановлены, а функция завершится.
function Get-Total { парам ( [int] $ Number1, [int] $ Number2 ) $ total = $ Number1 + $ Number2 вернуть $ total } Get-Total -Number1 2 -Number2 2
В приведенном выше примере эта простая функция содержит два параметра целочисленного типа. Логика функции складывает два числа вместе и возвращает целое число пользователю.
Ваша первая функция PowerShell
Взгляните на функцию PowerShell ниже. Обратите внимание, что макет соответствует тому, что мы рассмотрели ранее. Также обратите внимание, что в разделе справки содержится большое количество подробностей о назначении и использовании функции.
<# .СИНОПСИС Возвращает ваш публичный IP-адрес. .ОПИСАНИЕ Запрашивает API общедоступного IP-адреса ipify и возвращает ваш общедоступный IP-адрес. .ПРИМЕР Get-PublicIP Возвращает публичный IP. ВЫХОДЫ System.String .ПРИМЕЧАНИЯ https://github.com/rdegges/ipify-api #> function Get-PublicIP { $ uri = 'https://api.ipify.org' пытаться { $ invokeRestMethodSplat = @ { Uri = $ uri ErrorAction = 'Стоп' } $ publicIP = Invoke-RestMethod @invokeRestMethodSplat } поймать { Ошибка записи $ _ } вернуть $ publicIP } # Get-PublicIP
Поскольку фактическая логика этой функции довольно проста, может возникнуть соблазн оставить ее в виде сценария. Обратите внимание, что это делает одну конкретную вещь, и делает это хорошо.Теперь вы можете включить эту функцию в другую расширенную логику, вместо того, чтобы ссылаться на скрипт или импортировать его. Другие пользователи в вашей среде также могут начать использовать эту функцию, как только они с ней ознакомятся.
Объем функций
Как и в большинстве языков, PowerShell имеет правила области видимости для переменных. Когда переменная находится внутри функции, вы больше не сможете «видеть» ее значение. Вот пример такого поведения:
function Get-NumberTimesTwo { парам ( [int] $ Number ) $ total = $ Number * 2 вернуть $ total } # Get-NumberTimesTwo Get-NumberTimesTwo -Number 2
Функция работает должным образом и правильно умножает число на два.Однако в консоли попробуйте посмотреть, что такое $ всего . Вы не сможете. Это связано с тем, что $ total - это с областью действия для функции, а не для активного сеанса консоли.
Это может сбить с толку людей, плохо знакомых с PowerShell, и усложнить написание функций. Есть несколько способов справиться с этим.
Вы можете записать большую часть своей логики в формате типа скрипта, проверяя переменные по ходу дела.Убедившись, что логика работает так, как задумано, вы можете заключить ее в функцию.
В качестве альтернативы вы можете использовать Write-Host , Write-Output или еще лучше Write-Debug , чтобы увидеть, что происходит с вашими переменными внутри вашей функции!
function Get-NumberTimesTwo { [CmdletBinding ()] парам ( [int] $ Number ) $ total = $ Number * 2 Всего $ Write-Debug вернуть $ total } # Get-NumberTimesTwo Get-NumberTimesTwo -Number 2 -Debug
Обратите внимание, что с переключателем отладки мы получаем доступ к значению внутри $ total, чтобы наша логика выполняла то, что мы планировали.
Пример закрытия
Вот более крупный закрывающий пример двух функций PowerShell, которые позволят вам просматривать популярный веб-сайт reddit с помощью PowerShell!
Перейдите по ссылке GitHub gist ниже, чтобы получить доступ к коду и загрузить его в консоль.
https://gist.github.com/techoughtts2/cd2b720c9b291510cbd643e6ca73e05f
По мере изучения этих функций попытайтесь ответить на следующие вопросы:
- Какая из двух функций является основной функцией ?
- Это стандартные или расширенные функции?
- Какая функция будет поддерживать ввод конвейера?
Дополнительная литература
Навигация по сериям << Сценарии PowerShellУправление облаком с помощью PowerShell >>Просмотр содержимого функций PowerShell | PDQ.com
Вы когда-нибудь задумывались: «Я… как работает эта функция PowerShell?» Если да, то вам повезло! С PowerShell очень просто просматривать содержимое функции.
Фактически, мы собираемся показать вам несколько различных способов отображения этой информации.
Итак, держитесь за свои стулья и свои монокли! Давайте погрузимся и узнаем больше!
Определение функций PowerShell
Во-первых, нам нужно определить функцию, на которую нужно взглянуть.
Для этого упражнения я выбрал команду Пауза из-за ее простоты.Прежде чем продолжить, давайте убедимся, что эта команда действительно является функцией.
Get-Command Pause
Поскольку мы проверили, что это функция, давайте посмотрим, что на самом деле делает функция Pause под капотом.
Просмотр содержимого функции
Вот 3 различных способа просмотра содержимого функции. Вы можете выбрать, какой метод лучше всего подходит для вас.
Метод 1 - Использование команды Get
Команда Get
<Имя функции> | Выберите -ExpandProperty ScriptBlock
OR
(Get-Command <Имя функции>).ScriptBlock
Да да! Вот и все!
Get-Command Pause | Выберите -ExpandProperty ScriptBlock
Итак, похоже, что функция Pause запускает следующую команду:
$ null = Read-Host 'Нажмите Enter, чтобы продолжить ...'
Как красиво!
Метод 2 - Использование $ function
Еще один интересный способ увидеть содержимое функции паузы - использовать следующее:
$ Function: Pause
Так просто, так прекрасно.
Метод 3 - Использование функции: Drive
Функции автоматически сохраняются в функции: Drive. Вы можете убедиться в этом сами, набрав: Get-PSDrive
Поскольку это диск, мы можем просматривать его с помощью Get-ChildItem. Get-ChildItem, функция: пауза | Выберите *
Теперь мы можем видеть содержимое всех функций, если захотим.
Отображение всех доступных функций
Чтобы увидеть все доступные функции, вы можете запустить эту команду.Вы увидите много результатов.
Get-Command -CommandType Function
Заключение
Следует отметить, что это будет работать только для функций. Если вы хотите знать, что делают командлеты, вы можете взглянуть на проект с открытым исходным кодом PowerShell на GitHub (ссылка здесь).
Удачи и счастливого PowerShelling!
Чтобы увидеть это в действии, посмотрите это короткое видео:
Это сообщение в блоге является частью серии о PowerShell:
Как использовать функции в PowerShell - блог Джонатана Медда
За последние несколько недель у меня было несколько комментариев к сообщениям, в которых, по сути, задавался один и тот же вопрос: «Как мне использовать функции, которые вы публикуете в своем блоге?».Поэтому я подумал, что стоит делать пост, чтобы рекомендовать людям, а не пытаться отвечать тем же на каждый комментарий. Есть несколько способов сделать это в зависимости от ваших требований, и они перечислены ниже.
Прежде всего, давайте создадим простую функцию для тестирования:
function Get-TimesResult { Param ([int] $ a, [int] $ b) $ c = $ a * $ b Запись-вывод $ c }
1) Вставить в существующий сеанс PowerShell
Если вы работаете в интерактивном режиме в консоли, то функцию можно скопировать / вставить в этот сеанс, и тогда она будет доступна в течение этого сеанса.Я считаю, что это проще сделать через PowerShell ISE, чем через стандартную консоль.
Скопируйте функцию в панель сценария:
Нажмите Зеленую кнопку запуска сценария или нажмите F5 , и на панели консоли появится код:
Функция теперь доступна для использования, и при использовании ISE будет отображаться в интерактивном режиме, когда вы начнете вводить имя:
2) Профиль PowerShell
Если вы хотите регулярно использовать эту функцию в интерактивных сеансах PowerShell, вы можете поместить ее в свой профиль PowerShell, и она будет доступна каждый раз, когда вы открываете консоль PowerShell.
Если вы не знаете, что такое профиль PowerShell и как его использовать, здесь есть полезная информация. Быстрый способ его создания:
New-Item -Path $ profile -ItemType File -Force
После создания профиля PowerShell поместите функцию в профиль, сохраните и закройте. Теперь каждый раз, когда вы открываете консоль PowerShell, функция будет доступна.
3) Непосредственно в скрипте
Если вы хотите использовать функцию в сценарии, поместите функцию в сценарии над разделами, где вам нужно ее использовать.Обычно это будет вверху. Положительная сторона этого способа заключается в том, что все содержится в одном файле, а отрицательная в том, что если у вас есть несколько функций, читаемость сценария снижается, поскольку может быть долгий путь для прокрутки вниз, прежде чем что-либо важное начнет случаться.
4) Вызывается из другого скрипта
Один метод, который я довольно часто встречал в дикой природе (и я не являюсь его большим поклонником, пункт 5 - гораздо лучший подход), заключается в том, чтобы сохранить все регулярно используемые функции в файле сценария и указать источник файла сценария функций в скрипт, в котором вам нужно использовать одну или несколько функций.
Файл скрипта функций Tools.ps1:
Файл сценария Get-Results, вызывающий Tools.ps1:
Обратите внимание на точку и пробел перед ссылкой на файл Tools.ps1
. C: \ Users \ jmedd \ Documents \ WindowsPowerShell \ Scratch \ Tools.ps1 Get-TimesResult -a 6 -b 8
5) Хранится в модуле
Использование модуля PowerShell - более продвинутый, значительно более структурированный и мощный метод достижения того, что было сделано в п. 4).Если вы не использовали модули PowerShell до этого, я недавно написал введение в модули PowerShell, которое вы можете найти здесь.
По сути, они представляют собой способ упаковать ваши повторно используемые функции и сделать их доступными аналогично тому, как другие группы в Microsoft и сторонние компании создают наборы командлетов PowerShell для использования.
Для этого примера я создал модуль Tools для использования, который по сути является тем же содержимым, что и файл Tools.ps1, но хранится в *.psm1 (Tools.psm1) в папке Modules \ Tools на моей рабочей станции.
Примечание: имя файла * .psm1 должно совпадать с именем папки. Можно создать более усовершенствованный модуль, чем этот подход, используя манифест модуля, но нам это не нужно для целей этой публикации. Это описано далее в ранее упомянутой статье.
Теперь мы можем использовать командлеты * -Module PowerShell для работы с нашим контентом.
Для наблюдения за модулем мы можем использовать Get-Module:
Get-Module Tools -ListAvailable
Для использования функций, содержащихся в модуле, мы можем использовать Import-Module
Инструменты импорта-модуля Get-TimesResult -a 6 -b 8
Примечание: Начиная с PowerShell v3 поддерживается автоматическое обнаружение командлетов и загрузка модулей.(Вы можете узнать больше об этом здесь) Следовательно, вам фактически не нужно использовать Import-Module для получения доступа к функциям, если вы разместите модуль в правильном месте. Однако было бы неплохо добавить в сценарий строку Import-Module, чтобы другой пользователь знал, откуда вы получаете эту функциональность.
Поиск функций PowerShell - Power Tips - Power Tips
PowerShell 3.0 и выше
Чтобы быстро просканировать репозиторий сценариев PowerShell и найти все файлы, в которых есть заданная функция, попробуйте этот фильтр:
фильтр Find-Function { $ path = $ _.Полное имя $ lastwrite = $ _. LastWriteTime $ text = Get-Content -Path $ path если ($ text.Length -gt 0) { $ токен = $ ноль $ errors = $ null $ ast = [System.Management.Automation.Language.Parser] :: ParseInput ($ text, [ref] $ token, [ref] $ errors) $ ast.FindAll ({$ args [0] -is [System.Management.Automation.Language.FunctionDefinitionAst]}, $ true) | Select-Object -Property Name, Path, LastWriteTime | ForEach-Object { $ _. Путь = $ путь $ _. LastWriteTime = $ lastwrite $ _ } } }
Вот как вы сканируете свой профиль пользователя на наличие всех скриптов PowerShell, определяющих функции:
PS> dir $ home -Filter *.ps1 -Recurse -Exclude * .ps1xml | Функция поиска
Имя Путь LastWriteTime ---- ---- ------------- Inject-LogonCredentials C: \ Users \ Tobias \ Desktop ... 06.01.2014 02:43:00 Тестовая команда C: \ Users \ Tobias \ Desktop ... 06.03.2014 10:17:02 Тест C: \ Users \ Tobias \ Desktop ... 30.01.2014 09:32:20 Get-WebPictureOriginal C: \ Users \ Tobias \ Desktop... 11.12.2013 11:37:53 Get-ConnectionString C: \ Users \ Tobias \ Documen ... 23.05.2014 10:49:09 Convert-SID2User C: \ Users \ Tobias \ Documen ... 23.05.2014 15:33:06 Блокировка экрана C: \ Users \ Tobias \ Documen ... 19.03.2014 12:51:54 Показать-OpenFileDialog C: \ Users \ Tobias \ Documen ... 16.05.2014 13:42:16 Show-UniversalData C: \ Users \ Tobias \ Documen ... 16.05.2014 13:23:20 Start-TimebombMemory C: \ Users \ Tobias \ Documen ... 23.05.2014 09:12:28 Stop-TimebombMemory C: \ Users \ Tobias \ Documen... 23.05.2014 09:12:28 (...)
Просто передайте результат в Out-GridView, чтобы получить полную и неразрезанную информацию.
Повторите этот совет повторно!
Управление функциями PowerShell • Одинокий администратор
Большинство из вас, вероятно, знают, что я использую PowerShell с момента его бета-тестирования, а это означает, что сейчас у меня есть файлы PowerShell за 10 лет. Мне трудно что-либо выбросить. За это время мои сценарии профиля PowerShell также выросли, часто загружая функции, которые я придумал.В результате для запуска новой консоли PowerShell или сеанса ISE требуется немного больше времени. Поскольку в глубине души я знаю, что есть функции, которые я больше не использую, я подумал, что пришло время для некоторой очистки профиля. Первым шагом было определение моих функций.
Во-первых, о скольких функциях я говорю? PowerShell хранит определенные и активные функции в PSDrive, что означает, что довольно легко получить список и подсчитать «каталог».
Однако некоторые из этих функций определены Microsoft и другими модулями.
У меня нет проблем с функциями, определенными из данного источника. Моя проблема в тех 100, у которых нет источника. Опять же, некоторые из них определены Microsoft, и это нормально. Поэтому я рассмотрел один из них более подробно.
Я заметил, что эти функции включают HelpFile. Я знал, что ни одна из моих функций не работает. С помощью этой информации я могу получить список каталогов и отфильтровать с помощью Where-Object.
функция dir: | где {(-Не $ _. Источник) -И ($ _.HelpFile -notmatch "System \ .Management")}
Это функции, которые загружаются из точечного источника файла ps1. Кстати, в списке было 62 пункта.
В качестве альтернативы я мог бы использовать Get-Command, чтобы избавиться от любых фильтров.
get-command -CommandType function | где {(-Not $ _. Source) -AND ($ _. HelpFile -notmatch "System \ .Management")}
Знайте, что это будет искать функции в модулях, которые в данный момент не загружены, поэтому выполнение займет немного больше времени.Это дало мне 61 предмет.
Но теперь, по крайней мере, я могу просмотреть список и определить функции, которые я не использовал годами или которые сейчас устарели. К сожалению, с помощью функции PSDrive или Get-Command невозможно определить, откуда эта функция. К счастью, я храню все свои файлы на одном диске, и, скорее всего, функция будет определена в сценарии .ps1. Я могу использовать Select-String, чтобы найти его.
В моем списке есть функция под названием Show-Balloon, которую я, вероятно, не использовал годами.В каком это файле?
каталог c: \ scripts \ *. Ps1 | строка выбора "\ bshow-balloon \ b" –List
Я заключаю имя функции в границу слова регулярного выражения, чтобы не было совпадений с чем-то вроде show-balloontip. Параметр –List дает мне первое совпадение, которое мне действительно нужно.
Поскольку я пишу все свои функции в одном и том же формате, я мог бы выполнить такой поиск и получить тот же результат.
каталог c: \ scripts \ *. Ps1 | select-string "\ bFunction show-balloon \ b" –List
Результатом Select-String является объект, который включает свойство для имени файла или пути.
Теперь я могу собрать все воедино.
$ scripts = каталог c: \ scripts \ *. Ps1 функция dir: | где {(-Not $ _. Source) -AND ($ _. HelpFile -notmatch "System \ .Management")} | Выберите имя, @ {Name = "Source"; Expression = {($ scripts | select-string "\ b $ ($ _. Name) \ b" -list) .Path}}
Мне не нужно заново перечислять все файлы скриптов для каждой функции, поэтому я получу их один раз, а затем использую эту переменную в выражении Select-Object.
С помощью этой информации я могу изменить свои профили PowerShell и удалить строки, загружающие функции, которые мне не нужны, или отредактировать исходный файл, чтобы закомментировать функцию, если в том же файле, который я хотел сохранить, было что-то еще.Любая функция в этом списке без соответствующего источника, скорее всего, определена непосредственно в скрипте профиля или потребует ручного поиска.