今回も前回に続きPowerShell v5をコアとするWindows Management Framework 5.0 Preview September 2014 (v5.0) の機能詳細を触りつつ、何が変わるのかメモです。
ついにクラスがPowerShellで操作できます。やったー!
過去の記事はこちら
https://tech.guitarrapc.com/entry/2014/09/05/065912
https://tech.guitarrapc.com/entry/2014/09/08/042747
※ 追記 : PowerShel v5がリリースされました
できること
簡単にいうと、いわゆるobject-orientedなスタイルでの記述です。例を挙げると、
- Enumの宣言
- Class構文
- Properties
- Methods
- Inheritance (継承)
などなど。
これを使って、
- DSC Resourceの記述
- 独自型をPowerShel Scriptだけで規定、利用
- 規定した型のデバッグ
- 例外処理も行える
できないこと
現状まだできないことは多くあります。
- Propertyがpublicしかなく、ReadOnlyなどはできない
- Get-DSCResourceでは、Class構文で書かれたリソースを検知できない
- DSCエンジンキャッシュが、PowerShellスクリプトモジュールに向けて作りこまれているため、DebugModeを有効にする
- New-Objectでのクラス生成ができず、Static Methodである
[ClassName]::New()を使う
カスタムタイプ
規定できるものをさくっと見てみましょう。
Class Keyword
.NET Frameworkに基づく新しいクラスを規定します。
メンバーはパブリックですが、パブリックな範囲は「モジュールスコープ」に限定されています。
現段階では、 スクリプトやモジュールで規定したMyClassクラスを、モジュール/スクリプトの外部からMyClassのような形式で検知できません。
つまり、文字列からクラスを検知できないため、New-Objectを使うことができません。
構文
Class MyClass
{
}
Enum Keyword と列挙
もしJuly Previewを使っていた人がいたら破壊的変更になります。Enumのデリミタが,ではなく、,になりました。
ついにきました。Enumです。PowerShellでは、Enumが相当活躍するので、独自に規定できるのは大事です。
従来は、Class同様にC# で書いて、Add-Typeで読み込む必要がありました。
たとえば、Valentiaではこういった型を持っています。
これが、Enumキーワードを使えばこんな感じで規定できます。
素晴らしいです。もうTyr{}Catch{} も不要です。AppDomainで苦しまずにすみます。
構文
Enum MyEnum
{
}
制限
現状は、Enumerator ValueはEnumキーワード実行時に決まっている必要があります。 つまり、何かのコマンドの結果にできません。
たとえば、こうはできます。
Enum Colour { Blue = [int]::MaxValue }
が、こうはできません。
Enum Colour2 { Yellow = (Get-childItem).Count }
このような警告がでます。

算術結果はサポートしているのでこういうのはありです。
Enum SomeEnum { Max = 42 } Enum OtherEnum { Max = [SomeEnum]::Max + 1 }
Import-DscResouce
これまでもキーワードでしたが、正しくDynamic Keywordとなりました。
PowerShellは、このキーワードを使って、Rootモジュールを走査して[DSCResource()]属性をもったクラスを検知します。
Properies
ModuleInfoにImplementingAssemblyフィールドが追加されました。
これは、スクリプトモジュール内のクラスや、C# Cmdletで書かれたバイナリモジュールのためのです。なので、 ModuleTypeがManufest、つまりpsd1だとでません。
ImplementingAssemblyフィールドをリフレクションすると、どんなリソースがモジュールに含まれるかわかります。つまり、PowerShellや他の言語からどんなリソースが存在しているか調べられます。
Initializing
フィールドの初期化として
[int] = 5;
などとかくこともできます。
Static
Staticがサポートされているので、こうかけます。
Static [int] = 5;
やったね。

すべてPublic
現状はPublicのみです
ClassのスコープがLexical Scopeなので、クラス外部からの影響やクラス外部への影響はありません。
関数Function{}やScirptBlock Function{}で悩まされたあの問題が完全回避できるのはうれしいですね。
しかし、すべてPublicかぁ。
Constructor
Constructorも利用可能です。
C# 同様にクラスと同名である必要があります。また、overload可能です。
Static Constructorも利用可能で、Static PropertyはStatic Constructorの前に初期化されます。
同様に、インスタンスプロパティは、non-Static Constructorの前に初期化されます。
制限
現状は、C#にあるようなConstructorを別のConstructorから呼ぶシンタックスはないので次のような記述はできません。
: this()
インスタンス生成
クラスのインスタンス生成は、従来のNew-Objectがまだ使えないのでスタティックメソッドを利用します。
$MyClass = [MyClass]::new()
これで、$MyClassでもにょれます。
Constructorの例を見てみましょう。
thisがないのは、現状の制限です。
Method
PowerShellのClass構文におけるMethodは、ScriptBlockつまり匿名コンストラクタを使っています。
ScriptBlockのEnd節のみ使っているのが特徴です。型付けできるのでいい感じです。
属性
Classには、特定の属性が用意されています。
- DscResource
- DscResourceKey
- DscResourceMandatory
です。いずれもDSC Resourceとして組む場合のキーになるものです。
スコープ
先ほど説明したとおり、Lexical Scopeです。
リリースノートのサンプルはこんな感じですね。
まとめ
どうでしょうか。少しはとっつきやすくなったでしょうか。 初めはDefとかあって、Ruby... え。でしたが、リリースノートからはC# を意識しているようです。