tech.guitarrapc.cóm

Technical updates

PowerShell DSC Advent Calendar 2014 : Day 7 MOFファイル の生成

これは、アドベントカレンダー7日目の記事です。

https://www.adventar.org/calendars/579

6日目は、コンフィグレーションの記述について説明しました。ベストプラクティスから現状のコンフィグレーションの問題、v5での改善点など多岐にわたっています。

今日は書いたコンフィグレーションをMOFファイルにコンパイルする流れについて見ていきましょう。

コンフィグレーションの読み込みと検索

6日目に示したサービスに関するコンフィグレーションで見てみましょう。

https://gist.github.com/7a7fb502e3cee29a39a9

これを、一度読み込んで見てください。

image

すると以下のようにConfiguraionとして現在のスコープに追加されます。

https://gist.github.com/83fbf8e10494d54e9914

image

関数functionやフィルタfunctionと異なり、一度コンフィグレーションを読み込まないとインテリセンスインテリセンスに表示されないので注意です。*1

読み込みはこれでokです。

コンフィグレーションのデフォルトパラメータ

コンフィグレーションconfigurationも、関数configurationと同様にデフォルトのパラメータを持っています。

https://gist.github.com/fa0c4647ad2473958bf3

これはv4とv5で異なるので見てみましょう。

まずはv4です。

名前
    Service

構文
    Service [[-InstanceName] <string>] [[-OutputPath] <string>] [[-ConfigurationData] <hashtable>]


パラメーター
    -ConfigurationData <hashtable>

        必須                         false
        位置                         2
        パイプライン入力を許可する   false
        パラメーター セット名           (すべて)
        エイリアス                      なし
        動的                     false

    -InstanceName <string>

        必須                         false
        位置                         0
        パイプライン入力を許可する   false
        パラメーター セット名           (すべて)
        エイリアス                      なし
        動的                     false

    -OutputPath <string>

        必須                         false
        位置                         1
        パイプライン入力を許可する   false
        パラメーター セット名           (すべて)
        エイリアス                      なし
        動的                     false


入力
    なし


出力
    System.Object

エイリアス
    なし


注釈
    なし

次にv5です。

NAME
    Service

SYNTAX
    Service [[-InstanceName] <string>] [[-DependsOn] <string[]>] [[-OutputPath]
     <string>] [[-ConfigurationData] <hashtable>]


PARAMETERS
    -ConfigurationData <hashtable>

        Required?                    false
        Position?                    3
        Accept pipeline input?       false
        Parameter set name           (All)
        Aliases                      None
        Dynamic?                     false

    -DependsOn <string[]>

        Required?                    false
        Position?                    1
        Accept pipeline input?       false
        Parameter set name           (All)
        Aliases                      None
        Dynamic?                     false

    -InstanceName <string>

        Required?                    false
        Position?                    0
        Accept pipeline input?       false
        Parameter set name           (All)
        Aliases                      None
        Dynamic?                     false

    -OutputPath <string>

        Required?                    false
        Position?                    2
        Accept pipeline input?       false
        Parameter set name           (All)
        Aliases                      None
        Dynamic?                     false


INPUTS
    None


OUTPUTS
    System.Object

ALIASES
    None


REMARKS
    None

v5では、-DependsOnが追加されました。v4で、複数のコンフィグレーション間で依存関係を-DependsOnで担保するためです。ダイジダイジ。

コンフィグレーションの実行

デフォルトパラメータで必ず利用するのが-OutputPathです。実際は-OutputPathも多用するのですが、それは後日説明します。

-OutputPathに指定するのは、コンフィグレーションを実行して生成されるMOFファイルの生成パス(フォルダ名) です。

  • 絶対パス、相対パスいずれも問題ありません
  • -OutputPathに指定したフォルダが存在しなければ作成してくれます

では、現在パスでserviceというフォルダを指定してみましょう。現在のパス直下を指定する場合は、フォルダ名のみで大丈夫です。

https://gist.github.com/48ae9623340e3040195e

実行すると、以下のようにMOFが生成されたことがわかります。

今回はNodeセクションを省略しているので自動的にNodeで生成されています。

    Directory: D:\service


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2014/12/09      0:07           1850 localhost.mof

以下のようにNodeセクションを追加すると、Nodeに指定した名前でMOFが生成されます。Nodeセクションに複数ホスト名を配列で指定すれば、複数MOFが生成されます。

https://gist.github.com/d89fbd801be78b907924

    Directory: D:\service


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2014/12/09      0:15           2242 127.0.0.1.mof
-a----       2014/12/09      0:15           2246 192.168.1.1.mof

ね? わかりやすい。

コンフィグレーション実行時に外からパラメータを渡す

コンフィグレーションは、ハードコードを避けて使いまわしたいですよね? 当然です。PowerShellの関数(function) と同様に外から渡すことができます。

が、関数やよくあるこの書き方はだめです。

https://gist.github.com/f3ab643ac6e84d99dd26

必ずparamブロックを使う必要があります。

https://gist.github.com/1aa0ca915a0c8bb1d68e

これで実行時に外からパラメータを渡せますね!

image

ちなみにDynamicParamなどは使えません。つまり、動的なパラメータ列挙などはできないという。

image

コンフィグレーション構文で使える構文は以下で確認できます。

https://gist.github.com/a5d7e15b2cdfa19c4e2b

NAME
    Configuration

