about_Functions

应用到: Windows PowerShell 2.0, Windows PowerShell 3.0, Windows PowerShell 4.0

主题

about_Functions

简短说明

介绍如何在 Windows PowerShell® 中创建和使用函数。

详细说明

函数是 Windows PowerShell 语句的列表,具有你分配的名称。运行函数时,请键入函数名称。列表中语句的运行方式就如你已在命令提示符中键入它们之后一样。

函数可以很简单:

        function Get-PowerShellProcess {Get-Process PowerShell}

或与 cmdlet 或应用程序一样复杂。

与 cmdlet 一样,函数可以具有参数。参数可以为命名参数、位置参数、开关参数或动态参数。可以从命令行或从管道读取函数参数。

函数可以返回值,这些值可以被显示、分配给变量或传递给其它函数或 cmdlet。

函数的语句列表可以包含不同类型的语句列表,这些列表具有关键字 Begin、Process 和 End。这些语句列表以不同方式处理来自管道的输入。

筛选器是使用 Filter 关键字的特殊函数类型。

函数也可以充当 cmdlet。你可以创建工作方式类似于 cmdlet 的函数,而无需使用 C# 编程。有关详细信息,请参阅 about_Functions_Advanced (https://go.microsoft.com/fwlink/?LinkID=144511)。

语法

以下是函数的语法:

          function [<scope:>]<name> [([type]$parameter1[,[type]$parameter2])]  
          {
              param([type]$parameter1 [,[type]$parameter2])

              dynamicparam {<statement list>}
  
              begin {<statement list>}
              process {<statement list>}
              end {<statement list>}
          }

函数包括以下项:

          - A Function keyword
          - A scope (optional)
          - A name that you select
          - Any number of named parameters (optional)
          - One or more Windows PowerShell commands enclosed in braces ({})

有关函数中的 Dynamicparam 关键字和动态参数的详细信息,请参阅 about_Functions_Advanced_Parameters。

简单函数

函数无需复杂也可以很有用。最简单的函数具有以下格式:

          function <function-name> {statements}

例如,以下函数使用“以管理员身份运行”选项启动 Windows 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 {$_.LastWriteTime -gt $Start}
          }    

你可以创建一个有用小函数的工具箱。将这些函数添加到你的 Windows PowerShell 配置文件中,就如 about_Profiles 及本主题的后面内容中所介绍的那样。

函数名称

你可以将任何名称分配给函数,但你与其他人共享的函数应遵循已为所有 Windows PowerShell 命令建立的命名规则。

函数名称应该由动词/名词对构成,其中动词标识函数执行的操作,而名词标识 cmdlet 对其执行操作的项。

函数应使用已针对所有 Windows PowerShell 命令批准使用的标准动词。这些动词帮助我们使命令名称保持简单、一致,且使用户易于理解。

有关标准 Windows PowerShell 动词的详细信息,请参阅 MSDN 上的“Cmdlet 动词”,网址是 https://go.microsoft.com/fwlink/?LinkID=160773。

具有参数的函数

