Return Multiple Values from PowerShell Function

In PowerShell functions, by default, you can return only one object at a time. Since PowerShell does not apply any restriction on data type returned, it created a lot of possibilities on what can be returned as an output of the function. So if one needs to return multiple values or objects, it is generally suggested to create an array of the objects and then return the array. If the underlying values are simple strings, some would create a custom PSObject and then return the PSObject. In this blog post, we will discuss the other methods to return the multiple values from PowerShell functions.

The Simple Return Method

Below is one of the simple return methods, in which we return the Sum of the two integers by calling Get-Sum function. Since it needs only one object to return, we do not need to perform any special operations:


Function Get-Sum {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[int] $Number1,
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[int] $Number2
)
Begin {
Write-Verbose "In Begin Block: Get-Sum"
$Sum = 0
}
Process{
Write-Verbose "In Process Block: Get-Sum"
$Sum = $Number1 + $Number2
}
End{
Write-Verbose "In End Block: Get-Sum"
return $Sum
}
}
$Sum = 0
$Sum = Get-Sum -Number1 5 -Number2 7
Write-Host $Sum

Below is the output from one of the runs:

returning single value from PS function

The same can be extended to return an array of objects or a custom PowerShell Object. Again, since we are returning single object, at receiving end we do not need to do anything else.

Returning Multiple Arrays using Return Keyword

Let’s say that we need to return multiple arrays from PowerShell function. In below PowerShell function, we have created an array which contains names of the Persons as $PersonName and another array which contains ages of the Persons as $PersonAge:


Function Get-PersonDetails {
Begin {
Write-Verbose "In Begin Block: Get-PersonDetails"
$PersonName = @()
$PersonAge = @()
}
Process{
Write-Verbose "In Process Block: Get-PersonDetails"
$PersonName = "Keith", "Eddy", "Kevin", "Kate"
$PersonAge = 29, 34, 23, 15
}
End{
Write-Verbose "In End Block: Get-PersonDetails"
return $PersonName, $PersonAge
}
}
$PersonName = @()
$PersonAge = @()
$PersonName, $PersonAge = Get-PersonDetails
foreach($item in 0..3){
Write-Host "$($PersonName[$item]) is $($PersonAge[$item]) years old"
}

We can return those arrays by passing them using return keyword and separating using a comma. Again at the receiving time, we need to refer them consecutively.

Below’s the output from the code run:

return multiple arrays using return keyword

Returning Multiple Arrays without using Return Keyword

We can also return multiple Objects without using Return Keyword in a less conventional way. In below PowerShell function, we have created an array which contains names of the Persons as $PersonName and another array which contains ages of the Persons as $PersonAge:


Function Get-PersonDetails {
Begin {
Write-Verbose "In Begin Block: Get-PersonDetails"
$PersonName = @()
$PersonAge = @()
}
Process{
Write-Verbose "In Process Block: Get-PersonDetails"
$PersonName = "Keith", "Eddy", "Kevin", "Kate"
$PersonAge = 29, 34, 23, 15
}
End{
Write-Verbose "In End Block: Get-PersonDetails"
$PersonName
$PersonAge
}
}
$PersonName = @()
$PersonAge = @()
$returnedData = Get-PersonDetails
$PersonName = $returnedData[0], $returnedData[1], $returnedData[2], $returnedData[3]
$PersonAge = $returnedData[4], $returnedData[5], $returnedData[6], $returnedData[7]
foreach($item in 0..3){
Write-Host "$($PersonName[$item]) is $($PersonAge[$item]) years old"
}

When a PowerShell function outputs value, it creates an array behind the scenes and returns that array. So at the receiving time, we need to grab hold of items in the same order, as they would have been passed to array. Since we are returning arrays, it creates a little complexity at the receiving end.

Below’s the output from the code run:

return multiple arrays without using return keyword

Return multiple values using Hashtable

Here comes the scary one :). We can also use hashtables to create symbolic arrays and then return the hashtable using return keyword. Below code is the one of the examples for same:


Function Get-PersonDetails {
Begin {
Write-Verbose "In Begin Block: Get-PersonDetails"
[hashtable] $PersonDetails = @{}
}
Process{
Write-Verbose "In Process Block: Get-PersonDetails"
$PersonDetails = @{Keith=29; Eddy=24; Kevin=23; Kate=15}
}
End{
Write-Verbose "In End Block: Get-PersonDetails"
return $PersonDetails
}
}
[hashtable] $PersonDetails = @{}
$PersonDetails = Get-PersonDetails
foreach($key in $PersonDetails.Keys){
Write-Host "$key is $($PersonDetails[$key]) years old"
}

We can then use iterate through hashtable using keys at the receiving end. Below is the output from code run:

return multiple values using hashtables

Summary and Notes

We discussed several ways for returning multiple objects from PowerShell function. However, you need to account for the same at the receiving end to make sure it works as intended.

A full copy of the source code can be found from this GitHub repository under the blog/8384 and master branches.

You may not be able to see source code posted if you are using certain in-app browsers. In such a case, copy the blog link and open it in full or mobile versions of browsers directly.

4 thoughts on “Return Multiple Values from PowerShell Function

  1. Thanks for posting!

    Just a quick FYI, I think there is a typo on lines 13, 17, 21 in the first function…. When I was reading it, I was a bit confused at first why the lines said “Get-PersonalDetails” (were you meaning to call this function and include the return in the Write-Verbose output, etc) but then noticed this is the name of your function in the 2nd example, so assume is just a copy/paste error(?) — is only a minor thing, but just thought I should let you know. Thanks again for taking the time to write/share! 👍🏼

    Like

Leave a comment