Windows サーバーのサービスを遠隔で開始・停止・再起動したい場合、PowerShell のリモーティング(WinRM)を使うのが最も素直です。Windows PowerShell 5.1 では一部コマンドに -ComputerName
が用意されていますが、PowerShell 7 以降では互換性の都合で使えないこともあるため、確実に動かすなら Invoke-Command
(セッション経由)で統一すると安定します。以下では前提準備から単体操作、複数台一括、権限・ネットワークの注意点までを順に示します。
前提準備:WinRM を有効化し接続できる状態にする
# (対象サーバー側・管理者権限)初回のみ
Enable-PSRemoting -Force
# 動作確認
Test-WSMan
ドメイン外(ワークグループ)で接続する場合は、管理端末側の信頼済みホストに宛先を登録します。セキュリティ方針に従い最小限定で設定してください。
# (管理端末側・必要時のみ)ワークグループでの接続例
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "SERVER01,SERVER02"
基本パターン:単一サーバーのサービスを操作する
もっとも汎用的なのは資格情報を取得してセッションを張り、セッションに対してサービス操作を行う方法です。
$cred = Get-Credential # リモートで有効な管理アカウント
$s = New-PSSession -ComputerName SERVER01 -Credential $cred
# 状態の確認
Invoke-Command -Session $s -ScriptBlock { Get-Service -Name Spooler }
# 開始(存在しない・無効化サービスはエラー)
Invoke-Command -Session $s -ScriptBlock { Start-Service -Name Spooler }
# 停止(依存サービスがあれば -Force を検討)
Invoke-Command -Session $s -ScriptBlock { Stop-Service -Name Spooler -Force }
# 再起動(PowerShell 7 以降でも安定)
Invoke-Command -Session $s -ScriptBlock { Restart-Service -Name Spooler -Force }
# 自動起動へ変更
Invoke-Command -Session $s -ScriptBlock { Set-Service -Name Spooler -StartupType Automatic }
# 終了
Remove-PSSession $s
状態遷移を待機したいときは簡単なポーリングで確実に確認します。
Invoke-Command -Session $s -ScriptBlock {
Start-Service -Name Spooler
do {
$svc = Get-Service -Name Spooler
Start-Sleep -Seconds 1
} until ($svc.Status -eq 'Running')
$svc
}
Windows PowerShell 5.1 だけで完結させたい(-ComputerName を活用)
旧来環境なら Get-Service -ComputerName
が使えます。ただし Start/Stop/Restart-Service
には -ComputerName
がないため、開始・停止はリモート実行で補います。
# 状態確認(5.1)
Get-Service -Name Spooler -ComputerName SERVER01
# 開始・停止は Invoke-Command で代替
Invoke-Command -ComputerName SERVER01 -ScriptBlock { Restart-Service -Name Spooler -Force }
複数サーバーを一括で操作する(直列・並列)
少数台で確実性を取りたいなら直列ループ、大量台数で速度を重視するなら PowerShell 7 の並列処理を使います。
# 直列処理(5.1/7 共通)
$servers = @("SERVER01","SERVER02","SERVER03")
$cred = Get-Credential
foreach ($sv in $servers) {
Invoke-Command -ComputerName $sv -Credential $cred -ScriptBlock {
Restart-Service -Name "W32Time" -Force
Get-Service -Name "W32Time"
}
}
# 並列処理(PowerShell 7 以降)
$servers = @("SERVER01","SERVER02","SERVER03")
$cred = Get-Credential
$servers | ForEach-Object -Parallel {
Invoke-Command -ComputerName $_ -Credential $using:cred -ScriptBlock {
Stop-Service -Name "Spooler" -Force
Start-Service -Name "Spooler"
Get-Service -Name "Spooler"
}
} -ThrottleLimit 8
CIM を使った方法(WMI 経由)
WinRM が難しい環境や詳細制御が必要な場合は CIM セッションを使います。ファイアウォールやポート要件が異なるためネットワーク設計に合わせて選択します。
$cred = Get-Credential
$cim = New-CimSession -ComputerName SERVER01 -Credential $cred
# 取得
Get-CimInstance -CimSession $cim -ClassName Win32_Service -Filter "Name='Spooler'"
# 開始・停止(Invoke-CimMethod)
Invoke-CimMethod -CimSession $cim -ClassName Win32_Service -MethodName StartService -Key @{ Name = 'Spooler' }
Invoke-CimMethod -CimSession $cim -ClassName Win32_Service -MethodName StopService -Key @{ Name = 'Spooler' }
# 自動起動へ変更
Set-CimInstance -CimSession $cim -ClassName Win32_Service -Property @{ StartMode = 'Automatic' } -Key @{ Name='Spooler' }
Remove-CimSession $cim
よくあるエラーと対処の要点
接続で WinRM cannot process the request
が出る場合は対象で Enable-PSRemoting
とファイアウォール例外を再確認します。資格情報の問題で Access is denied
が出る場合はリモート側のローカル管理者権限や UAC リモート制限を見直します。ワークグループでの接続失敗は TrustedHosts
未設定や名前解決が典型です。サービス操作の失敗は依存関係や無効化状態が原因のことが多く、Get-Service -DependentServices
と Set-Service -StartupType
の組み合わせで順序を整えると解決します。
運用のベストプラクティス
恒常運用では JEA(Just Enough Administration)でサービス操作だけを許可した限定エンドポイントを用意すると安全です。アドホック操作は毎回 Get-Credential
で対話入力にし、スクリプトへ生のパスワードを埋め込まない方針にします。広範囲への一括操作は先に Get-Service
で影響範囲を可視化し、再起動や停止はメンテナンス時間帯や冗長構成の片系ずつなど段階的に実施するとリスクを抑えられます。
まとめ:最小レシピ
$cred = Get-Credential
Invoke-Command -ComputerName SERVER01 -Credential $cred -ScriptBlock {
Set-Service -Name "Spooler" -StartupType Automatic
Restart-Service -Name "Spooler" -Force
Get-Service -Name "Spooler"
}
まずは WinRM を整えて Invoke-Command
ベースで統一し、単体・複数台・待機・起動種別変更の基本4点を押さえれば、日常のサービス運用は滑らかに回るようになります。