WindowsServer 2025 総合ガイド 第04回
PowerShellスクリプティング基礎 ― 自動化への第一歩
第3回では、PowerShellを使ったファイル・フォルダ操作、ディスク管理、ローカルユーザーとグループの管理を学びました。第4回となる今回は、PowerShellスクリプティングの基礎を学びます。変数、データ型、条件分岐、ループ処理、関数の定義、そしてエラーハンドリングまで、自動化スクリプトを作成するために必要な知識を習得しましょう。
4.1 この記事で学ぶこと
- 変数とデータ型を理解し、使用できる
- 条件分岐とループ処理を記述できる
- 関数を定義し、スクリプトファイルを作成できる
4.2 前提条件
- 第3回完了(PowerShellの基本操作が可能)
- Windows Server 2025にリモートデスクトップ接続できる状態
- PowerShell 7.4を管理者として起動できる状態
4.3 変数の基礎
プログラミングにおいて「変数」は、データを一時的に保存しておく箱のようなものです。PowerShellでは、変数を使うことで、コマンドの実行結果を保存したり、繰り返し使う値を管理したりできます。
4.3.1 変数の宣言と代入
PowerShellでは、変数名の前に $(ドル記号)を付けて変数を定義します。
[実行環境: PowerShell 7.4 (管理者)]
# 変数に値を代入
$message = "Hello, PowerShell!"
$number = 42
$isEnabled = $true
# 変数の値を表示
$message
$number
$isEnabled
実行結果の例:
Hello, PowerShell!
42
True
変数名の命名規則
変数名には以下のルールがあります。
- 英数字とアンダースコア(_)が使用可能
- 大文字小文字を区別しない(
$Nameと$nameは同じ変数) - 数字で始めることはできない
- スペースや特殊文字は使用できない(ただし
${変数名}の形式なら可能)
可読性のために、以下のような命名規則を推奨します。
| スタイル | 例 | 説明 |
|---|---|---|
| キャメルケース | $userName |
最初の単語は小文字、以降の単語は大文字で始める |
| パスカルケース | $UserName |
すべての単語を大文字で始める |
本シリーズでは、ローカル変数にはキャメルケース、グローバル変数やパラメータにはパスカルケースを使用します。
4.3.2 データ型
PowerShellは動的型付け言語であり、変数に代入した値によって自動的にデータ型が決まります。主要なデータ型を紹介します。
| データ型 | .NET型名 | 例 | 説明 |
|---|---|---|---|
| 文字列 | [String] | "Hello" |
テキストデータ |
| 整数 | [Int32] | 42 |
32ビット整数(約±21億) |
| 長整数 | [Int64] | 9999999999 |
64ビット整数 |
| 小数 | [Double] | 3.14 |
倍精度浮動小数点数 |
| 真偽値 | [Boolean] | $true, $false |
真または偽 |
| 配列 | [Array] | @(1, 2, 3) |
複数の値を格納 |
| ハッシュテーブル | [Hashtable] | @{Key = "Value"} |
キーと値のペア |
4.3.3 型の確認と変換
GetType()メソッド
変数のデータ型を確認するには、GetType()メソッドを使用します。
[実行環境: PowerShell 7.4 (管理者)]
# 各変数の型を確認
$text = "Hello"
$num = 100
$decimal = 3.14
$flag = $true
$text.GetType().Name
$num.GetType().Name
$decimal.GetType().Name
$flag.GetType().Name
実行結果の例:
String
Int32
Double
Boolean
型のキャスト(変換)
明示的に型を指定するには、型名を角括弧で囲んで変数の前に置きます。
# 文字列を整数に変換
[int]$stringToInt = "123"
$stringToInt.GetType().Name # Int32
# 整数を文字列に変換
[string]$intToString = 456
$intToString.GetType().Name # String
# 小数を整数に変換(小数点以下は切り捨て)
[int]$doubleToInt = 3.7
$doubleToInt # 4(四捨五入される)
注意:変換できない値をキャストしようとするとエラーになります。例えば、
[int]"abc"はエラーになります。
4.3.4 特殊変数
PowerShellには、システムが自動的に設定する特殊な変数があります。
| 変数 | 説明 |
|---|---|
$null |
値が存在しないことを表す |
$true |
真偽値の「真」 |
$false |
真偽値の「偽」 |
$_ |
パイプラインの現在のオブジェクト |
$PSVersionTable |
PowerShellのバージョン情報 |
$HOME |
ユーザーのホームディレクトリ |
$PWD |
現在の作業ディレクトリ |
$Error |
直近のエラー情報を格納する配列 |
[実行環境: PowerShell 7.4 (管理者)]
# 特殊変数の例
$PSVersionTable.PSVersion # PowerShellのバージョン
$HOME # ホームディレクトリ
$PWD # 現在のディレクトリ
実行結果の例:
Major Minor Patch PreReleaseLabel BuildLabel
----- ----- ----- --------------- ----------
7 4 7
C:\Users\Administrator
C:\Users\Administrator
4.4 文字列操作
サーバー管理では、ログメッセージの生成、設定ファイルの編集、レポートの作成など、文字列を扱う場面が多くあります。PowerShellでの文字列操作を学びましょう。
4.4.1 文字列の結合
文字列を結合するにはいくつかの方法があります。
[実行環境: PowerShell 7.4 (管理者)]
# 方法1: + 演算子
$firstName = "Taro"
$lastName = "Yamada"
$fullName = $firstName + " " + $lastName
$fullName # Taro Yamada
# 方法2: -join 演算子
$parts = @("2025", "01", "20")
$date = $parts -join "-"
$date # 2025-01-20
# 方法3: -f 演算子(フォーマット文字列)
$name = "Server01"
$status = "Running"
$message = "サーバー {0} の状態: {1}" -f $name, $status
$message # サーバー Server01 の状態: Running
4.4.2 変数展開(ダブルクォート vs シングルクォート)
PowerShellでは、ダブルクォート(")とシングルクォート(')で文字列の扱いが異なります。
[実行環境: PowerShell 7.4 (管理者)]
$serverName = "WS2025-01"
# ダブルクォート:変数が展開される
"サーバー名: $serverName" # サーバー名: WS2025-01
# シングルクォート:変数が展開されない(リテラル文字列)
'サーバー名: $serverName' # サーバー名: $serverName
サブ式演算子
ダブルクォート内で複雑な式を展開するには、$()(サブ式演算子)を使用します。
# プロパティやメソッドを展開する場合
$service = Get-Service -Name W32Time
"サービス状態: $($service.Status)"
# 計算結果を展開する場合
$a = 10
$b = 20
"合計: $($a + $b)" # 合計: 30
4.4.3 ヒアストリング(複数行文字列)
複数行にわたる文字列を定義するには、ヒアストリングを使用します。
[実行環境: PowerShell 7.4 (管理者)]
# 変数展開ありのヒアストリング
$serverName = "WS2025-01"
$multiLine = @"
サーバー情報レポート
====================
サーバー名: $serverName
作成日時: $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")
"@
$multiLine
実行結果の例:
サーバー情報レポート
====================
サーバー名: WS2025-01
作成日時: 2025-01-20 10:30:45
# 変数展開なしのヒアストリング(リテラル)
$literal = @'
これは $変数 が展開されません。
$(コマンド) も実行されません。
'@
$literal
注意:ヒアストリングの開始記号(
@"または@')の後ろには何も記述できません。また、終了記号("@または'@)は行頭に置く必要があります。
4.4.4 文字列メソッド
文字列オブジェクトには、便利なメソッドが多数用意されています。
[実行環境: PowerShell 7.4 (管理者)]
$text = " Hello, Windows Server 2025! "
# 大文字・小文字変換
$text.ToUpper() # " HELLO, WINDOWS SERVER 2025! "
$text.ToLower() # " hello, windows server 2025! "
# 文字列の検索
$text.Contains("Server") # True
$text.Contains("Linux") # False
$text.StartsWith(" Hello") # True
$text.EndsWith("! ") # True
# 文字列の置換
$text.Replace("2025", "2026") # " Hello, Windows Server 2026! "
# 空白の除去
$text.Trim() # "Hello, Windows Server 2025!"(前後の空白を除去)
$text.TrimStart() # "Hello, Windows Server 2025! "(前の空白を除去)
$text.TrimEnd() # " Hello, Windows Server 2025!"(後の空白を除去)
# 文字列の分割
"apple,banana,cherry".Split(",") # @("apple", "banana", "cherry")
# 部分文字列の取得
"PowerShell".Substring(0, 5) # "Power"
"PowerShell".Substring(5) # "Shell"
4.5 配列とハッシュテーブル
複数のデータをまとめて扱うには、配列やハッシュテーブルを使用します。
4.5.1 配列の作成とアクセス
配列は、複数の値を順序付けて格納するデータ構造です。
[実行環境: PowerShell 7.4 (管理者)]
# 配列の作成方法
$servers = @("Server01", "Server02", "Server03")
$numbers = 1, 2, 3, 4, 5 # @() は省略可能
$empty = @() # 空の配列
# 配列の要素数
$servers.Count # 3
# インデックスによるアクセス(0から始まる)
$servers[0] # Server01(最初の要素)
$servers[1] # Server02(2番目の要素)
$servers[-1] # Server03(最後の要素)
# 範囲指定
$servers[0..1] # @("Server01", "Server02")
配列への要素追加
# 要素の追加
$servers += "Server04"
$servers # @("Server01", "Server02", "Server03", "Server04")
パフォーマンスの注意:
+=演算子は、実際には新しい配列を作成して全要素をコピーします。大量の要素を追加する場合は、System.Collections.ArrayListやSystem.Collections.Generic.Listの使用を検討してください。
foreachでの繰り返し処理
# 配列の各要素に対して処理
$servers = @("Server01", "Server02", "Server03")
foreach ($server in $servers) {
Write-Host "Processing: $server"
}
実行結果の例:
Processing: Server01
Processing: Server02
Processing: Server03
4.5.2 ハッシュテーブルの作成とアクセス
ハッシュテーブルは、キーと値のペアでデータを格納するデータ構造です。設定情報やプロパティの管理に便利です。
[実行環境: PowerShell 7.4 (管理者)]
# ハッシュテーブルの作成
$serverInfo = @{
Name = "WS2025-01"
IPAddress = "192.168.1.10"
Role = "WebServer"
IsProduction = $true
}
# 値へのアクセス方法
$serverInfo["Name"] # WS2025-01(ブラケット記法)
$serverInfo.IPAddress # 192.168.1.10(ドット記法)
# 値の変更
$serverInfo.Role = "AppServer"
# キーと値の追加
$serverInfo["OS"] = "Windows Server 2025"
$serverInfo.Memory = "16GB"
# キーの存在確認
$serverInfo.ContainsKey("Name") # True
$serverInfo.ContainsKey("CPU") # False
# すべてのキーと値を取得
$serverInfo.Keys # すべてのキー
$serverInfo.Values # すべての値
ハッシュテーブルの表示
# ハッシュテーブルの内容を表示
$serverInfo | Format-Table -AutoSize
実行結果の例:
Name Value
---- -----
Name WS2025-01
IPAddress 192.168.1.10
Role AppServer
IsProduction True
OS Windows Server 2025
Memory 16GB
4.6 条件分岐
条件に応じて異なる処理を実行するには、条件分岐を使用します。
4.6.1 比較演算子
PowerShellの比較演算子は、他の言語とは異なる表記を使用します。
| 演算子 | 意味 | 例 |
|---|---|---|
-eq |
等しい(equal) | 5 -eq 5 → True |
-ne |
等しくない(not equal) | 5 -ne 3 → True |
-gt |
より大きい(greater than) | 5 -gt 3 → True |
-ge |
以上(greater or equal) | 5 -ge 5 → True |
-lt |
より小さい(less than) | 3 -lt 5 → True |
-le |
以下(less or equal) | 5 -le 5 → True |
パターンマッチング演算子
| 演算子 | 意味 | 例 |
|---|---|---|
-like |
ワイルドカードパターンに一致 | "Server01" -like "Server*" → True |
-notlike |
ワイルドカードパターンに一致しない | "Server01" -notlike "Web*" → True |
-match |
正規表現に一致 | "Server01" -match "Server\d+" → True |
-notmatch |
正規表現に一致しない | "Server01" -notmatch "^\d+" → True |
コレクション演算子
| 演算子 | 意味 | 例 |
|---|---|---|
-contains |
配列が値を含む | @(1,2,3) -contains 2 → True |
-notcontains |
配列が値を含まない | @(1,2,3) -notcontains 5 → True |
-in |
値が配列に含まれる | 2 -in @(1,2,3) → True |
-notin |
値が配列に含まれない | 5 -notin @(1,2,3) → True |
4.6.2 論理演算子
複数の条件を組み合わせるには論理演算子を使用します。
| 演算子 | 意味 | 例 |
|---|---|---|
-and |
両方が真 | ($a -gt 0) -and ($a -lt 10) |
-or |
どちらかが真 | ($a -eq 0) -or ($a -eq 1) |
-not / ! |
否定 | -not $false / !$false |
4.6.3 if文
最も基本的な条件分岐は if 文です。
[実行環境: PowerShell 7.4 (管理者)]
# 基本的なif文
$diskUsage = 85
if ($diskUsage -ge 90) {
Write-Host "警告: ディスク使用率が危険水準です!" -ForegroundColor Red
}
elseif ($diskUsage -ge 80) {
Write-Host "注意: ディスク使用率が高くなっています。" -ForegroundColor Yellow
}
else {
Write-Host "正常: ディスク使用率は問題ありません。" -ForegroundColor Green
}
実行結果の例:
注意: ディスク使用率が高くなっています。
実践例:サービス状態のチェック
# サービスの状態をチェックして適切なメッセージを表示
$service = Get-Service -Name "W32Time"
if ($service.Status -eq "Running") {
Write-Host "$($service.Name) は正常に実行中です。" -ForegroundColor Green
}
elseif ($service.Status -eq "Stopped") {
Write-Host "$($service.Name) は停止しています。" -ForegroundColor Yellow
}
else {
Write-Host "$($service.Name) の状態: $($service.Status)" -ForegroundColor Cyan
}
4.6.4 switch文
複数の条件を効率的に処理するには switch 文を使用します。
[実行環境: PowerShell 7.4 (管理者)]
# 基本的なswitch文
$dayOfWeek = (Get-Date).DayOfWeek
switch ($dayOfWeek) {
"Monday" { Write-Host "月曜日です。週の始まり!" }
"Tuesday" { Write-Host "火曜日です。" }
"Wednesday" { Write-Host "水曜日です。週の折り返し。" }
"Thursday" { Write-Host "木曜日です。" }
"Friday" { Write-Host "金曜日です。もうすぐ週末!" }
"Saturday" { Write-Host "土曜日です。休日!" }
"Sunday" { Write-Host "日曜日です。休日!" }
default { Write-Host "不明な曜日です。" }
}
ワイルドカードと正規表現の使用
# -Wildcard オプション
$fileName = "report_2025.xlsx"
switch -Wildcard ($fileName) {
"*.xlsx" { Write-Host "Excelファイルです。" }
"*.docx" { Write-Host "Wordファイルです。" }
"*.pdf" { Write-Host "PDFファイルです。" }
default { Write-Host "その他のファイルです。" }
}
# -Regex オプション
$ipAddress = "192.168.1.100"
switch -Regex ($ipAddress) {
"^10\." { Write-Host "クラスAプライベートアドレスです。" }
"^172\.(1[6-9]|2[0-9]|3[0-1])\." { Write-Host "クラスBプライベートアドレスです。" }
"^192\.168\." { Write-Host "クラスCプライベートアドレスです。" }
default { Write-Host "パブリックアドレスの可能性があります。" }
}
4.6.5 三項演算子(PowerShell 7以降)
PowerShell 7以降では、三項演算子(条件演算子)が使用できます。
[実行環境: PowerShell 7.4 (管理者)]
# 三項演算子: 条件 ? 真の場合 : 偽の場合
$isProduction = $true
$environment = $isProduction ? "本番環境" : "開発環境"
$environment # 本番環境
# 従来のif文での記述(比較用)
if ($isProduction) {
$environment = "本番環境"
} else {
$environment = "開発環境"
}
補足:三項演算子はPowerShell 7以降の機能です。Windows PowerShell 5.1では使用できません。
4.7 ループ処理
同じ処理を繰り返し実行するには、ループ処理を使用します。
4.7.1 foreach文
コレクション(配列など)の各要素に対して処理を行います。
[実行環境: PowerShell 7.4 (管理者)]
# 配列の各要素を処理
$services = @("W32Time", "Spooler", "WinRM")
foreach ($serviceName in $services) {
$service = Get-Service -Name $serviceName
Write-Host "$serviceName : $($service.Status)"
}
実行結果の例:
W32Time : Running
Spooler : Running
WinRM : Running
4.7.2 for文
カウンタを使った繰り返し処理に適しています。
[実行環境: PowerShell 7.4 (管理者)]
# 1から5まで繰り返し
for ($i = 1; $i -le 5; $i++) {
Write-Host "カウント: $i"
}
実行結果の例:
カウント: 1
カウント: 2
カウント: 3
カウント: 4
カウント: 5
配列のインデックスを使ったアクセス
# インデックスを使って配列にアクセス
$servers = @("Server01", "Server02", "Server03")
for ($i = 0; $i -lt $servers.Count; $i++) {
Write-Host "サーバー $($i + 1): $($servers[$i])"
}
4.7.3 while文とdo-while文
条件が真の間、処理を繰り返します。
[実行環境: PowerShell 7.4 (管理者)]
# while文:条件を先に評価
$count = 1
while ($count -le 3) {
Write-Host "while: $count"
$count++
}
# do-while文:処理を先に実行してから条件を評価
$count = 1
do {
Write-Host "do-while: $count"
$count++
} while ($count -le 3)
実践例:サービス起動の待機
# サービスが起動するまで待機(最大30秒)
$serviceName = "W32Time"
$maxWait = 30
$waited = 0
while ((Get-Service -Name $serviceName).Status -ne "Running" -and $waited -lt $maxWait) {
Write-Host "サービスの起動を待機中... ($waited 秒)"
Start-Sleep -Seconds 1
$waited++
}
if ((Get-Service -Name $serviceName).Status -eq "Running") {
Write-Host "サービスが起動しました。"
} else {
Write-Host "タイムアウト: サービスが起動しませんでした。"
}
4.7.4 ForEach-Objectコマンドレット
パイプラインで使用するループ処理です。
[実行環境: PowerShell 7.4 (管理者)]
# パイプラインでForEach-Objectを使用
Get-Service | Where-Object { $_.Status -eq "Running" } | ForEach-Object {
Write-Host "実行中: $($_.Name)"
} | Select-Object -First 5
簡略構文
# $_ は現在のオブジェクトを表す
1..5 | ForEach-Object { $_ * 2 } # 2, 4, 6, 8, 10
並列処理(PowerShell 7以降)
PowerShell 7以降では、-Parallel パラメータで並列処理が可能です。
# 並列処理(大量のデータ処理時に有効)
$servers = @("Server01", "Server02", "Server03", "Server04", "Server05")
$servers | ForEach-Object -Parallel {
Write-Host "Processing: $_"
Start-Sleep -Seconds 1 # 何らかの処理をシミュレート
} -ThrottleLimit 3 # 同時実行数を制限
補足:
-ParallelはPowerShell 7以降の機能です。並列処理内では、外部の変数に直接アクセスできない点に注意してください($using:スコープ修飾子を使用)。
4.7.5 ループ制御(break、continue)
ループの実行を制御するキーワードです。
[実行環境: PowerShell 7.4 (管理者)]
# break:ループを完全に終了
foreach ($i in 1..10) {
if ($i -eq 5) {
Write-Host "5でループを終了"
break
}
Write-Host "数値: $i"
}
# 出力: 1, 2, 3, 4 の後に "5でループを終了"
# continue:現在の反復をスキップして次へ
foreach ($i in 1..5) {
if ($i -eq 3) {
continue # 3をスキップ
}
Write-Host "数値: $i"
}
# 出力: 1, 2, 4, 5(3はスキップ)
4.8 関数の定義
繰り返し使用する処理は、関数として定義することで再利用できます。
4.8.1 関数の基本構文
[実行環境: PowerShell 7.4 (管理者)]
# 基本的な関数の定義
function Get-Greeting {
return "Hello, PowerShell!"
}
# 関数の呼び出し
Get-Greeting # Hello, PowerShell!
パラメータの定義
# パラメータを持つ関数
function Get-Greeting {
param (
[string]$Name
)
return "Hello, $Name!"
}
# パラメータを指定して呼び出し
Get-Greeting -Name "Administrator" # Hello, Administrator!
Get-Greeting "Administrator" # 位置パラメータでも可
4.8.2 戻り値(return)
PowerShellでは、関数内で出力されたすべての値が戻り値となります。return は明示的に値を返し、関数を終了します。
[実行環境: PowerShell 7.4 (管理者)]
# 戻り値の例
function Get-DiskUsage {
param (
[string]$DriveLetter = "C"
)
$volume = Get-Volume -DriveLetter $DriveLetter
$usedPercent = [math]::Round((($volume.Size - $volume.SizeRemaining) / $volume.Size) * 100, 1)
return $usedPercent
}
$usage = Get-DiskUsage -DriveLetter "C"
Write-Host "Cドライブ使用率: $usage%"
4.8.3 パラメータの詳細設定
型指定とデフォルト値
[実行環境: PowerShell 7.4 (管理者)]
function Test-ServiceStatus {
param (
[string]$ServiceName = "W32Time", # デフォルト値
[int]$TimeoutSeconds = 30 # デフォルト値
)
$service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($null -eq $service) {
return "サービス '$ServiceName' が見つかりません。"
}
return "サービス '$ServiceName' の状態: $($service.Status)"
}
# デフォルト値を使用
Test-ServiceStatus
# パラメータを指定
Test-ServiceStatus -ServiceName "Spooler" -TimeoutSeconds 60
必須パラメータ
function New-ServerReport {
param (
[Parameter(Mandatory)] # 必須パラメータ
[string]$ServerName,
[Parameter(Mandatory)]
[string]$ReportPath
)
Write-Host "サーバー: $ServerName のレポートを $ReportPath に作成します。"
}
# 必須パラメータを省略するとプロンプトが表示される
# New-ServerReport
ValidateSet による値の制限
function Set-Environment {
param (
[Parameter(Mandatory)]
[ValidateSet("Development", "Staging", "Production")]
[string]$Environment
)
Write-Host "環境を '$Environment' に設定しました。"
}
Set-Environment -Environment "Production" # OK
# Set-Environment -Environment "Test" # エラー: 許可されていない値
4.8.4 スコープの概念
変数にはスコープ(有効範囲)があります。
[実行環境: PowerShell 7.4 (管理者)]
# グローバルスコープとローカルスコープ
$globalVar = "グローバル変数"
function Test-Scope {
$localVar = "ローカル変数"
Write-Host "関数内から見たグローバル変数: $globalVar"
Write-Host "関数内から見たローカル変数: $localVar"
}
Test-Scope
Write-Host "関数外から見たグローバル変数: $globalVar"
# Write-Host "関数外から見たローカル変数: $localVar" # エラー: 存在しない
グローバル変数の明示的な指定
# 関数内からグローバル変数を変更
$counter = 0
function Increment-Counter {
$global:counter++
}
Increment-Counter
Increment-Counter
Write-Host "カウンター: $counter" # 2
ベストプラクティス:グローバル変数の多用は避け、パラメータと戻り値を使って関数間でデータを受け渡すことを推奨します。
4.9 スクリプトファイルの作成
ここまで学んだ内容を組み合わせて、再利用可能なスクリプトファイルを作成しましょう。
4.9.1 .ps1ファイルの作成
PowerShellスクリプトは .ps1 という拡張子のファイルに保存します。
まず、スクリプトを保存するフォルダを作成します。
[実行環境: PowerShell 7.4 (管理者)]
# スクリプト用フォルダを作成
New-Item -Path C:\Scripts -ItemType Directory -Force
次に、簡単なスクリプトファイルを作成します。
# スクリプトファイルを作成
$scriptContent = @'
# Hello-World.ps1
# 簡単な挨拶スクリプト
param (
[string]$Name = "World"
)
Write-Host "Hello, $Name!" -ForegroundColor Cyan
Write-Host "現在の日時: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
'@
Set-Content -Path "C:\Scripts\Hello-World.ps1" -Value $scriptContent
4.9.2 スクリプトの実行方法
スクリプトを実行するにはいくつかの方法があります。
[実行環境: PowerShell 7.4 (管理者)]
# 方法1: フルパスで実行
C:\Scripts\Hello-World.ps1
# 方法2: 相対パスで実行(カレントディレクトリがC:\Scriptsの場合)
Set-Location C:\Scripts
.\Hello-World.ps1
# 方法3: パラメータを指定して実行
C:\Scripts\Hello-World.ps1 -Name "Administrator"
実行結果の例:
Hello, Administrator!
現在の日時: 2025-01-20 11:30:45
4.9.3 コメントの書き方
コードを読みやすくするために、適切なコメントを記述しましょう。
# 単一行コメント
# これは単一行のコメントです
<#
複数行コメント
これは複数行に
わたるコメントです
#>
# 関数やスクリプトの説明にはヘルプコメントを使用
<#
.SYNOPSIS
サービスの状態を確認するスクリプト
.DESCRIPTION
指定されたサービスの状態を確認し、結果を表示します。
.PARAMETER ServiceName
確認するサービスの名前
.EXAMPLE
.\Check-Service.ps1 -ServiceName "W32Time"
W32Timeサービスの状態を確認します
#>
4.9.4 実践的なスクリプト例
サービス状態レポートを作成するスクリプトを作成しましょう。
[ファイル: C:\Scripts\Get-ServiceReport.ps1]
<#
.SYNOPSIS
重要なサービスの状態レポートを作成します
.DESCRIPTION
指定されたサービスの状態を確認し、レポートを出力します。
.PARAMETER Services
確認するサービス名の配列
.PARAMETER OutputPath
レポートの出力先パス(省略時は画面に表示)
.EXAMPLE
.\Get-ServiceReport.ps1
デフォルトのサービスリストでレポートを表示
#>
param (
[string[]]$Services = @("W32Time", "Spooler", "WinRM", "EventLog", "Dnscache"),
[string]$OutputPath
)
# レポートのヘッダー
$report = @()
$report += "=================================="
$report += "サービス状態レポート"
$report += "作成日時: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
$report += "=================================="
$report += ""
# 各サービスの状態を確認
foreach ($serviceName in $Services) {
$service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
if ($null -eq $service) {
$report += "[不明] $serviceName - サービスが見つかりません"
}
elseif ($service.Status -eq "Running") {
$report += "[正常] $serviceName - 実行中"
}
else {
$report += "[注意] $serviceName - $($service.Status)"
}
}
$report += ""
$report += "=================================="
# 出力
if ($OutputPath) {
$report | Set-Content -Path $OutputPath -Encoding UTF8
Write-Host "レポートを保存しました: $OutputPath" -ForegroundColor Green
}
else {
$report | ForEach-Object { Write-Host $_ }
}
このスクリプトを作成して実行します。
[実行環境: PowerShell 7.4 (管理者)]
# スクリプトファイルを作成(上記の内容をコピー)
# 実行
C:\Scripts\Get-ServiceReport.ps1
実行結果の例:
==================================
サービス状態レポート
作成日時: 2025-01-20 11:45:30
==================================
[正常] W32Time - 実行中
[正常] Spooler - 実行中
[正常] WinRM - 実行中
[正常] EventLog - 実行中
[正常] Dnscache - 実行中
==================================
4.10 エラーハンドリング基礎
スクリプトの信頼性を高めるには、エラーを適切に処理することが重要です。
4.10.1 エラーの種類
PowerShellのエラーには2種類あります。
| 種類 | 説明 | 例 |
|---|---|---|
| 終了エラー(Terminating Error) | 処理を中断するエラー | コマンドレットの致命的エラー、throw |
| 非終了エラー(Non-Terminating Error) | エラーを表示して処理を継続 | ファイルが見つからない、アクセス拒否 |
4.10.2 -ErrorActionパラメータ
コマンドレットのエラー動作を制御するには、-ErrorAction パラメータを使用します。
| 値 | 動作 |
|---|---|
| Continue | エラーを表示して処理を継続(デフォルト) |
| Stop | エラーを終了エラーとして処理を中断 |
| SilentlyContinue | エラーを表示せずに処理を継続 |
| Ignore | エラーを完全に無視($Errorにも記録されない) |
[実行環境: PowerShell 7.4 (管理者)]
# エラーを無視して処理を継続
$service = Get-Service -Name "存在しないサービス" -ErrorAction SilentlyContinue
if ($null -eq $service) {
Write-Host "サービスが見つかりませんでした。"
}
4.10.3 try-catch-finally構文
エラーをキャッチして適切に処理するには、try-catch-finally 構文を使用します。
[実行環境: PowerShell 7.4 (管理者)]
# 基本的なtry-catch
try {
# エラーが発生する可能性のある処理
$service = Get-Service -Name "存在しないサービス" -ErrorAction Stop
Write-Host "サービス状態: $($service.Status)"
}
catch {
# エラー発生時の処理
Write-Host "エラーが発生しました: $($_.Exception.Message)" -ForegroundColor Red
}
finally {
# 必ず実行される処理(省略可能)
Write-Host "処理を完了しました。"
}
実行結果の例:
エラーが発生しました: Cannot find any service with service name '存在しないサービス'.
処理を完了しました。
特定の例外をキャッチ
# 特定の例外タイプをキャッチ
try {
$content = Get-Content -Path "C:\存在しないファイル.txt" -ErrorAction Stop
}
catch [System.Management.Automation.ItemNotFoundException] {
Write-Host "ファイルが見つかりません。" -ForegroundColor Yellow
}
catch [System.UnauthorizedAccessException] {
Write-Host "アクセスが拒否されました。" -ForegroundColor Red
}
catch {
Write-Host "予期しないエラー: $($_.Exception.Message)" -ForegroundColor Red
}
4.10.4 $Error変数
$Error は、セッション中に発生したエラーを格納する自動変数です。
[実行環境: PowerShell 7.4 (管理者)]
# 直近のエラーを確認
$Error[0]
# エラーの詳細を確認
$Error[0] | Format-List -Force
# エラーをクリア
$Error.Clear()
4.10.5 実践的なエラーハンドリング例
サービス管理スクリプトにエラーハンドリングを追加します。
[ファイル: C:\Scripts\Check-ServiceStatus.ps1]
<#
.SYNOPSIS
サービスの状態を確認し、必要に応じて起動します
#>
param (
[Parameter(Mandatory)]
[string]$ServiceName
)
function Test-AndStartService {
param (
[string]$Name
)
try {
# サービスの取得を試行
$service = Get-Service -Name $Name -ErrorAction Stop
Write-Host "サービス '$Name' を確認しました。" -ForegroundColor Cyan
Write-Host "現在の状態: $($service.Status)"
# サービスが停止している場合は起動を試行
if ($service.Status -eq "Stopped") {
Write-Host "サービスを起動しています..." -ForegroundColor Yellow
try {
Start-Service -Name $Name -ErrorAction Stop
Write-Host "サービスを起動しました。" -ForegroundColor Green
}
catch {
Write-Host "サービスの起動に失敗しました: $($_.Exception.Message)" -ForegroundColor Red
return $false
}
}
return $true
}
catch [Microsoft.PowerShell.Commands.ServiceCommandException] {
Write-Host "サービス '$Name' が見つかりません。" -ForegroundColor Red
return $false
}
catch {
Write-Host "予期しないエラーが発生しました: $($_.Exception.Message)" -ForegroundColor Red
return $false
}
}
# メイン処理
$result = Test-AndStartService -Name $ServiceName
if ($result) {
Write-Host "`n処理が正常に完了しました。" -ForegroundColor Green
}
else {
Write-Host "`n処理中にエラーが発生しました。" -ForegroundColor Red
exit 1
}
4.11 まとめ
第4回では、以下の内容を学びました。
- 変数の基礎
$記号で変数を定義、GetType()で型を確認- 主要なデータ型:String、Int32、Double、Boolean、Array、Hashtable
- 特殊変数:
$null、$true、$false、$_、$Error
- 文字列操作
- ダブルクォートで変数展開、シングルクォートでリテラル
- ヒアストリング(
@" "@)で複数行文字列 - 文字列メソッド:
ToUpper()、Split()、Replace()、Trim()など
- 配列とハッシュテーブル
- 配列:
@()で作成、インデックスでアクセス - ハッシュテーブル:
@{}で作成、キーと値のペア
- 配列:
- 条件分岐
- 比較演算子:
-eq、-ne、-gt、-lt、-like、-match if-elseif-else文、switch文- 三項演算子(PowerShell 7以降):
条件 ? 真 : 偽
- 比較演算子:
- ループ処理
foreach文:コレクションの反復処理for文:カウンタベースの繰り返しwhile、do-while文:条件ベースの繰り返しForEach-Object:パイプラインでの使用、-Parallelで並列処理break、continueでループ制御
- 関数の定義
functionキーワードとparam()ブロック[Parameter(Mandatory)]で必須パラメータ[ValidateSet()]で値を制限- スコープ:ローカル変数とグローバル変数
- スクリプトファイルの作成
.ps1ファイルの作成と実行- コメント:
#(単一行)、<# #>(複数行)
- エラーハンドリング
- 終了エラーと非終了エラー
-ErrorActionパラメータ:Stop、SilentlyContinue などtry-catch-finally構文$Error変数でエラー情報を確認
これらのスクリプティング技術は、今後のサーバー管理の自動化に直接活用できます。
4.12 次回予告
第5回では「Windowsサービスの管理 ― サーバーの心臓部を理解する」と題して、サービスの概念と役割、状態確認・起動・停止の方法、スタートアップの種類の設定、そしてサービス監視スクリプトの作成を学びます。今回学んだスクリプティング技術を活用して、実践的なサービス管理を行いましょう。
4.13 参考リンク
- about_Variables – Microsoft Learn
- about_Operators – Microsoft Learn
- about_Comparison_Operators – Microsoft Learn
- about_If – Microsoft Learn
- about_Foreach – Microsoft Learn
- about_Functions – Microsoft Learn
- about_Functions_Advanced_Parameters – Microsoft Learn
- about_Try_Catch_Finally – Microsoft Learn
- PowerShell 7.4 の新機能 – Microsoft Learn
