Reputation: 1922
I want to be able to pass multiple values through the pipeline for a module I am building. The module is built around a specific SQL Database Schema so i designed this function to return all databases of that schema:
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
}
}
This works fine but what I want is to be able to pass both the $serverAddress and the $rValue variables through the pipeline. This is so i can run other commands like so:
Get-TRISDatabases -name -ServerAddress "server1" | Remove-TRISDeadLinks
Instead of what i have at the moment which would be:
Get-TRISDatabases -name -ServerAddress "server1" | Remove-TRISDeadLinks -ServerAddress "server1"
I tried putting the server address in the rValue object as well but i would have to change every other script to user the server address rValue.ServerAddress for that to work.
Remove-TRISDeadLinks Param block:
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
Upvotes: 1
Views: 5075
Reputation: 437082
Generally, a process
script block allows outputting multiple objects just like any other script block; e.g.:
PS> 'one', 'two' | & { param([Parameter(ValueFromPipeline)] $str) process { $str; 'hi' } }
one
hi
two
hi
Remember that return <object>
is just syntactic sugar for outputting <object>
and returning from the script block, and that you don't need return
to output an object.
Given your specific requirements, however - binding two parameters of another function with your function's output via the pipeline - you need to:
make Get-TRISDatabases
output a custom object whose properties are the arguments to pass to both parameters.
define your other function to bind those properties from the pipeline by property name.
# 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 }
}
}
# ...
Then define your Remove-TRISDeadLinks
param()
block as follows (PSv3+; note that parameters are non-mandatory by default, and that their position is implied by their declaration order):
# Remove-TRISDeadLinks ...
[CmdletBinding()]
param (
[Parameter(ValueFromPipelineByPropertyName)]
$ServerAddress = "localhost"
,
[Parameter(ValueFromPipelineByPropertyName)]
$Databases
)
Upvotes: 4