前回はシステムやアプライアンス、組み込み機器などを運用していく上で「再起動」が現実的な方法の一つつであることを説明した。今回は、組み込み機器の再起動をPowerShellから実施する場合のサンプルスクリプトを取り上げる。

→連載「PowerShell Core入門 - 基本コマンドの使い方」の過去回はこちらを参照。

ルータの再起動準備

組み込み機器やアプライアンス、または何らかのシステムでもよいのだが、再起動の処理をWebブラウザから行うような仕組みになっているのであれば、これまで取り上げてきたPowerShellとSeleniumの機能を使うことで自動化が可能だ。

ここではそのサンプルとして、PowerShellスクリプトからルータを再起動する方法を取り上げる。まず、ルータの管理画面にMicrosoft Edgeからアクセスする。

  • ルータの管理インターフェース(Web)

    ルータの管理インタフェース(Web)

ルータの再起動を行うためのページを開く。

  • ルータの再起動を行うページを開く(メニューフレームあり)

    ルータの再起動を行うページを開く(メニューフレームあり)

このページはフレームで表示されているので、メニューのフレームを表示させずに再起動ページのみを表示させる。

  • ルータの再起動を行うページを開く

    ルータの再起動を行うページを開く

PowerShellから、この再起動ボタンをクリックすればよいので、このボタンを特定するために、Microsoft Edgeの開発者ツールを起動し、要素やそのXPathを調査しておく。

  • Microsoft Edge開発者ツールを起動してXPathなどを調べておく

    Microsoft Edge開発者ツールを起動してXPathなどを調べておく

対象 XPath
再起動ボタン //∗[@id="REBOOT"]

再起動ボタンは、IDが「REBOOT」またはXPathが「//*[@id="REBOOT"]」だ。使いやすい方で特定すればよい。

ちなみに、このルータの場合は再起動ボタンを押すと次のように確認用のダイアログが表示される。

  • 再起動の確認を求めるダイアログ

    再起動の確認を求めるダイアログ

この処理をPowerShellスクリプトから自動的に実行するようにすればよいわけだ。

PowerShellスクリプトにまとめる

では、上記処理をPowerShellスクリプトにまとめていく。まず、PowerShellから制御するためのMicrosoft Edge WebDriverを起動する。このスクリプトは稿末に付録として添付しておくのでそちらを参考にしていただきたい。

webdriver_edge_start.ps1

WebDriver経由でルータの再起動ページを開く。このルータはベーシック認証を使っているので、URLの指定にはベーシック認証のユーザー名とパスワードも含めてある。

Set-SeUrl -Url http://ユーザ名:パスワード192.168.1.1/ntt/userMaintenance/reboot

次に「再起動」ボタンの要素を取得してクリックする。

$Element = Get-SeElement -By Id -Value REBOOT
Invoke-SeClick -Element $Element -Action Click

この状態でMicrosoft Edgeには確認用のダイアログが表示されているので、「OK」をクリックする。

SeShouldHave -Alert -PassThru | Clear-SeAlert -Action Accept

このルータはシステムの再起動に3分ほどかかるので、処理が完了するまで待機する。

Start-Sleep 190

処理が終わったら、最後にMicrosoft Edge Driverを終了する。この終了スクリプトについても、稿末の付録を参考にしていただきたい。

Stop-SeDriver
webdriver_edge_stop.ps1

上記の処理をまとめたPowerShellスクリプト「router_reboot.ps1」は、次のようになる。

# Microsoft Edge Webドライバを起動
webdriver_edge_start.ps1

# ルータ再起動ページをオープン
'ルータ再起動ページをオープンします。'
Set-SeUrl -Url http://ユーザ名:パスワード@192.168.1.1/ntt/userMaintenance/reboot

# 再起動ボタンをクリック
'再起動ボタンをクリックします。'
$Element = Get-SeElement -By Id -Value REBOOT
Invoke-SeClick -Element $Element -Action Click
SeShouldHave -Alert -PassThru | Clear-SeAlert -Action Accept

# 3分間とちょっと待機
'ルータを再起動しています。3分ほどお待ちください。'
Start-Sleep 190

# Microsoft Edge Webドライバを終了
Stop-SeDriver
webdriver_edge_stop.ps1

このPowerShellスクリプトを実行すると、PowerShell経由で制御できるMicrosoft Edgeが起動し、管理用Webページから再起動ボタンが押下されてルータが再起動する。

スクリプトにして再起動処理を自動化する

この手の再起動は手動で処理しても数分程度で済む。だが、これを毎日手動で行うとなると時間の無駄だ。また、対象となるデバイスが1つではなく10、100と増えてくると、手動で行うのは全く現実的ではない。再起動忘れといったヒューマンエラーも発生しやすくなる。

プログラムで自動化できる処理に関しては、基本的に全て自動化してしまうのがシステム運用管理のポイントだ。再起動処理を自動的に行い、実際に再起動が行われているかどうかは、ログを自動的に収集する仕組みを使って調査すればよい。ログを解析して、再起動状況をステータスとして表示するWebページを用意してもよいだろう。管理者はそのページを時々確認する程度に、手間を減らした方がよい。

