毎日１回YahooにPingを打つだけのお仕事

## この記事は

- 毎日18時になったら、YahooにPingを打つ
- Ping応答の結果はメールでお知らせしてもらう
    - メールは自宅のぷららメールを使う

### 前提

OSはWindows11 Homeをつかう

Cドライブ直下に`ExPing`フォルダーを作る

```bat
C:\ExPing
│  create-pass-text.ps1 <--- メールアカウントのパスワードを平文からSecure Stringに変換する
│  ExPing.def
│  ExPing.def.#CONFIG#
│  ExPing.exe
│  ExPing.ini
│  ExPing.txt
│  main.ps1 <--- PowerShell
│  pass.txt <--- メールアカウントのパスワード(Secure String)
│  task.bat <--- タスクスケジューラーから呼び出されるバッチファイル
│
└─log
        20221221-064725.csv
        20221221-064920.csv
        20221221-064939.csv
        ...
```

## タスクスケジューラーを設定する

1. `Windows` + `R`
1. `taskschd.msc` + `Enter`

18時になったら`task.bat`を起動する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/7f0d24bf-9bce-e4ac-7cb9-b35d95b0f1ee.png)

:::note info
「開始のオプション」には task.bat が入っているフォルダを指定する
:::

## プログラムを作成する

18時に起動する`task.bat`をつくる

### `task.bat`

と言っても、`task.bat`はPowerShellを呼び出すだけのバッチ
メールを送信したりするのは、PowerShellのほうが簡単にできるから！

```bat:main.ps1を起動するバッチ
powershell -NoProfile -ExecutionPolicy Unrestricted .\main.ps1
exit

# ほかの書き方
%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -ExecutionPolicy Unrestricted .\main.ps1
```

`task.bat`はタスクスケジューラーに登録して、PowerShellを呼び出すだけ

### `main.ps1`

こちらがメインの処理
`task.bat`が18時に起動して、直後にこの`main.ps1`（PowerShellのスクリプト）が起動する

```Powershell:main.ps1
#Requires -Version 5.0

# ExPing を使って Ping を打つ
$DateTime = Get-Date -Format "yyyyMMdd-HHmmss"
$LogFile = ".\log\$Datetime.csv"
C:\ExPing\ExPing.exe -R -C -O $LogFile | Out-Null
# 注意: Out-Null をつけて同期しないと
# ログファイルが生成される前に次の処理に行ってしまう

# Pingのログファイルから、NGの行を拾う
$NGList = Get-Content -Encoding oem $LogFile | Select-String -Pattern "ＮＧ"

if($null -eq $NGList) {
    $Result = "OK"
} else {
    $Result = ($NGList -join "`r`n")
}

Write-Host $Result

$UserName = "{メールアカウント}"
$SecurePassword = Get-Content ".\pass.txt" | ConvertTo-SecureString

$Credential = New-Object System.Management.Automation.PSCredential ($UserName, $SecurePassword)

$MailParam = @{
    SmtpServer = "purple.plala.or.jp";
    From       = "{メールアカウント}@purple.plala.or.jp";
    To         = "{宛先}@yahoo.co.jp";
    Subject    = "test pwsh"
    Body       = $Result
    Encoding   = [System.Text.Encoding]::UTF8
    Port       = 587
    Credential = $Credential
}

Send-MailMessage @MailParam
```

#### ExPingの説明

オプション|説明
-|-
`-R`|起動時にPingをうつ
`-C`|Pingを打ったあとにExPingを閉じる
`-O hoge.log`|ExPingの結果を hoge.log に出力する

```bat
ExPing.exe -R -C -O hoge.log
```

:::note info
メールと連携せず、単純に毎日Pingを打つだけなら、このままスケジューラーに登録すればよい
:::

http://www.woodybells.com/softs/ExPing.txt

#### メール送信コマンドの説明

`Send-MailMessage`はObsoleteになっているので、クリティカルな場面では使わないほうがよさそう
[MailKit](https://github.com/jstedfast/MailKit)を使えとのことだけど
GitHubにビルド済のdllが転がっておらず、NuGetパッケージを取得しなくてはいけないので
PowerShellから使うのは手間がかかるため、今回は使わなかった

C#で書くときは、従順にNuGetからMailKitをつかえばいいと思う

> WARNING: The command 'Send-MailMessage' is obsolete. This cmdlet does not guarantee secure connections to SMTP servers. While there is no immediate replacement available in PowerShell, we recommend you do not use Send-MailMessage at this time. See https://aka.ms/SendMailMessage for more information.

https://techmania.jp/blog/powershell0002/

### セキュアパスワード生成用スクリプト

メールアカウントのパスワードを平文からSecure Stringに変換し
`pass.txt`に保存するだけのスクリプト

基本的に１回しか使わない

```powershell:create-pass-text.ps1
$UserName = "{メールアカウント}"
$Credential = Get-Credential -UserName $UserName
$Credential.Password | ConvertFrom-SecureString | Set-Content ".\pass.txt"
```

#### 余談：パスワードだけセキュアストリングで保存する方法

```powershell:create-secure-pass
$pass = Read-Host -AsSecureString -Prompt "Enter your password"
ConvertFrom-SecureString -SecureString $pass -Key (1..16) | Set-Content ".\pass.txt"
# ConvertTo-SecureString するときも、同様に -Key (1..16) をつける
```

https://hosopro.blogspot.com/2017/02/powershell-securestring-to-bstr.html

https://qiita.com/Kill_In_Sun/items/0f1798d42dbd35d248e9

## メールを送った結果

NG行だけをメールで受け取ることができた！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/9a125f48-b2ba-c0d6-c037-953e0887e9e6.png)


# 糸冬了！！