PowerShell V2 介绍(7)- 高级函数(下)

今天我们将来介绍高级函数的最后一部分内容。共分两个方面,一是如何使用注释内容作为高级函数的帮助信息,而是如何使用高级函数的动态参数功能。接下来我们先来看一下高级函数如何利用注释内容作为其帮助信息,以及之前我们提及的参数集。这部分内容,我还是给出一段示例代码,代码中不会执行任何实际的功能,只是单纯的测试我提到的两点内容。而有关更多如何使用基于注释内容的帮助,大家可以通过输入“help about_Comment_Based_Help -full”查看,主要是掌握几个关键词的应用。

Function Test-AdvancedFunction
{
    <#
        .SYNOPSIS
        这是一个测试函数用来说明高级函数如何将注释内容转化为自身的帮助信息
        以及如何指定参数属于哪个参数集
        .Description
        这是一个测试函数用来说明高级函数如何将注释内容转化为自身的帮助信息
        以及如何指定参数属于哪个参数集
        要了解更多内容请输入"help about_Comment_Based_Help -full"查看
        .Link
        How to Write Cmdlet Help
http://msdn.microsoft.com/en-us/library/aa965353.aspx
    #>

    [CmdletBinding(SupportsShouldProcess=$True,
    ConfirmImpact="none",
    DefaultParameterSetName="FileSystem")]
    Param
    (
        [parameter(Mandatory=$true,
        Position=0,
        ParameterSetName="FileSystem")]
        [int]$Param1,
        [parameter(Mandatory=$true,
        Position=1,
        ParameterSetName="FileSystem")]
        [int]$Param2,
        [parameter(Mandatory=$true,
        Position=2,
        ParameterSetName="Registry")]
        [int]$Param3,
        [parameter(Mandatory=$true,
        Position=0,
        ParameterSetName="Registry")]
        [int]$Param4
    )
}

接下来还是让我们来看一下最终效果,而查看效果的命令很简单,就是我们常用的“help Test-AdvancedFunction -full”

首先大家可以看下摘要信息。这是我在注释信息中指定的说明信息。然后我们接着看到语法这一块。很明显Param1、Param2与Param3、Param4分别对应于不同的使用方法,这就是DefaultParameterSetName及ParameterSetName联合作用下产生的结果。在高级函数中嵌入帮助信息有助于他人了解我们所编写的高级函数的作用,与在代码中嵌入注释信息相比,这种方式更直观也更接近我们平常的使用体验。

接下来我们将介绍如何使用高级函数的动态参数功能。下面先给出先关代码:

Function Test-DynamicParam
{
[CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact="High")]
Param
(
[Parameter(Mandatory=$True,Position=0)]
[String]$Param1,
[Parameter(Mandatory=$True,Position=1)]
[String]$Param2
)
DynamicParam
{
if ($Param1 -match "powershell")
{

$paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary

$dyParam3 = New-Object `
System.Management.Automation.RuntimeDefinedParameter("Param3", `
[String],$attrCol1)

$attrCol1 = New-Object System.Management.Automation.ParameterAttribute
$attrCol1.Mandatory = $True
$dyParam3.Attributes.Add($attrCol1)

$paramDictionary.Add("Param3",$dyParam3)

return $paramDictionary
}
}
process
{
Write-Host "Param1: $Param1`nParam2: $Param2"
if ($dyParam3 -ne $null)
{
Write-Host "Param3:"$dyParam3.Value
}
}
}

接着,我们来具体看一下相关代码的具体含义。

首先我们按照上次介绍中的方法使用CmdletBinding将此函数定义为高级函数,然后我们定义了两个静态参数,分别为Param1和Param2.接着是本次介绍的主角,动态参数(DynamicParam)。和Begin,Process,End类似,DynamicParam代表是代码块。在DynamicParam中,我们通常使用if语句对已知参数值进行判断,如果符合特定条件的话,我们就创建动态参数。这里我使用的判断条件是Param1的值中是否存在PowerShell,如果有PowerShell就创建动态参数Param3。接下来让我们来看一下动态参数的创建过程。

动态参数的创建将使用.Net的相关类。首先我们初始了System.Management.Automation.RuntimeDefinedParameterDictionary的一个实例$dyParam3(这里的对象名称切勿与参数名相同)。该类代表了在运行时创建的参数集合,DynamicParam返回的对象必须是RuntimeDefinedParameterDictionary,否则PowerShell将报错。接下来我们将使用System.Management.Automation.RuntimeDefinedParameter来定义具体的参数。在构造该类的实例时,我们可以依次指定我们所需的参数名,参数类型,以及参数的属性集。这里分别是参数名Param3,参数类型[string],以及等下我们要定义的参数属性集$attrCol1。

下面我们就要定义的是$attrCol1。这与我们在上次的介绍中提到的如何在Param中定义参数的属性有点类似,只不过我们这次将使用原生的.Net方法。首先使用New-Object初始ParameterAttribute类的一个实例$attrCol1。接着我们为该实例的Mandatory属性赋值,当这个属性的值为真时表明该参数是必要参数。最后,我们将属性集添加到之前我们初始的参数对象$dyParam3中。

接下来,我们将该参数添加到参数集$paramDictionary中,然后使用Return退出DynamicParam代码块。

接下来我们在Process中使用Write-Host来显示我们输入的参数值。需要注意的是我使用了if语句,使得Param3参数存在时才输出该参数值。

最后,就是测试环节了。我们可以用以下代码来测试:

Write-Host "Test1" 
Test-DynamicParam "powershell" "dynamicparam"
Write-Host "`n"
Write-Host "Test2"
Test-DynamicParam "dynamicparam" "powershell"

测试结果如下:

我们总共进行了两次测试来完成对比。第一次我们将Param1参数值设为PowerShell,按照预先的定义,此时PowerShell将会生成动态参数。如图所示,在参数属性Mandatory的作用下,PowerShell提示用户为Param3提供参数值。最后的输出结果也符合我们的预期。

第二次测试时Param1参数值不为PowerShell,此时不应该生成动态参数。最终测试结果于我们的预期也相符。

本次关于如何使用动态参数的介绍就到此结束了,同时关于高级函数的介绍也行将告一段落。希望各位除了看我的介绍文章之外能多看看帮助文档来尽快熟悉高级函数的使用方法。

下次我们将介绍如何使用Windows PowerShell v2的模块功能,敬请期待。

此条目发表在PowerShel V2 CTP3 intro分类目录。将固定链接加入收藏夹。

留下评论