PowerShellでよく使うコマンドレット

本記事はPowerShellで筆者が使う、使えそうなコマンドレットを集めたものです。PowerShellの使い方、構文については別記事にあります。

コマンドレット

コマンドレットを探す

Get-Command

全てのコマンドを取得する。動詞や名詞、モジュールなどを指定して取得するコマンドを限定できる。

Get-Command -Verb New
(out)
(out)CommandType     Name                                               Version    Source
(out)-----------     ----                                               -------    ------
(out)Function        New-AutologgerConfig                               1.0.0.0    EventTracingManagement
(out)Function        New-DAEntryPointTableItem                          1.0.0.0    DirectAccessClientComponents
(out)Function        New-DscChecksum                                    1.1        PSDesiredStateConfiguration
(out)(省略)
(out)
Get-Command -Noun Item
(out)
(out)CommandType     Name                                               Version    Source
(out)-----------     ----                                               -------    ------
(out)Cmdlet          Clear-Item                                         3.1.0.0    Microsoft.PowerShell.Management
(out)Cmdlet          Copy-Item                                          3.1.0.0    Microsoft.PowerShell.Management
(out)(省略)

Find-Command

モジュール内のコマンドを検索する。

Get-Alias

エイリアスを取得する。

Get-Alias | ft Name, ResolvedCommandName
(out)
(out)Name    ResolvedCommandName
(out)----    -------------------
(out)%       ForEach-Object
(out)?       Where-Object
(out)ac      Add-Content
(out)asnp    Add-PSSnapin
(out)cat     Get-Content
(out)cd      Set-Location
(out)(省略)

オブジェクト操作

Object

Select-Object

Select-Objectでオブジェクトまたはそのプロパティを選択する。

特定のプロパティだけを取り出すSelect-Object -Property プロパティ名
特定のプロパティを取り除くSelect-Object -ExclueProperty プロパティ名
コレクションのプロパティを展開するSelect-Object -ExpandProperty プロパティ名(コレクション)
コレクションから重複を排除するSelect-Object -Unique
コレクションの最初または最後を取り出すSelect-Object -First N
Select-Object -Last N
コレクションの最初または最後を飛ばすSelect-Object -Skip N
Select-Object -SkipLast N
他の変数、メンバーの情報などを元にプロパティを追加するSelect-Object -Property 存在するプロパティ名,...,,{スクリプトブロック}

※表下部の例参照

プロパティの追加

例:lsの結果にKB単位のサイズを追加する

ls | select-object Name,@{label="Size(KB)";expression={$_.length/1KB}}
(out)
(out)Name             Size(KB)
(out)----             --------
(out)yearSchedule.pdf    11.30

@{l="...";e={...}}と省略可能

ExpandPropertyによる入力オブジェクトの破壊

ExpandPropertyが入力オブジェクトを破壊することがある。

$object = [PSCustomObject]@{a=5;b=[PSCustomObject]@{b1=3;b2=4};c=10}
$object
(out)
(out)a b              c
(out)- -              -
(out)5 @{b1=3; b2=4} 10
(out)
$object | Select-Object -Property c -ExpandProperty b
(out)
(out)b1 b2  c
(out)-- --  -
(out) 3  4 10
(out)
$object
(out)
(out)a b                    c
(out)- -                    -
(out)5 @{b1=3; b2=4; c=10} 10

これはExpandPropertyはプロパティの中身を展開するだけで無く、展開した結果で書き換えるためである。

Where-Object

Where-Objectで条件を満たしたオブジェクトだけを取り出す。エイリアス、where、?も使用可能。

ls | ? Name -cmatch "JPG$"
(out)(省略)
(out)Mode                 LastWriteTime         Length Name
(out)----                 -------------         ------ ----
(out)-a----        2023/08/20     11:01        7207135 DSC01111.JPG
(out)-a----        2023/08/20     11:01        7538724 DSC01113.JPG

Where-Objectには大きく2種類の書き方がある。

Where-Object [-Property] プロパティ名 -演算子 [[-Value] 値]

Where-Object [-FilterScript] {フィルタスクリプト}

最初の例をスクリプトブロックで書くと以下のようになる。

where {$_.Name -cmatch "JPG$"}

ForEach-Object

