如何解决PowerShell函数无法返回[string[]]类型数组的问题及设置out-host为默认输出
Why You're Seeing the Count Property Error
First off, the core issue here is how PowerShell handles array output. When your function returns an array with only one element, PowerShell automatically "unwraps" that array and returns just the single string object instead of the string[] array you expect. That's why $wlf.GetType() shows System.Object (it's actually a System.String under the hood) — and single strings don't have a Count property (that's an array-only property).
Also, keep in mind that the [OutputType('string[]')] attribute is just metadata for IntelliSense; it doesn't force PowerShell to return that type.
Fixing the Return Type
There are a few reliable ways to make sure your function always returns a string[], even with one element:
- Prepend a comma to force array output
The comma operator creates a single-element wrapper array around your target array, which prevents PowerShell from unwrapping it:
return ,$arr
- Use
Write-Output -NoEnumerate
Instead of usingreturn, useWrite-Outputwith the-NoEnumerateflag to tell PowerShell not to split up the array:
Write-Output $arr -NoEnumerate
- Force cast the result when calling the function
You can explicitly convert the function's output tostring[]at the call site:
[string[]]$wlf = MyGetFiles "\.wlf`$"
One more thing: In your original function, $arr.GetType() | out-host is safe because out-host sends output directly to the console (it doesn't get included in the function's return value). But if you ever remove that | out-host, the type info will get added to your return stream, mixing with your array and causing more issues — so stick to out-host or Write-Host for debug output.
Setting Default Output to out-host
Actually, PowerShell already sends all unassigned/uncaptured output to the console by default (which is exactly what | out-host does). If you're trying to make sure debug output doesn't end up in your function's return value, use Write-Host instead of just outputting expressions. Write-Host writes directly to the console and never enters the pipeline:
# Replace this: $arr.GetType() | out-host # With this: Write-Host $arr.GetType()
There's no need to globally set out-host as default because the default behavior already matches what you want. Write-Host is the cleanest way to separate debug output from your function's actual return data.
Full Fixed Function
Here's your updated function with the fixes applied:
function MyGetFiles { [OutputType('string[]')] [CmdletBinding()] param([string]$filter) $found = New-Object -TypeName System.Collections.Generic.List[System.String] $cwd = (Get-Location).Path [string[]]$fileEntries = [IO.Directory]::GetFiles($cwd); foreach ($file in $fileEntries) { if ($file -match $filter) { $found.Add($file) } } $arr = [string[]]$found.ToArray() Write-Host $arr.GetType() # Debug output, doesn't affect return value return ,$arr # Force return array instead of unwrapping } [string[]]$wlf = MyGetFiles "\.wlf`$" $wlf.GetType() | Out-Host $wlf.Count
Now $wlf will always be a string[] array, and you can access the Count property without errors.
内容的提问来源于stack exchange,提问作者pico




