Skip to content

MS_PowerShell

nishi_74322014 edited this page Aug 3, 2026 · 1 revision

PowerShell

概要

PowerShell のトピックを纏めています。

特徴

オブジェクトベースのシェル

MS_PowerShellObjectBasedShell.md
パイプで流れるのがテキストではなく .NET オブジェクトである点が、 UNIX 系シェルとの最大の違い。

WSHを置き換えている

同系列であるから置き換え。

CMDを置き換えるものではない

別物として使用(併用)する必要がある。

  • 例えば、
    • ipconfig などのコマンドを実行すると、おなじみの出力が表示される。
    • netsh などのコマンドを実行して設定するぐらいはPowerShellで実行可能。
  • ただし、Cmd.exeを置き換えるものではない。
    • 標準出力をテキストとしてパイプできない。
    • BATの構文を使用できない。

移行メモ: 「標準出力をテキストとしてパイプできない」は、 PowerShell コマンドレット間の話。 外部 EXE の標準出力は文字列として扱われるため、 ipconfig | Select-String "IPv4" のようなテキスト処理自体は可能。 「オブジェクトが前提なので、テキスト前提の CMD スクリプトはそのまま流用できない」
という趣旨と解される。

いつの間にか、Linuxでも利用可能になってた

.NET Coreもそうですが、いつの間にか、Linuxでも利用可能になってますね。

環境構築

PowerShell の各バージョンは、以下のOSに添付されているか、別途ダウンロードできます。

  • 新しいOSほど、新しいPowerShellに対応します。
  • また、旧OSでは、新しいPowerShellのサポートがありません。
  • PowerShellのバージョンに依存しそうな場合は、対象とするOSが何か確認ください。

インストール

  • いつの間にか、7.1になってた…。
  • 潔く、MSIでインストール(Windows)

補足(最新化): 現在は PowerShell 7.x(旧称 PowerShell Core)が クロスプラットフォーム版の系統で、pwsh.exe として、 Windows 同梱の Windows PowerShell 5.1powershell.exe)とは 併存インストールされる(置き換えではない)。 Windows PowerShell 5.1 は機能追加が凍結され、セキュリティ修正のみ。 インストールは winget install Microsoft.PowerShell が手軽。

プロキシ設定

プロキシの設定方法を参照。

基本

実行方法

インタラクティブな逐次実行は、

  • スタートメニューから PowerShell コマンドプロンプトを開いても、
  • コマンドプロンプトから PowerShell.exe を実行しても、

どちらの方法でも PowerShell を手で(シェルとして)逐次実行できます。

.ps1 スクリプトの実行には実行ポリシーが関わる。
既定(Windows クライアントは Restricted)ではスクリプトが実行できないため、
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned などの設定が必要。

出力フォーマット

Get-XXXXXコマンドの出力は以下のようなパイプでフォーマット可能。

Get-XXXXX | Format-Wide
Get-XXXXX | Format-List
Get-XXXXX | Format-Table

Format-* を通すと以降はオブジェクトではなく整形用オブジェクトになるため、
パイプラインの最後で使うこと。

スクリプティング

変数

定義

変数は $ で始まる英数字記号の名前を使用します。
後述の様にスコープ($global:, $script:)をつけることも出来ます。

下の様に ${ } で囲むと、名前にスペースを含むこともできますが、
混乱やスペルミスの元になりやすいので避けましょう。

PS E:\temp> ${var test 1} = 123
PS E:\temp> $a = ${var test 1} + "123"
PS E:\temp> $a
246

移行メモ(正誤): 原文はこの例の出力を 246 としているが、 123(数値)+ "123"(文字列)は、左辺の型に合わせるPowerShell の規則により 右辺が数値に変換され、246 になる。ここは原文どおり正しい。 (逆に "123" + 123 なら文字列連結で 123123 になる。)

未初期化の初期状態は $null と同じです。文脈によっては 0 や ""(空文字列)と解釈されます。

PS E:\temp> $var001
PS E:\temp> $var001 -eq 0
False
PS E:\temp> $var001 -eq $null
True
PS E:\temp> $a1 = $var001 + 2
PS E:\temp> $a1
2
PS E:\temp> $a1 = $var001 + "abc"
PS E:\temp> $a1
abc

上の例では、変数 $var001 は未初期化なので、$null と同じです。
変数をそのまま出力すると、$null は何も表示されません。
また、-eq 比較演算子を使って、0 や $null と比較すると、$null であることが判断できます。

未初期化変数は、数値を足し算した場合は 0 が、文字列を連結した場合は "" が、それぞれ仮定されます。

