PowerShell セッションで作業している間、その状態(または環境)をさまざまな方法で変更することができます。 モジュールのインポート、関数の作成、エイリアスの指定、変数の定義など、さまざまな方法でその状態 (または環境) を変更することができます。 しかし、これらはすべて一過性のものであり、PowerShellセッションを閉じるとすぐにその効果は消えてしまいます。 しかし、PowerShellにはPowerShellプロファイルと呼ばれる仕組みがあり、新しいPowerShellセッションを起動するたびに、そのような環境構成や設定を再作成することができるようになっています。 そして、プロファイルは1つで良いなら、もっとあった方が良いのでは? 1つのPowerShellセッションで4つの異なるプロファイルのいずれか(またはすべて)を使用することができ、異なるPowerShellホストではさらに多くのプロファイルを選択できることが判明しています。 しかし、すべての可動部品がどこに配置されているかを理解すれば、見た目よりもずっとシンプルに使用することができます。
PowerShell のシェル
PowerShell では、シェルとホストを区別しています。 Don Jones 氏は、The Shell vs. The Host という適切なタイトルの投稿で、キーボードで入力するユーザーであるあなたは、PowerShell のシェル (またはエンジン) と直接対話することはないと説明しています。 正確には、ランスペース (PowerShell エンジンのインスタンス) を作成するホストアプリケーション (powershell.exe や powershell_ise.exe など) と対話するのです。 この違いは、$Host
システム変数のNameプロパティの内容を$ShellId
変数と一緒に表示することで実際に確認することができます。 最も一般的な 3 つの PowerShell ホストの値を調べると、それぞれが異なるユーザー インターフェイス (ホスト) を提示しながらも、すべて同じエンジン (シェル) を使用していることがわかります。Name
Microsoft.PowerShell
他の PowerShell ホストは異なる $ShellId
値を持つ可能性があります(たとえば、自由に使用できる PowerShell IDE には、PowerGUI、PowerShell Analyzer、PowerShell Plus などがありますが、それらの $ShellId
値は確認したことがありません)。
The PowerShell Profile
PowerShell プロファイルは、PowerShell ホストの起動時に実行されるスクリプトの仮の名前に過ぎません。 PowerShell の標準ヘルプの about_profiles を引用すると、「プロファイルをログオン スクリプトとして使用して、環境をカスタマイズすることができます。 コマンド、エイリアス、関数、変数、スナップイン、モジュール、Windows PowerShellドライブを追加することができます。 また、他のセッション固有の要素をプロファイルに追加して、インポートまたは再作成することなく、すべてのセッションで利用できるようにすることもできます」
各 PowerShell ホストは実際には 2 つのプロファイルをサポートしています。1つはユーザー レベルで、各ユーザーごとに異なり、もう 1つはシステム レベルですべてのユーザーに対して共通となります。 これは、多くの Windows アプリケーションで見られる、馴染みのあるパラダイムであるはずです。 PowerShellは、同様にホストレベル(各ホストに1つのプロファイル)とシステムレベル(すべてのホストに1つの共通プロファイル)を区別しています。
したがって、ユーザーとホストのすべての組み合わせを考慮すると、4 つの異なるプロファイルのいずれか (またはすべて) を使用する可能性があります。
- AllUsersAllHosts
- AllUsersCurrentHost
- CurrentUserAllHosts
- CurrentUserCurrentHost
これらのプロファイルは平和に共存しているので、優先順位に注意する必要があります – 実行順に上にリストアップされています。 4 つのプロファイルすべてに同じ変数を定義した場合、PowerShell ホストを起動し、最後にプロンプトが表示されると、変数は最後のプロファイル CurrentUserCurrentHost
によって割り当てられた値になるため、後続の各プロファイルはその値を上書きします。 別の例として、プロファイル間の競合ではなく、協力関係を示す、変数のインクリメントがあります。 まず AllUsersAllHosts
で定義し、初期値 (たとえば $someVar
= 0) を設定し、次に他のプロファイル (たとえば $someVar++
または $someVar += 5
) のそれぞれで値を増やします。 複数のホストを使用する場合、”all hosts” プロファイルと特定のホストプロファイルを区別する必要があるかもしれません。 これについては、「プロファイルはいくつ必要ですか」
$Profile 変数
プロファイルを作成または編集するには、もちろん、プロファイルがどこにあるのかを知る必要があります。 PowerShell 自体が簡単に教えてくれますが、パスを明示的に気にすることなく、編集のために 1 つを開くこともできます。 パスを確認するには、$Profile
変数の値を表示します。 これは、CurrentUserCurrentHost
プロファイルへのパスです。 標準的な PowerShell ホストでは、私のは次のように表示されます:
1
2
|
PS> $Profile
C:\Usersmsorens╱ WindowsPowerShellⒸMicrosoft.PowerShell_profile.ps1
|
Note that this makes no claim about the file exists, only that is the path it must have if it exists.This is no claim about the path of the file exists. 存在を確認するには、Test-Path
を使用する。
1
2
|
PS> Test-Path $Profile
True
|
もしそのファイルが存在しないなら…そのプロファイルが存在するかどうかを確認します。 をクリックすると、簡単に作成できます。
1
|
PS> New-Item -Type file -Path $Profile -Force
|
またスクリプトで持つ場合、上記の方法を組み合わせ、必要に応じてのみファイルを作成すればよいのです。
1
2
|
PS> if (!(Test-Path $Profile)) {
New-Item -Type file -Path $Profile -Force }.
|
最後に、プロファイルを編集するには、ファイル上でお気に入りのエディタを起動するか、いつもどこにでもあるメモ帳エディタを使用します。
1
|
PS> notepad $Profile
|
上の例のすべては、前述の “default” (CurrentUserCurrentHost
) profile 向けのものです。 しかし、同じコマンドのすべてを、特定の参照によって 4 つのプロファイルのいずれにも適用できます。これらのいずれでも同じ結果が得られます:
1
2
|
PS> メモ帳 $Profile
PS> メモ帳 $Profile.CurrentUserCurrentHost
|
デフォルト以外のプロファイルのいずれかにアクセスするには、他の 3 つのプロファイル プロパティ名のいずれかを代用します。
特定の Microsoft ツール (例: notepad) ではそれが可能ですが、特定の非 Microsoft ツール (例: 私のお気に入りのエディター vim) ではできません。 不思議なことに、vim は私のために動くように見せかけて、実は動かなかったのです。 ファイルを作成し、エディタを完全に閉じ、再びエディタを開いてファイルを呼び出すことができましたが、そのファイルはWindows Explorerに表示されず、起動時にPowerShellで見ることもできませんでした! (この問題の根本的な原因はよく分かりませんが、昇格権限の欠如が原因ではありません)。
一方、メモ帳はどうやら秘密の呪文を知っているようで、期待どおりに動作します。 もうひとつの回避策は、自分のユーザーディレクトリに「すべてのユーザー」プロファイルを作成し、それを適切なシステムディレクトリにコピーまたは移動することです。
Profile File Names & Locations
前のセクションでは、プロファイルがファイルシステム上のどこにあるかを実際に知らずに編集する方法を説明しましたが、あなたは開発者なので、それらがどこに隠れているかを知る生来の衝動があるはずです! 表はそれぞれのパスを示しています。 ( HostId はプレースホルダーです。少し説明します。)
Profile | Location | |
AllUsersAllHosts | $PsHomeprofile.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXps1 | |
AllUsersCurrentHost | $PsHomeHostId_profile.AllUsersCurrentHosts | $PsHomeId_profile.ps1 |
CurrentUserAllHosts | $HomeDocuments | |
CurrentUserCurrentHost | $HomeDocuments | |
全ユーザー | 全ホスト.ps1 |
Web で入手できる多くの記事で目にしたエラーは、「すべてのユーザー」プロファイルが $env:WinDir\System32
以下にあるということでした。 これは誤りです! $PsHome
は、いくつかのホストでは偶然にも $env:WinDir\System32
に解決されるかもしれませんが、すべてのホストでは解決されないかもしれません。 たとえば、私のシステムでは、Visual Studio パッケージ マネージャ コンソールは、「すべてのユーザー」プロファイルを $env:WinDir\SysWOW64
の下に保存します。 (このエラーは、この MSDN 記事のような非常に評判の良いソースの記事でも表示されます。)
位置を確認すると、命名規則を理解するのは簡単です。 システム レベルのプロファイル (すべてのユーザーのためのもの) は、$PsHome
で示されるシステム ディレクトリにあります。 ユーザレベルのプロファイルは、各ユーザのホームディレクトリにあります。 説明が必要なのは、表の中でホスト固有のプロファイルに示されているHostId
という点である。 残念ながら、このホスト ID はホストの説明とも $Host.Name
プロパティとも直接的には一致しない! HostId
を発見する方法は、単にパスの一部である $Profile
変数の値を表示することです。 便宜上、最も一般的なホストの HostId
の値を以下に示します:
Host | HostId | $Host.Host | $Host.Name | |
PowerShell | Microsoft.PowerShell | ConsoleHost | ||
PowerShell ISE | Microsoft.PowerShell | Microsoft.PowerShell | PowerShell ISE | Windows PowerShell ISE Host |
Visual Studio Package Manager Console | NuGet |
別のエラーも野放しになっている状態ですね。 あまり一般的ではありませんが、HostId
は先に述べた$ShellId
変数と同等であるとされています。 これは間違っています。 ご覧のように、上に示した 3 つの一般的なホストはすべて同じ $ShellId
を持っており、偶然にも標準の PowerShell ホストの HostId
にのみ一致します。 (このエラーは、たとえば、書籍 Windows PowerShell Unleashed に記載されています。)
How Many Profiles Do You Need? ここに示した VS パッケージ マネージャーを加えると、さらに 2 つになります。 他のPowerShell IDEを追加すると、それぞれ2つずつ追加されます。 これだけの数のプロファイルをどのように管理するのですか。
公式の MSDN 教義 ( about_profiles ) を解釈すると、三者構成のソリューションが考えられます。
- 最初に、本当に共通のものを
AllUsersAllHost
に入れます。 - 次に、特定のホストに特殊性がある場合、その不届きなホストには
AllUsersCurrentHost
を使用します。 - 最後に、各ユーザーはユーザー固有のプロファイルで自分の好みや設定を管理できるようにする。
しかし、繰り返しになりますが、システム レベルとユーザー レベルの両方で、「現在のホスト」に対して多くの異なるプロファイルが存在する可能性があります。 ここで選択について熟考しているときに、1 つの良い参考文献として、Ed Wilson (The Scripting Guy) の投稿「Deciding Between One or Multiple PowerShell Profiles」があります。 この記事には、1つのプロファイルと複数のプロファイルを選択した場合のメリットとデメリットが記載されています。 しかし、私にとっては、単一のプロファイルの利点は、複数のプロファイルの利点をはるかに上回ります。 セットアップに少し手間がかかりますが、ホストごとの違いを考慮しつつ、すべてを1つの場所にまとめることができ、長期的なメンテナンスがずっと簡単になります。
プロファイルの内容のほとんどは、おそらくどのホストでも共通なので、単一のプロファイルを使用することは、将来的なあらゆる変更が正確に 1 つのファイルで行われることを意味します。 ホスト間で異なるものについては、気になる各ホスト固有のセクションを含めます。 私のは以下のような内容です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
if ($Host.Layer.Layer) {4848>
11
12
{4848>11 11
{4849>11 11
{
Import-Module PSReadline
# verbose と warnings を区別してください!
$privData = (Get-Host).PrivateData
$privData.VerboseForegroundColor = “cyan”
}
elseif ($Host.Name -like ‘*ISE Host’)
{
Start-Steroids
Import-Module PsIseProjectExplorer
}
if (!$env:github_shell)
{
# なぜかわかりませんが、これは git-flavored ホストで失敗します
Add-PSSnapin Microsoft.TeamFoundation.PowerShell
}
|
$Host.Name
で現在のホストを識別してから選択的にコードを実行していることに注目しましょう。 上記の例は、標準の PowerShell ホストと PowerShell ISE ホストについてです。 前者では、PowerShell ホストでのみ機能する PSReadline 拡張をロードしています。 後者では、PsISEProjectExplorer と ISE Steroids モジュールがロードされますが、これらはいずれも ISE 環境でのみ機能します。
最後に、Git を使用していて、使用した特定のインストーラーが Git PowerShell ホストを作成した場合、$Host.Name
によって標準の PowerShell ホストと区別することができないことに注意してください。 その代わりに、Git-flavored ホストにのみ存在する、独自に定義された変数 $env:github_shell
を識別しました。
What to Put in your Profile
この質問への答えは、個々のニーズに依存するので、非常に抽象的でなければなりません: より生産的になるために使えるものをプロファイルに入れましょう。 したがって、これに対する唯一の答えはありませんが、あなたの創造力を引き出すために、いくつかの提案を提供することは可能です。 以上、サードパーティモジュールをインポートして、与えられたホストに機能を追加する例をいくつか見てきました。 モジュールのインポート以外にも、以下のセクションでは、何を入れたらいいか考えるためのほんの少しのアイデアを提供しています。 また、What’s in your PowerShell `profile.ps1` file? (on StackOverflow) を参照してください。
エイリアス
Many built-in PowerShell cmdlets has aliases; some has multiple aliases. たとえば、Get-ChildItem
と入力する代わりに、ls
または dir
または gci
を使用することができます。 エイリアスを提供していないコマンドレット (または独自のカスタム関数やコマンドレット) を定期的に使用する場合、Set-Alias
を使用して独自のエイリアスを作成できます。 Set-Alias
は、コマンドレットや関数の名前を省略したい場合に適しています。 しかし、例えば、コマンドレット名と常に使用する傾向があるパラメーターを含めたエイリアスを作成したい場合があります。 このような場合、単純な関数でエイリアスをエミュレートすることができます。 例として、コマンドレット Import-Module
を考えてみましょう。 私はこれを頻繁に使用しますが、頻繁に使用するすべてのコマンドレットは、各コンポーネントの最初の文字を使用するだけでよいと思っています。 これは、そのためにエイリアス im
を設定します。
1
|
Set-Alias im Import-Module
|
しかし開発者として、私は -Force
スイッチで Import-Module
も頻繁に使用しなければなりません。 だから、そのためには関数に頼る必要がある。 私の命名規則では、スイッチの最初の文字を追加しているので、ここでは imf
です:
1
|
function imf($name) { Import-Module $name -force }.
|
それから、たとえば、im foobar
を使ってそのままインポートしたり、imf foobar
を使って -Force
を適用してインポートできます。
簡易関数
関数は疑似エイラースを作成する、つまり、本質的にタイピングを減らす手段として言及されています。 しかし、もちろん、その目的に限定されるものではありません。 入力の手間を省き、あまり使用しないコマンドレットの詳細を覚えておく必要がないような、さまざまな「ワンライナー」をプロファイルに含めるとよいかもしれません。 コマンド履歴の最後の50項目を表示するにはどうしたらいいですか? よくわからない? 使用するコマンドレットは Get-History
です (標準では h という文字だけのエイリアスがあります)。 Get-History -Count 50
や h50 だけなら覚えやすいですか? 以下は、私の h50 の定義です (念のため h10 も入れています):
1
2
|
function h50 { Get-History -Count 50 } 。
function h10 { Get-History -Count 10 }.
|
ここで、もっと面白い関数を紹介します。 エイリアスの背後にあるコマンドレット、プログラム名から実行ファイルへのパス、指定されたコマンドレットで使用可能なパラメーター セット、またはユーザー定義関数のコンテンツをどのように明らかにするのでしょうか。 私はこのワンライナーを使って、これらすべてを行います (同様の機能を持つ unix/linux コマンドにちなんで命名しました):
1
|
function which($cmd) { (Get-Command $cmd).Definition }.
|
以下、使ってみた結果です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
PS> which h
PS> どのメモ帳
C:\Windowssystem32 notepad.exe
PS> which
param($cmd)
(Get-Command $cmd)です。定義
PS> which import-module
Import-Module <string> <string> -。PSSession <PSSession>
Import-Module <string> -CimSession <CimSession>
|
やっとこ。 もう一つの便利なワンライナーで、これもまたUNIX/Linuxコマンドのように動作し、ドメイン修飾されたユーザー名を報告します。
1
|
function whoami { (get-content env:\userdomain) + “\” + (get-content env:\username }; (取得内容) + (取得内容) + (取得者) – (取得者) – (取得者) – (取得者) – (取得者)
|
複雑な関数
仕事の過程で、単純なワンライナーよりはるかに複雑なユーティリティ関数を作成することがあると思われます。 もちろん、それらをプロファイルに埋め込むこともできますが、そうするとプロファイルが長くなり、ごちゃごちゃになりがちです。 そのような関数のコレクションがある場合、それらを真のPowerShellモジュールに整理して、プロファイルにImport-Module
を追加するだけで、それらを取り込むことができるようになります。 この2つの極端な方法の中間の方法として、次の方法を考えてみてください。 私のプロファイルでは、起動時にローカルの profile_scripts ディレクトリにあるすべてのスクリプトをスコープに含めるために、次のコマンドを実行しています:
1
2
3
|
Resolve-Path $PSScriptRoot Filterprofile_scripts*.ps1 |
Where-Object { -not ($_.ProviderPath.Contains(“.Tests.”))) } |
Foreach-Object { . $_.ProviderPath }.
|
$PSScriptRoot
は、実行中のスクリプトのコンテキスト内にのみ存在する標準システム変数です。 これは $Home
DocumentsWindowsPowerShell に解決されます。 したがって、私の profile_scripts ディレクトリはこのパスの下にあります。 すべてのスクリプト (テスト スクリプトを除く) はドット ソース化され、起動後にプロンプトが表示されるとすぐに現在のスコープで表示されます。
アクションの実行
このセクションの前の項目はすべて受動的です。 しかし、起動中に実行されるアクティブな項目を含めることもできます。 4668>
1
|
Set-PSDebug -Strict
|
弱型言語 (e.k.a.>
は、rokely-types) の言語であることです。JavaScript や PowerShell など) では、安全に作業するかどうかの選択肢がありますが、強く型付けされた言語では一般的に安全に作業することを強いられます。 主に、安全とは、宣言される前の変数を使用できないようにすることである。 これにより、不用意なミスタイプを防いで、コードが動作しない原因を突き止めようとするときに、数え切れないほどの悲しみを味わうことになります。 (おそらく、弱い型付けの言語の人たちは、安全に操作することを負担に感じる人がいるかもしれないと考え、オプションにしているのでしょう)。 プロファイルに Set-PSDebug
を入れてください。 安全にね。 4668>
プロファイルに入れる可能性のある他のタイプのアクションは、たとえば、稼働時間、ディスク容量、または PowerShell 実行ポリシーなどの統計情報を表示するようなものです。 複数のマシンを管理する場合、’リモート’ したマシンに関する詳細 (ドメイン名、コンピュータ名、IP アドレスなど) を表示して、自分がいるマシンであることを確認したいと思うかもしれません。 システムを安全に保つためにファイアウォールとアンチウィルスを使用します。 同様に、あなた自身のプロファイルを含め、実行する PowerShell スクリプトについても考慮する必要があります。 PowerShell は、スクリプトを実行させないというデフォルト設定を始めとして、セキュリティに対するサポートが充実しており、そのままでは PowerShell コマンドのみを対話的に使用できます。 コンピュータの実行ポリシーを設定することにより (Set-ExecutionPolicy 参照)、必要な作業を行えるよう、システムを十分に開放する必要があります。 これは PowerShell スクリプトに限ったことではなく、コンピュータ上のあらゆるものが危険にさらされる可能性がありますが、PowerShell はこのような状況を軽減するのに役立ちます。 PowerShell では、必要に応じて実行ポリシーをさまざまなセキュリティレベルに設定することができます。 すべてのスクリプトを認証するように要求したり、ダウンロードしたスクリプトを認証するように要求したり、さまざまなオプションがあります。 この場合、認証とは、スクリプトにデジタル署名 (Set-AuthenticodeSignature を参照) を付けて、ファイルが (悪意の有無にかかわらず) 変更された場合、デジタル署名が改ざんを検出し、スクリプトが実行されないようにすることを指します。 (この記事の長さの倍以上になってしまいます!) しかし、あなたを導くための良い情報がすでにたくさんあります。 このSimple-Talkの他の記事、Nicolas PrigentのPowerShell Day-to-Day SysAdmin Tasksから始めることをお薦めします。 スクリプトの安全性を確保する About_signing はこのトピックの良いイントロダクションで、New-SelfSignedCertificate は独自の自己署名証明書を作成することができ、Get-ChildItem for Certificate は証明書ストアを参照する際の Get-ChildItem
のあまり知られていない差異を明らかにします。 マイクロソフトはコードサイニングのベストプラクティスについて、古いが今でも有用なリファレンスを提供している。 Geoff Bard の Signing PowerShell Scripts も一見の価値があります。
Get That Profile Out of the Way! しかし、他のスーパーパワーと同様に、そのダークサイドを認識する必要があります。 まあ、ダークサイドというほどではないが、自分のプロファイルが邪魔にならないようにしたい場合もある。
コマンド リテラルまたは実行するスクリプト ファイルで実際に powershell.exe を実行したい状況はさまざまあります。 たとえば、同僚と共有したい PowerShell スクリプトを作成したとします。 バッチファイルとは異なり、PowerShellスクリプトをダブルクリックして実行することはできません。これは、システムを安全に保つためのPowerShellのセキュリティモジューの一部なのです。 しかし、PowerShell スクリプト ファイルをパラメーターとして powershell.exe をターゲットとする Windows 標準のショートカットを作成することにより、簡単に回避できます (推奨しているわけではありません!)。 MSBuild は PowerShell スクリプトを実行する方法を生来知らないので、通常、powershell.exe への引数としてスクリプトを提供することにより実行します。
ただし、powershell.exe は常に、新しい PowerShell ホストを開くことになります。 そして、ホストを開くと何が起こるのでしょうか。 4 つのプロファイルのいずれか (またはすべて) が実行されます。 しかし、powershell.exe を直接起動してホストを開く場合は、ほとんど常に、オーバーヘッドや発生しうるコンフリクトのために、プロファイルを実行させたくはないでしょう。 もし、あなたがpowershell.exeを実行するコマンドを導入したビルドを他の人が実行している場合、その人のマシンで実行されるのはその人のプロファイルであり、そこに何が潜んでいるかはわからないということを念頭に置いておいてください。 さらに、プロファイルの何かに依存することは避けなければなりません。 したがって、powershell.exeを起動するときは常にプロファイルを無視するというベストプラクティスを採用するのが最も安全です(もちろん、プロファイルを無視すべきだという意味ではなく、PowerShellに無視するように伝えるべきだということです)。
結論
PowerShell プロファイルはあなたの友人です。 この記事で示したロードマップにより、利用できるプロファイルの種類を確認し、自分に合ったものを選択できるようになりました。 あるいは、必要に応じてホスト固有の項目を区別し、1つのプロファイルを使用することもできます。 プロファイルはシンプルかつ強力なツールであり、使い方は全く複雑ではなく、その用途はあなたの想像力によってのみ制限されます。 唯一の欠点は、プロフィールに追加する便利で賢いものを探すのに時間がかかることです。 (Go-Shell モジュールを含めることを検討すべきであると申し上げましたでしょうか?)
。