95

一部の PowerShell スクリプトでカスタム型を定義して使用できるようにしたいと考えています。たとえば、次の構造を持つオブジェクトが必要だったとします。

Contact
{
    string First
    string Last
    string Phone
}

次のような関数で使用できるように、これを作成するにはどうすればよいですか。

function PrintContact
{
    param( [Contact]$contact )
    "Customer Name is " + $contact.First + " " + $contact.Last
    "Customer Phone is " + $contact.Phone 
}

このようなことは可能ですか、または PowerShell で推奨されていますか?

4

8 に答える 8

151

PowerShell 3 より前

PowerShell の Extensible Type System では、パラメーターで行った方法に対してテストできる具体的な型を作成できませんでした。そのテストが必要ない場合は、上記の他の方法で問題ありません。

サンプルスクリプトのように、キャストまたはタイプチェックできる実際のタイプが必要な場合は、C#またはVB.netで記述してコンパイルしないと実行できません。PowerShell 2 では、「Add-Type」コマンドを使用して非常に簡単に実行できます。

add-type @"
public struct contact {
   public string First;
   public string Last;
   public string Phone;
}
"@

歴史的なメモ: PowerShell 1 では、さらに困難でした。CodeDom を手動で使用する必要がありました。非常に古い関数new-structスクリプトが PoshCode.org にあり、これが役に立ちます。あなたの例は次のようになります。

New-Struct Contact @{
    First=[string];
    Last=[string];
    Phone=[string];
}

Add-Typeorを使用New-Structすると、実際にクラスをテストし、param([Contact]$contact)などを使用して新しいクラスを作成できます$contact = new-object Contact...

PowerShell 3 では

キャストできる「実際の」クラスが必要ない場合は、Steven と他の人が上で示した Add-Member の方法を使用する必要はありません。

PowerShell 2 以降では、New-Object に -Property パラメーターを使用できます。

$Contact = New-Object PSObject -Property @{ First=""; Last=""; Phone="" }

また、PowerShell 3 では、PSCustomObjectアクセラレータを使用して TypeName を追加できるようになりました。

[PSCustomObject]@{
    PSTypeName = "Contact"
    First = $First
    Last = $Last
    Phone = $Phone
}

まだ単一のオブジェクトしか取得していないため、すべてのオブジェクトが同じであることを確認する関数を作成する必要がありますが、パラメーターを属性New-Contactで装飾することにより、パラメーターがそれらの型の 1 つであることを簡単に確認できるようになりました。PSTypeName

function PrintContact
{
    param( [PSTypeName("Contact")]$contact )
    "Customer Name is " + $contact.First + " " + $contact.Last
    "Customer Phone is " + $contact.Phone 
}

PowerShell 5 では

PowerShell 5 ではすべてが変更され、最終的に型を定​​義するための言語キーワードとして and を取得しました (存在しませんclassが、問題ありません)。enumstruct

class Contact
{
    # Optionally, add attributes to prevent invalid values
    [ValidateNotNullOrEmpty()][string]$First
    [ValidateNotNullOrEmpty()][string]$Last
    [ValidateNotNullOrEmpty()][string]$Phone

    # optionally, have a constructor to 
    # force properties to be set:
    Contact($First, $Last, $Phone) {
       $this.First = $First
       $this.Last = $Last
       $this.Phone = $Phone
    }
}

New-Object:を使用せずにオブジェクトを作成する新しい方法も取得しました[Contact]::new()。実際、クラスをシンプルに保ち、コンストラクターを定義しない場合は、ハッシュテーブルをキャストすることでオブジェクトを作成できます (ただし、コンストラクターがなければ方法はありません)。すべてのプロパティを設定する必要があることを強制するには):

class Contact
{
    # Optionally, add attributes to prevent invalid values
    [ValidateNotNullOrEmpty()][string]$First
    [ValidateNotNullOrEmpty()][string]$Last
    [ValidateNotNullOrEmpty()][string]$Phone
}

$C = [Contact]@{
   First = "Joel"
   Last = "Bennett"
}
于 2008-09-15T20:36:56.360 に答える
58

カスタム型の作成は、PowerShell で行うことができます。
実際、Kirk Munro は 2 つの優れた投稿でプロセスを詳しく説明しています。

Manning著の『Windows PowerShell In Action』にも、カスタム型を作成するためのドメイン固有言語を作成するためのコード サンプルがあります。この本は全体的に優れているので、本当にお勧めします。

上記を簡単に行う方法を探しているだけなら、次のようなカスタム オブジェクトを作成する関数を作成できます。

function New-Person()
{
  param ($FirstName, $LastName, $Phone)

  $person = new-object PSObject

  $person | add-member -type NoteProperty -Name First -Value $FirstName
  $person | add-member -type NoteProperty -Name Last -Value $LastName
  $person | add-member -type NoteProperty -Name Phone -Value $Phone

  return $person
}
于 2008-09-12T21:13:15.300 に答える
18

これはショートカット メソッドです。

$myPerson = "" | Select-Object First,Last,Phone
于 2008-09-14T13:05:17.047 に答える
9

Steven Murawski の答えは素晴らしいですが、私は短い方が好きです (または、add-member 構文を使用する代わりに、よりきちんとした select-object の方が好きです):

function New-Person() {
  param ($FirstName, $LastName, $Phone)

  $person = new-object PSObject | select-object First, Last, Phone

  $person.First = $FirstName
  $person.Last = $LastName
  $person.Phone = $Phone

  return $person
}
于 2011-01-12T10:11:43.897 に答える
6

カスタム オブジェクトを作成するためのこの単純なオプション (vs 3 以降) について誰も言及していないことに驚きました。

[PSCustomObject]@{
    First = $First
    Last = $Last
    Phone = $Phone
}

ただし、型は PSCustomObject であり、実際のカスタム型ではありません。しかし、これはおそらくカスタム オブジェクトを作成する最も簡単な方法です。

于 2015-09-10T15:56:43.153 に答える
4

使用できるPSObjectとAdd-Memberの概念があります。

$contact = New-Object PSObject

$contact | Add-Member -memberType NoteProperty -name "First" -value "John"
$contact | Add-Member -memberType NoteProperty -name "Last" -value "Doe"
$contact | Add-Member -memberType NoteProperty -name "Phone" -value "123-4567"

これは次のように出力します:

[8] » $contact

First                                       Last                                       Phone
-----                                       ----                                       -----
John                                        Doe                                        123-4567

もう1つの方法(私が知っている)は、C#/ VB.NETで型を定義し、そのアセンブリをPowerShellにロードして直接使用することです。

この動作により、他のスクリプトまたはスクリプトのセクションが実際のオブジェクトで動作できるようになるため、この動作は確実に推奨されます。

于 2008-09-12T20:36:22.360 に答える