PowerShell(パワーシェル)は、マイクロソフトが開発した拡張可能なコマンドラインインターフェイス (CLI) シェルおよびスクリプト言語である。オブジェクト指向に基づいて設計されており、.NET Framework (Windows PowerShell 5系以前) あるいは.NET Core (PowerShell Core 6系以降) を基盤としている。

かつてはMicrosoft Shell(MSH、コードネーム Monad)と呼ばれていた。

Windows 7以降のオペレーティングシステム (OS) には標準で搭載されている。

## 歴史

マイクロソフトによるOSにはMS-DOSからWindowsに至るまで、どのバージョンにもコマンドラインシェルが付属した。それは、かつては`COMMAND.COM`であり、Microsoft Windows NTベースの製品においては`cmd.exe`であった。これらのツールはグラフィカルユーザインタフェース (GUI) で提供されるような管理機能の自動化や再利用に必ずしも長けているとは言えなかった。これはコマンドライン内の制限によるものであり、マイクロソフトが高品質なコマンドラインツールを提供しなかったためでもあった。

マイクロソフトはコマンドラインツールの短所を補うものとして、1998年にWindows 98でWindows Script Host (WSH) を提供した。これは様々なスクリプト言語を実装するための新しいソフトウェアであった。しかしWSHはシェルに統合されていないという欠点があり、ドキュメントも非常に使いにくいものだった。またWSHの持つセキュリティ上の欠陥をつくコンピュータウイルスがいくつか出現したため、システム上の脆弱性とみなされたこともあり、広く普及するには至らなかった。

そして2003年、マイクロソフトはWindowsや自社製品のシステム管理・自動化を行うための新世代シェルとして、またスクリプトとして実行可能なプログラミング言語としてMonad(後の PowerShell)を発表した。

2015年9月現在、Windows PowerShellの正式な最新バージョンは5.0であり、Windows 10に標準搭載されている。Windows 8.1に標準搭載されているバージョンは4.0、Windows 8に標準搭載されているバージョンは3.0、Windows 7に標準搭載されているバージョンは2.0となる。

2016年8月には、PowerShellのオープンソース化、並びにLinuxとOS Xへの移植が発表された。これは同年6月にリリースされたオープンソースの.NET Coreに続くものとなった。

## 変遷

### Windows PowerShell

#### Windows PowerShell1.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 PowerShell2.0

2009年10月リリース。

#### Windows PowerShell3.0

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

#### Windows PowerShell4.0

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

#### Windows PowerShell5.0

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

#### Windows PowerShell5.1

2016年8月リリース。Windows 10 Anniversary Update及びWindows Server 2016の標準バージョン。

Windows PowerShell 5.1はDesktopとCoreの2つのエディションを提供する。Desktop Editionは従来どおりのWindows PowerShellで、Core EditionはNano Serverで実行するために、.NET Core上に構築され、いくつかの機能が削減されている。

Windows PowerShellのバージョンと対応OS

| 項目 | 1.0 | 2.0 | 3.0 | 4.0 | 5.0 |
| --- | --- | --- | --- | --- | --- |
| Windows Server 2003 | ○SP1 | ○SP2 | × | × | × |
| Windows Server 2003 R2 | ○SP1 | ○SP2 | × | × | × |
| Windows Server 2008 | ○SP1 | ○SP1 | ○SP2 | × | × |
| Windows Server 2008 R2 | → | ◎ | ○SP1 | ○SP1 | ○SP1 |
| Windows Server 2012 | → | → | ◎ | ○ | ○ |
| Windows Server 2012 R2 | → | → | → | ◎ | ○ |
| Windows XP x64 | ○SP1 | ○SP2 | × | × | × |
| Windows XP | ○SP2 | ○SP3 | × | × | × |
| Windows Vista | ○ | ○SP1 | × | × | × |
| Windows 7 | → | ◎ | ○SP1 | ○SP1 | ○SP1 |
| Windows 8 | → | → | ◎ | × | × |
| Windows 8.1 | → | → | → | ◎ | ○ |
| Windows 10 | → | → | → | → | ◎ |
| Windows 11 | → | → | → | → | ◎ |

「◎」標準搭載、「○」インストールして利用可能、「→」上位バージョン標準搭載、「×」利用不可

