5

I have a section of PowerShell code that reads a list of items from Azure, and formats them into a table for the user to choose from:

if ($SubscriptionArray.Count -eq 1) {
    $SelectedSub = 1
}
# Get SubscriptionID if one isn't provided
while ($SelectedSub -gt $SubscriptionArray.Count -or $SelectedSub -lt 1) {
    Write-host "Please select a subscription from the list below"
    $SubscriptionArray | Select-Object "#", Id, Name | Format-Table
    try {
        $SelectedSub = Read-Host "Please enter a selection from 1 to $($SubscriptionArray.count)"
    }
    catch {
        Write-Warning -Message 'Invalid option, please try again.'
    }
}

When executed in the main area of the script, this outputs the expected result:

AzureTableOutput

I want to use this logic multiple times, and therefore moved it into a method:

function Get-IndexNumberFromArray(
    [Parameter(Mandatory = $True)]
    [array]$selectArray,

    [Parameter(Mandatory = $True)]
    [string]$message
) {
    [int]$SelectedIndex = 0
    # use the current subscription if there is only one subscription available
    if ($selectArray.Count -eq 1) {
        $SelectedIndex = 1
    }

    # Get SubscriptionID if one isn't provided
    while ($SelectedIndex -gt $selectArray.Count -or $SelectedIndex -lt 1) {
        Write-Host "$message"

        $selectArray | Select-Object "#", Id, Name | Format-Table

        try {
            $SelectedIndex = Read-Host "Please enter a selection from 1 to $($selectArray.count)"
        }
        catch {
            Write-Warning -Message 'Invalid option, please try again.'
        }
    }

    return $SelectedIndex
}

Everything in this method works great, except now my table is no longer outputting to the window. Instead, the user just get a prompt to pick a number from 1 to x with no context for what each number represents.

Why is the table working in the main area of the script, but not working in a function?

1 Answer 1

13

Format-Table actually doesn't print a table, it outputs objects that are then printed as the table. So if you're using a function, then the Format-Table output gets part of the return value of your function.

You can add Out-Host to the pipeline to force Format-Table's result to end up on the host, i.e. the console:

$selectArray | Select-Object "#", Id, Name | Format-Table | Out-Host
Sign up to request clarification or add additional context in comments.

3 Comments

The answer is so simple... Thanks! I figured that Out-Host was the default.
It's the default cmdlet that is effectively added to every pipeline you write interactively. But not in scripts (or functions, which are effectively the same).
Frustratingly, this now (PS 7.1) outputs Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData. $item | Format-Table | Out-String | Write-Host as described by stackoverflow.com/questions/36585500/… worked for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.