ForEach-Objectで複数のオブジェクトに対して一括処理を行う。エイリアス、foreach、%も使用可能。

ls | ForEach-Object -begin {write-host "!!start!!"} -end {write-host "!!!end!!!"} {write-host $_.Name}
(out)
(out)!!start!!
(out)desktop
(out)downloads
(out)files
(out)music
(out)pictures
(out)programs
(out)videos
(out)!!!end!!!

Sort-Object

Sort-Objectでオブジェクトを並び替える。

ls
(out)Mode                 LastWriteTime         Length Name
(out)----                 -------------         ------ ----
(out)d-r---        2024/11/13      9:26                desktop
(out)d-r---        2024/12/10     20:14                downloads
(out)d-r---        2024/12/10     23:37                files
(out)d-r---        2024/12/10     23:06                music
(out)d-r---        2024/11/13      9:26                pictures
(out)d-----        2024/10/21     20:18                programs
(out)d-r---        2024/11/13      9:26                videos
(out)
(out)
ls | sort Mode
(out)Mode                 LastWriteTime         Length Name
(out)----                 -------------         ------ ----
(out)d-----        2024/10/21     20:18                programs
(out)d-r---        2024/11/13      9:26                pictures
(out)d-r---        2024/11/13      9:26                videos
(out)d-r---        2024/12/10     23:06                music
(out)d-r---        2024/11/13      9:26                desktop
(out)d-r---        2024/12/10     20:14                downloads
(out)d-r---        2024/12/10     23:37                files
(out)
ls | sort  LastAccessTime
(out)Mode                 LastWriteTime         Length Name
(out)----                 -------------         ------ ----
(out)d-r---        2024/11/13      9:26                pictures
(out)d-r---        2024/11/13      9:26                videos
(out)d-r---        2024/12/10     20:14                downloads
(out)d-r---        2024/12/10     23:06                music
(out)d-r---        2024/12/10     23:37                files
(out)d-r---        2024/11/13      9:26                desktop
(out)d-----        2024/10/21     20:18                programs
-Top N上位N件のみ抽出
-Bottom N下位N件のみ抽出
-Stable安定なソートを使う
-Descending逆順に並び替える
-Unique重複を排除する (大文字・小文字の区別はない点に注意)

Group-Object

Group-Objectで複数のオブジェクトをグループ化する。グループ化する前のオブジェクトはGroupに格納される。不要であればNoElementプロパティを付ける。

Get-ChildItem | Group-Object extension
(out)
(out)Count Name                      Group
(out)----- ----                      -----
(out)   27                           {0717, Adobe, AndroidStudioProjects, Audacity...}
(out)    9 .pdf                      (省略)
(out)    3 .mp4                      (省略)
(out)(以下略)

Propertyでグループ化の仕方をスクリプトブロックで指定することも可能。

Compare-Object

Compare-Objectで2つのオブジェクトを比較する。

$obj1 = @(1,3,5,7,9)
$obj2 = @(2,3,5,7)
(out)
Compare-Object $obj1 $obj2
(out)
(out)InputObject SideIndicator
(out)----------- -------------
(out)          2 =>
(out)          1 <=
(out)          9 <=

この結果は1と9が$obj1だけにあり、2が$obj2だけにあることを示している。デフォルトでは差分だけが表示されるが、-IncludeEqualと-ExcludeDifferentと組み合わせることで同じ部分だけ表示したりもできる。

Measure-Object

Measure-Objectでオブジェクトを集計する。単に数を数えたり、特定のプロパティの値を集計したりできる。

ls | Measure-Object
(out)Count    : 63
(out)Average  :
(out)Sum      :
(out)Maximum  :
(out)Minimum  :
(out)Property :
(out)
ls | Measure-Object -Property Length -Minimum -Maximum -Sum -Average
(out)Count    : 36                         # Lengthプロパティを持たないものは集計の対象になっていない
(out)Average  : 1672546.69444444
(out)Sum      : 60211681
(out)Maximum  : 17912562
(out)Minimum  : 0
(out)Property : Length

項目の操作

項目(Item)とは、ファイルやディレクトリ、シンボリックリンク、ジャンクション、ハードリンク、レジストリなどPowerShellで操作可能なパスにあるもののことである。