なお、これまでに何度も強調しているが、この手のスクリプトにはアカウントデータが直接書き込まれている。つまり、スクリプトにアクセスされるとアカウントデータが漏洩するリスクがあるわけだ。人の出入りが物理的に隔離された場所でセキュリティが担保されているPCで使うならまだしも、誰もがアクセスできるPCやサーバには、こうしたデータは決して置いてはならない。この点には、くれぐれも注意していただきたい。

付録

webdriver_edge_start.ps1

#!/usr/bin/env pwsh

#========================================================================
# Microsoft Edge WebDriverを起動する
#========================================================================

#========================================================================
# 動作しているMicrosoft Edge WebDriverをすべて終了
#========================================================================
webdriver_edge_stop.ps1

#========================================================================
# Seleniumモジュールがない場合にはインストール
#========================================================================
if (-Not (Get-InstalledModule -Name Selenium 2> $Null)) {
    'Seleniumモジュールをインストールします。'
    Install-Module -Name Selenium -AllowPrerelease -Force
    Get-InstalledModule -Name Selenium
}

#========================================================================
# Microsoft Edge WebDriverを起動
#========================================================================
'Microsoft Edge WebDriverを起動します。'
$Size = '1200,800'
if  (-Not (Start-SeDriver -Browser Edge -Size $Size 2> $Null 3> $Null))
{
    #================================================================
    # Microsoft EdgeとMicrosoft Edge WebDriverのバージョンが一致して
    # いないためにドライバが動作しなかった可能性がある。
    #================================================================

    #================================================================
    # 不要なドライバプロセスを終了
    #================================================================
    webdriver_edge_stop.ps1

    #================================================================
    # Microsoft Edgeのバージョン番号
    #================================================================
    $EdgeDir='C:\Program Files (x86)\Microsoft\Edge\Application\'
    $EdgeVersion=(  Get-ChildItem -Name $EdgeDir                    | 
                    Where-Object { $_ -NotMatch "[a-zA-Z]+" }       |
                    Select-Object -First 1                          )
                    # ↑ 【Select-Object -First 1の理由】
                    # 更新前のバージョンと更新後のバージョンが同時に
                    # 存在するタイミングがあるので、更新後のバージョン
                    # のみを取得するためにSelect-Objectを実行している。

    #================================================================
    # Microsoft Edge WebDriverダウンロードURLとデプロイ先パス
    #================================================================
    $DriverURL="https://msedgedriver.azureedge.net/$EdgeVersion/edgedriver_win64.zip"

    $SeModVer=(Get-InstalledModule -Name Selenium).Version -replace "-.+$",""
    $DriverDir="$env:HOME\Documents\powershell\Modules\Selenium\$SeModVer\assemblies"
    $DriverDownloadDir="$DriverDir\_download"

    #================================================================
    # WebDriverダウンロード用の一時ディレクトリを作成
    #================================================================
    New-Item        $DriverDownloadDir -ItemType Directory -Force

    #================================================================
    # Microsoft Edgeと同じバージョンのMicrosoft Edge WebDriverを
    # ダウンロード
    #================================================================
    "Microsoft Edge WebDriver version $EdgeVersion をダウンロードします。"
    curl            -get                                            `
                    -o      $DriverDownloadDir\edgedriver_win64.zip `
                    $DriverURL

    #================================================================
    # Microsoft Edge WebDriverをデプロイ
    #================================================================
    "Microsoft Edge WebDriver version $EdgeVersion をインストールします。"
    Expand-Archive  -Path $DriverDownloadDir\edgedriver_win64.zip   `
                    -Destination $DriverDownloadDir                 `
                    -Force

    Copy-Item       -Path $DriverDownloadDir\msedgedriver.exe       `
                    -Destination $DriverDir\msedgedriver.exe        `
                    -Force

    #================================================================
    # WebDriverダウンロード用の一時ディレクトリを削除
    #================================================================
    Remove-Item     $DriverDownloadDir -Recurse -Force

    #================================================================
    # Microsoft Edge WebDriverを起動する
    #================================================================
    if      (-Not (Start-SeDriver -Browser Edge -Size $Size 2> $Null 3> $Null)) 
    {
            #========================================================
            # 原因不明の起動不能
            #========================================================

            #========================================================
            # 不要なドライバプロセスを終了
            #========================================================
            webdriver_edge_stop.ps1

            Exit
    }
}
'Microsoft Edge WebDriverの起動処理完了。'

webdriver_edge_stop.ps1

#!/usr/bin/env pwsh

#========================================================================
# Microsoft Edge WebDriverを終了する
#========================================================================

#========================================================================
# WebDriverプロセスを終了
#========================================================================
if  (Get-Process -Name msedgedriver 2> $Null) 
{
    '動作しているMicrosoft Edge WebDriverを終了します。'
    Get-Process -Name msedgedriver 2> $Null

    # Microsoft Edge WebDriverを終了
    Stop-SeDriver 2> $Null

    # まだ動作しているほかのMicrosoft Edge WebDriverを終了
    if      (Get-Process -Name msedgedriver 2> $Null) 
    {
            Get-Process -Name msedgedriver 2> $Null | Stop-Process
    }

    '動作しているMicrosoft Edge WebDriverの終了処理完了。'
}