1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Get-TypeName

Last updated at Posted at 2020-04-25

緒言

Effective Windows PowerShell: The Free eBook は PowerShell 2.0 までをあつかっていますが、いまでもおそわることはおおくあるとおもいます。公式のドキュメントではきづかなかったことがたくさんかかれています。

その Effective Windows PowerShell.pdfItem 3: Know What Objects Are Flowing Down the Pipeline1

PowerShell

filter Get-TypeName {if ($_ -eq $null) {''} else {$_.GetType().Fullname }}


は `$profile` にいれておきたいくらい便利とあります。ただし、

> ```
PS> @() | Get-TypeName

とするとなにも出力されません。配列はパイプにおくられるときに要素に展開されますが、ここで @() の要素はからなのでパイプにはなにもおくられないということでしょう。

The PowerShell Community Extensions (PSCX) の Get-TypeName をつかうと、このようなばあいに警告を表示してくれるとのことです。

しかし、さしあたり Get-TypeName のみがほしいのと、これを PS の function で実装できないかしらとおもったのでした2

移植

PSCX の Get-TypeName の C♯ の ソース コード を PS におきかえただけです。

function Get-TypeName {
    [CmdletBinding()]
    [OutputType([String], [PSObject])]
    param(
        [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
        [AllowNull()]
        [PSObject]$InputObject,
        [Parameter(Mandatory=$false)]
        [Switch]$FullName,
        [Parameter(Mandatory=$false)]
        [Switch]$PassThru
    )

    begin {
        $_processedAnyInput = $false
    }

    process {
        if ($null -eq $InputObject) {
            Write-Host -Object '<null>'
        } else {
            $name = if ($FullName) {
                    $InputObject.GetType().FullName
                } else {
                    $InputObject.GetType().Name
                }
            if ($PassThru) {
                Write-Host -Object $name
                Write-Output -InputObject $InputObject
            } else {
                Write-Output -InputObject $name
            }
        }
        $_processedAnyInput = $true
    }

    end {
        if (-not $_processedAnyInput) {
            Write-Warning -Message (
                'Get-TypeName did not receive any input. The input may be an empty ' +
                'collection. You can either prepend the collection expression with ' +
                'the comma operator e.g. ",$collection | gtn" or you can pass the ' +
                'variable or expression to Get-TypeName as an argument e.g. ' +
                '"gtn $collection".'
            )
        }
    }
}

Set-Alias gtn Get-TypeName -Description "PSCX alias"

なお、オリジナルのコードできになるのは

C#
            string name = InputObject.TypeNames[0];
            if (!FullName)
            {
                if (name.Contains("`"))
                {
                    string nonGenericPart = name.Split('[')[0];
                    int ndx = nonGenericPart.LastIndexOf('.');
                    if ((ndx >= 0) && (ndx < (nonGenericPart.Length - 1)))
                    {
                        name = nonGenericPart.Substring(ndx + 1);
                    }
                }
                else
                {
                    // ...
                }
            }

ですが、この部分は、たとえば

PS> ([System.Collections.Generic.List[int]]::new()).GetType().FullName
System.Collections.Generic.List1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] PS> ([System.Collections.Generic.List[int]]::new()).GetType().Name List1


というふうになるので、 `GetType().Name` でまきとれているとおもいます。 

# 2020/07/22 追記

```powershell
    process {
        if ($InputObject -eq $null) {
    # ...

としていましたが、 Everything you wanted to know about arrays | $null or empty にしたがい

    process {
        if ($null -eq $InputObject) {
    # ...

に修正しました。

ただ、当該記事で

$array = @('one',$null,'three')
if ( $array -eq $null)
{
'I think Array is $null, but I would be wrong'
}


はバージョン 5.1.19041.1 では著者の意図どおりにはなりませんでした。たしかに、

```console
PS> Get-Member -InputObject ($array -eq $null)


   TypeName: System.Object[]
...

となるので、 $array -eq $null$null が要素の要素数 1 の配列つまり $true 相当と評価されてしかるべきとおもいますが…。

  1. もとになったブログは Effective PowerShell Item 6: Know What Objects Are Flowing Down the Pipe

  2. PS 2.0 まででは不可能だったのかもしれません。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?