ファイルやディレクトリ

カレントディレクトリの取得Get-Locationpwd, gl
カレントディレクトリの変更Set-Location <NewPath>cd, chdir
カレントディレクトリの子要素取得Get-ChildItemdir, ls, gci
ファイル・ディレクトリの取得Get-Itemgi
ファイル・ディレクトリの作成・コピー・移動・名前変更・削除New-Item 名前 -ItemType File|Directory
Copy-Item コピー元 コピー先
Move-Item 移動元 移動先
Rename-Item 変更前 変更後
Remove-Item 名前
ni
cp, copy, cpi
move, mi, mv
ren, rni
rm, rmdir, del, rd, erase, ri
ファイル・ディレクトリの実行(オープン)Invoke-Itemii
ファイルの内容の取得・設定・追加・削除Get-Content
Set-Content
Add-Content
Clear-Content
cat, gc
-
ac
clc
プロパティの取得Get-ItemProperty

ロケーションの履歴

PowerShell 6.2以降から、Set-Locationの履歴が20記録されるようになった。移動先を-にすることで前の履歴、+で後の履歴へ移動できる。

set-location 1
set-location 2
set-location 3
set-location -
set-location -
set-location +
set-location +
set-location -
 

Push-Location(pushd) および Pop-Location(popd)を使うと、ロケーションの履歴をスタックに記録しながら移動できる。

pushd files\adobe
popd
pushd files
pushd adobe
popd
popd
 

レジストリ

レジストリでは、regeditの左側のツリー(レジストリキー)がアイテムのパスであり、PowerShellではRegistry::HKCU\Environment\...のように書く。

Set-Locationを使って、レジストリの中を普通のディレクトリのように移動できる。

Set-Location Registry::HKCU
Set-Location .\Environment\
 

regeditの右側の値はプロパティとして取得できる。一部PowerShellが追加したパスに関するプロパティがあるので注意。

Get-ItemProperty .
(out)
(out)TEMP             : C:\Users\Username\AppData\Local\Temp
(out)TMP              : C:\Users\Username\AppData\Local\Temp
(out)OneDrive         : C:\Users\Username\OneDrive
(out)Path             : C:\Users\Username\AppData\(省略)
(out)PYTHONPATH       : D:\files\Python
(out)OneDriveConsumer : C:\Users\Username\OneDrive
(out)PSPath           : Microsoft.PowerShell.Core\Registry::HKCU\Environment
(out)PSParentPath     : Microsoft.PowerShell.Core\Registry::HKCU
(out)PSChildName      : Environment
(out)PSProvider       : Microsoft.PowerShell.Core\Registry

もちろん直接パスを指定して取得しても問題ない。

Get-ItemProperty Registry::HKCU\Environment
(out)
(out)TEMP             : C:\Users\Username\AppData\Local\Temp
(out)TMP              : C:\Users\Username\AppData\Local\Temp
(out)(省略)

特定の値だけを取り出すときはSelect-Objectを併用する。

Get-ItemProperty Registry::HKCU\Environment | select -ExpandProperty PYTHONPATH
(out)D:\files\Python

プロセス

プロセスの取得Get-Processps
プロセスの停止Stop-Processkill
プロセスの開始Start-Processstart
プロセスの停止を待機Wait-Process
プロセスにデバッガーをアタッチDebug-Process

サービス

サービスを取得Get-Service
サービスを再起動Restart-Service
中断中のサービスを再開Resume-Service
停止中のサービスを開始Start-Service
サービスを停止Stop-Service
サービスを中断Suspend-Service
サービスを開始/停止/中断/変更Set-Service
新しいサービスを作成
サービスを削除
New-Service
Remove-Service

ネットワーク関連

ネットワーク設定・情報の確認

Get-NetAdapterNICの情報を表示
Get-NetIPConfigurationゲートウェイやDNSなどの情報を含むIP設定を表示
Get-NetIPAddress割り当てられたIPアドレス設定を表示
Get-NetRouteルートテーブルを表示
Get-NetNeighborARPテーブルを表示
Find-NetRoute -RemoteIPAddress 宛先指定の宛先との通信で使用される送信元IPアドレスとルート設定を検索
Get-NetIPv4Protocol
Get-NetIPv6Protocol
Get-NetTCPSetting
Get-NetUDPSetting
プロトコル別の設定を表示

