はじめに
前のシリーズ(未経験からの基盤構築挑戦記)で、無料の範囲で基盤構築の主要な要素に一通り触れた。今回は新しい章として、PowerShellに挑戦してみる。
以前の現場で、PowerShellを使いこなしていた人を見たことがあった。手順書代わりに、次にやるべきコマンドを生成してくれるスクリプトを組んでいて、それをコピペしながら作業を進めていた。ただ、自分自身は触ったことがなく、「Windows Serverの案件で、ちょこちょこ名前を聞く」という以上の理解はなかった。他の求人でもPowerShellの名前が挙がることがあり、今回改めて触ってみることにした。
こんな方におすすめ
- PowerShellという名前は知っているが、触ったことがない方
- Linuxのコマンド操作には慣れているが、PowerShellとの違いが気になる方
- 「Excelの関数やVBAでも同じことができるのでは」と思っている方
PowerShellをインストールする
今回もGoogle Cloud Shell(Linux環境)上で試す。Cloud Shellには最初から入っていなかったので、案内に従ってインストールした。
pwsh --version
を打つと、インストール手順が案内された。
sudo apt-get update && sudo apt-get install -y wget
wget -q https://packages.microsoft.com/config/ubuntu/$(source /etc/os-release && echo $VERSION_ID)/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb
sudo apt-get update && sudo apt-get install -y powershell
pwsh --versionでPowerShell 7.6.6と表示され、インストール完了。pwshと打てば、そのままPowerShellのプロンプトに入れる。PowerShell自体はオープンソースで、Linux上でも無料で動く。
そもそもbashと何が違うのか
基本操作に入る前に、根本的な違いを整理しておく。
これまで触ってきたbashは、コマンドの実行結果を基本的に「ただの文字列(テキスト)」としてやり取りする。一方PowerShellは、実行結果を「オブジェクト」という、項目名(プロパティ)を持った構造化データとしてやり取りするのが最大の特徴。
Get-ChildItem
bashで言うlsにあたる。結果には「Name」「Length(サイズ)」「LastWriteTime(更新日時)」といった項目が最初から付いている。
Get-ChildItem | Select-Object Name
Select-Objectで「Name」という項目だけを選んで取り出せる。bashだとawkやcutで文字の位置を頼りに切り刻む必要があるところを、PowerShellでは項目の名前で直接指定するだけで済む。
Get-ChildItem | Sort-Object Length
「Length(サイズ)」という項目を基準に並び替える。これも同じ発想で、項目名を指定するだけで完結する。
つまずいたポイント:Where-Objectで結果が空になった
条件で絞り込むWhere-Objectを試した際、$_.Length -gt 1000(サイズが1000より大きい)という条件で、結果が空になった。
原因は2つ。手元のファイルがどちらも1000バイトを超えていなかったこと、そしてもう一つ、フォルダにはLengthという項目自体が存在しないため、比較の対象にすらならなかったこと。閾値を500に下げたところ、狙い通りに絞り込めた。
Get-ChildItem | Where-Object { $_.Length -gt 500 }
「結果が空だったらエラー」ではなく、「条件に合うものが単に無かった」という、正常な動作もあることを実感した場面だった。
コマンドの命名規則
Get-ChildItem、Select-Object、Sort-Object、Where-Objectは、すべて**「動詞-名詞」という統一されたパターン**で名前が付いている。
-
Get-〇〇:情報を取得する -
Set-〇〇:設定・変更する -
New-〇〇:新しく作る -
Remove-〇〇:削除する
このルールのおかげで、初めて見るコマンドでも、名前からおおよその役割が推測しやすくなっている。
応用:ログ解析とレポート生成
練習用の疑似ログファイルを作り、そこからエラーを抽出・集計・レポート化するところまでやってみる。
@"
2026-09-24 10:00:01 INFO Request processed successfully
2026-09-24 10:00:05 ERROR Database connection timeout
2026-09-24 10:00:10 INFO Request processed successfully
2026-09-24 10:00:15 ERROR Database connection timeout
2026-09-24 10:00:20 WARNING High memory usage detected
2026-09-24 10:00:25 ERROR Authentication failed
2026-09-24 10:00:30 INFO Request processed successfully
2026-09-24 10:00:35 ERROR Database connection timeout
2026-09-24 10:00:40 WARNING High memory usage detected
"@ | Out-File -FilePath server.log -Encoding UTF8
まずERRORの行だけ抽出。
Get-Content server.log | Where-Object { $_ -match "ERROR" }
次に、エラーメッセージの種類ごとに件数を集計する。
Get-Content server.log | Where-Object { $_ -match "ERROR" } | ForEach-Object { ($_ -split "ERROR ")[1] } | Group-Object | Select-Object Name, Count
ForEach-Objectで各行からメッセージ本体を取り出し、Group-Objectで同じ値ごとにまとめる(bashで言うsort | uniq -cに近い)。結果は「Database connection timeout」が3件、「Authentication failed」が1件。文字列を切り出した時点ではただのテキストだったはずが、Group-Objectを通すとまた「Name」「Count」という項目名を持ったデータに戻る。常にオブジェクトとして扱う、という設計の一貫性を感じた部分だった。
最後にレポート形式で出力。
$errorSummary = Get-Content server.log | Where-Object { $_ -match "ERROR" } | ForEach-Object { ($_ -split "ERROR ")[1] } | Group-Object | Select-Object Name, Count
Write-Output "===== サーバーログ エラーレポート ====="
Write-Output "総エラー件数: $((Get-Content server.log | Where-Object { $_ -match 'ERROR' }).Count)"
Write-Output ""
$errorSummary | ForEach-Object { Write-Output "・$($_.Name):$($_.Count)件" }
生のログ(時系列の羅列)から、人が一目で把握できるレポートの形まで、一連のパイプラインで組み立てられた。
そもそも、なぜPowerShellが必要なのか
一連の操作をやっていて、「これ、Excelの関数を組み合わせているのと似ているのでは」と感じた。実際、発想としては近い部分がある。ただ、決定的な違いがあった。
Excel(VBA含む)は、「誰かが入力したデータ」を扱う道具。一方PowerShellは、「コンピューターやシステムそのものの状態」を直接扱う道具。
- Excel:「サーバーのCPU使用率を見たい」→ 誰かが手動で調べて、Excelに入力する必要がある
- PowerShell:
Get-Processのようなコマンドで、システム自身から直接、生きた情報を取得できる
さらに、実行できる場所も違う。Excel/VBAはExcelが起動している1台のパソコンの中でしか動かないが、PowerShellはGUIもExcelもないサーバーの中でも単体で動き、リモートの別サーバーに対して指示を送ることもできる。「100台のサーバーを毎晩自動チェックする」といった処理は、Excelでは原理的に不可能だが、PowerShellなら人が見ていない深夜でも自動で完結できる。
実際に試してみる:Get-Process
Get-Process | Select-Object Name, CPU, Id | Sort-Object CPU -Descending | Select-Object -First 5
これで、今このマシンで実際にCPUを多く使っているプロセス上位5件が表示された。誰かが入力したデータではなく、今この瞬間の生きた情報を、さっきまでファイル一覧に使っていたのと全く同じ書き方(Select-Object、Sort-Object)で扱えている。対象が変わっても考え方は変わらない、というのを実感できた。
これをCSVとして出力すれば、そのままレポートとして残せる。
Get-Process | Select-Object Name, CPU, Id | Sort-Object CPU -Descending | Select-Object -First 5 | Export-Csv -Path process_report.csv -NoTypeInformation
一連の処理を、自分だけの関数にする
function Get-TopProcessReport {
param(
[int]$Top = 5,
[string]$OutputPath = "process_report.csv"
)
Get-Process | Select-Object Name, CPU, Id | Sort-Object CPU -Descending | Select-Object -First $Top | Export-Csv -Path $OutputPath -NoTypeInformation
Write-Output "レポートを $OutputPath に出力しました(上位 $Top 件)"
}
Get-TopProcessReport -Top 3 -OutputPath "top3_report.csv"
これで、さっきまで4行かけて書いていた処理が、パラメータ付きの1個のコマンドとして再利用可能になった。
厳密には、これは「ゼロから作った」というより、PowerShellが用意している既存の部品(Get-Process、Sort-Objectなど)を、自分なりの組み合わせで束ねたもの。Excelの関数が「完成品を1個使う」道具だとすれば、PowerShellは「部品を自分の目的に合わせて組み立てる」道具、という違いがある。組み合わせの数自体は有限でも、その並べ方・条件の付け方次第で、Excel関数の世界にはない「自分専用の道具」を、その場で作れる。
まとめ
今回、以下を体験できた。
- PowerShellのインストールと、bashとの根本的な違い(オブジェクトとして扱う設計)の理解
-
Select-Object・Sort-Object・Where-Objectによる基本操作 - ログ解析からレポート生成までの一連のパイプライン構築
-
Get-Processで、システムの生きた情報を取得する - 一連の処理を、パラメータ付きの自作関数としてまとめる
最後に、それぞれ何のためにやったのか、狙いを簡潔にまとめておく。
- ファイル一覧・ログ解析・プロセス取得と、対象を変えながら同じコマンド(Select-Object、Sort-Objectなど)を使い続けたこと:対象が変わっても、PowerShellの「オブジェクトとして扱う」考え方は一貫している、ということを体感するため
- Excel/VBAとの違いをあえて深掘りしたこと:「関数っぽい」という直感で終わらせず、PowerShellにしかできないこと(システムの生きた状態への直接アクセス、無人での自動実行)を明確にするため
PowerShellの本領(Active Directoryやサービス管理といった、Windows特有の機能)は、今回のLinux環境ではまだ体験できていない。ただ、「動詞-名詞の命名規則」「オブジェクトとして扱う」という土台の考え方は、対象がWindowsになっても変わらないはずなので、次はその応用に進んでいきたい。