ServerCore のログオンシェルを変える


WindowsServer 2008 より導入された ServerCore ではサービスの実行に直接関係のないコンポーネントをあえてインストールしないことでディスク容量の削減と余計なパッチ適用の回避を実現しています。ServerCore でインストールされた Windows にコンソールから、あるいは RDP 経由でログオンするといつものエクスプローラではなく簡素なコマンドプロンプトウィンドウだけが表示され、各種コマンドや sconfig によるメニューによるキャラクタベースでの管理となります。

 このとき、コマンドプロンプトウィンドウで動作するシェルはいつもながらの CMD.EXE です。

PowerShell を使いたい場合、C>のプロンプトに powershell.exe を入力、PowerShellを起動してからようやく使用可能になります。このような迂遠な操作を避け、ちょくせつ PowerShell が動いていてほしいものです。
デスクトップエクスペリエンスの入った Windows ならこれは簡単です。チェックボックス一つで PowerShell をデフォルトのシェルにすることができます。


では、ServerCore ではどうすればいいでしょう。それを探ってみました。

Windows Server 2008 R2 の場合(全ユーザ)

Windows Server 2008 R2 では、以下のレジストリでログオン時に起動するシェルが決定されます。

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon

ここの「Shell」という値に、シェルとなるプログラムの実行ファイル名が記入されています。
デスクトップエクスペリエンスの入った普通の Windows では、ここには explorer.exe と記載されております。

では、WindowsServer 2008 R2 での ServerCore ではどうでしょう?

このように、Shell には以下の値が記載されています。

cmd.exe /c "cd /d %USERPROFILE% & start cmd.exe /k runonce.exe /AlternateShellStartup"

ちょっとややこしいですが、こういう事です。

  • 最初のcmd.exe が続くコマンドを実行、この cmd.exe 事態は (/k オプション)
  • 続くコマンドの中で %USERPROFILE% カレントディレクトリを変更、2段目 cmd.exe を起動する。
  • cmd.exe /k オプションにより、その cmd.exe の中で runonce.exe /AlternateShellstartup オプション付きで起動

runonce.exe はレジストリなどに記載された RunOnce、つまり一度は起動しなければならないプログラムを実行するコマンドです。

ServerCore で上がってくる cmd.exe はこの指定によって起動されています。この Shell の値を書き換えることで、cmd.exe 以外のコマンドを起動させることが可能になるわけです。

変更の前に、まず保存しておこう

Shellの値を書き換える前に、後で戻せるよう現在の設定をエクスポートして残しておくといいでしょう。
レジストリのエクスポートは regedit からもできますが、reg コマンドでもできます。




PowerShell を有効にしておく

エクスポートが済んだら、PowerShell をログオンシェルにしてみます。
ところで、
PowerShell は有効になってますか? WindowsServer 2008 R2 ServerCore ではデフォルトでは PowerShell はインストールされてません。(なんてこったい)

powershell とコマンドプロンプトに打って実行してみて、エラーになっていたら sconfig PowerShell をインストールしておきましょう。「4. リモート管理の構成」の、「2. WindowsPowerShell を有効にする」がそれです。

レジストリの書き換えと動作確認

powershell.exe が使えるようになったら、先ほどのレジストリのShell の値を「powershell.exe」に書きかえます。

動作確認にはRDPか何かを使ってもう一セッション立ち上げるか、あるいは単純に現在のセッションをログオフして、ログインしなおしてみます。
プロンプトが変わったことで、
PowerShell が動作しているのが分かります。

ただし、このままですとカレントディレクトリが \Windows\System32 になってしまってます。
気になる場合は、先ほどの Shell の値を「cmd.exe /c "cd %USERPROFILE% & powershell.exe"」にしておくと、ホームディレクトリがカレントディレクトリになります。

Windows Server 2008 R2 の場合(個別ユーザ)

レジストリの Winlogon にある Shell を書き換えた場合、全てのユーザのログインシェルが PowerShell になります。それはとても素晴らしいことだと思うのですが、中にはそれをのぞまない管理者の方もいらっしゃるかもしれません。
ログオンシェルをユーザごと個別に指定したい場合は、HKLMの下ではなく、HKCU の下のレジストリを操作することでそれぞれで設定できます。

まずは、シェルを変えたいユーザでログオンします。そして以下のレジストリキーに対して、「Shell」の値を追加します。

HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon


