0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【PowerShell】Windowsサービスを検索し、起動/停止/再起動するスクリプトを書いてみた

Last updated at Posted at 2024-09-18

Qiita初投稿です。

目次

1.背景
2.環境
3.処理フロー
4.ソース
5.ソースの説明
6.改善点

1.背景

VS CodeでOracleを扱っていて、WindowsのOracleサービスを手動で起動したい時に、

もっと手っ取り早くできないかと考え、どうせなら検索できるようにしてしまえ、

ということで作成。

2.環境

Windows 11 Pro 22H2

Windows PowerShell ISE(x86)

Oracle Database 21c Express Edition

Visual Studio Code 1.92.2 (system setup)

3.処理フロー

開始

Windowsサービスの情報を取得

検索ワードをコンソールから入力 ※GUIの方がベターだが、一旦コンソールとする

検索結果を取得

検索結果がない場合の処理

複数のWindowsサービスがヒットした場合に起動するサービスを選択する処理

停止状態のWindowsサービスを起動させる

起動状態のWindowsサービスを停止/再起動させる

続けて検索するかの確認 ※ユーザーが「 No 」を入力するまで繰り返す

終了

4.ソース

SearchandControlWindowsServices.ps1
#------------------------------------------------------
# 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 キーを押下した時の
挙動がおかしいので、その修正

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?