疎通確認

Test-Connection

Test-ConnectionでPing(ICMP Echo Request)を実行できる。

Test-Connection example.com.
(out)
(out)Source        Destination     IPV4Address      IPV6Address         Bytes    Time(ms)
(out)------        -----------     -----------      -----------         -----    --------
(out)(非表示)      example.com.    (非表示)          (非表示)                32       117
(out)(非表示)      example.com.    (非表示)          (非表示)                32       118
(out)(非表示)      example.com.    (非表示)          (非表示)                32       118
(out)(非表示)      example.com.    (非表示)          (非表示)                32       117
-Countエコー要求回数
-Delayエコー要求間隔(秒)
-MaxHops最大ホップ数(TTL)
-BufferSizeデータサイズ
-DontFragmentフラグメント禁止

以下のパラメータを実行するには管理者権限が必要である。

-RepeatCtrl-Cまで継続実行
-TracerouteTraceRoute実行 → Test-NetConnection
-MtuSizeMTUサイズを算出
-TcpPort NTCP Pingを実行

Test-NetConnection

Test-NetConnectionを使うとPingを含む接続テストを行える。

何も指定しないとPingのみを行う。

Test-NetConnection example.com.
(out)
(out)ComputerName           : example.com.
(out)RemoteAddress          : (非表示)
(out)InterfaceAlias         : イーサネット 4
(out)SourceAddress          : (非表示)
(out)PingSucceeded          : True
(out)PingReplyDetails (RTT) : 118 ms

-Portを付けるとTCP接続が確立できるか検査する。

Test-NetConnection example.com. -Port 80
(out)
(out)ComputerName     : example.com.
(out)RemoteAddress    : (非表示)
(out)RemotePort       : 80
(out)InterfaceAlias   : イーサネット 4
(out)SourceAddress    : (非表示)

-InformationLevel DetailedでPingとTCP接続の検査を同時にできる。

Test-NetConnection example.com. -Port 80 -InformationLevel Detailed
(out)
(out)ComputerName            : example.com.
(out)RemoteAddress           : (非表示)
(out)RemotePort              : 80
(out)NameResolutionResults   : (非表示)
(out)                          (非表示)
(out)MatchingIPsecRules      :
(out)NetworkIsolationContext : Internet
(out)IsAdmin                 : False
(out)InterfaceAlias          : イーサネット 4
(out)SourceAddress           : (非表示)
(out)NetRoute (NextHop)      : (非表示)
(out)TcpTestSucceeded        : True

-TracerouteでTraceRouteを取得できる。

Test-NetConnection example.com. -TraceRoute
(out)(省略)
(out)TraceRoute             : (IPアドレス非表示)
(out)                         (IPアドレス非表示)
(out)                         (IPアドレス非表示)
(out)                         ...

連続Ping

連続Pingには、コマンドプロンプトでも使用できるping -tが使用できる。結果をオブジェクトとして受け取って何かの処理をしたいなら、管理者権限でTest-Connectionを使うか、無限ループでTest-Connectionを実行する。

無限ループでTest-Connectionを行う例(シンプル)
<#
.SYNOPSIS
Pingを連続して実行する

.DESCRIPTION
指定の宛先に対してPingを連続して実行します。

.PARAMETER Destination
Pingの宛先(IPアドレスまたはFQDN)

.PARAMETER Timeout
Pingのタイムアウト値(秒)
デフォルト 3秒

.PARAMETER Interval
Pingの実行間隔(ミリ秒)
デフォルト 5000ミリ秒

.EXAMPLE
Test-PingContinueSimple example.com -Timeout 3 -Interval 1000 | ft @{l="Time";e={$_.Time.ToString("yyyy-MM-dd HH:mm:ss.fff")}},Status,Latency,TTL
時刻をミリ秒まで表示して、Ping結果を表示します。

