これは PowerShell Advent Calendar 2013 21日目の記事です。
本記事では、最近のWindows OSに標準搭載されているIDE、PowerShell ISEの基本操作について紹介します。
- はじめに
Windows 8 に搭載のPowerShell ISEではインテリセンスが使えるようになり、だいぶ実用的になりました。
OSに標準で搭載されていることもあり、ISEを使ってスクリプトを書いてる人も多いかと思います。
本記事ではPowerShell ISEを利用する上で、知っておくと便利な機能について紹介します。
- PowerShell ISEの基本操作
PowerShell ISEの基本操作に関しては、MSよりチートシートをが公開されています。
基本操作については、これを見て使いながら覚えるのが速いかと思います。
PowerShell 3.0 ISE Cheat Sheet
以下、覚えていると便利そうなショートカットを抜粋して紹介します。
- Ctrl+F1
- 現在のカーソル位置にあるコマンドレットのヘルプをダイアログで表示します。
またパラメータ未指定の場合、標準のコマンド検索アドオンのダイアログが表示されます - #TAB
- コマンド実行履歴がインテリセンスに表示されます。PSコンソールにおけるF7ショートカットと同様の機能です
- Ctrl+M
- アウトラインの展開/折畳みです。長いスクリプトを書くときは、ハッシュテーブルの初期化処理等のコードブロックは閉じておくことでコードが見やすくなります
- Ctrl+D / Ctrl+I
- それぞれ、コンソール/エディタへのカーソル移動に対応します。マウスを使わずキーボードのみでスクリプトを書く場合は必須のショートカットです。
- ISEのオプション設定変更
PowerShell ISEは、オプション設定によるカスタマイズをサポートしています。 変更可能な項目は大きく分けて以下の2点です。
- フォント、キーワードの色変更等のTheme切り替え
- ISEの動作に関する基本的な設定
普通のエディタであれば、他にインデントタブサイズやタブ/スペースの切替等、エディタの動作を細かく設定できますが、PowerShell ISEではそこまで細かい設定はできません。また、残念ながらPowerShell ISEのインデントはスペース固定の仕様です。
なお、ISEのオプションはPowerShell側でもオブジェクトモデルが公開されています。各種設定をスクリプトから設定変更することも可能です。下記のコマンドで設定項目の一覧を確認することができます。
$psIse.Options
- psEditコマンド
ISE内で使える組込み関数としてpsEditが用意されています。
これは、パラメータに指定したファイルをISEエディタで開くためのコマンドです。
使用方法は下記の通りです。
psEdit $profile #ISEのプロファイルファイルを開く
psEdit $file1,$file2 #指定した2つのファイルをISEで開く
psEdit "*.Tests.ps1" #ワイルドカードでファイルを指定
psEditの関数定義は下記のコマンドで確認できます。
見てわかるとおり、ISEのオブジェクトモデルを呼び出すだけの単なるラッパーとなっています。
${function:psedit}.Ast.Extent.ToString()
function psEdit([Parameter(Mandatory=$true)]$filenames)
{
foreach ($filename in $filenames)
{
dir $filename | where {!$_.PSIsContainer} | %{
$psISE.CurrentPowerShellTab.Files.Add($_.FullName) > $null
}
}
}
PowerShellにはプロファイルと呼ばれる機能があります。
これは、PowerShell起動時に指定のパスのPSスクリプト(ps1)を自動的に読込んで実行する機能となります。
頻繁に使用する設定は、PowerShellプロファイルに記述しておくと便利に使用できます。
PowerShellのプロファイルは複数存在し、プロファイルが対象とするユーザー/ホストに応じたファイルが使用されます。 各プロファイルのパスは、以下のコマンドで確認することができます。
$profile.CurrentUserCurrentHost #現在のユーザー、現在のホストを対象とするプロファイル
$profile.CurrentUserAllHosts #現在のユーザー、全ホストを対象とするプロファイル
$profile.AllUsersCurrentHost #全ユーザー、現在のホストを対象とするプロファイル
$profile.AllUsersAllHosts #全ユーザー、全ホストを対象とするプロファイル
$profile #CurrentUserCurrentHostと同値
使うプロファイルとしては、現在のユーザーの現在のホスト(ISEホスト)に適用されるCurrentUserCurrentHostが基本となります。 ISE上で、単に$profile 変数を参照した場合、自動的にこのプロファイル(Microsoft.PowerShellISE_profile.ps1)が使用されます。
以下、ISE用のプロファイルを利用する手順について説明します。
- まず最初にPowerShellプロファイルのファイルを作成する必要があります。下記のコマンドを使用してプロファイルファイルを既定のパスに作成します。
([IO.FileInfo]$profile).Directory.Create() #プロファイルディレクトリを作成
([IO.FileInfo]$profile).Create() > $null #プロファイルのPS1ファイルを作成
- 次にプロファイルファイルの編集を行います。psEditコマンドを使い、ISEのエディタでプロファイルを開きます。
psEdit $profile
- プロファイルを編集します。今回はサンプルとして下記のスクリプトをプロファイルに記述し保存します。
Write-Host ("Loading PowerShell profile({0})..." -f $MyInvocation.MyCommand.Name)
- 最後にPowerShell ISEを別プロセスで開きます。ホストにプロファイルで指定した文字列が表示されることを確認できます。
PowerShellを使いやすくするには、プロファイルのカスタマイズが有効です。
手元の環境では下記の用途でPowerShellプロファイルをカスタマイズして使用しています。
- 自作のPowerShel ISEアドインの読込み
- PowerShell/.NETのカレントディレクトリを作業用フォルダに変更(管理者権限で起動すると既定のSystem32配下になり、誤操作が怖いため)
- 新規作成の一時ファイルが他と被らないように変更(保存時のリネームの手間を減らすため)
PowerShell プロファイルをカスタマイズする場合は下記の点に注意する必要があります。
- プロファイル内で定義したスクリプトは、グローバルのスコープで実行されます。
一時変数を使用した場合は、Remove-Variableを使用して変数を消す必要があります。 - プロファイル内で重いスクリプト処理(Add-Typeによるアセンブリロード等)を書くと、ISEの起動が遅くなります。
重い処理は非同期で読み込む等の工夫が必要です。
PowerShell ISEにはコードスニペット機能が付いており、事前に登録したスニペットの一覧を Ctrl+J
で表示できます。
既定のスニペットはあまり役に立たないので、下記のコマンドで表示しない設定としたほうがよいかと思います。
$psISE.Options.ShowDefaultSnippets =$false
###自作コードスニペット機能の登録### コードスニペットの登録はコマンドレット(New-ISESnippet)が用意されていますが、文字列でコードを指定する必要があり、あまり便利とは言えません。 以下のURLで公開している、ユーティリティ関数を使うと、スクリプトブロックを使用してスニペットの登録が可能となります。 https://gist.github.com/altrive/7973332
###自作コードスニペット機能の利用方法### コードスニペットの機能はVSと比べて、大分貧弱なので、コードのコピペ元として割り切って使用する必要があります。 下記の例のように、定型のコード、入力が面倒なコードを自作のスニペットとして登録するのがおすすめです。
- Stopwatch/Measure-Commandによる時間計測
- New-Object によるPSCredential生成
- #Requires RunAsAdministrator 等の補完できないコード
PowerShell ISEで編集中のファイルは、定期的に自動保存されています(既定では2分間隔)
なんらかの理由でISEが強制終了した場合は、次回起動時に開いていたファイルが起動時に自動復旧されます。
自動保存ファイルは下記のパスに格納されています。間違ってISE編集中のファイルを閉じてしまった場合でも、ここから復旧できる可能性があるので、覚えておくと役に立つことがあるかもしれません。
%LocalAppData%\Microsoft_Corporation\powershell_ise.exe_StrongName_lw2v2vm3wmtzzpebq33gybmeoxukb04w\3.0.0.0\AutoSaveFiles
自動バックアップはISEが終了したタイミングで削除されます。 このため、間違ってISEごと閉じてしまった場合は自動バックアップは役に立ちませんので注意してください。(特にOSの再起動時で作業中のISEを閉じる必要があるとき)
ISEとは直接関係ありませんが、便利な機能なので、ここで紹介します。
PowerShell関連のファイル(ps1/psm1)は既定ではWindowsSearchの検索インデックス作成対象にはなっていません。
Windows Searchの設定を変更し、拡張子を検索インデックス対象に追加することでエクスプローラからスクリプトを検索できるようになります。
以下、WindowsSearchの設定手順を紹介します。
1. [インデックスのオプション] コントロールパネルを開くには下記のコマンドを使用します。 2.
Get-ControlPanelItem -CanonicalName Microsoft.IndexingOptions | Show-ControlPanelItem
2. 次に、[詳細設定]-[ファイルの種類]より対象の拡張子(ps1/psm1)を選び、
"プロパティとファイルのコンテンツのインデックスを作成する"に設定を変更します。
これでPowerShellのファイルが検索インデックスの作成対象となります。
3. 既定ではWindowsSearchの検索対象は、ユーザーフォルダ配下のみとなります。 他のパスにスクリプトを配置している場合は、インデックス作成対象のパスを追加します。
下記のスクリプトを管理者権限で実行することにより、エクスプローラのプレビューウインドウ内にスクリプトを表示できるようになります。
Set-ItemProperty Registry::HKEY_CLASSES_ROOT\.ps1 -Name PerceivedType -Value text
Set-ItemProperty Registry::HKEY_CLASSES_ROOT\.psm1 -Name PerceivedType -Value text
### Windows Searchの動作確認 ###
設定完了後、エクスプローラ右上の検索ボックスより、PowerShellスクリプトの検索が可能となります。
(※検索インデックスの作成完了まで多少時間がかかる場合があります)
以上、Windows Search関連の設定となります。
使い捨てのつもりで書いたスクリプトでも、後になって必要になることがあります。
自分の環境では、使い捨てスクリプトは"無題XXX"のまま、テンポラリフォルダに保存しておき、
必要に応じて検索して利用できるようにして運用しています。
TabExpansion++は
PowerShell組込みの機能拡張用インターフェースTabExpansion2を利用して補完機能を拡張してくれるモジュールです。
ISE標準では[CmdletBinding][Parameter]等の属性を入力する際にIntellisenseが表示されませんが、
このモジュールを導入することにより、補完が強化され、Ctrl+Spaceによる補完が効くようになります。
また、TabExpansion++ではコマンドレットパラメータに対するIntelliSenseを、コマンドレット外部から拡張する機能が用意されています。
以下、TabExpansion++に組込みのIntellisense拡張の例です。
Get-Process [Ctrl+Space] #現在稼働中のプロセス一覧をIntellisenseに表示
Get-NetAdapter [Ctrl+Space] #現在のPCのネットワークアダプタ一覧をIntellisenseに表示
Get-VM [Ctrl+Space] #現在Hyper-Vで動作中のVM一覧をIntellisenseに表示
PowerShell標準の[ValidateSet]属性では、特定の候補しかIntelliSenseに表示できませんが、
TabExpansion++を利用することにより、コンテキスト依存パラメータの動的補完が可能になっていることがわかります。
コマンドレットに動的パラメータの補完機能が欲しいときは、TabExpansion++の拡張を書くのがおすすめです。
PowerShell ISEはv3になり、ある程度実用的になりましたが、機能面ではVisual Studio等の統合開発環境と比べるとまだまだ力不足です。
ただ、PowerShellの言語設計者のjnover氏のTwitterとかをみる限り、サードパーティに任せられるところは任せて、言語コアの部分に注力するとか言ってたようなので、近い将来のPowerShell ISEの大幅な機能強化には、それほど期待できそうにありません。
当面はPowerShellの開発環境は、ISEをベースとして、アドイン等で足りない機能を補って使っていく形で スクリプトを書いてく形が主流になるのではないかと考えています。
以上、PowerShell Advent Calendar 21日目の記事でした。