こんにちは。(株)EIT2年目のMです。
今回は、2016年8月にオープンソース化したことで話題のPowershellの機能の1つ「PowershellDSC」についての記事です。
Powershell 5.0が公開されてもうすぐ1年が経とうとしていますが、皆さんはもう乗り換えましたか?Powershell 5.0ユーザがDSCを使用する場合に陥ってしまう、
プロパティ ○○ は未定義です
というエラーについてその対処法をご紹介します。
※今回の記事はPowershell4.0を使っていた方及びPowershell5.0を使っていく方向けの内容です※
もくじ
PowershellDSCとは、
PowershellDSCとは、
のことです。
サーバの自動構成ツールとしては「chef」「Ansible」「Puppet」「Itamae」などが普及していますが、その中でも「PowershellDSC」は
- ・Windowsに標準搭載されている(※Windows 8.1,Windows Server 2012R2以降)
- ・Windowsの構成管理に強い
といった特徴があります。
Powershellは進化を続ける
冒頭でも述べたようにPowershellはオープンソース化が宣言され、今後さらなる機能の追加や利便性の向上が見込まれています。
Powershell 5.0からは操作可能なWindows機能が追加されただけではなくLinuxやMacOSへ対応を始めており、今後活用の場面が増えていくと予想しています。最新の動向を知りたい場合は、公式GitHub「PowershellTeam」を見てみるといいでしょう!
プロパティの未定義エラーが発生したら・・・
さて、前置きが長くなりましたが本題に入りましょう。
今回想定する環境は管理マシンのPowershellバージョンを5.0にアップデートしたユーザが、Windows Server 2012R2などのPowershell 4.0を搭載したサーバに対してPowershellDSCを使用する場合です。
PowershellDSCユーザがPowershellのバージョンを5.0にアップデートし、従来通りにMOFファイルをプッシュした場合、こんなエラーが発生するかもしれません。(※一部”*”で伏せています)
PS C:work> Start-DscConfiguration -Wait-Verbose -Path .Hoge -CimSession $CimSession VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ''methodName'= SendConfigurationApply,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName ' = root/Microsoft/Windows/DesiredStateConfiguration'. VERBOSE: コンピューター WIN-*****、ユーザー SID *-*-*-**-*****-******-******-**** から LCM メソッドが呼び出されました。 VERBOSE: [WIN-******]: LCM: [ 開始 設定 ] VERBOSE: [WIN-******]: LCM: [ 終了 設定 ] プロパティ ConfigurationName は未定義です 行:18、文字:2 バッファー: nName = "Hoge"; };^ insta + CategoryInfo : SyntaxError: (root/Microsoft/...gurationManager:String) [], CimException + FullyQualifiedErrorId : MiClientApiError_Failed + PSComputerName : HogeServer VERBOSE: Operation 'Invoke CimMethod' complete. VERBOSE: Time taken for configuration job to complete is 2.343 seconds
早速、エラーの原因を探ってみましょう。
使用したConfigurationを確認する
以下に示すのは、今回対象のサーバ(HogeServer)にプッシュしたConfiguration(コンフィグレーション)です。
Configuration Hoge { Import-DscResource -ModuleName 'PSDesiredStateConfiguration' Node HogeServer { WindowsFeature FeatureAdd { Ensure = "Present" Name = "Web-Server" } Service ServiceStart { Name = "W3SVC" StartupType = "Manual" State = "Running" } File FilePut { Ensure = "Present" Type = "File" Contents = "<html><head><title>タイトル</title></head><body>This is PowershellDSC!</body></html>" DestinationPath = "C:inetpubwwwrootindex.html" } } }
HogeServerというサーバにIISをインストールし、デフォルトページに「This is PowershellDSC!」を表示させるという非常にシンプルなConfigurationです。
特殊な操作をしているわけではない一般的なConfigurationなので、Powershell 4.0を使用していた頃は特に問題は起きていませんでした。
Configurationは問題はないため、次はMOFファイルを確認してみましょう。
Powershell 5.0で作成したMOFファイル
もう一度エラー文を確認してみましょう。
プロパティ ConfigurationName は未定義です 行:18、文字:2
MOFファイルの18行目に原因がありそうです。18行目辺りまでを見てみます。
/* @TargetNode='HogeServer' @GeneratedBy=User @GenerationDate=10/16/2016 19:30:36 @GenerationHost=User-PC */ instance of MSFT_RoleResource as $MSFT_RoleResource1ref { ResourceID = "[WindowsFeature]FeatureAdd"; Ensure = "Present"; SourceInfo = "::6::9::WindowsFeature"; Name = "Web-Server"; ModuleName = "PSDesiredStateConfiguration"; ModuleVersion = "1.0"; ConfigurationName = "Hoge"; }; instance of MSFT_ServiceResource as $MSFT_ServiceResource1ref { ~~~~以下略~~~~
どうやら18行目に該当する部分は
<pre class=”theme:powershell-ise lang:ps decode:true”> ConfigurationName = “Hoge”;</pre>
のようです。この部分はMOFの作成元となったConfigurationの定義名を表しています。
エラー文から考えるとMOFファイルの<strong>ConfigurationName</strong> <strong>プロパティ</strong>が定義されていないことが原因だと考えられます。つまり、
<strong>MOFの受信先となるサーバでは、このプロパティが認識できていない!</strong>
ということなんですね。
<h3>Powershell 4.0で作成したMOFファイル</h3>
プッシュ元とプッシュ先ではPowershellのバージョンが違います。この辺りに原因があるだろうということで、バージョン4.0で作成したMOFファイルを確認してみましょう。
<pre class=”lang:ps decode:true”>/*
@TargetNode=’HogeServer’
@GeneratedBy=User
@GenerationDate=9/11/2016 19:15:59
@GenerationHost=User-PC
*/
instance of MSFT_RoleResource as $MSFT_RoleResource1ref
{
ResourceID = “[WindowsFeature]FeatureAdd”;
Ensure = “Present”;
SourceInfo = “::6::9::WindowsFeature”;
Name = “Web-Server”;
ModuleName = “PSDesiredStateConfiguration”;
ModuleVersion = “1.0”;
};
instance of MSFT_ServiceResource as $MSFT_ServiceResource1ref
{
~~~~以下略~~~~
先ほど問題となった18行目に注目してみてください。ご覧のとおり、
ConfigurationNameというプロパティが存在していない!
ということが分かります。
この「ConfigurationName」というプロパティはPowershell5.0から追加された新しいプロパティだったんですね。
複数のConfigurationからMOFファイルを作成する場合に、どのConfigurationから追加されたResource(リソース)なのかを判別するためのプロパティですが、Powershell 4.0では認識できないという落とし穴なんです。
ConfigurationやMOFに文法ミスがなくてもバージョン差異によって、こんなところでエラーに苦しめられるんですね・・・
ここまでで発生したエラーの原因はある程度判明しましたが、対処の方法はあるのでしょうか。
プロパティの未定義エラーの対処方法
対処は非常に簡単です。先ほど2つのMOFファイルの中身を載せましたが基本的に異なる部分は
ConfigurationName = "Hoge";
というプロパティのみです。このプロパティ部分を削除するとPowershell 4.0に対してDSCを使用しても問題なくプッシュすることができます。
最終的にエラーの原因となるプロパティを全て削除したMOFファイル(v5.0作)を以下に示します。
/* @TargetNode='HogeServer' @GeneratedBy=User @GenerationDate=10/16/2016 19:30:36 @GenerationHost=User-PC */ instance of MSFT_RoleResource as $MSFT_RoleResource1ref { ResourceID = "[WindowsFeature]FeatureAdd"; Ensure = "Present"; SourceInfo = "::6::9::WindowsFeature"; Name = "Web-Server"; ModuleName = "PSDesiredStateConfiguration"; ModuleVersion = "1.0"; }; instance of MSFT_ServiceResource as $MSFT_ServiceResource1ref { ResourceID = "[Service]ServiceStart"; State = "Running"; SourceInfo = "::12::9::Service"; Name = "W3SVC"; StartupType = "Manual"; ModuleName = "PSDesiredStateConfiguration"; ModuleVersion = "1.0"; }; instance of MSFT_FileDirectoryConfiguration as $MSFT_FileDirectoryConfiguration1ref { ResourceID = "[File]FilePut"; Type = "File"; Ensure = "Present"; Contents = "<html><head><title>タイトル</title></head><body>This is PowershellDSC!</body></html>"; DestinationPath = "C:inetpubwwwrootindex.html"; ModuleName = "PSDesiredStateConfiguration"; SourceInfo = "::19::9::File"; ModuleVersion = "1.0"; }; instance of OMI_ConfigurationDocument { Version="2.0.0"; Author="User"; GenerationDate="10/16/2016 19:30:36"; GenerationHost="User-PC"; };
エラー文に沿って、未定義と警告される部分を削除していくことで上記のMOFファイルが完成します。
では、このMOFファイルをプッシュしてみましょう。
無事にプッシュ成功!
実際にプッシュした結果がこちらです。
PS C:work> Start-DscConfiguration -Wait -Verbose -Path .Hoge -CimSession $SimSession VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = SendConfigurationApply,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName ' = root/Microsoft/Windows/DesiredStateConfiguration'. VERBOSE: コンピューター WIN-*******、ユーザー SID *-*-*-*-******-*****-*******-*** から LCM メソッドが呼び出されました。 VERBOSE: [WIN-*******]: LCM: [ 開始 設定 ] VERBOSE: [WIN-*******]: LCM: [ 開始 リソース ] [[WindowsFeature]FeatureAdd] VERBOSE: [WIN-*******]: LCM: [ 開始 テスト ] [[WindowsFeature]FeatureAdd] VERBOSE: [WIN-*******]: [[WindowsFeature]FeatureAdd] 操作 'Get-WindowsFeature' が開始されました: Web-Server VERBOSE: [WIN-*******]: [[WindowsFeature]FeatureAdd] 操作 'Get-WindowsFeature' は成功しました: Web-Server VERBOSE: [WIN-*******]: LCM: [ 終了 テスト ] [[WindowsFeature]FeatureAdd] 51.7820 秒かかりました。 VERBOSE: [WIN-*******]: LCM: [ 開始 設定 ] [[WindowsFeature]FeatureAdd] VERBOSE: [WIN-*******]: [[WindowsFeature]FeatureAdd] インストールを開始しました... VERBOSE: [WIN-*******]: [[WindowsFeature]FeatureAdd] 前提条件の処理が開始されました... VERBOSE: [WIN-*******]: [[WindowsFeature]FeatureAdd] 前提条件の処理が正常に完了しました。 WARNING: [WIN-*******]: [[WindowsFeature]FeatureAdd] Windows 自動更新が有効になっていません。新しくインストールした役割または機能が自動的に更新されるようにするには、[Windows Update] を有効にしてください。 VERBOSE: [WIN-*******]: [[WindowsFeature]FeatureAdd] インストールが正常に完了しました。 VERBOSE: [WIN-*******]: [[WindowsFeature]FeatureAdd] successfully installed the feature Web-Server VERBOSE: [WIN-*******]: LCM: [ 終了 設定 ] [[WindowsFeature]FeatureAdd] 143.2100 秒かかりました。 VERBOSE: [WIN-*******]: LCM: [ 終了 リソース ] [[WindowsFeature]FeatureAdd] VERBOSE: [WIN-*******]: LCM: [ 開始 リソース ] [[Service]ServiceStart] VERBOSE: [WIN-*******]: LCM: [ 開始 テスト ] [[Service]ServiceStart] VERBOSE: [WIN-*******]: [[Service]ServiceStart] サービス 'W3SVC' の開始の種類は 'Auto' です。'Manual' と一致しません。 VERBOSE: [WIN-*******]: LCM: [ 終了 テスト ] [[Service]ServiceStart] 1.1880 秒かかりました。 VERBOSE: [WIN-*******]: LCM: [ 開始 設定 ] [[Service]ServiceStart] VERBOSE: [WIN-*******]: [[Service]ServiceStart] サービス 'W3SVC' は既に開始されています。操作は必要ありません。 VERBOSE: [WIN-*******]: LCM: [ 終了 設定 ] [[Service]ServiceStart] 1.0160 秒かかりました。 VERBOSE: [WIN-*******]: LCM: [ 終了 リソース ] [[Service]ServiceStart] VERBOSE: [WIN-*******]: LCM: [ 開始 リソース ] [[File]FilePut] VERBOSE: [WIN-*******]: LCM: [ 開始 テスト ] [[File]FilePut] VERBOSE: [WIN-*******]: [[File]FilePut] 宛先オブジェクトが見つかったため、何もする必要はありません。 VERBOSE: [WIN-*******]: LCM: [ 終了 テスト ] [[File]FilePut] 0.4680 秒かかりました。 VERBOSE: [WIN-*******]: LCM: [ スキップ 設定 ] [[File]FilePut] VERBOSE: [WIN-*******]: LCM: [ 終了 リソース ] [[File]FilePut] VERBOSE: [WIN-*******]: LCM: [ 終了 設定 ] VERBOSE: [WIN-*******]: LCM: [ 終了 設定 ] (221.1170 秒)。 VERBOSE: Operation 'Invoke CimMethod' complete. VERBOSE: Time taken for configuration job to complete is 223.029 seconds
「Operation ‘Invoke CimMethod’ complete.」ということで無事に成功していることがわかります。
Windows 自動更新に関するWARNINGが表示されていますがサーバで有効にしていないだけですので、これは特に問題ありません。
まとめ
今回のようにPowershellDSCにおいて「バージョン差異に起因するプロパティの未定義エラー」が発生した場合は、該当箇所を削除することで解決できます。
また今回のようなバージョン差異による落とし穴に陥らないためには、プッシュ先サーバのPowershellバージョン合わせてMOFを作成することが望ましいでしょう。
PowershellDSCは他の構成管理ツールに比べると歴史が浅く情報も少ないため、エラーが起きてしまった場合は対処に困るかもしれません。そんな時はエラー内容をよく確認し、可能性のある要因を1つ1つ解消していきましょう。
またコミュニティによって公開されているリソースを使用することで、想定外のエラーを未然に防ぐことも大切です。
これから更に発展していく可能性のある分野ですので、是非皆さんも挑戦してみてください!