通过管道传递多个值

时间:2018-10-23 02:46:02

标签: powershell pipeline parameterbinding

我希望能够通过管道为我正在构建的模块传递多个值。该模块是围绕特定的SQL数据库架构构建的,因此我设计了此函数以返回该架构的所有数据库:

function Get-TRISDatabases {
    param (
        [parameter(mandatory=$false)]
        [string]$ServerAddress = "localhost",
        [parameter(mandatory=$false)]
        [switch]$Name
    )
    Begin {
        $Query_GetDatabases = "
            SELECT Name, create_date, user_access_desc, state_desc, recovery_model_desc FROM   sys.databases WHERE  CASE
                WHEN state_desc = 'ONLINE' THEN OBJECT_ID(QUOTENAME(name) + '.[dbo].[CRISFiles]', 'U')
            END IS NOT NULL
        "
    }

    Process {
        ## Get Data
        $rValue = Invoke-Sqlcmd2 -Query $Query_GetDatabases -ServerInstance $ServerAddress

        ## Return values
        if ($Name) {
            Return $rValue.Name
        }
        else {
            Return $rValue
        }
    }

    End {
        ## Purge Variables
        Remove-Variable Query_GetDatabases, rValue
    }
}

这工作正常,但是我想要的是能够通过管道传递$ serverAddress和$ rValue变量。这样我就可以运行其他命令,例如:

Get-TRISDatabases -name -ServerAddress "server1" | Remove-TRISDeadLinks

而不是我现在所拥有的:

Get-TRISDatabases -name -ServerAddress "server1" | Remove-TRISDeadLinks -ServerAddress "server1"

我也尝试将服务器地址放在rValue对象中,但是我必须更改其他所有脚本以使用服务器地址rValue.ServerAddress才能工作。

删除-TRISDeadLinks参数块:

param (
    [parameter(
        Mandatory=$false, Position=1,ValueFromPipeline=$false
    )]
    $ServerAddress = "localhost",

    [parameter(
        Mandatory=$false, Position=2,ValueFromPipeline=$true
    )]
    $Databases
)

-

.EXAMPLE
Remove-TRISBrokenLinks -ServerAddress "localhost" -Databases "Database1"

    Manually entering the server address and database

.EXAMPLE 
Remove-TRISBrokenLinks -ServerAddress "localhost" -Databases "Database1", "Database2"

    Runs against an array of databases names

.EXAMPLE 
Get-TRISDatabases -ServerAddress "Localhost" -name | Remove-TRISBrokenLinks

    Uses the Get-TRISDatabases function to pass all TRIS databases to the function

1 个答案:

答案 0 :(得分:2)

通常,process脚本块允许输出多个对象,就像其他任何脚本块一样。例如:

PS> 'one', 'two' | & { param([Parameter(ValueFromPipeline)] $str) process { $str; 'hi' } } 
one
hi
two
hi

请记住,return <object>只是用于输出<object> 从脚本块返回的语法糖,并且您不需要return输出一个对象。


但是,鉴于您的特定要求-通过管道将另一个函数的两个参数与函数的输出绑定-您需要:

  • make Get-TRISDatabases输出一个自定义对象,其属性是传递给两个参数的参数。

  • 定义您的其他函数,以按属性名称 从管道绑定这些属性。

# Get-TRISDatabases ...

Process {
    ## Get Data
    $rValue = Invoke-Sqlcmd2 -Query $Query_GetDatabases -ServerInstance $ServerAddress

    # Output a custom object with both $rValue and the server address
    [pscustomobject] @{
      ServerAddress = $ServerAddress
      Databases = if ($Name) { $rValue.Name } else { $rValue }
    }

}

# ...

然后按如下所示定义Remove-TRISDeadLinks param()块(PSv3 +;请注意,默认情况下参数是非强制性的,并且其位置由其声明顺序隐含):

# Remove-TRISDeadLinks ...
[CmdletBinding()]
param (
    [Parameter(ValueFromPipelineByPropertyName)]
    $ServerAddress = "localhost"
    ,   
    [Parameter(ValueFromPipelineByPropertyName)]
    $Databases
)