#>
function Test-PingContinueSimple
{
	param([string]$Destination, [uint]$Timeout=3, [uint]$Interval=5000)

    $destination_ip = $null
    if(-not [System.Net.IPAddress]::TryParse($Destination, [ref]$destination_ip)){
        try {
            $destination_ip = Resolve-DnsName $Destination -ErrorAction Stop | select-object -ExpandProperty IPAddress -First 1
        }
        catch {
            write-error "Cannot find $Destination."
			return
        }
    }

    write-host "`nPing to $Destination($destination_ip)."
    
	while($true){
		$pingtime = Get-Date
		$tc_result = Test-Connection $destination_ip -Count 1 -TimeoutSeconds $Timeout
		
		[PSCustomObject]@{
			Time = $pingtime
			Latency = $tc_result.Latency
			TTL = $tc_result.Reply.Options.TTL
			Status = $tc_result.Status
		}
		
		$sleeptime = (($pingtime + (New-TimeSpan -Millisecond $interval)) - (Get-Date)).TotalMilliseconds
		if($sleeptime -gt 0){
			start-sleep -Milliseconds $($sleeptime)
		}
	}
}
無限ループでTest-Connectionを行う例(複雑)
class PingResult{
	[DateTime] $Time
	[string] $Status
	[int] $Latency
	[int] $TTL

	[bool] IsSuccess(){
		return $this.Status -eq 'Success'
	}
}

<#
.SYNOPSIS
Pingを連続して実行する

.DESCRIPTION
指定の宛先に対してPingを連続して実行します。

.PARAMETER Destination
Pingの宛先(IPアドレスまたはFQDN)

.PARAMETER Timeout
Pingのタイムアウト値(秒)
デフォルト 3秒

.PARAMETER Interval
Pingの実行間隔(ミリ秒)
デフォルト 5000ミリ秒

.PARAMETER ResultOnly
実行中の進捗を表示しない
#>
function Test-PingContinue
{
	param([string]$Destination, [uint]$Timeout=3, [uint]$Interval=5000, [switch]$ResultOnly)

    $destination_ip = $null
    if(-not [System.Net.IPAddress]::TryParse($destination, [ref]$destination_ip)){
        try {
            $destination_ip = Resolve-DnsName $destination -ErrorAction Stop | select-object -ExpandProperty IPAddress -First 1
        }
        catch {
            write-error "Cannot find $destination."
			return
        }
    }

    write-host "`nPing to $destination($destination_ip)."
    
    $counter = @{Total=[uint]0;Success=[uint]0;Latency=@{Sum=[uint]0;Min=[int]::MaxValue;Max=[int]::MinValue}}
    try{
	    while($true){
			$pingtime = Get-Date
			$tc_result = Test-Connection $destination_ip -Count 1 -TimeoutSeconds $timeout
			$result = [PingResult]@{
				Time = $pingtime
				Status = $tc_result.Status
				Latency = $tc_result.Latency
				TTL = $tc_result.Reply.Options.TTL
			}
			$counter.Total++
			if( $result.IsSuccess ){
				$counter.Success++
				$counter.Latency.Sum += $result.Latency
				if( $result.Latency -lt $counter.Latency.Min){
					$counter.Latency.Min = $result.Latency
				} elseif( $result.Latency -gt $counter.Latency.Max){
					$counter.Latency.Max = $result.Latency
				}
			}
	        
			if(-not $ResultOnly){
				$result
			}
			$sleeptime = (($pingtime + (New-TimeSpan -Millisecond $interval)) - (Get-Date)).TotalMilliseconds
	        if($sleeptime -gt 0){
	            start-sleep -Milliseconds $($sleeptime)
	        }
	    }
    }
    finally{
		if($counter.Success -gt 0){
			$report = [PSCustomObject]@{
	            Packet  = [PSCustomObject]@{Sent=$counter.Total;Success=$counter.Success;Fail=$counter.Total - $counter.Success}
	            Latency = [PSCustomObject]@{Average=[Math]::round($counter.Latency.Sum/$counter.Success, 1);Max=$counter.Latency.Max;Min=$counter.Latency.Min}
	        }
		}else{
			$report = [PSCustomObject]@{
	            Packet  = [PSCustomObject]@{Sent=$counter.Total;Success=$counter.Success;Fail=$counter.Total - $counter.Success}
	            Latency = [PSCustomObject]@{Average=-1;Max=-1;Min=-1}
	        }
		}
		
		write-host "`n==Ping Status Report=="
		write-host "ICMP Packet: $($report.Packet.Sent) sent, $($report.Packet.Success) successed, $($report.Packet.Fail) failed."
		write-host "Latency(ms): Average = $($report.Latency.Average), Max = $($report.Latency.Max), Min = $($report.Latency.Min)"

		write-output $report
    }
}

