PowerShell

PowerShell（パワーシェル）は、マイクロソフトが開発した拡張可能なコマンドラインインターフェイス (CLI) シェルおよびスクリプト言語である。オブジェクト指向に基づいて設計されており、.NET Framework (Windows PowerShell 5系以前) あるいは.NET Core (PowerShell Core 6系以降) を基盤としている。
かつてはMicrosoft Shell（MSH、コードネーム Monad）と呼ばれていた。
以降のオペレーティングシステム (OS) には標準で搭載されている。

**歴史**
マイクロソフトによるOSにはlang|en|MS-DOSからlang|en|Windowsに至るまで、どのバージョンにもコマンドラインシェルが付属した。それは、かつてはCOMMAND.COMであり、lang|en|Microsoft Windows NTベースの製品においてはcmd.exeであった。これらのツールはグラフィカルユーザインタフェース (GUI) で提供されるような管理機能の自動化や再利用に必ずしも長けているとは言えなかったpages=4,6。これはコマンドライン内の制限によるものであり、マイクロソフトが高品質なコマンドラインツールを提供しなかったためでもあったpage=6。
マイクロソフトはコマンドラインツールの短所を補うものとして、1998年にlang|en|Windows 98でlang|en|Windows Script Host (WSH) を提供した。これは様々なスクリプト言語を実装するための新しいソフトウェアであった。しかしWSHはシェルに統合されていないという欠点があり、ドキュメントも非常に使いにくいものだった。またWSHの持つセキュリティ上の欠陥をつくコンピュータウイルスがいくつか出現したため、システム上の脆弱性とみなされたこともあり、広く普及するには至らなかった。
そして2003年、マイクロソフトはWindowsや自社製品のシステム管理・自動化を行うための新世代シェルとして、またスクリプトとして実行可能なプログラミング言語としてMonad（後の PowerShell）を発表した。
2015年9月現在、Windows PowerShellの正式な最新バージョンは5.0であり、lang|en|Windows 10に標準搭載されている。Microsoft Windows 8#Windows 8.1|Windows 8.1に標準搭載されているバージョンは4.0、lang|en|Windows 8に標準搭載されているバージョンは3.0、Windows 7に標準搭載されているバージョンは2.0となる。
2016年8月には、PowerShellのオープンソース化、並びにLinuxとOS Xへの移植が発表された。これは同年6月にリリースされたオープンソースの.NET Coreに続くものとなった。

**変遷**

**Windows PowerShell**

**Windows PowerShell 1.0**
2003年9月、コードネーム Monadが公開された。2006年4月、正式名称がWindows PowerShellとなることが発表され、リリース候補 (RC) 1がリリースされた。2006年9月、RC2リリース。
2006年11月、Windows PowerShell 1.0がウェブ上でリリースされた (RTW)。動作には .NET Framework 2.0を必要とする。2007年1月、PowerShell 1.0 for Vistaがリリースされた。
マイクロソフトはこれからの主なGUIツールはPowerShell上に構築されると表明し、主な管理機能がスクリプト可能になるとした。例えば、Exchange Server 2007の管理ツールはPowerShellの上に構築されている。多くの日常的な場面でPowerShellはcmd.exeやWSHを置き換えるものとして利用できる。

**Windows PowerShell 2.0**
2009年10月リリース。

**Windows PowerShell 3.0**
2012年9月リリース。動作には.NET Framework 4を必要とする。

**Windows PowerShell 4.0**
2013年10月リリース。動作には.NET Framework 4.5を必要とする。

**Windows PowerShell 5.0**
2015年12月リリース。動作には.NET Framework 4.5を必要とする。

**Windows PowerShell 5.1**
2016年8月リリース。Windows 10 Anniversary Update及びWindows Server 2016の標準バージョン。
5.1はDesktopとCoreの2つのエディションを提供する。Desktop Editionは従来どおりのWindows PowerShellで、Core EditionはNano Serverで実行するために、.NET Core上に構築され、いくつかの機能が削減されている。
「◎」標準搭載、「○」インストールして利用可能、「→」上位バージョン標準搭載、「×」利用不可

