Qiita初投稿です。
目次
1.背景
2.環境
3.処理フロー
4.ソース
5.ソースの説明
6.改善点
1.背景
VS CodeでOracleを扱っていて、WindowsのOracleサービスを手動で起動したい時に、もっと手っ取り早くできないかと考え、どうせなら検索できるようにしてしまえ、
ということで作成。
2.環境
Windows 11 Pro 22H2Windows PowerShell ISE(x86)
Oracle Database 21c Express Edition
Visual Studio Code 1.92.2 (system setup)
3.処理フロー
開始
↓
Windowsサービスの情報を取得
↓
検索ワードをコンソールから入力 ※GUIの方がベターだが、一旦コンソールとする
↓
検索結果を取得
↓
検索結果がない場合の処理
↓
複数のWindowsサービスがヒットした場合に起動するサービスを選択する処理
↓
停止状態のWindowsサービスを起動させる
↓
起動状態のWindowsサービスを停止/再起動させる
↓
続けて検索するかの確認 ※ユーザーが「 No 」を入力するまで繰り返す
↓
終了
4.ソース
#------------------------------------------------------
# Windowsサービスをキーワードで検索し、
# 指定したWindowsサービスを起動するスクリプト
# 注意:本スクリプトは管理者権限でないと実行できない
#------------------------------------------------------
# エラーが発生してもスクリプトを停止させない
$ErrorActionPreference = "Continue"
do {
# Windowsサービス情報を取得
$services = Get-Service | Select-Object Status, Name, DisplayName
# 検索ワードを入力
$searchWord = (Read-Host "検索したいWindowsサービス名を入力してください (*<検索キーワード>*で部分一致検索、Enterキー押下で全量検索します)").ToLower()
# 検索結果を取得
$matches = $services | Where-Object { $_.Name.ToLower() -like "*$searchWord*" -or $_.DisplayName.ToLower() -like "*$searchWord*" }
# 検索結果がヒットしない場合、再度検索するか確認
if (-not $matches) {
Write-Host "該当するWindowsサービスが見つかりません。再度検索しますか? (Yes/No)"
$confirm = (Read-Host "選択してください (Yes / No)").ToLower()
if ($confirm -ne "yes") {
break
}
continue
}
# スタートアップの種別変更は別ファイルで行う
# 複数のWindowsサービスがヒットした場合、起動するWindowsサービスを選択
if ($matches.Count -gt 1) {
Write-Host "複数のWindowsサービスがヒットしました。起動するWindowsサービスを選択してください"
for ($i = 0; $i -lt $matches.Count; $i++) {
Write-Host "$($i + 1): $($matches[$i].DisplayName)"
}
# TODO : 「 選択してください 」表示後にEnterキーを押下した時の挙動がおかしい
$index = [int](Read-Host "選択してください")
$serviceToStartOrStop = $matches[$index - 1]
} else {
$serviceToStartOrStop = $matches[0]
}
# 停止状態のWindowsサービスを起動する
if ($serviceToStartOrStop.Status -eq "Stopped") {
try {
Write-Host "Windowsサービス '$($serviceToStartOrStop.DisplayName)' の稼働ステータスは '$($serviceToStartOrStop.Status)' です"
Write-Host "1: 起動"
Write-Host "2: 再度検索し直す"
Write-Host "3: ツールの終了"
$choice = Read-Host "選択してください(1, 2, 3,)"
Switch($choice) {
1 {
start-Service $serviceToStartOrStop.Name
Write-Host "Windowsサービス '$($serviceToStartOrStop.DisplayName)' が起動されました"
}
2 {
Write-Host "検索に戻ります"
continue
}
3 {
Write-Host "ツールを終了します"
exit
}
default {
Write-Host "無効な選択です。ツールを終了します"
exit
}
}
} catch {
Write-Host "エラーが発生しました: $($_.Exception.Message)"
Write-Warning "スタックトレース:"
$_.Exception.StackTrace | Out-String
}
} else {
Write-Host "Windowsサービス '$($serviceToStartOrStop.DisplayName)' は既に起動しています"
}
# 起動状態のWindowsサービスを停止または再起動する
if ($serviceToStartOrStop.Status -eq "Running") {
try {
Write-Host "Windowsサービス '$($serviceToStartOrStop.DisplayName)' の稼働ステータスは '$($serviceToStartOrStop.Status)' です。停止または再起動しますか?"
Write-Host "1: 停止"
Write-Host "2: 再起動"
Write-Host "3: 再度検索する"
Write-Host "4: ツールの終了"
$choice = Read-Host "選択してください(1, 2, 3, 4)"
switch ($choice) {
1 {
Stop-Service $serviceToStartOrStop.Name
Write-Host "Windowsサービス '$($serviceToStartOrStop.DisplayName)' が停止されました"
}
2 {
Restart-Service $serviceToStartOrStop.Name
Write-Host "Windowsサービス '$($serviceToStartOrStop.DisplayName)' が再起動されました"
}
3 {
Write-Host "検索に戻ります"
continue
}
4 {
Write-Host "ツールを終了します"
exit
}
default {
Write-Host "無効な選択です。ツールを終了します"
exit
}
}
} catch {
Write-Host "エラーが発生しました: $($_.Exception.Message)"
Write-Warning "スタックトレース:"
$_.Exception.StackTrace | Out-String
}
} else {
Write-Host "処理が完了しました"
}
# 続けて検索するかの確認
$confirm = (Read-Host "続けて検索しますか? (Yes / No)").ToLower()
}
while ($confirm -eq "yes")
Write-Host "ツールを終了します"
exit
5.コードの説明
あいまい検索
例:Oracle関連サービスを「 ora*xe 」で検索するケース
ToLower()を用いて大文字小文字の区別をなくしている。
$searchWord = (Read-Host "検索したいWindowsサービス名を入力してください (*<検索キーワード>*で部分一致検索)").ToLower()
実行例
検索したいWindowsサービス名を入力してください (*<検索キーワード>*で部分一致検索): ora*xe
複数のWindowsサービスがヒットしました。起動するWindowsサービスを選択してください
1: OracleJobSchedulerXE
2: OracleServiceXE
3: OracleVssWriterXE
選択してください:
サービスが複数ヒットした時の結果リスト表示
$matches.Countにヒット数を格納し、 forループで検索結果をあるだけリストアップさせる。# 複数のWindowsサービスがヒットした場合、起動するWindowsサービスを選択
if ($matches.Count -gt 1) {
Write-Host "複数のWindowsサービスがヒットしました。起動するWindowsサービスを選択してください"
for ($i = 0; $i -lt $matches.Count; $i++) {
Write-Host "$($i + 1): $($matches[$i].DisplayName)"
}
$index = [int](Read-Host "選択してください")
$serviceToStart = $matches[$index - 1]
} else {
$serviceToStart = $matches[0]
}
停止中のWindowsサービスを起動
変数「 serviceToStartOrStop 」にあいまい検索結果($matches)が格納されており、
サービスのステータスをif文で照合している。
# 停止状態のWindowsサービスを起動する
if ($serviceToStartOrStop.Status -eq "Stopped") {
try {
Write-Host "Windowsサービス '$($serviceToStartOrStop.DisplayName)' の稼働ステータスは '$($serviceToStartOrStop.Status)' です"
Write-Host "1: 起動"
Write-Host "2: 再度検索し直す"
Write-Host "3: ツールの終了"
$choice = Read-Host "選択してください(1, 2, 3,)"
Switch($choice) {
1 {
start-Service $serviceToStartOrStop.Name
Write-Host "Windowsサービス '$($serviceToStartOrStop.DisplayName)' が起動されました"
}
2 {
Write-Host "検索に戻ります"
continue
}
3 {
Write-Host "ツールを終了します"
exit
}
default {
Write-Host "無効な選択です。ツールを終了します"
exit
}
}
} catch {
Write-Host "エラーが発生しました: $($_.Exception.Message)"
Write-Warning "スタックトレース:"
$_.Exception.StackTrace | Out-String
}
} else {
Write-Host "Windowsサービス '$($serviceToStartOrStop.DisplayName)' は既に起動しています"
}
起動状態のWindowsサービスの停止または再起動
対象のサービスが起動中の場合は、停止または再起動を選択する。※検索に戻ることも可能
# 起動状態のWindowsサービスを停止または再起動する
if ($serviceToStartOrStop.Status -eq "Running") {
try {
Write-Host "Windowsサービス '$($serviceToStartOrStop.DisplayName)' の稼働ステータスは '$($serviceToStartOrStop.Status)' です。停止または再起動しますか?"
Write-Host "1: 停止"
Write-Host "2: 再起動"
Write-Host "3: 再度検索する"
Write-Host "4: ツールの終了"
$choice = Read-Host "選択してください(1, 2, 3, 4)"
switch ($choice) {
1 {
Stop-Service $serviceToStartOrStop.Name
Write-Host "Windowsサービス '$($serviceToStartOrStop.DisplayName)' が停止されました"
}
2 {
Restart-Service $serviceToStartOrStop.Name
Write-Host "Windowsサービス '$($serviceToStartOrStop.DisplayName)' が再起動されました"
}
3 {
Write-Host "検索に戻ります"
continue
}
4 {
Write-Host "ツールを終了します"
exit
}
default {
Write-Host "無効な選択です。ツールを終了します"
exit
}
}
} catch {
Write-Host "エラーが発生しました: $($_.Exception.Message)"
Write-Warning "スタックトレース:"
$_.Exception.StackTrace | Out-String
}
} else {
Write-Host "処理が完了しました"
}
# 続けて検索するかの確認
$confirm = (Read-Host "続けて検索しますか? (Yes / No)").ToLower()
}
while ($confirm -eq "yes")
Write-Host "ツールを終了します"
exit
6.改善点
・冒頭でも書いたGUI化
・スタートアップの種類を編集可能にする ※20240926追記:別ファイルで用意
・ 「 選択してください 」表示後に Enter キーを押下した時の
挙動がおかしいので、その修正