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-Location | pwd, gl |
カレントディレクトリの変更 | Set-Location <NewPath> | cd, chdir |
カレントディレクトリの子要素取得 | Get-ChildItem | dir, ls, gci |
ファイル・ディレクトリの取得 | Get-Item | gi |
ファイル・ディレクトリの作成・コピー・移動・名前変更・削除 | 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-Item | ii |
ファイルの内容の取得・設定・追加・削除 | 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-Process | ps |
プロセスの停止 | Stop-Process | kill |
プロセスの開始 | Start-Process | start |
プロセスの停止を待機 | Wait-Process | |
プロセスにデバッガーをアタッチ | Debug-Process |
サービス
サービスを取得 | Get-Service | |
サービスを再起動 | Restart-Service | |
中断中のサービスを再開 | Resume-Service | |
停止中のサービスを開始 | Start-Service | |
サービスを停止 | Stop-Service | |
サービスを中断 | Suspend-Service | |
サービスを開始/停止/中断/変更 | Set-Service | |
新しいサービスを作成 サービスを削除 | New-Service Remove-Service |
ネットワーク関連
ネットワーク設定・情報の確認
Get-NetAdapter | NICの情報を表示 |
Get-NetIPConfiguration | ゲートウェイやDNSなどの情報を含むIP設定を表示 |
Get-NetIPAddress | 割り当てられたIPアドレス設定を表示 |
Get-NetRoute | ルートテーブルを表示 |
Get-NetNeighbor | ARPテーブルを表示 |
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 | フラグメント禁止 |
以下のパラメータを実行するには管理者権限が必要である。
-Repeat | Ctrl-Cまで継続実行 |
-Traceroute | TraceRoute実行 → Test-NetConnection |
-MtuSize | MTUサイズを算出 |
-TcpPort N | TCP 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 | ローカルキャッシュのみを使う |
-DnsOnly | DNSプロトコルのみを使う |
-NoHostsFile | hostsファイルを使わない |
-NoRecursion | サーバに非再帰的問い合わせで問い合わせる |
-TcpOnly | TCPで問い合わせる |
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 : {}
他の機能
プロキシ、ステートフルWebサービスを利用するためのセッションなどいろいろな機能が利用できる。詳細は公式ドキュメントを参照。
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)
(out)
(out)
(out)