**PowerShell Core**

**PowerShell Core 6.0**
2016年8月、オープンソース化、Linux/OS Xへの移植を発表。
2018年1月、PowerShell Core 6.0リリース。ランタイムとして.NET Frameworkに代わり.NET Core 2.0を使用する。これによりPowerShell Core6はWindows、macOS、Linuxで動作が可能になった。

**PowerShell Core 6.1**
2018年9月、PowerShell Core 6.1リリース。
Windows 10およびWindows Server 2019との互換性強化、サポートプラットフォームの強化"Core 6.1"が図られている。.NET Core 2.1を使用する。

**PowerShell Core 6.2**
2019年3月、PowerShell Core 6.2リリース。

**PowerShell 7.0**
2020年3月、PowerShell 7.0リリース。.NET Core 3.1を使用する。

**PowerShell 7.1**
2020年11月、PowerShell 7.1リリース。.NET 5.0を使用する。

**基本的な概念**
はオブジェクト指向言語であり、基本的な機能をもつ様々なコンポーネントを組み合わせたタスクによって構成される。コンポーネントは、コマンドレット (cmdlet) と呼ばれるプログラムであり、その実体は.NETのクラスであるpage=33。
コマンドレット間でのデータの受け渡しは、古典的なUNIX型アプローチ（テキスト入出力をパイプする）とは異なり、オブジェクト（構造化されたデータ）で行なわれる。コマンドラインから個別にアクセスされた場合、コマンドレットの出力は自動的にテキストに変換されるが、出力が他のコマンドレットに渡されるのであれば、そのコマンドレットの入力として最も適切な形式に変換され、渡されるpages=49-60。これにより、UNIX型システムで一般的なテキスト処理ユーティリティ（lang|en|grepやlang|en|awkなど）が不要となり、インタラクティブに、またはスクリプト環境（より複雑なプログラミング言語が必要）の中で、様々なコマンドレットを結合することができる。例えば、プロセスの一覧を出力する場合、それらは単なるテキストの一覧ではなく、プロセスの情報を表すオブジェクトの一覧である。従ってそれらのオブジェクトに対して、明示的に外部の構造やライブラリを使用することなく、直接的にメソッドを適用することができる。