Set-StrictMode を使用すると、未初期化変数を参照する際にエラーとして検出できます。

PS E:\temp> Set-StrictMode -Version 1.0
PS E:\temp> $a1 = $var001 + 2
変数 '$var001' は、設定されていないために取得できません。

スコープ

PowerShellの変数は、変数を使用する場所がスコープの範囲になります。

  • function の中
  • PowerShell モジュールの中
  • .ps1 スクリプトの中(MS_PowerShellPS1File.md

などがスコープの境界になります。

if文

if文は、下の様に - で始まる比較演算子を使います。

$var1 = sub2 $arg1 $arg2
if ( ( $var1 -eq 1 ) -or ( $var1 -gt 10 ) ) {
   ...
}

条件のANDやORは、それぞれを ( ... ) で囲んで -and-or で結びます。
ビット演算は、-band-bor-b で始まる演算子を使います。

$file = Get-Item $dirname
if ( $file.Attributes -band [System.IO.FileAttributes]::Directory ) {
   ...
}

bit演算結果が0以外の場合は、真とみなされます。

if文の演算子の詳細は、get-help about_Comparison_Operators を参照してください。

配列

配列は、以下の形式で定義できます。

$array1 = @()
$array2 = @(1,2,3)
$array3 = 1,2,3

( ) で囲まなくても、「,」で並べると、配列になります。
コマンドや関数への引数を「,」で区切った場合も配列になるので、書き間違いに注意。

$ret1 = sub1 2,3,4    # これは @(2,3,4) の配列で引数1つ
$ret2 = sub1 2 3 4    # これは 引数3つ
$ret3 = sub1 2,3 4    # これは @(2,3)の配列1つと 数値4 の 引数2つ

また、配列の添え字は $変数名[添え字] で参照します。
添え字に負数を指定すると、配列の末尾からの添え字を指定できます。

$var1 = $array2[1]   # 上の $array2 から 2 を取り出す
$var2 = $array2[-1]  # 上の $array2 から 3 を取り出す

配列について詳しくは、get-help about_array を参照ください。

拡張

  • PSSnapin と Module(MS_PowerShellModuleVsSnapin.md
  • PowerShellのPS1ファイルの作成と実行(MS_PowerShellPS1File.md
  • PowerShell Cmdletの作り方(MS_PowerShellCmdlet.md
  • PowerShell プロバイダとドライブ(MS_PowerShellProvider.md

情報の探し方

Get-Command

コマンドを探すには、コマンド名の一部を * で省略して Get-Command を実行します。

Get-Command *event

get-help コマンド名

  • コマンドの説明や引数の構文を確認するには、get-help を使います。
get-help get-childitem
  • ヘルプの文章が online から取得する様になっていることがあります。
    • 必要に応じて get-help コマンド -online のようにするか、
    • Update-Help でローカルのヘルプを取得する。

Get-Member

オブジェクトのメンバーやプロパティを確認するには、
コマンドの出力をパイプで Get-Member に渡します。

Get-ChildItem | Get-Member

Get-WmiObject

Get-WmiObject -List

補足(最新化): Get-WmiObjectPowerShell 6 以降で削除された。 後継は CIM コマンドレットGet-CimInstance / Get-CimClass)で、 WinRM ベースのためリモート実行との相性も良い。 例:Get-CimInstance Win32_NetworkAdapter

勘所1

エラー処理

.ps1 ファイルの中でエラーが発生すると、既定では、
赤文字でエラー表示されて、そのまま次の行が実行されます。
エラーを処理するには、下のいずれかが必要です。

-ErrorAction (省略形は -EA) オプション

Trap {
  エラー処理
}
コマンド ....  -ErrorAction "stop"

try/catch で囲む

$ErrorActionPreference = "stop"
try {
  コマンド ....
} catch [Exception] {
  エラー処理
}

補足: PowerShell のエラーには 終了エラー非終了エラーがあり、 try/catch で捕まえられるのは終了エラーのみ。 コマンドレットの非終了エラーを捕まえるには -ErrorAction Stop が必須。 なお 外部 EXE の失敗は例外にならないので、$LASTEXITCODE を確認する (PowerShell 7.3 以降は $PSNativeCommandUseErrorActionPreference で変更可能)。

デバッグ

debugは、debug用print文、デバッグ用環境、を使ってデバッグできます。

debug用print文

Write-Host コマンドをスクリプトの中に埋め込む方法です。
Write-Output は関数の出力になるので、debug用には使わないでください。)

※ 現在は Write-Debug-Debug 指定時のみ出力)や
Write-Verbose-Verbose 指定時のみ出力)を使うほうが、後始末が要らない。

デバッグ用環境

PowerShell ISE (Integrated Scripting Environment) 環境が使用できます。
ブレークポイントの設定、ステップ実行が、メニュー操作で行えます。

補足(最新化): PowerShell ISE は Windows PowerShell 5.1 専用で、 PowerShell 7 では動作しない(新機能開発も終了)。 現在の標準は Visual Studio Code + PowerShell 拡張

debug用のコマンド

通常の PowerShell コマンドプロンプトのままでも、
Set-PSBreakpoint 等の debug用のコマンドを使用して、1行ずつステップ実行することも出来ます。

PS E:\temp> Set-PSBreakpoint -command .\ps_scope1.ps1

  ID Script            Line Command           Variable         Action
  -- ------            ---- -------           --------         ------
   0                        .\ps_scope1.ps1

PS E:\temp> .\ps_scope1.ps1
デバッグ モードを開始します。ヘルプを表示するには、h または ? を使用してください。

ヒット '.\ps_scope1.ps1' のコマンドのブレークポイント
[DBG]: PS E:\temp>>> s
ps_scope1.ps1:2   $global:g1 = "0"
[DBG]: PS E:\temp>>> s
ps_scope1.ps1:3   $script:s1 = "0"
  • 変数が変更されたときに停止するようにブレークポイントを設定することもできます
    Set-PSBreakpoint -Variable)。
  • 詳細は about_Debuggers を参照。

