tech.guitarrapc.cóm

Technical updates

.NET Framework を PowerShell DSC でインストール自動化

Connect での .NET Framework Core の RC に感化されたわけではないのです。が、.NET Framework 4.6.1 RC1 が先月でています。

https://blogs.msdn.com/b/dotnet/archive/2015/10/29/announcing-net-framework-4-6-1-rc.aspxblogs.msdn.com

それも受けて、.NET Framework のインストールを自動化しようと思ったのですが、公式、コミュニティともに既存の DSC リソースには.NET Framework のインストールが可能なものがないので作りました。今回はその紹介です。

目次

Github

ver.3.6.0 から入っています。

github.com

なぜ DSC でインストールを制御したいのか

.NET Framework は、.NET のインフラ基盤なのでこれを数百台にスクリプトや人力展開とか刺身たんぽぽ業は間違ってもやってはいけません。

スクリプト展開は規模が小さいならいいのですが、

  • 環境に応じてパラメータを変えて実行する
  • 実行結果が将来も適用されていることを保証する

といった、継続的にあるべき状態を維持する仕組みを作るのは面倒なのです。DSC (あるいはChef など)を使うのはそういう理由もあります。

さくっと捨てて、サクッと起動するので、1回だけ走らせればok。も事実ですが、展開状況が見やすいか、保証されているか。というのも考慮して選べばいいでしょう。

前提

GraniResource に Grani_DotNetFramework を作りました。

ので、 GraniResource をモジュールパス $env:ProgramFiles\WindowsPowerShell\Modules に配置しておきましょう。

インストール

ダウンロードからインストールまで行っています。*1

gist.github.com

パラメータを説明します。

KB

.NET Framework は、インストールされると実質KB扱いになります。またOS環境によって、同じ.NET Framework でもKBが変わるのでご注意ください。

今回作成したリソースは、OS環境を透過的に扱うため KB で判別することにしました。

KB自体は Microsoft から公開されているので見ればいいでしょう。

OS 場所 KB
Windows 8 または Windows Server 2012 [コントロール パネルの [インストールされた更新プログラムの Microsoft Windows の更新プログラム」 KB3045562
Windows 8.1 または Windows Server 2012 R2 [コントロール パネルの [インストールされた更新プログラムの Microsoft Windows の更新プログラム」 KB3045563
Ensure

インストールされていてほしいなら、Present を指定します。アンインストールされてほしいなら Absent を指定します。

InstallerPath

このリソースは、.NETFramework のオフラインインストーラを前提としています。IntallerPath に.NETFramework のオフラインインストーラのフルパスを指定します。

NoRestart

DSC には、コンフィグレーションの適用後に再起動するスイッチがあるので、その制御です。

.NET Framework 自体は、/norestartでインストールされています。

LogPath

ログの掃き出し先にどうぞ。

アンインストール

すでにインストールされていたら、アンインストールしてくれます。インストールされていなければ何も設定しません。

gist.github.com

シンプルですね。KB と Ensure さえ渡せばokです。これも実行後に再起動するかは選択してください。

インストール判定について

.NET Framework は、インストール判定にいくつかの手段が考えられます。

  1. ログの文字列解析
  2. レジストリでの判別
  3. ファイルでの判別
  4. KB での判定

今回利用したのは、KB での判定です。

ログの文字列解析

なしです。おしまい。

レジストリでの判別

これはMSDNでも推奨されています。

.NET Framework deployment guide for developers - .NET Framework | Microsoft Learn

以下のレジストリパスをみることで確認できます。

gist.github.com

が、この反映はインストール後の再起動後です。オンタイムでの確認ができない時点でありえないですね。おしまい。

.NET Framework 4.6 installed on all OS versions other than Windows 10 の場合は 393297 になっているか確認となります。

ファイルでの判別

よくあるのが、C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework や、C:\Windows\Microsoft.NET\Framework\v4.0.30319 ですがなしですね。

バージョン判定まではここでは確定できません。おしまい。

KB での判定

.NET Framework が KB 扱いであることを利用するのが一番素直でしょう。

再起動なしにオンラインで確認できるので、テストも容易です。今回のリソースは、そのKBを判定することを前提にしています。

幸いにも、インストーラーによるプロセスの Exit Code 判定も公開されているので容易です。

.NET Framework のアンインストールは KB のアンインストール。ここを .NET でやるのはちょっとつらさがあるので、wusa.exe の利用が一番素直かなと。

ここまで考えると、実装と、確実性とコストパフォーマンスを考えると KBが一番いいと判断しています。

.NET 4.6 のアドバイサリについて

.NET 4.6 では 末尾最適化に関して RyuJIT でバグがあり報告されています。一応触れておきましょう。

概要

特定の状況で発生しうる、RyuJIT の末尾最適化に関するバグがあったよということです。

https://blogs.msdn.com/b/dotnet/archive/2015/07/28/ryujit-bug-advisory-in-the-net-framework-4-6.aspxblogs.msdn.com

nickcraver.com

これに関しては KB が発行されているのでいれればok です。

[MS15-092] .NET Framework の脆弱性により、特権が昇格される (2015 年 8 月 11 日)

また、4.6.1 RC1 では当該問題は発生しません。

KBを入れればい環境やその他RyuJIT起因の問題かの切り分け

アドバイサリーにあるようにRyuJIT 無効化と末尾最適化の無効化で状況を切りわければいいのです。

  • If you run into an issue that you cannot diagnose, try disabling RyuJIT. (再現するか調査できない環境なら RyuJIT 無効化)
  • If disabling RyuJIT resolves the issue, please re-enable RyuJIT and disable tail call optimization.(RyuJIT 無効化で当該問題がでないなら、RyuJIT有効かして 末尾最適化を無効化)
  • If your issue is mitigated with the tail call optimization disabled, then you know that your app is subject to this issue. You can run your app in production in that configuration (tail call optimization disabled), to get the other .NET Framework 4.6 benefits. This work around will disable only the tail call optimization feature and should not negatively impact performance.(もし末尾最適化無効化で問題がでなくなったなら該当していることがわかります。プロダクションでも RyuJIT有効、末尾最適化無効で走らせることができるでしょう。4.6の他のメリットを享受できるし、悪い影響は他には基本的にはないはずです。)
  • If your issue is not mitigated with the tail call optimization disabled, but is mitigated with RyuJIT disabled, we want to hear from you on .NET Framework Connect. You can also run your app in production in this configuration (RyuJIT disabled).(末尾最適化無効でも問題があって、RyuJIT無効で問題でないなら .NET Framework Connect で報告がほしいです。プロダクションでも RyuJIT 無効で実行できます。)
  • If your issue is not mitigated by disabling RyuJIT or tail call optimization, then it something else and unrelated to this advisory.(RyuJIT 無効化でも末尾最適化無効でも問題が改善しない場合、このアドバイサリとは別問題の可能性があります。)
それぞれの無効化方法

KBを入れれば関係ありませんが、それ以外で RyuJIT などで問題が起こったときのために使うかもしれません。

すでに公開されています。

まとめ

刺身タンポポだめ絶対

*1:ここではRyuJIT の末尾最適化に関する KB のインストールを含んでいません