標準状態では、「Shell」がありませんので、新規の文字列値を作成、名前を「Shell」、値として「powershell.exe」を指定します。
その後、ログオフ、ログオンをし直すと、このユーザでログオンした場合のみ PowerShell がログオンシェルになっております。

Windows Server 2012 R2 の場合(全ユーザ)

 Windows Server 2012 の場合は、ちょっと事情が変わってきます。Windows Server 2008 R2の時と同じ Winlogon Shell の値を見ると、ServerCore でインストールされているにもかかわらず、GUI 月の場合と同じ「explorer.exe」が記載されています。


一方、AlternateShells\AvailableShells というサブキーができており、こちらに cmd.exe の記述があります。

これはどういうことでしょう?

柔軟になったシェルの指定

Windows Server 2012 R2 では、シェルの選択方法が段階的になりました。
まずはこれまでの Windows と同じく、Winlogon の Shell をみて、この値のシェルを立ち上げようとします。
しかし
Shell に設定されたシェルが存在しない場合、サブキーである AvailableShells で指定されたシェルから、実際に存在するもので名前として設定された数値の最も大きいものが選ばれます。
デフォルトで
20000 の数値で cmd.exe が指定されていますので、20000 より大きい数値を名前として指定すると cmd.exe より優先できるわけです。

2008 R2 の時と同じく Shell の値を書き換えても目的は達成しますが、AvailableShells 40000ぐらいの数値で「cmd.exe /c "cd /d "%USERPROFILE%" & start powershell.exe」とでも設定してあげる方が、2012 R2 的でよろしいでしょう。

レジストリの書き換え

設定をするにあたって一つ注意点があります。実は AvailableShells は所有者が TrustedInstaller で、かつデフォルトで読み取りのみのアクセス許可になっているため、そのままでは Administrator でも書き換えができないのです。
まず所有権を取得し、フルコントロールを設定する必要があります。 

regedit での場合、AvailableShells で右クリック、「アクセス権」を選択、「詳細設定」ボタンを押します。 

  

表示されたパネルの上、「所有者」の右側にある「変更」のリンクをクリック、所有者を TrustedInstaller から Administrator にしてしまいます。

 
所有者を変えてしまえば、あとは「アクセス権」で Administrator でフルコントロールにチェックを入れて書き込みできるようにして、AvailableShells に「文字列値」を設定、名前を40000、値を powershell.exe にするだけです。

  

 なお、言うまでもないことですが、Windows Server 2012 R2 では標準で PowerShell が有効になっています。(やったぜ)

Windows Server 2012 R2 の場合(個別ユーザ)

 2008R2 の時と同じく、「HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon」に Shell を新規作成、シェルとなるコマンドを書き込んでおくことでユーザごと個別にログオンシェルを変えることができます。
こちらは各ユーザのレジストリなので書き換えに当たって権限の変更などは必要ありません。

【参考】Windows Server 2016 TP3 の場合

現在提供されている Windows Server 2016 Tech Preview 3 Windows Server 2012 R2 と同じです。
2008譲りの Winlogon の直接書き換えも可能で、また AvaiableShells に定義を追加することで優先順位づけたログオンシェルの選択も可能です。AvailableShells TrustedInstaller の所有権であるのも同じなので、その点はお気をつけください。HKCUでの個別ユーザのログオンシェルの指定もまた可能です。

仮想化基盤やクラウドで動作する仮想マシンは増大の一方で、今後、ディスクの利用効率は重要になってきます。ディスク容量は有限ですし、クラウドの場合、占有するディスク容量がコストに跳ね返ってきます。
ServerCore や、Windows Server 2016 の NanoServer といった、軽量化されたインストール方式も今後より使われていくでしょう。そのようなときでも管理者の強い味方である PowerShell はあなたのすぐそばに居られる訳です。

【補足】AvailableShells の所有者を TrustedInstaller に戻す

先の手順で、AvailableShells の所有者を一時的に Administrator なりに変更することでアクセス権を書き換えれるようにしました。そのままではやはり心地よくないので TrustedInstaller に所有者を戻したいと思うことでしょう。
ところが、単に「TrustedInstaller」と指定しても、そんなプリンシパルは存在しないとエラーになってしまいます。

TrustedInstaller に戻すには「NT Service\TrustedInstaller」という指定をしてください。( NT と Service の間は空白がひとつ入ります。)

これで、元通りに戻すことができます。


Comments (0)

Skip to main content