你可以对函数使用参数,包括命名参数、位置参数、开关参数和动态参数。有关函数中动态参数的详细信息,请参阅 about_Functions_Advanced_Parameters (https://go.microsoft.com/fwlink/?LinkID=135173)。

命名参数

你可以定义任何数量的命名参数。你可以包括一个命名参数的默认值,如本主题后面内容所述。

你可以在括号内使用 Param 关键字定义参数,如以下示例语法中所示:

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

也可以不使用 Param 关键字而在括号外定义参数,如以下示例语法中所示:

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

这两种方法之间没有区别。使用你偏好的方法。

当运行函数时,你为某个参数提供的值将被分配给包含该参数名称的变量。可以在函数中使用此变量的值。

以下示例是称为 Get-SmallFiles 的函数。该函数具有 $size 参数。该函数显示所有比 $size 参数的值小的文件,并且它排除目录:

          function Get-SmallFiles {
              param ($size)
              Get-ChildItem c:\ | where {$_.Length -lt $Size -and !$_.PSIsContainer} 
          }

在该函数中,你可以使用 $size 变量,它是为参数定义的名称。

若要使用该函数,请键入以下命令:

          C:\PS> function Get-SmallFiles –Size 50

你也可以为命名参数输入一个值,而无需参数名称。例如,以下命令与命名 Size 参数的命令给出相同的结果:

          C:\PS> function Get-SmallFiles 50

若要为参数定义默认值,在参数名称后键入等号和值,如以下 Get-SmallFiles 示例的变体中所示:

          function Get-SmallFiles ($size = 100) {
              Get-ChildItem c:\ | where {$_.Length -lt $Size -and !$_.PSIsContainer} 
          }

如果你键入 "Get-SmallFiles" 而不提供值,函数会将 100 分配给 $size。如果你提供一个值,函数将会使用此值。

(可选)通过将 PSDefaultValue 特性添加到参数的描述中,并指定 PSDefaultValue 的 Help 属性,你可以提供一个描述参数的默认值的简短帮助字符串。若要提供描述 Get-SmallFiles 函数中 Size 参数的默认值 (100) 的帮助字符串,如以下示例所示添加 PSDefaultValue 特性。

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

有关 PSDefaultValue 特性类的详细信息,请参阅 MSDN 上的 PSDefaultValue 特性成员。(https://msdn.microsoft.com/library/windows/desktop/system.management.automation.psdefaultvalueattribute\_members(v=vs.85).aspx

位置参数

位置参数是没有参数名称的参数。Windows PowerShell 使用参数值顺序将每个参数值与函数中的一个参数相关联。

当你使用位置参数时,在函数名称后键入一个或多个值。位置参数值被分配给 $args 数组变量。跟在函数名称后面的值被分配到 $args 数组中的第一个位置,$args[0]。

以下 Get-Extension 函数将 .txt 文件扩展名添加到你提供的文件名称:

          function Get-Extension {
              $name = $args[0] + ".txt"
              $name
          }
          C:\PS> Get-Extension myTextFile
          myTextFile.txt

开关参数

开关是不需要值的参数。但是,你要键入后跟开关参数名称的函数名称。

若要定义开关参数,在参数名称前指定类型[开关],如以下示例所示:

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

当你在函数名称后键入 On 开关参数时,函数将会显示 "Switch on"。如果没有开关参数,它将会显示 "Switch off"。

          C:\PS> Switch-Item -on
          Switch on

          C:\PS> Switch-Item
          Switch off

运行函数时,你也可以将一个布尔值分配给开关,如以下示例所示:

          C:\PS> Switch-Item -on:$true
          Switch on

          C:\PS> Switch-Item -on:$false
          Switch off

使用“展开”表示命令参数

你可以使用展开表示命令的参数。Windows PowerShell 3.0 中引入了此功能。

将此技术用于在会话中调用命令的函数。你无需声明或枚举命令参数,也无需在命令参数更改时更改函数。

以下示例函数调用 Get-Command cmdlet。该命令使用 @Args 表示 Get-Command 的参数。

          function Get-MyCommand { Get-Command @Args }

当调用 Get-MyCommand 函数时,你可以使用 Get-Command 的所有参数。使用 @Args 将参数和参数值传递给命令。

         PS C:\>Get-MyCommand -Name Get-ChildItem
         CommandType     Name                ModuleName
         -----------     ----                ----------
         Cmdlet          Get-ChildItem       Microsoft.PowerShell.Management

@Args 功能使用 $Args 自动参数,该自动参数表示剩余实参中的未声明的 cmdlet 参数和值。

有关展开的详细信息,请参阅 about_Splatting (https://go.microsoft.com/fwlink/?LinkId=262720)。

通过管道将对象传递给函数

任何函数都可以从管道获取输入。你可以控制函数使用 Begin、Process 和 End 关键字处理来自管道的输入的方式。以下示例语法显示了这 3 个关键字:

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

Begin 语句列表只在函数的开头运行一次。

Process 语句列表为管道中的每个对象运行一次。Process 块在运行时,每个管道对象都被分配给 $_ 自动变量,一次分配一个管道对象。

在函数接收管道中的所有对象之后,End 语句列表运行一次。如果不使用 Begin、Process 或 End 关键字,则所有语句将被视为 End 语句列表。

下面的函数使用 Process 关键字。该函数显示管道中的示例:

          function Get-Pipeline 
          { 
              process {"The value is: $_"} 
          }

若要演示此函数,则输入由逗号分隔的数字的列表,如以下示例所示:

          C:\PS> 1,2,4 | Get-Pipeline
          The value is: 1
          The value is: 2
          The value is: 4

当你在管道中使用函数时,通过管道传递给函数的对象被分配给 $input 自动变量。在还没有任何来自管道的对象之前,该函数运行具有 Begin 关键字的语句。在接收了所有来自管道的对象之后,该函数运行具有 End 关键字的语句。

以下示例显示了具有 Begin 和 End 关键字的 $input 自动变量。

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

如果此函数是通过使用管道运行,则它显示以下结果:

          C:\PS> 1,2,4 | Get-PipelineBeginEnd
          Begin: The input is 
          End:   The input is 1 2 4

当 Begin 语句运行时,该函数不具有来自管道的输入。在函数具有值以后,End 语句运行。

如果函数具有 Process 关键字,则函数会读取 $input 中的数据。以下示例具有 Process 语句列表:

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

在此示例中,每个通过管道传递给函数的对象都被发送到 Process 语句列表。Process 语句在每个对象上运行,一次一个对象。当函数到达 End 关键字时,$input 自动变量为空。

          C:\PS> 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 {$_.DependentServices} }

当某个函数位于全局作用域中时,你可以在脚本、函数和命令行中使用此函数。

函数通常创建一个作用域。在函数中创建的项(比如变量)仅存在于函数作用域中。

有关 Windows PowerShell 中的作用域的详细信息,请参阅 about_Scopes (https://go.microsoft.com/fwlink/?LinkID=113260)。

使用 Function: 查找和管理函数创建的文件

Windows PowerShell 中的所有函数和筛选器被自动存储到 Function:驱动器中。此驱动器由 Windows PowerShell Function 提供程序公开。

引用 Function:驱动器时,在 Function 之后键入一个冒号,如同引用计算机的 C 或 D 驱动器时将会做的那样。

以下命令显示 Windows PowerShell 的当前会话中的所有函数:

          Get-ChildItem function:

函数中的命令被作为脚本块存储在函数的定义属性中。例如,若要显示 Windows PowerShell 附带的 Help 函数中的命令,请键入:

          (Get-ChildItem function:help).Definition

有关 Function:驱动器的详细信息,请参阅 Function 提供程序的帮助主题。键入 "Get-Help Function" 或登录 https://go.microsoft.com/fwlink/?LinkID=113436,在 TechNet 库中查看它。

在新会话中重复使用函数

当你在 Windows PowerShell 命令提示符处键入一个函数时,该函数会变为当前会话的一部分。该函数在会话结束前一直可用。

若要在所有 Windows PowerShell 会话中使用你的函数,则将该函数添加到 Windows PowerShell 配置文件中。有关配置文件的详细信息,请参阅 about_Profiles (https://go.microsoft.com/fwlink/?LinkID=113729)。

你也可以将函数保存在 Windows PowerShell 脚本文件中。在文本文件中键入函数,然后使用 .ps1 文件扩展名保存此文件。

编写有关函数的帮助

Get-Help cmdlet 获取有关函数以及 cmdlets、提供程序和脚本的帮助。若要获取有关函数的帮助,请键入 Get-Help,后跟函数名称。

例如,若要获取有关 Get-MyDisks 函数的帮助,请键入:

        Get-Help Get-MyDisks

你可以使用以下两个方法之一编写有关函数的帮助:

有关函数的基于注释的帮助

通过在注释中使用特殊关键字创建帮助主题。若要创建关于函数的基于注释的帮助,则必须将注释置于函数正文的开头或结尾处,或置于函数关键字之前的行上。有关基于注释的帮助的详细信息,请参阅 about_Comment_Based_Help。

关于函数的基于 XML 的帮助

创建基于 XML 的帮助主题,例如通常为 cmdlet 创建的类型。如果你要将帮助主题本地化为多种语言,则需要基于 XML 的帮助。

若要将函数与基于 XML 的帮助主题相关联,则使用 .ExternalHelp 基于注释的帮助关键字。如果没有此关键字,则 Get-Help 无法找到函数帮助主题,并且对函数的 Get-Help 的调用仅返回自动生成的帮助。

有关 ExternalHelp 关键字的详细信息,请参阅 about_Comment_Based_Help。有关基于 XML 的帮助的详细信息,请参阅 MSDN 中的“如何编写 Cmdlet 帮助”。

另请参阅

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

Function(提供程序)