**特徴・機能**
Windows PowerShell/PowerShell Coreには次の機能が含まれる。
*オブジェクト指向言語である
*パイプを使える
*オープンソースである (PowerShell Core)
*既定の文字コードは、Windows PowerShellはShift-JIS (日本語環境の場合)、PowerShell CoreはUTF-8である
*実行ファイル名は、Windows PowerShell の場合 powershell.exe、PowerShell Core の場合 pwsh.exe である。
*スクリプト言語。ハッシュテーブル、正規表現によるswitch文、配列のスライシング、匿名メソッドなどの機能。ループ構文 (for、foreach、while)、条件文 (if、switch)、変数のスコープ (global、script、local)、関数の定義などがサポートされる2007。
*ユーザがエラー処理方法などといった共通の設定を指定するため、コマンドレットは一定のオプションを継承する。副作用のあるコマンドレットは-WhatIf、-Confirmオプションをサポートする。-WhatIfは何が起こるかをユーザに通知するが、実際には何も行わないpages=8,9,416。-Confirmは何が起こるのかユーザに通知し、実行するかどうか確認を求めるpages=8,9。
*エラー処理を制御するオプションに「一時停止」機能がある。これは、ユーザが新しいコマンドシェルに入ることで問題を分析し、もとのコマンドに復帰できるようにするというものである。こうした状況で表示されるプロンプトをユーザが定義することもできるpages=321-328。
*拡張可能な「プロバイダ」モデルにより、ファイルシステムなどの階層的データ構造の処理をすることができる。例えば、PowerShellにはシステムのレジストリにアクセスするレジストリプロバイダが存在する。これを用いれば、例えばシェルプロンプトで次のようなコマンドを打つことによってレジストリの内容を表示することができるpages=14-16。dir HKLM:SOFTWARE\MicrosoftPowerShell には認証ストア、環境変数、シェル機能とエイリアスなどのプロバイダが存在するpages=14-16,67,68。プロバイダモデルはコマンドレットと同様に拡張可能であり、第三者が独自のプロバイダを作成してPowerShellに組み込むことができる。
*「実行ポリシー (execution policies)」という概念により、PowerShellによるスクリプトの実行に対して大まかなセキュリティ上の制約を課すことができる。実行ポリシーはPowerShellが設定ファイルを読み込み、スクリプトを実行するための制約を定義する。Restricted、AllSigned、RemoteSigned、Unrestrictedという四つの実行ポリシーが存在するpages=510-514。
*スクリプト作成者の識別や、スクリプトの安全性の保証のため、デジタル署名によってスクリプトに署名することができるpages=514-527。
*通常、コマンドラインオプションは省略せずに完全な英単語を用いるが、曖昧でない範囲で文字数を小さくすることができるpage=6。例えば、-show-detailed-informationオプションは他に「s」で始まるオプションがなければ-sと指定することができる。
*ユーザ定義のタブ補完機能が利用できるpages=17-19。Windowsのcmd.exeはファイル名やディレクトリ名しか補完できなかった。
*コマンドの出力を変数に代入することができる。この変数はオブジェクトやオブジェクトの配列であり、後に任意の方法で処理することができるpage=160-166。
*PowerShellの文が可変長個数のオブジェクトを返す場合、既定値では0個の場合は$nullが、1個の場合はオブジェクトが、2個以上の場合はオブジェクトの配列を返す。明示的に配列を返したい場合は "@()"で文をくくる。この考慮が洩れると次の例のように一見予想外の挙動をする。
# Get-ChildItem が返戻する要素数が1のため、$bad には サイズ1024バイトのファイルを表すFileInfo型のオブジェクトが代入される。
$bad = Get-ChildItem "1個のサイズ1024バイトのファイルがあるディレクトリ"  
# 一見、$bad.Lengthはディレクトリの要素数1が予想されるが、結果は1024が帰ってくる。$badは配列ではなくFileInfo型のオブジェクトで、Lengthプロパティが1024のためである。
$bad.Length
1024            # !?
# 明示的に配列を返したい場合は"@()"でくくる。
$good = @(Get-ChildItem "1個のサイズ1024バイトのファイルがあるディレクトリ" )
# $goodは正しく要素数1の配列のため、Lengthプロパティは1になる。
$good.Length
1

**使用例**
「p」で始まるプロセスを全て停止するpage=556。
PS> Get-Process p* | Stop-Process
1000 MB以上のメモリを占有するプロセスを検索し、停止するpages=556, 557。
PS> Get-Process | Where { $_.WS -gt 1000MB } | Stop-Process
ディレクトリ中に含まれる全ファイルの合計サイズを計算して出力するpages=557,558。
PS> Get-Childitem | Measure-Object -property length -sum
文字列に含まれる小文字を大文字に変換した文字列を作るpage=560。
PS> "hello, world!".ToUpper()
"internal"という文字列の5文字目の直後に"natio"という文字列を挿入し、結果として"international"を得るpages=560,561。
PS> "internal".Insert(5, "natio")
指定したRSSフィードをダウンロードし、最新の8エントリーのタイトルを表示するpage=415。
PS> $rssUrl = "http://blogs.msdn.com/powershell/rss.aspx"
PS> $blog = xml(New-Object System.Net.WebClient).DownloadString($rssUrl)
PS> $blog.rss.channel.item | Select title -first 8
変数 $UserProfile に環境変数 UserProfile の値を代入する。
PS> $UserProfile = $env:UserProfile

**脚注**

**注釈**

**出典**

**参考文献**
ref=harv
*ref=harv

**外部リンク**
 PowerShell ドキュメント- PowerShell/PowerShell-  PowerShell スクリプト - Microsoft Docs-   PowerShell Team Blog - PowerShell開発チームによるブログ-  Windows PowerShell徹底解説 - 日経 xTECH