しばたテックブログ

気分で書いている技術ブログです。

PowerShellの起動時に表示されるプロファイルに関するメッセージについて

小ネタです。

Windows 10などでPowerShellの起動時に以下の様なメッセージが表示され、プロファイルの読み込みにかかった時間が表示される場合があります。

パーソナル プロファイルとシステム プロファイルの読み込みにかかった時間は xxx ミリ秒です。
(英文だと Loading personal and system profiles took xxx ms.)

表示例)

f:id:stknohg:20170313184238p:plain

本エントリではこのメッセージがどういった場合に表示されるのかについて説明します。

このメッセージの実体について

残念ながらこのメッセージについてのドキュメントはない様です。

仕方ないのでソースファイルを検索して情報を探します。

細かい手順は省いて結果だけ説明すると、このメッセージはConsoleHostクラス(ConsoleHost.cs)のDoRunspaceInitializationメソッドで呼ばれて表示されています。

ソース中で該当する箇所はこちらとなり、その内容を以下に転記します。

// ConsoleHost.DoRunspaceInitialization() メソッドより転記

// Run the profiles.
// Profiles are run in the following order:
// 1. host independent profile meant for all users
// 2. host specific profile meant for all users
// 3. host independent profile of the current user
// 4. host specific profile  of the current user

var sw = new Stopwatch();
sw.Start();
RunProfile(allUsersProfile, exec);
RunProfile(allUsersHostSpecificProfile, exec);
RunProfile(currentUserProfile, exec);
RunProfile(currentUserHostSpecificProfile, exec);
sw.Stop();

var profileLoadTimeInMs = sw.ElapsedMilliseconds;
if (profileLoadTimeInMs > 500 && s_cpp.ShowBanner)
{
    Console.Error.WriteLine(ConsoleHostStrings.SlowProfileLoadingMessage, profileLoadTimeInMs);
}

見ての通り、PowerShellの起動時に呼ばれる4つのプロファイル(AllUsersAllHostsAllUsersCurrentHostCurrentUserAllHostsCurrentUserCurrentHost)が実行されるのにかかる時間を計測し、その時間が500msを超える場合にメッセージが表示されることがわかります。

このメッセージを表示させない様にするにはPowerShellを起動する際に-NoLogoを指定するしかない様です。
ユーザーがこの設定に介入する余地はありませんが、このメッセージが出るのはプロファイルの呼び出しに時間がかかっているのが根本的な問題ですので、プロファイルで呼ばれる処理を見直すことで対処するのが筋だと思います。

また、このメッセージはPowerShell 5.1から導入されており、以前のバージョンで表示されることはありません。

まとめ

とりあえずこんな感じです。

このメッセージが導入された経緯は正確にはわかりませんが、おそらく、起動が遅いと散々言われているPowerShellの起動時間を改善していくなかで、PowerShellそのものに起因する部分とユーザーの設定(プロファイルの設定)に起因する部分を切り分けたいという意図があるのではないかと思われます。

もしこのメッセージが出てPowerShellの起動が遅いと感じる様でしたら各プロファイルで呼ばれている処理を見直すことで改善できますのでぜひ試してみてください。

AppImage版のPowerShellが提供されました

PowerShell on Linuxの話です。

先日リリースされた PowerShell 6.0.0.Alpha17 からAppImageの実行バイナリが提供されました。

AppImageについて

公式サイトは以下。

appimage.org

かつてklikPortableLinuxAppsと呼ばれていたプロジェクトで、ディストリビューションを問わずに実行可能な単一のバイナリファイル(*.AppImage)でアプリケーションを提供するための仕組みだそうです。

このツールで作られた*.AppImageなバイナリファイルはダウンロードしてファイルに実行権限を付けるだけでアプリケーションが利用可能になります。

正直まだよくわかっていないのですが、仕組みを調べてみた結果、AppImageではアプリケーションの実行バイナリと依存モジュール一式を一つの*.AppImageなファイルにまとめ、この*.AppImageなファイルの実行時にFUSEを使って仮想ファイルシステムに依存パッケージごと展開して(サンドボックス的な環境を作ってるっぽい?)実行バイナリを起動している様です。

このためディストリビューションを選ばないと言うものの、実行環境にFUSEがインストールされている必要があります。

インストール方法

公式な手順はこちら

今回は例としてCentOS 7.3での方法を紹介します。
他のディストリビューションでも基本的な流れは変わらないはずです。

1. FUSEのインストール

先ほど述べた通りAppImageのバイナリを実行するためにはFUSEがインストールされている必要があります。

今回の検証環境にFUSEはインストールされていなかったのでYum(EPELリポジトリ)からインストールします。

FUSEが利用可能な環境ではこの手順は不要です。