DNS

Resolve-DnsName

Resolve-DnsNameで名前解決を実行できる。

Resolve-DnsName -Name example.com. -Type SOA -Server 1.1.1.1
(out)
(out)Name                        Type TTL   Section    PrimaryServer               NameAdministrator           SerialNumber
(out)----                        ---- ---   -------    -------------               -----------------           ------------
(out)example.com                 SOA  3600  Answer     ns.icann.org                noc.dns.icann.org           2024081462
-CacheOnlyローカルキャッシュのみを使う
-DnsOnlyDNSプロトコルのみを使う
-NoHostsFilehostsファイルを使わない
-NoRecursionサーバに非再帰的問い合わせで問い合わせる
-TcpOnlyTCPで問い合わせる

DnsClient-PS

ネットワーク技術者であれば、Resolve-DnsNameはかゆいところに手が届かないと感じるかもしれない。インストールが必要だがDnsClient-PSモジュールを使うと低レベルな情報を確認できる。

(out)# 初回のみ
Install-Module -Name DnsClient-PS -Scope CurrentUser
(out)
(out)
Resolve-Dns www.example.com A -NameServer 1.1.1.1 -UseTcpFallback
(out)
(out)NameServer   : 1.1.1.1:53
(out)Additionals  : {.}
(out)AllRecords   : {www.example.com., .}
(out)AuditTrail   :
(out)Answers      : {www.example.com.}
(out)Authorities  : {}
(out)ErrorMessage : No Error
(out)HasError     : False
(out)Header       : ;; ->>HEADER<<- opcode: Query, status: No Error, id: 29657
(out)               ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
(out)Questions    : {www.example.com. IN A}
(out)MessageSize  : 60
(out)Settings     : DnsClient.LookupClientSettings
(out)
(out)
Resolve-Dns www.example.com A -NameServer 1.1.1.1 -UseTcpFallback | Select-Object -ExpandProperty Answers
(out)
(out)DomainName       TimeToLive RecordClass RecordType RecordData
(out)----------       ---------- ----------- ---------- ----------
(out)www.example.com. 1725       IN          A          **masked**
(out)

ウェブリクエスト

Invoke-WebRequest

Invoke-WebRequestでウェブアクセスを実行できる。

Invoke-WebRequest -Uri https://www.google.com/
(out)
(out)StatusCode        : 200
(out)StatusDescription : OK
(out)Content           : ; tagName=IMG; alt=
(out)                    Google; height=92; src=/images/branding/googlelogo/1x/googlelogo_white_background_color_272x92dp.pn
(out)                    g; style=padding:28px 0 14px; width=272; id=hplogo}}
(out)InputFields       : {@{outerHTML=; tagName=INPUT; value=ja; name=hl; type=hid
(out)                    den}, @{outerHTML=; tagName=INPUT; name=source; type=
(out)                    hidden; value=hp}, @{outerHTML=; tagName=INPUT; name=biw; type=hidd
(out)                    en}, @{outerHTML=; tagName=INPUT; name=bih; type=hidden}…}
(out)Links             : {@{outerHTML=検索; tagName=A; class=gbzt gbz0l gbp1; id=gb_1; hre
(out)                    f=https://www.google.co.jp/webhp?tab=ww}, @{outerHTML=…}
(out)RawContentLength  : 56471
(out)RelationLink      : {}

Invoke-RestMethod

Invoke-RestMethodはRestful APIで使用することを想定したウェブアクセス用のコマンドレットである。GET/POSTなどのメソッド指定や、リクエストの本文指定などREST APIで使用する機能が用意されている。

Invoke-RestMethod -Method GET -Uri https://example.com/
(out)
(out)
(out)(中略)
(out)
(out)

Example Domain

(out)

This domain is for use in illustrative examples in documents. You may use this (out) domain in literature without prior coordination or asking for permission.

(out)

More information...

(out)
(out) (out)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です