最新情報
2016/8/6 WMF5.1 Preview で本件が修正されました。Windows 10 Anniversary Update から確認ができます。
WMF5 においては、ワークアラウンドを利用するしかないのでご注意ください。
以前の状況
WMF5 がリリースされて数か月たちました。そろそろ皆様の環境も PowerShell 5.0 に置き換わったころではないでしょうか?特に DSC に関しては、これまで CIM Method を直接たたかなくては操作ができなかった部分が、Cmdlet で置き換えられています。また、ConfigurationId も撤廃され、PULL Server から PULL Node への mof document 配信も格段に楽になりました。
と、いいこと尽くめならいいのですが、まだまだ発展途上の技術です。バグも多くあります。ことごとく踏み抜いて対処してきましたが、1つ皆様の投票 (Vote) ご協力いただきたい事案があります。PowerShell Team から User Voiceを依頼されたので挙げましたが、投票数によって優先順位が変わるため PULL Server をお使いの(予定も含めて)方はぜひ清き一票を... (うさんくさい
https://windowsserver.uservoice.com/forums/301869-powershell/suggestions/15496698-minimumcompatibleversion-cause-cannot-find-modulewindowsserver.uservoice.com
目次
概要
DSC を PULL で組んでおいたとしましょう。PULL クライアントが PULL サーバーから Update-DscConfiguration
や 定期Consistency Check で最新mof を取得したときに、以下のエラーがおこる状況がありえます。
Cannot find module PSDesiredStateConfiguration_1.0 from the server https://DSCPull:8080/PSDSCPullServer.svc/Modules(ModuleName='PSDesiredStateConfiguration',ModuleVersion='1.0')/ModuleContent";
日本語でも、同様の意味で PSDesiredStateConfiguration_1.0 を PULL Server から 取得できません という内容です。
このエラーが出たが最後、このPULLクライアントは対処しない限り、Consistency Check が実行できなくなります。つらい。
どういうときにおこるのか
初めに、WMF5 にしようとしている方が不安に思わないように条件を明示します。
- WMF4 では起こりません
- WMF5 でも WMF4 と全く同じ Configuration を使っていると起こりません
つまりタダのアップグレードなら発生しません。やったね。必ずしも起こるわけではなく、次の条件を満たしたときに発生します。
- PULL クライアントが PULL サーバーから モジュールを取得する
- Configuration で、PSDesiredStateConfiguration リソースを利用している
- MinimumCompatibleVersion が 2.0 になっている
端的に言うと次の状況をすべて満たしたときに必ず発生します。
Import-DscResource -ModuleName PSDesiredStateConfiguration -ModuleVersion 1.1
を明示していない
- WMF 5 で追加された Configuration のプロパティ、例えば
PsDscRunAsCredential
を使う
- PSDesiredStateConfiguration のいずれかのリソースを利用している
- PSDesiredStateConfiguration 以外のカスタムリソースを併用している
- Configurationをネストしている
- PULL モードを利用した PULL クライアントを利用している
何が問題なのか
少し説明しましょう。
Import-DscResource -ModuleName PSDesiredStateConfiguration -ModuleVersion 1.1
を明示していない
PowerShell DSC を使っている方の多くは数10の Configuration を用意して、それぞれで様々なリソースを利用すると思います。しかし、Configuration で 利用するリソースは、Import-DscResource
を使ってインポートしないと利用できません。*1
また、リソースはどんどんアップデートされるので、PULL Server に最新リソースだけ配置することで、Import-DscResource
でリソースのバージョンを明示せず最新版のみを自動的に使うようにするのではないでしょうか。*2
ここはいいのです。当然の ユーザーシナリオです。
問題の始まりは、 WMF5 にはPSDesiredStateConfiguration 1.1 しかないにも関わらず、Import-DscResource -ModuleName PSDesiredStateConfiguration
をしただけ/あるいは明示しなかった場合、mof document は ModuleVersion 1.0 となる ことにあります。
順に見てみましょう。まず、Get-DscResource
をすると、PSDesiredStateConfiguration は 1.1 とわかります。
gist.github.com
次に、PSDesiredStateConfiguration の WindowsFeature
リソースを使った簡単な Configuration を書き、mof にコンパイルすると次の結果が得られます。
gist.github.com
コンパイルされた mof の PSDesiredStateConfiguration
の下にある、ModuleVersion
を見てください。1.0 になっていますね。
通常のリソースでは、mofで利用したリソースのバージョンが出力されます。たとえば、一覧にあった GraniResource は 3.7.8.1 なので Import-DscResource -ModuleName GraniResource
とすると ModuleVersion は 3.7.8.1 がmof にも出ます。当然です。ここを見てPULLノードはサーバーに取得依頼するモジュールバージョンを決定しているので、mof の ModuleVersion は、Configuration から mof をコンパイル時に利用したバージョンに厳密であるべきなのです。
WMF 5 で追加された Configuration のプロパティ、例えば PsDscRunAsCredential
を使う
先ほどの ModuleVersionの明示がなくても、MinimumCompatibleVersion が 1.0 のうちは問題ありません。1.0 はつまり WMF4 と同様の機能しか使っていないことを示します。この場合、「PSDesiredStateConfiguration に限ってModuleVersionが1.0 と PULLクライアントに存在しなくても PULLServerに問い合わせに行かずエラーが発生しない」という挙動をします。(なんだこれ
しかし、MinimumCompatibleVersion が 2.0 になると話は変わります。「PSDesiredStateConfiguration も、他のリソース同様に PULL クライアントに無い ModuleVersion 1.0 が提示されたため、PULLServerに問い合わせに行きますが、PULL Server も WMF5 なので 1.1 のモジュールしかなくエラーで終わる」という挙動に変わり、PULLクライアントが永遠にPULLを開始できない状況になります。
さて、MinimumCompatibleVersion が 2.0 になる条件が、WMF5 で追加された Configuration の追加プロパティ、「PsDscRunAsCredentialを使う」などといったことです。通常 DSC の実行は SYSTEM アカウントですが、PsDscRunAsCredential
を使うと指定したユーザープロファイルで動作します。素晴らしいプロパティです。使いどころによっては、これまでのプロファイルを横断する方法をとらなくて済むので最高ですが、まさかこんな落とし穴が。
gist.github.com
なお、PSDesiredStateConfiguration リソースで PsDscRunAsCredential を使うと、ModuleVersion が 0.0 になり問題は回避できます。ただし、無駄に指定が必要ですが。
PSDesiredStateConfiguration のいずれかのリソースを利用している
問題は、PSDesiredStateConfiguration と、そのほかのカスタムリソースの併用で起こります。さて、先日の記事でも書きましたが、xPSDesiredStateConfiguration モジュールは、ビルトインの PSDesiredStateConfiguration モジュールの機能も移植して機能改善を高品質、高速に回そうとしています。
tech.guitarrapc.com
github.com
さて、今回の問題は PSDesiredStateConfiguraion
のリソースを使うと発生します。この中で Fileリソース
を除いて*3 xPSDesiredStateConfiguration モジュールの xリソースに置き換えが可能です。
逆にいうと、Fileリソースを利用している場合は、遭遇してしまう可能性があるということです。
Configurationをネストしている
これまでの条件をすべて満たす Configuration のネストで発生します。具体的には次のようなものです。
gist.github.com
ここまでの事例のいずれかのみを満たすだけなら問題は発生しません。
単純な Configuration
gist.github.com
PsDscRunAsCredentialの利用
gist.github.com
同一 Configuration での指定
gist.github.com
PSDesiredStateConfiguration のみの ネスト
gist.github.com
PULL モードを利用した PULL クライアントを利用している
本件は、PUSH では発生しません。PULL でのみ発生します。
一時対応 (Workaround)
問題が明確なので、一時対応も取れます。
PSDesiredStateConfiguraion を xPSDesiredStateConfiguraion で置き換える。
今後は、xPSDesiredStateConfiguraionを 使うことを検討してください。WMF5 なら、Import-Module xPSDesiredStateConfiguration
で最新版を取得可能なのでいい感じででしょう。
唯一 File リソースを使っている場合のみ次の方法をとって回避してください。
方法1. Import-DSCResource -ModuleName PSDesiredStateConfiguraion -ModuleVersion 1.1 を明示する
1つの方法は、先述したバージョンの明示です。これで mof のPSDesiredStateConfiguration バージョンが PULL クライアント (WMF5) の 1.1 と合致するので問題が回避できます。
ただし、WMF4 と WMF5 が混在する環境では、WMF4 用の Configuration と WMF5 用のConfiguration で分ける必要があるため、後方互換性が失われます。
方法2. mof document の ModuleVersion を 0.0 に書き換える
先ほど、mofに書かれた PSDesiredStateConfiguraion の ModuleVersion が 1.1と言いました。実は、この ModuleVersion を 0.0 にすると、PULLクライアントは自分が持っているリソースの最新バージョンを使おうとします。
これでいい場合は、mof 生成後にパースかけて置き換えればいいでしょう。
しかし、本来mof は人が読む、操作することを前提にしていません。何しろ mof 生成のための糖衣構文こそが PowerShell DSCですから。本質ではないのです。
方法3. PSDesiredStateConfiguration の利用では必ず PsDscRunAsCredential を利用する
PsDscRunAsCredential を使うと、PSDesiredStateConfiguration の ModuleVersion が 0.0 になるのでこれでも回避できます。
gist.github.com
方法4. ネストを避ける
なるほどありえない。
根本解決の手段
mof を触るのが一番楽です。後方互換性もあります。しかし現状のImport-DscResource
は mof で ModuleVersion 0.0 を生成する方法を持っていません。そこで、根本解決として、Import-DscResource
に [bool]AllowUseLatest
のパラメータ追加を提示しています。
これによって、Configuration から mof で利用するバージョン を 0.0 にする手段を得ることができ、柔軟性が高まる上、副作用もないはずです。
まとめ
ここまで読まれた方はまずいらっしゃらないでしょうが、これが問題の概要です。今後の Configuration の書き心地、リソースの更新の負荷に大きくかかわるため、ぜひVoteをしていただけると嬉しいです。
https://windowsserver.uservoice.com/forums/301869-powershell/suggestions/15496698-minimumcompatibleversion-cause-cannot-find-modulewindowsserver.uservoice.com
Vote が 100件行けば即対応入る可能性が高いので、ぜひ Vote していただけると嬉しいです。意見などは UserVoice に書いていただけると PowerShell Team に直で伝わります。
よろしくお願いします。
ちなみに私は、-ModuleVersion を明示しました。今後のWMF更新が鬱ですが仕方ない...。