### PowerShell Core

#### PowerShell Core6.0

2016年8月、オープンソース化、Linux/OS Xへの移植を発表。

2018年1月、PowerShell Core 6.0リリース。ランタイムとして.NET Frameworkに代わり.NET Core 2.0を使用する。これによりPowerShell Core6はWindows、macOS、Linuxで動作が可能になった。

#### PowerShell Core6.1

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

#### PowerShell Core6.2

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

#### PowerShell7.0

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

#### PowerShell7.1

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

## 基本的な概念

PowerShellはオブジェクト指向言語であり、基本的な機能をもつ様々なコンポーネントを組み合わせたタスクによって構成される。コンポーネントは、コマンドレット (cmdlet) と呼ばれるプログラムであり、その実体は.NETのクラスである。

コマンドレット間でのデータの受け渡しは、古典的なUNIX型アプローチ(テキスト入出力をパイプする)とは異なり、オブジェクト(構造化されたデータ)で行なわれる。コマンドラインから個別にアクセスされた場合、コマンドレットの出力は自動的にテキストに変換されるが、出力が他のコマンドレットに渡されるのであれば、そのコマンドレットの入力として最も適切な形式に変換され、渡される。これにより、UNIX型システムで一般的なテキスト処理ユーティリティ(grepや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`)、関数の定義などがサポートされる。
- ユーザがエラー処理方法などといった共通の設定を指定するため、コマンドレットは一定のオプションを継承する。副作用のあるコマンドレットは`-WhatIf`、`-Confirm`オプションをサポートする。`-WhatIf`は何が起こるかをユーザに通知するが、実際には何も行わない。`-Confirm`は何が起こるのかユーザに通知し、実行するかどうか確認を求める。
- エラー処理を制御するオプションに「一時停止」機能がある。これは、ユーザが新しいコマンドシェルに入ることで問題を分析し、もとのコマンドに復帰できるようにするというものである。こうした状況で表示されるプロンプトをユーザが定義することもできる。
- 拡張可能な「プロバイダ」モデルにより、ファイルシステムなどの階層的データ構造の処理をすることができる。例えば、PowerShellにはシステムのレジストリにアクセスするレジストリプロバイダが存在する。これを用いれば、例えばシェルプロンプトで次のようなコマンドを打つことによってレジストリの内容を表示することができる。
  `dir HKLM:SOFTWARE\Microsoft`
  PowerShell には認証ストア、環境変数、シェル機能とエイリアスなどのプロバイダが存在する。プロバイダモデルはコマンドレットと同様に拡張可能であり、第三者が独自のプロバイダを作成してPowerShellに組み込むことができる。
- 「実行ポリシー (execution policies)」という概念により、PowerShellによるスクリプトの実行に対して大まかなセキュリティ上の制約を課すことができる。実行ポリシーはPowerShellが設定ファイルを読み込み、スクリプトを実行するための制約を定義する。Restricted、AllSigned、RemoteSigned、Unrestrictedという四つの実行ポリシーが存在する。
- スクリプト作成者の識別や、スクリプトの安全性の保証のため、デジタル署名によってスクリプトに署名することができる。
- 通常、コマンドラインオプションは省略せずに完全な英単語を用いるが、曖昧でない範囲で文字数を小さくすることができる。例えば、`-show-detailed-information`オプションは他に「`s`」で始まるオプションがなければ`-s`と指定することができる。
- ユーザ定義のタブ補完機能が利用できる。Windowsの`cmd.exe`はファイル名やディレクトリ名しか補完できなかった。
- コマンドの出力を変数に代入することができる。この変数はオブジェクトやオブジェクトの配列であり、後に任意の方法で処理することができる。
- 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」で始まるプロセスを全て停止する。

1000 MB以上のメモリを占有するプロセスを検索し、停止する。

ディレクトリ中に含まれる全ファイルの合計サイズを計算して出力する。

文字列に含まれる小文字を大文字に変換した文字列を作る。

`"internal"`という文字列の5文字目の直後に`"natio"`という文字列を挿入し、結果として`"international"`を得る。

指定したRSSフィードをダウンロードし、最新の8エントリーのタイトルを表示する。

変数 $UserProfile に環境変数 UserProfile の値を代入する。