PowerShellでPCの起動からシャットダウンまでの時刻が分かるGUIアプリを作ってみた

# はじめに
PowerShellでGUIアプリが作れるらしいと聞き、今まで**イベントビューア**や自作のExcelマクロで確認していたPCの起動/シャットダウン時刻をPowerShellでGUIアプリとして実現してみました。

指定した日付でイベントログを取得し、その日の一番早いPC起動時刻/ログイン時刻、一番遅いログオフ時刻/シャットダウン時刻を表示させます。
イベントコードの割り当ては以下のとおりです。このコードと日付をもとにイベントログから検索をしてくるわけです。

<details><summary>使用したイベントコードはこちら！</summary><div>

- 6005：PCの起動
- 6006：シャットダウン
- 7001：ログオン
- 7002：ログオフ
</div></details>

# 開発環境💻
- OSエディション：Windows 10 Pro
- OSバージョン：20H2
- OSビルド：19042.630
- Powershellバージョン：5.1.18362.1171

# ソースコード
<details><summary>FromStartupToShutdown.ps1</summary><div>

```powershell
using namespace System.Windows.Forms
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# ラベル
#region Label
    $lbl1 = New-Object Label
    $lbl1.Text = "検索日付:"
    $lbl1.Location = "15, 30"
    $lbl1.AutoSize = $True

    $lbl2 = New-Object Label
    $lbl2.Text = "起動:"
    $lbl2.Location = "15, 60"
    $lbl2.AutoSize = $True

    $lbl3 = New-Object Label
    $lbl3.Text = "ログイン:"
    $lbl3.Location = "15, 90"
    $lbl3.AutoSize = $True

    $lbl4 = New-Object Label
    $lbl4.Text = "ログオフ:"
    $lbl4.Location = "15, 120"
    $lbl4.AutoSize = $True

    $lbl5 = New-Object Label
    $lbl5.Text = "シャットダウン:"
    $lbl5.Location = "15, 150"
    $lbl5.AutoSize = $True
#endregion

# 入力欄
#region Date 
    $Date = New-Object System.Windows.Forms.DatetimePicker
    $Date.location = "100,30"
    $Date.Format = "Long"
    $Date.AutoSize = $True
    $Date.Width = 150
#endregion

# 出力欄
#region TextBox
    $txt1 = New-Object TextBox
    $txt1.location = "100,60"
    $txt1.Width = 100

    $txt2 = New-Object TextBox
    $txt2.location = "100,90"
    $txt2.Width = 100

    $txt3 = New-Object TextBox
    $txt3.location = "100,120"
    $txt3.Width = 100

    $txt4 = New-Object TextBox
    $txt4.location = "100,150"
    $txt4.Width = 100

    $txtTemp = New-Object TextBox
#endregion

# 確認ボタン
#region Button
    $btn = New-Object Button
    $btn.Text = "確認"
    $btn.Size = "150, 40"
    $btn.Location = "100, 180"
    $btn.AutoSize = $True
#endregion

# ボタンのクリック処理
$button_Click = {

    #マウスカーソル：待機状態
    [System.Windows.Forms.Cursor]::Current = [System.Windows.Forms.Cursors]::WaitCursor

    #検索結果格納
    $txt1.Text = getEventLog(6005)
    $txt2.Text = getEventLog(7001)
    $txt3.Text = getEventLog(7002)
    $txt4.Text = getEventLog(6006)

    #マウスカーソル：デフォルト
    [System.Windows.Forms.Cursor]::Current = [System.Windows.Forms.Cursors]::Default
}
$btn.Add_Click($button_Click)


function getEventLog($eventId)
{    
    $dd = $Date.Value.Day
    if ($dd.toString().length -eq 1) {
        $dd = "0" + $Date.Value.Day
    }
    $MM = $Date.Value.Month
    if ($MM.toString().length -eq 1) {
        $MM = "0" + $Date.Value.Month
    }
    $replace = "@{TimeGenerated="+$MM+"/"+$dd+"/"+$Date.Value.Year+" "
    $before = $Date.Value.Date + " 23:59:59"
    $after = $Date.Value.Date + " 00:00:00"
    $txtTemp.Text = ""
    try
    {
        $eventLog = GET-EVENTLog System -After $after -before $before| Where-Object{$_.EventId -eq $eventId} | select-Object TimeGenerated
        If(($eventId -eq "6005") -or ($eventId -eq "7001"))
        {
            $length = $eventLog.Length
            $txtTemp.Text = $eventLog[$length - 1]
        }
        Else {
            $txtTemp.Text = $eventLog[0]
        }
        $txtTemp.Text = $txtTemp.Text.Replace($replace,"").Replace("}","")
    }
    catch
    {
        Write-host $eventId"取得結果なし"
    }
    return $txtTemp.Text
}

# フォーム
#region Form
    $f = New-Object Form
    $f.Text = "起動から終了まで"
    $f.Size = "330, 270"
    $f.MaximumSize  =$f.Size
    $f.MinimumSize  =$f.Size
    $f.MaximizeBox = $false
    $f.MinimizeBox = $false
    $f.StartPosition = "CenterScreen"
    $f.Controls.AddRange(@($lbl1,$lbl2,$lbl3,$lbl4,$lbl5,$Date,$txt1,$txt2,$txt3,$txt4,$btn))
    $f.ShowDialog()
#endregion
```
</div></details>

# 実行例
以下コマンドを実行します。
<details><summary>↓↓コピペ用↓↓</summary><div>

```powershell
powershell -NoProfile -ExecutionPolicy Unrestricted .\FromStartupToShutdown.ps1
```
</div></details>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528240/9f66b48d-6d6d-ca0e-4eb5-2e7d3370b19e.png)
実行時すると画面が表示されます。カレンダーから選択するか直接日付を入力して確認ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528240/e6b2979c-85d8-165e-29a5-3d08759834ba.png)
確認ボタンを押すと、イベントログの取得結果がテキストボックスに入ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528240/f27c1805-570a-e6bd-7064-a8b2bec63e16.png)
# あとがき📓
テキストボックスやボタンも使えてGUIアプリ（Windowsフォームを使用したアプリ）が作れて面白かったです。
VBやC#で実装した方が早いのですが、あえてのPowerShellってことに**浪漫**を感じやってみたってところです。
また、GUIアプリということでCUIアプリに比べ、見た目的に分かりやすく使い方の説明をする手間も減るのも良いですね。

最後に、この記事が「いいね！」と思ったら**Looks Good To Me!**ボタンのクリックと**フォロー**の方よろしくお願いします！！