SYNTAX
    Configuration [[-ModuleDefinition] <Object>] [[-ResourceDefinition] <Object
    >] [[-OutputPath] <Object>] [[-Name] <Object>] [[-Body] <scriptblock>] [[-A
    rgsToBody] <hashtable>] [[-ConfigurationData] <hashtable>] [[-InstanceName]
     <string>]  [<CommonParameters>]


PARAMETERS
    -ArgsToBody <hashtable>

        Required?                    false
        Position?                    5
        Accept pipeline input?       false
        Parameter set name           (All)
        Aliases                      None
        Dynamic?                     false

    -Body <scriptblock>

        Required?                    false
        Position?                    4
        Accept pipeline input?       false
        Parameter set name           (All)
        Aliases                      None
        Dynamic?                     false

    -ConfigurationData <hashtable>

        Required?                    false
        Position?                    6
        Accept pipeline input?       false
        Parameter set name           (All)
        Aliases                      None
        Dynamic?                     false

    -InstanceName <string>

        Required?                    false
        Position?                    7
        Accept pipeline input?       false
        Parameter set name           (All)
        Aliases                      None
        Dynamic?                     false

    -ModuleDefinition <Object>

        Required?                    false
        Position?                    0
        Accept pipeline input?       false
        Parameter set name           (All)
        Aliases                      None
        Dynamic?                     false

    -Name <Object>

        Required?                    false
        Position?                    3
        Accept pipeline input?       false
        Parameter set name           (All)
        Aliases                      None
        Dynamic?                     false

    -OutputPath <Object>

        Required?                    false
        Position?                    2
        Accept pipeline input?       false
        Parameter set name           (All)
        Aliases                      None
        Dynamic?                     false

    -ResourceDefinition <Object>

        Required?                    false
        Position?                    1
        Accept pipeline input?       false
        Parameter set name           (All)
        Aliases                      None
        Dynamic?                     false

    <CommonParameters>
        This cmdlet supports the common parameters: Verbose, Debug,
        ErrorAction, ErrorVariable, WarningAction, WarningVariable,
        OutBuffer, PipelineVariable, and OutVariable. For more information, see

        about_CommonParameters (https://go.microsoft.com/fwlink/?LinkID=113216).



INPUTS
    None


OUTPUTS
    System.Object

ALIASES
    None


REMARKS
    Get-Help cannot find the Help files for this cmdlet on this computer. It is
     displaying only partial help.
        -- To download and install Help files for the module that includes this
     cmdlet, use Update-Help.

Nodeはparam にするべきなの?

コンフィグレーションの例に、Node をコンフィグレーション実行時に受け取れるようにNodeブロックに指定する例がよくあります。これはDSCのモードによりますが余り使いません。

https://gist.github.com/34a940d83763adb8fa06

PULLモードの場合、ノードが誰かということはDSCサーバーは知る必要がないためです。(対象のConfiguraionIdごとにコンフィグレーションを生成するだけなので常に1つだけ生成します)

PUSHモードの場合でも、ConfigurationDataを使って対象ロールごとに別途定義可能です。これは8日目で詳細を説明します。

MOFファイルの中身

少しお見せしましたが、MOFファイルは定義の集まりです。

https://gist.github.com/48ae9623340e3040195e

実行結果のMOFを見てみましょう。

https://gist.github.com/749b016ef65d1a00755e

生成日時など

一番上部生成日技、ユーザー、マシン名です。コメントアウトされています。

/*
@TargetNode='localhost'
@GeneratedBy=acquire
@GenerationDate=12/07/2014 01:06:00
@GenerationHost=WINDOWS81X64
*/

MOFファイルの記述内容

コンフィグレーションのコンパイル結果であるMOFファイルの中身を見てみましょう。単純ですが、読みにくいです。

Key 意味 注意
ResourceID リソース名 + Key名 一意になる必要があります。今回はサービス名ですね
State コンフィグレーションで使ったプロパティ
SourceInfo 生成元のコンフィグレーションの行、文字番号、リソース名 後から追えます
StartupType State同様にプロパティ名
ModuleName リソースのモジュール リソースはモジュールの中に複数存在しえます
モジュールバージョン モジュールのバージョン バージョンを変えた時とか大事
ConfiguraionName コンフィグレーション名
instance of MSFT_ServiceResource as $MSFT_ServiceResource1ref
{
ResourceID = "[Service]WinRM";
 State = "Running";
 SourceInfo = "::9::9::Service";
 Name = "WinRM";
 StartupType = "Automatic";
 ModuleName = "PSDesiredStateConfiguration";
 ModuleVersion = "1.0";

 ConfigurationName = "Service";

};
instance of MSFT_ServiceResource as $MSFT_ServiceResource2ref
{
ResourceID = "[Service]Winmgmt";
 State = "Running";
 SourceInfo = "::9::9::Service";
 Name = "Winmgmt";
 StartupType = "Automatic";
 ModuleName = "PSDesiredStateConfiguration";
 ModuleVersion = "1.0";

 ConfigurationName = "Service";

};

DSCサーバー情報

まぁそのままです。

instance of OMI_ConfigurationDocument
{
 Version="1.0.0";
 Author="acquire";
 GenerationDate="12/07/2014 01:06:00";
 GenerationHost="WINDOWS81X64";
 Name="Service";
};

MOF読み読み

MOFファイル見にくいですね。とはいえ、比較的KV形式で読めるは読めるかと。大事なのは、後からコンフィグレーションのどこを参照しているか参照できることです。

まとめ

MOFファイルはさくっとおわっちゃった.... です。

8日目は、ConfiguraionDataについて説明します。

*1:これはv5でも変わらない残念な現状