【PowerShell】を扱う上でのコツ, where-objectとselect-object | SEの道標
Windows基礎

【PowerShell】を扱う上でのコツ, where-objectとselect-object

PowerShell を扱う上で最初に認知すべきことをいくつかご紹介します。

Get, Set, New, Add, Remove, Install, Start といった接頭辞で操作がおおよそ決まっている

PowerShell のコマンドでは接頭辞で操作内容がおおよそ決まっています。パターンも多くありませんので馴染めば馴染むほど、他のコマンドを使うときにどんなコマンドなのか直感的に分かりやすいです。

Get-* で始まるコマンドは情報を取得するコマンドです。

例えば Get-NetAdapter でネットワークアダプタの一覧が表示されますし、Get-NetFirewallRule で Windows Defender Firewall のルールの一覧が表示されます。

PS C:\> Get-NetAdapter

Name                      InterfaceDescription                    ifIndex Status       MacAddress             LinkSpeed
----                      --------------------                    ------- ------       ----------             ---------
Wi-Fi                     Intel(R) Wi-Fi 6 AX201 160MHz                20 Up           DC-1B-A1-0A-D9-A3       360 Mbps
Bluetooth ネットワーク... Bluetooth Device (Personal Area Netw...      15 Disconnected DC-1B-A1-0A-D9-A7         3 Mbps
VirtualBox Host-Only N... VirtualBox Host-Only Ethernet Adapter        13 Up           0A-00-27-00-00-0D         1 Gbps
イーサネット              Realtek PCIe GbE Family Controller           10 Disconnected 80-FA-5B-86-C1-25          0 bps

Set-* で始まるコマンドはオブジェクトの設定変更をするためのコマンドです。例えば Set-NetAdapter でネットワークアダプタに関する設定変更ができます。Get と Set は対になっているケースも多いです。

New-* は新たなオブジェクトを生成するときや新たな属性値を追加するときに使われます。

Set が上書きを許すのに対し、New-* は上書きを許さない、というニュアンスがあるようです。(並列して別のものを作るか、もしくはエラーを返す)

Add-* はオブジェクトに別のオブジェクトを追加するためのコマンドです。

例えば Add-WindowsCapability では Windows の機能の追加を行います。WindowsCapability というオブジェクトの中に、1つ1つの機能がオブジェクトとしてまとまっていて、そのうちの1つの機能を追加するときのコマンドになります。

Remove-* は New や Add で追加したものを削除するためのコマンドです。

Install-* はモジュールなどをインストールするときのコマンドです。

Start-* はサービスを起動するとき等のコマンドです。

PowerShell では Object が中心的な役割を担う

Object とは様々な説明が為されますが、ここでは「関連する色々な属性値を持ったもの」と捉えて下さい。

例えばドラクエにおいて各キャラクターは「HP, MP, Lv, 力, 素早さ, 運の良さ」等の属性値を持っており、一人ひとりがオブジェクトと考えられます。

Windows ではあらゆるものがオブジェクトとして作られています

具体的にはファイル、レジストリ、ユーザー、グループ、アクセストークン、ネットワークアダプタ設定、Windows Denfeder Firewall 設定、等です。

Get-*コマンドは Object を出力し Set-* や New-* コマンドは設定変更対象の Object を入力とする

さて、先ほど示した通り、Get-NetAdapter でネットワークアダプタの設定オブジェクトを取得できます。

このオブジェクトをそのまま Set-NetAdapter コマンドに渡せば、そのオブジェクトの設定変更をすることができます。

例えば以下の例では Get-NetAdapter の -ifIndex 20 (Wi-Fi Intel(R) Wi-Fi 6 AX201 160MHz) で指定されたネットワークアダプタについて、IP アドレスや DGW を設定しています。

PS C:> Get-NetAdapter -ifIndex 20 | New-NetIPAddress -AddressFamily IPv4 -IPAddress 192.168.0.201 -PrefixLength 24 -DefaultGateway 192.168.0.1

Where-Object と Select-Object の違い

Get-* コマンドではもっぱら、入力は何も無いですが出力はオブジェクトになります。

実際にはオブジェクトからテキストに変換されて見えますので findstr で対象行だけを表示させることができますが、より本来的なやり方としては、Where-Object を使います。

Set-* コマンドで設定対象としたいオブジェクトを一意に選ぶためには、Get-* コマンドからパイプラインで Where-Object に渡し、それを Set-* コマンドに渡せばよいのです。

先ほどは -ifIndex というオプションを使いましたが、コマンドによってオプションやマチマチなので1つ1つ覚えななきゃいけません。

ですが Where-Object さえ覚えておけばそんなオプションをいちいち覚える必要はありません。ほぼ全ての Get-* コマンドで使えるはずです。

PS C:> Get-NetAdapter | where-object ifIndex -like 20
Name                      InterfaceDescription                    ifIndex Status       MacAddress             LinkSpeed
----                      --------------------                    ------- ------       ----------             ---------
Wi-Fi                     Intel(R) Wi-Fi 6 AX201 160MHz                20 Up           DC-1B-A1-0A-D9-A3       270 Mbps

ちなみに -like はダブルクォーテーション等で囲んでワイルドカードを使うことができます。

PS C:\> Get-NetAdapter | where-object ifindex -like "1*"

Name                      InterfaceDescription                    ifIndex Status       MacAddress             LinkSpeed
----                      --------------------                    ------- ------       ----------             ---------
Bluetooth ネットワーク... Bluetooth Device (Personal Area Netw...      15 Disconnected DC-1B-A1-0A-D9-A7         3 Mbps
VirtualBox Host-Only N... VirtualBox Host-Only Ethernet Adapter        13 Up           0A-00-27-00-00-0D         1 Gbps
イーサネット              Realtek PCIe GbE Family Controller           10 Disconnected 80-FA-5B-86-C1-25          0 bps

一方、特定の属性だけを見たいときは Select-Object を使います。

PS C:> Get-NetAdapter | where-object ifindex -like 20 | Select-Object Name, ifIndex, Status, LinkSpeed

Name  ifIndex Status LinkSpeed
----  ------- ------ ---------
Wi-Fi      20 Up     360 Mbps

つまり、図示すると以下のようなイメージです。

なお、Select-Object を指定しないときは全ての属性が表示されているか、というと実はそうではありません。デフォルトで表示されるものと表示されないものがあります。

全ての属性を表示するときは | Select-Object * と指定します。

試しに自宅の PC で Get-NetAdapter と Get-NetAdapter | Select-Object * を比較してみて下さい。

オブジェクトの中にオブジェクト

オブジェクトの中の属性値としてさらにオブジェクトを持つこともあります。

先ほどの WindowsCapability もそうですし、もう 1 つ例を挙げると、Windows Defender Firewall はファイアウォールルールを定義する Rule というオブジェクトの中に AddressFilter や PortFilter といったオブジェクトを持っています。

【Win2022】Servercoreの使い方と初期Setup ~OpenSSH+PowerShell~
サーバーコアとデスクトップエクスペリエンス Windows Server はデス...

上記リンク先 [Windows FW ルールの確認] の章を注意深く見てみて下さい。Get-NetFirewallRule で出力した Object を Get-NetFirewallAddressFilter や Get-NetFirewallPortFilter に入力として渡しています。つまり FW ルールの Object の中に AddressFilter や PortFilter といった Object がある、ということです。

コメント

タイトルとURLをコピーしました