I'm trying to understand two related PowerShell behaviors. These functions receive the output of Get-ChildItem:
function Test-Weird1 {
param([array[]]$InputObject)
$obj = $InputObject[0][0]
$obj.GetType().FullName
($obj -is [PSObject])
}
function Test-Weird2 {
param([object[]]$InputObject)
$obj = $InputObject[0]
$obj.GetType().FullName
($obj -is [PSObject])
}
Test-Weird1 (Get-ChildItem) returns System.IO.DirectoryInfo and False, while Test-Weird2 (Get-ChildItem) returns System.IO.DirectoryInfo and True.
There is also this behavior:
$obj = (Get-ChildItem)[0].PSObject
$obj.GetType() -eq [System.Management.Automation.PSObject] # True
$obj -is [System.Management.Automation.PSObject] # False
Why does the first parameter type change the indexing and PSObject result, and why does the PSObject property report that it has the PSObject type while the -is operator says otherwise?
3 Answers
One extra edge case: indexing an empty result can leave you with `$null`, so `$InputObject[0].GetType()` may fail. If you need a consistently safe first-element lookup, use `@($InputObject)[0]`. In PowerShell 7, a null-conditional call such as `($obj)?.GetType().FullName` can also avoid calling a method on `$null`.
The `.PSObject` member is not simply the same thing as asking whether the value itself is a `PSObject`. It exposes an object view represented by a member-set object, essentially a PowerShell inspection interface around the original value.
So in this example, `$obj.GetType()` reports the runtime type of that view, `System.Management.Automation.PSObject`, but the `-is` check tests the value in the other direction and does not consider the member-set view to be an instance of `PSObject`. In practice, `.PSObject`, `.PSAdapted`, and related intrinsic members are special PowerShell member sets rather than ordinary properties containing a normal PSObject wrapper.
The first difference comes from the parameter conversion. `[array[]]` means an array whose elements are themselves arrays, so the input is coerced into a jagged array. `$InputObject[0][0]` reaches the underlying .NET `DirectoryInfo` object. During that conversion, PowerShell removes the `PSObject` wrapper, which is why `-is [PSObject]` is false.
`[object[]]` is just a one-dimensional object array. In that case, `$InputObject[0]` is the original PowerShell object, including its wrapper, so `-is [PSObject]` is true. The wrapper’s base object is still a `System.IO.DirectoryInfo`, which explains the type name returned by `GetType()`.
PowerShell normally preserves extended type system members when it unwraps and later rewraps objects, although some types—strings are a common example—can lose added members during conversion.

Related Questions
How To: Running Codex CLI on Windows with Azure OpenAI
Set Wordpress Featured Image Using Javascript
How To Fix PHP Random Being The Same
Why no WebP Support with Wordpress
Replace Wordpress Cron With Linux Cron
Customize Yoast Canonical URL Programmatically