PowerShell
#23
TIOBE#44
PYPL#18
GitHub#23
RedMonk#18
プログラミング言語
PowerShell
概要
PowerShellは、Microsoft社が開発したオブジェクト指向ベースのコマンドライン・スクリプト言語です。
詳細
PowerShellは2006年にMicrosoft社のJeffrey Snover氏によって開発されたタスクベースのコマンドライン・シェルおよびスクリプト言語で、.NET Frameworkを基盤として構築されています。従来のテキストベースのシェルとは異なり、.NETオブジェクトを直接操作できることが最大の特徴です。Windows PowerShellからPowerShell Core(現在はPowerShell 7+)への進化により、Windows、Linux、macOSでの動作が可能になり、クロスプラットフォーム対応を実現しました。システム管理、自動化、DevOps、クラウド管理などの分野で広く活用されており、豊富なコマンドレット(cmdlet)と強力なパイプライン機能を提供します。
書き方の例
Hello World
# 基本的な出力
Write-Host "Hello, World!"
# 変数を使った出力
$message = "こんにちは、PowerShell!"
Write-Host $message
# フォーマット出力
$name = "太郎"
$age = 25
Write-Host "私の名前は$nameで、$age歳です。"
# 配列の出力
$fruits = @("りんご", "バナナ", "オレンジ")
Write-Host "果物: $($fruits -join ', ')"
# 複数の出力方法
"シンプルな文字列出力"
Write-Output "パイプラインに送信"
Write-Information "情報メッセージ" -InformationAction Continue
変数とデータ型
# スカラー変数
$number = 42
$float = 3.14
$string = "文字列"
$boolean = $true
# 配列
$fruits = @("りんご", "バナナ", "オレンジ")
$numbers = @(1, 2, 3, 4, 5)
$mixed = @("文字列", 42, $true)
# ハッシュテーブル(連想配列)
$person = @{
Name = "田中太郎"
Age = 30
City = "東京"
}
# 厳密な型指定
[int]$integerVar = 100
[string]$stringVar = "型指定された文字列"
[datetime]$dateVar = Get-Date
# 配列の特殊な作成方法
$range = 1..10 # 1から10までの連続数値
$letters = 'A'..'Z' # AからZまでの文字
Write-Host "数値: $number"
Write-Host "配列の要素数: $($fruits.Count)"
Write-Host "ハッシュテーブルの値: $($person.Name)"
Write-Host "型情報: $($number.GetType().Name)"
条件分岐
# 基本的なif文
$score = 85
$grade = ""
if ($score -ge 90) {
$grade = "A"
} elseif ($score -ge 80) {
$grade = "B"
} elseif ($score -ge 70) {
$grade = "C"
} else {
$grade = "D"
}
Write-Host "得点: $score, 評価: $grade"
# 複数条件の組み合わせ
$age = 20
$hasLicense = $true
if ($age -ge 18 -and $hasLicense) {
Write-Host "運転できます"
} elseif ($age -ge 18) {
Write-Host "免許を取得してください"
} else {
Write-Host "18歳になってから免許を取得してください"
}
# switch文
$day = "水曜日"
switch ($day) {
"月曜日" { Write-Host "週の始まり" }
"水曜日" { Write-Host "週の中間" }
"金曜日" { Write-Host "週末まであと少し" }
default { Write-Host "他の曜日" }
}
# 比較演算子の例
$value = 10
if ($value -eq 10) { "等しい" }
if ($value -ne 5) { "等しくない" }
if ($value -gt 5) { "より大きい" }
if ($value -lt 20) { "より小さい" }
if ("Hello" -like "He*") { "パターンマッチ" }
if ("[email protected]" -match "\w+@\w+\.\w+") { "正規表現マッチ" }
配列とハッシュテーブルの操作
# 配列の操作
$fruits = @("りんご", "バナナ", "オレンジ")
# 要素の追加
$fruits += "ぶどう"
$fruits = $fruits + @("いちご", "メロン")
# 配列の要素にアクセス
Write-Host "最初の果物: $($fruits[0])"
Write-Host "最後の果物: $($fruits[-1])"
Write-Host "最初の3つ: $($fruits[0..2] -join ', ')"
# 配列の操作メソッド
$fruits | ForEach-Object { Write-Host "果物: $_" }
$longFruits = $fruits | Where-Object { $_.Length -gt 3 }
Write-Host "3文字より長い果物: $($longFruits -join ', ')"
# ハッシュテーブルの操作
$person = @{
Name = "田中太郎"
Age = 30
City = "東京"
}
# 新しいキーと値の追加
$person.Job = "エンジニア"
$person["Hobby"] = "読書"
# キーの存在確認
if ($person.ContainsKey("Age")) {
Write-Host "年齢: $($person.Age)"
}
# すべてのキーと値を取得
foreach ($key in $person.Keys) {
Write-Host "$key : $($person[$key])"
}
# ハッシュテーブルから配列への変換
$keys = $person.Keys
$values = $person.Values
Write-Host "キー: $($keys -join ', ')"
ループ処理
# ForEach-Object(パイプライン)
1..5 | ForEach-Object {
Write-Host "$_ の2乗は $($_ * $_) です"
}
# for文
for ($i = 1; $i -le 5; $i++) {
Write-Host "$i の2乗は $($i * $i) です"
}
# foreach文
$numbers = @(1, 2, 3, 4, 5)
foreach ($num in $numbers) {
$double = $num * 2
Write-Host "数値: $num, 2倍: $double"
}
# while文
$count = 0
while ($count -lt 5) {
Write-Host "カウント: $count"
$count++
}
# do-while文
$counter = 0
do {
$counter++
Write-Host "実行回数: $counter"
} while ($counter -lt 3)
# 配列のループ(インデックス付き)
for ($i = 0; $i -lt $fruits.Count; $i++) {
Write-Host "インデックス $i : $($fruits[$i])"
}
関数の定義と呼び出し
# 基本的な関数
function Get-Greeting {
param([string]$Name)
return "こんにちは、$Name さん!"
}
# パラメータのデフォルト値
function Get-Area {
param(
[int]$Width,
[int]$Height = 10
)
return $Width * $Height
}
# 複数の値を返す関数
function Get-NameAge {
return @("田中太郎", 25)
}
# 高度なパラメータ定義
function Get-ProcessInfo {
param(
[Parameter(Mandatory=$true)]
[string]$ProcessName,
[Parameter()]
[switch]$IncludeModules,
[Parameter()]
[ValidateSet("Name", "Id", "CPU")]
[string]$SortBy = "Name"
)
$processes = Get-Process -Name $ProcessName -ErrorAction SilentlyContinue
if ($IncludeModules) {
return $processes | Select-Object Name, Id, Modules
} else {
return $processes | Select-Object Name, Id, CPU | Sort-Object $SortBy
}
}
# 関数の呼び出し
$message = Get-Greeting -Name "山田"
Write-Host $message
$area = Get-Area -Width 5 # Heightはデフォルト値を使用
Write-Host "面積: $area"
$name, $age = Get-NameAge
Write-Host "名前: $name, 年齢: $age"
オブジェクト指向とクラス
# クラスの定義(PowerShell 5.0以降)
class Car {
[string]$Make
[string]$Model
[int]$Year
[int]$Mileage = 0
# コンストラクタ
Car([string]$make, [string]$model, [int]$year) {
$this.Make = $make
$this.Model = $model
$this.Year = $year
}
# メソッド
[void]Drive([int]$distance) {
$this.Mileage += $distance
Write-Host "$distance km 運転しました。総走行距離: $($this.Mileage) km"
}
[string]GetInfo() {
return "$($this.Year)年式 $($this.Make) $($this.Model)"
}
# 静的メソッド
static [string]GetCarCount() {
return "車の総数を取得する機能"
}
}
# オブジェクトの作成と使用
$myCar = [Car]::new("トヨタ", "プリウス", 2022)
Write-Host $myCar.GetInfo()
$myCar.Drive(50)
$myCar.Drive(30)
# カスタムオブジェクトの作成(PSCustomObject)
$customPerson = [PSCustomObject]@{
Name = "山田花子"
Age = 28
Department = "開発部"
}
$customPerson | Add-Member -MemberType ScriptMethod -Name "GetDescription" -Value {
return "名前: $($this.Name), 年齢: $($this.Age), 部署: $($this.Department)"
}
Write-Host $customPerson.GetDescription()
ファイル操作とテキスト処理
# ファイルの作成と書き込み
$content = @"
これはテストファイルです。
PowerShellでファイル操作を学んでいます。
複数行のテキストを書き込めます。
"@
$content | Out-File -FilePath "sample.txt" -Encoding UTF8
# ファイルの読み込み
$fileContent = Get-Content -Path "sample.txt" -Encoding UTF8
foreach ($line in $fileContent) {
Write-Host "読み込み: $line"
}
# CSV形式のデータ処理
$csvData = @"
Name,Age,Job
田中太郎,30,エンジニア
山田花子,25,デザイナー
佐藤次郎,35,マネージャー
"@
$csvData | Out-File -FilePath "employees.csv" -Encoding UTF8
# CSVファイルの読み込みとオブジェクト化
$employees = Import-Csv -Path "employees.csv" -Encoding UTF8
foreach ($employee in $employees) {
Write-Host "名前: $($employee.Name), 年齢: $($employee.Age), 職業: $($employee.Job)"
}
# ファイルシステムの操作
$files = Get-ChildItem -Path "." -Filter "*.txt"
foreach ($file in $files) {
Write-Host "ファイル: $($file.Name), サイズ: $($file.Length) bytes"
}
# JSONデータの処理
$jsonData = @{
Name = "API Response"
Data = @(
@{Id = 1; Title = "項目1"},
@{Id = 2; Title = "項目2"}
)
Status = "Success"
}
$jsonString = $jsonData | ConvertTo-Json -Depth 3
Write-Host "JSON形式:"
Write-Host $jsonString
$parsedJson = $jsonString | ConvertFrom-Json
Write-Host "パース後: $($parsedJson.Name)"
システム管理とコマンドレット
# プロセス管理
$processes = Get-Process | Where-Object { $_.CPU -gt 10 } |
Sort-Object CPU -Descending |
Select-Object -First 5 Name, CPU, WorkingSet
Write-Host "CPU使用率の高いプロセス TOP 5:"
$processes | Format-Table -AutoSize
# サービス管理
$services = Get-Service | Where-Object { $_.Status -eq "Running" } |
Sort-Object Name |
Select-Object Name, Status, StartType
Write-Host "実行中のサービス数: $($services.Count)"
# ネットワーク情報
$networkAdapters = Get-NetAdapter | Where-Object { $_.Status -eq "Up" }
foreach ($adapter in $networkAdapters) {
Write-Host "アダプター: $($adapter.Name), 速度: $($adapter.LinkSpeed)"
}
# イベントログの確認
$recentErrors = Get-EventLog -LogName System -EntryType Error -Newest 5 -ErrorAction SilentlyContinue
if ($recentErrors) {
Write-Host "最近のシステムエラー:"
$recentErrors | Select-Object TimeGenerated, Source, Message | Format-Table -Wrap
}
# レジストリ操作
$regValue = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Name "ProductName" -ErrorAction SilentlyContinue
if ($regValue) {
Write-Host "Windows版: $($regValue.ProductName)"
}
特徴的な機能
パイプラインとフィルタリング
# 強力なパイプライン処理
Get-Process |
Where-Object { $_.ProcessName -like "chrome*" } |
Sort-Object WorkingSet -Descending |
Select-Object ProcessName, Id, @{Name="Memory(MB)"; Expression={[math]::Round($_.WorkingSet/1MB, 2)}} |
Format-Table -AutoSize
# 配列のフィルタリングと変換
$numbers = 1..20
$evenSquares = $numbers |
Where-Object { $_ % 2 -eq 0 } |
ForEach-Object { $_ * $_ }
Write-Host "偶数の2乗: $($evenSquares -join ', ')"
# グループ化と集計
$files = Get-ChildItem -Path "C:\Windows\System32" -File -ErrorAction SilentlyContinue
$filesByExtension = $files |
Group-Object Extension |
Sort-Object Count -Descending |
Select-Object Name, Count
Write-Host "拡張子別ファイル数:"
$filesByExtension | Format-Table -AutoSize
エラーハンドリング
# try-catch-finally
try {
$result = 10 / 0
Write-Host "結果: $result"
}
catch [System.DivideByZeroException] {
Write-Error "ゼロで割ろうとしました: $($_.Exception.Message)"
}
catch {
Write-Error "予期しないエラー: $($_.Exception.Message)"
}
finally {
Write-Host "処理を完了しました"
}
# エラーアクション設定
Get-Process -Name "NonExistentProcess" -ErrorAction SilentlyContinue
if (-not $?) {
Write-Host "プロセスが見つかりませんでした"
}
# カスタムエラーの生成
function Test-Value {
param([int]$Value)
if ($Value -lt 0) {
throw [System.ArgumentException]::new("値は0以上である必要があります")
}
return $Value * 2
}
並行処理とジョブ
# バックグラウンドジョブ
$job1 = Start-Job -ScriptBlock { Start-Sleep 5; Get-Date }
$job2 = Start-Job -ScriptBlock { Start-Sleep 3; Get-Process | Measure-Object }
Write-Host "ジョブを実行中..."
Wait-Job $job1, $job2
$result1 = Receive-Job $job1
$result2 = Receive-Job $job2
Write-Host "ジョブ1結果: $result1"
Write-Host "ジョブ2結果: プロセス数 $($result2.Count)"
Remove-Job $job1, $job2
# 並列処理(PowerShell 7+)
$servers = @("server1", "server2", "server3")
$servers | ForEach-Object -Parallel {
# 仮想的なサーバー応答確認
Start-Sleep (Get-Random -Minimum 1 -Maximum 3)
Write-Output "$_ : 応答OK"
} -ThrottleLimit 3
バージョン
バージョン | ステータス | 主要な特徴 | リリース年 |
---|---|---|---|
PowerShell 7.4 | Latest | 改善されたパフォーマンス | 2023 |
PowerShell 7.3 | Current | $PSStyle、クラス改善 | 2022 |
PowerShell 7.2 | LTS | クロスプラットフォーム安定化 | 2021 |
PowerShell 7.1 | Current | 実験的機能、PSReadLine改善 | 2020 |
PowerShell 7.0 | Major | .NET Core移行、Linux/macOS対応 | 2020 |
Windows PowerShell 5.1 | Legacy | Windows標準、クラスサポート | 2016 |
参考ページ
公式ドキュメント
- PowerShell Documentation - Microsoft公式ドキュメント
- PowerShell Gallery - モジュールリポジトリ
- PowerShell GitHub - オープンソースリポジトリ
学習リソース
- PowerShell.org - コミュニティサイト
- Microsoft Learn PowerShell - 公式学習パス
- PowerShell Explained - 詳細解説サイト
開発ツール
- PowerShell ISE - 統合スクリプト環境
- Visual Studio Code - PowerShell拡張対応
- Windows Terminal - モダンなターミナル