勘所2

Windows Server 2012以降の管理

Windows Server 2012以降は管理コンソールの裏はPowerShellコマンドレットになる。

  • 現行、管理コンソールはCUI → WMIで構成されている。
  • コマンドレットの裏は.NET、その裏はWMI(Windows Management Instrumentation)。
  • MS的には、今後PowerShell押し。
    • コマンドレットは <操作>-<ターゲット> の名称ルールに準拠。
    • WSH(MS_VBS.md)(VBSとJS)は凍結される。
    • BATは今後もエンハンス有り。
    • PowerShellからBATや、WSHを実行可能。
    • また、Get-WmiObject(現在は Get-CimInstance)でWMIも実行可能。
    • 難しい事をやるなら、まだWMIが必要。
  • Windows Management Framework 3.0 で標準化:
    PowerShell → WS-Management → CIMOM、SMI-S(WS-Management 以下から他のPFも管理できる)
    • Windows PowerShell 3.0
    • WinRM
    • WMI(アップデート)
    • Windows PowerShell Web Service(WPWS)
    • Server Manager CIM Provider

移行メモ(正誤): 原文の「管理コンソールはCUI → WMI で構成されている」は、 GUI(管理コンソール)→ PowerShell コマンドレット → WMI/CIM という積み上げの意。 Windows Server 2012 以降のサーバーマネージャーは、 GUI 操作の実体としてコマンドレットを呼び出す構造になっている。

リモート、非同期ジョブ、ワークフロー

リモート

MS_PowerShellRemoting.md

Invoke-Command -ComputerName マシン名 -ScriptBlock { ・・・コード・・・ }
Invoke-Command -Session $s -FilePath ファイルパス

※ Session を指定すれば処理中のジョブ等に再接続することも可能。

非同期ジョブ

Start-Job -ScriptBlock { ・・・コード・・・ }
Start-Job -FilePath ファイルパス

※ 結果はSessionの範囲でしか有効では無い。

ワークフロー

  • ファイルとして登録
  • クライアントでもサーバでも実行できる。
  • サーバが停止しても処理をレジュームできる。非同期ジョブと異なり、結果は永続化されている。
  • その他、並列処理等も可能。

補足(最新化): PowerShell Workflow は PowerShell 6 以降では未サポート (Windows Workflow Foundation が .NET Core に移植されなかったため)。 並列処理は ForEach-Object -Parallel(PowerShell 7 以降)、 永続的なジョブは Azure Automation などで代替する。

その他

VBScriptから変換

サンプル

PowerShellの御蔭で、昨今、CUIだけで結構イケる説。

豆知識

  • エイリアスを使ってUnix風にできる。
  • Windows Server 2012 から GUI のアンインストールが可能で、サーバコア風に運用可能。

参考

その他

  • PowerShell ISE(MS_PowerShellISE.md
  • Azure PowerShell(MS_AzurePowerShell.md
  • Azure Cloud Shell(MS_AzureCloudShell.md
  • PowerShell Core(MS_PowerShellCore.md

Tags: シェル, インフラストラクチャ, Windows, Linux

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally