powershellpropertiesalias

Adding alias properties (AliasProperty members)


I just wonder why this works:

$s = "hi there"
$s = Add-Member -InputObject $s -MemberType AliasProperty -Name Length2 -Value Length -PassThru
$s | gm -MemberType AliasProperty #the property is there
$s.Length2 #8

means: the aliasproperty Length2 is there, but this doesn't work:

$s = dir
$s = Add-Member -InputObject $s -MemberType AliasProperty -Name Length2 -Value Length -PassThru
$s | gm -MemberType AliasProperty #the property is not there

means: there is no aliasproperty Length2, but suprisingly enough:

$s.Length2 #458

works just fine?


Solution

  • $s = dir

    Given that dir is a built-in alias for Get-ChildItem, this typically results in an array being stored in $s, i.e. whenever two or more child items (files or subdirectories) are present.[1]

    $s = Add-Member -InputObject $s ...

    Due to use of Add-Member's -InputObject parameter, you're adding the alias property (as an ETS (Extended Type System) member) to the array itself.

    $s | gm -MemberType AliasProperty

    By contrast, due to using the pipeline here, which enumerates arrays, it is the elements of the array stored in $s that are being sent to Get-Member (whose built-in alias is gm) - and these do not have your alias property.

    $s.Length2 #458

    Here you're accessing the alias property directly on the array, which therefore works.


    As for your first attempt (which worked as expected):

    $s = "hi there"
    $s = Add-Member -InputObject $s -MemberType AliasProperty -Name Length2 -Value Length -PassThru

    Optional reading: Why attaching ETS (Extended Type System) members to instances of [string] and .NET value types is best avoided:

    Note:

    Avoid attaching ETS instance members in the following cases:

    Note:


    Optional reading: Instance-level vs. type-level ETS members:

    ETS members can also be defined at the type level (rather than at the instance level, i.e. for a particular object only), namely via Update-TypeData, which is often preferable, though not always called for / possible.


    [1] Specifically, it is an [object[]] array containing System.IO.FileInfo and/or System.IO.DirectoryInfo instances.