# bash
# FUSEのインストール
sudo yum install -y epel-release
sudo yum install -y --enablerepo=epel fuse-sshfs

2. AppImageのインストールと実行

FUSEをインストールした後はAppImageのバイナリ(PowerShell-x86_64.AppImage)をダウンロードして実行権限をつけるだけでOKです。

# bash
# バイナリのダウンロードと実行権限の付与
curl -OL https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.17/PowerShell-x86_64.AppImage
chmod a+x ./PowerShell-x86_64.AppImage

# 実行
./PowerShell-x86_64.AppImage

実行した結果は以下の様になり、PowerShellの起動前に/tmp/に対して仮想ファイルシステムの展開がなされているのがわかります。

f:id:stknohg:20170311145017p:plain

あとは普通にPowerShellを利用することができます。

注意点

あまり影響はないと思いますが1点だけ気を付けておいた方がよさそうな点があります。

AppImageの仕組み上、実際の実行ファイル(powershell)は/tmp/.mount_[ランダム文字列]/usr/binに展開されます。
このためPowerShellを実行するたびに$PSHOMEのディレクトリが変わります。

f:id:stknohg:20170311145550p:plain

試してはいませんが都度$PSHOMEが変わってしまう以上PSRemotingのサーバー側になることはできないでしょう。
PowerShellのクライアント側の機能しか使えないと思われます。

また、/tmp/.mount_[ランダム文字列]配下はReadOnlyになります。
このため$PSHOMEにファイルを置くことができずAllUsers*なプロファイルを作ることができません。

最後に

若干制限はありますが、環境によっては一番気軽にPowerShellを実行できる方法かもしれません。

個人的にはテスト用の一時的な環境を作るのに向ていると感じています。

PowerShell on Linuxに普通にPSRemotingしてみる - その3

その1その2の続き的な。

以前のエントリで書いた、

github.com

のIssueがクローズされ、OMIおよびPowerShell on Linux OMI Providerpackages.microsoft.comリポジトリからインストール可能になったので試してみました。

インストール

私が使い慣れているCentOS 7.3で検証します。

はじめにpackages.microsoft.comリポジトリの追加とPowerShellのインストールをしておきます。

# CentOS 7, Bash
curl https://packages.microsoft.com/config/rhel/7/prod.repo | sudo tee /etc/yum.repos.d/microsoft.repo
sudo yum install -y powershell

こちらは以前のエントリで書いた通りですのでとくに問題はないでしょう。

続けてPowerShell on Linux OMI Providerをインストールします。

パッケージ名はomi-psrp-serverで、依存パッケージにOMI(omi)が登録されているので、こちらをインストールすればOMIも同時にインストールされます。
ですので以下の様にyum install一回でインストールできます。

# CentOS 7, Bash
sudo yum install -y omi-psrp-server

実行結果は以下の様な感じになります。

f:id:stknohg:20170309185812p:plain

インストールが完了したあとはOMIDが動いてればOKです。

OMIDが起動しているかはservice(またはsystemctl status)コマンドで確認してください。

# OMIDが動作しているのを確認
service omid status
# または
# systemctl status omid.service

f:id:stknohg:20170309190015p:plain

ちなみに、現時点の各パッケージのバージョンは、

  • PowerShell - Ver.6.0.0.alpha16
  • PowerShell on Linux OMI Provider - Ver.1.1.0-alpha18 (1.0.0.18)
  • OMI - Ver.1.2.0

となっています。

接続確認

例によってWindows Server 2012 R2(PowerShell 5.1)から接続確認をしてみます。
接続先のIPは192.168.33.209、ユーザーはvagrantおよびrootで試しています。

# Enter-PSSessionで接続
$o = New-PSSessionOption -SkipCACheck -SkipRevocationCheck -SkipCNCheck
Enter-PSSession -ComputerName 192.168.33.209 -Credential vagrant -Authentication basic -UseSSL -SessionOption $o

f:id:stknohg:20170309183812p:plain

普通に使えますが、切断時に謎なエラーが出ました...

f:id:stknohg:20170309183837p:plain

とりあえずこいつは気にしないことにして、CIM情報の取得をします。

# Get-CimInstanceで情報取得
# こっちは要root
$o = New-CimSessionOption -SkipCACheck -SkipRevocationCheck -SkipCNCheck -UseSsl
$s = New-CimSession -ComputerName 192.168.33.209 -Credential root -Authentication Basic -SessionOption $o
Get-CimInstance -CimSession $s -Namespace root/omi -ClassName OMI_Identify

f:id:stknohg:20170309183853p:plain

こちらもこれまで試した結果と同じです。

最後に

とりあえずこんな感じです。

各パッケージのインストールがかなり楽になったのであとは動作が安定してくれれば使い物になるのかな、と思います。