powershellattributesanalyzer

OutputType attribute warning in PowerShell with PSScriptAnalyzer


Below is a sample function which declares OutputType.

I understand this is only for documentation purposes but the problem here is when I invoke PSScriptAnalyzer:

invoke-scriptanalyzer . -IncludeRule PSUseOutputTypeCorrectly

it will tell me this:

The cmdlet 'Test-Function' returns an object of type 'System.Object[]' but this type is not declared in the OutputType attribute.

function Test-Function
{
    [CmdletBinding()]
    [OutputType([System.Management.Automation.PSCustomObject[]])]
    param ()

    [PSCustomObject[]] $TestObject = @()

    for ($i = 0; $i -lt 5; $i++)
    {
        $TestObject += [PSCustomObject]@{
            Key1 = "Value1"
            Key2 = "Value2"
        }
    }

    return $TestObject
}

The question is that I suspect this informational message is false positive but can't confirm.

I think I declared the OutputType attribute just fine, or maybe not?

Why would I need to specify [OutputType([System.Object[]])] as output type? if I'm returning PSCustomObject[]?


Solution

  • Unless otherwise specified, whatever you return from a function is enumerated by the pipeline, so by the time you assign anything to a variable for example, your [psobject[]] will have been "unpacked" and stuffed back into a dynamically size [object[]].

    Use Write-Output -NoEnumerate if you want to return an enumerable collection as-is:

    function Test-Function
    {
        [CmdletBinding()]
        [OutputType([System.Management.Automation.PSCustomObject[]])]
        param ()
    
        [PSCustomObject[]] $TestObject = @()
    
        for ($i = 0; $i -lt 5; $i++)
        {
            $TestObject += [PSCustomObject]@{
                Key1 = "Value1"
                Key2 = "Value2"
            }
        }
    
        Write-Output $TestObject -NoEnumerate
    }