お友達から
従業員が出勤してるか確認する方法何かない?
との相談があったのでちょっと考えてみた。
目次
要件定義
お友達の要望
出勤時間になっても誰も出勤していない場合、それが外から分かるようにして欲しい
平日は13:00、土日は9:30
あと、なるべく業務が増えるのは避けたい
なるほどなるほど。
ではでは日常業務の中で勝手に機能している感じにしてみよう。
システム要件
タスクスケジューラでログインチェックツールを起動し、時間になってもPCにログインされていない場合に複数の宛先へメール送信する
- ログインチェック機能
- メール送信機能
こんな感じかな。
業務でパソコン使うので出勤したら意識しなくてもPCにはログインするはず。いや、してくれ。
次はこれを実現するための条件を考えよう。
条件
PCが起動していないとチェック用のスクリプトが実行出来ない。
あと、メール送信はCDOを使いたい。
- BIOSにOS自動起動の設定がある事
- SSL/TLS認証のSMTPサーバが使える事
- 各店舗に行ってBIOSとタスクスケジューラの設定が出来る人
はい、遠くまでは行きたくないです。
ので、設定方法だけ伝えて頑張ってもらいます。
あとはBIOSの機能もあるっぽいしメールはGmailがあるそうなので多分条件クリア。
CDOを使う事については個人的なわがままです。もう検証が終わっているので(笑)
しかし、CDOだとTLS/STARTTLS認証は使えないっぽいので、SSL/TLS認証の我らがGmail先生にメール届けてもらう事にするざます。
という事でスクリプト書いてみよー。
スクリプト作成
前に投稿したVBSでメール送るやつを使います。
ちょっと長いけどいちお貼り付けておこう。
CheckGoToWork.vbs
Option Explicit
'*************************************************
'* ↓↓ メール設定 ↓↓ *
'*************************************************
Const sTo = "***@yahoo.co.jp,***@gmail.com" 'メール送信先(カンマ区切り)
Const sUser = "***@gmail.com" 'SMTPサーバログインユーザー名
Const sPass = "***" 'SMTPサーバログインパスワード
Const sSubject = "【出勤確認自動メール】***店" '件名
Const sBody = "出勤確認が取れませんでした。" '本文
'*************************************************
'* ↑↑ メール設定 ↑↑ *
'*************************************************
'=====変数宣言====================================
Dim oWsh,oFso,oPrm,oMsg
Dim sSfn,sDir,sChk,sUrl
'=====オブジェクト設定============================
Set oWsh = CreateObject("WScript.Shell")
Set oFso = CreateObject("Scripting.FileSystemObject")
Set oPrm = WScript.Arguments
Set oMsg = CreateObject("CDO.Message")
'=====変数設定====================================
sSfn = WScript.ScriptFullName
sDir = oFso.getParentFolderName(sSfn) & "\"
sChk = sDir & "chk.txt"
sUrl = "http://schemas.microsoft.com/cdo/configuration/"
'===引数により処理内容分岐========================
'引数が1つでm、d、cのどれかの場合のみ処理実行
If oPrm.Count = 1 Then
Select Case oPrm(0)
Case "m"
Call MakeFile
Case "d"
Call DelFile
Case "c"
Call Check
Case Else
LogEventWarn
End Select
Else
LogEventWarn
End If
'=====引数mの処理=================================
'作業フォルダに判定用ファイルを作成する(引数m)
Sub MakeFile()
On Error Resume Next
oFso.CreateTextFile(sChk) 'ファイル作成
'イベントログに結果書き込み
Call LogEvent(Err.Number,Err.Description)
On Error Goto 0
End Sub
'=====引数dの処理====================================
'作業フォルダに判定用ファイルがあれば削除する(引数d)
Sub DelFile()
On Error Resume Next
If oFso.FileExists(sChk) Then oFso.DeleteFile(sChk)
Call LogEvent(Err.Number,Err.Description)
On Error Goto 0
End Sub
'=====引数cの処理====================================
'作業フォルダに判定用ファイルが無ければメールを送信する(引数c)
Sub Check()
If Not oFso.FileExists(sChk) Then
oMsg.From = sUser
oMsg.To = sTo
oMsg.Subject = sSubject
oMsg.TextBody = sBody
oMsg.TextBodyPart.Charset = "ISO-2022-JP"
With oMsg.Configuration.Fields
.Item(sUrl & "sendusing") = 2
.Item(sUrl & "smtpserver") = "smtp.gmail.com"
.Item(sUrl & "smtpserverport") = 465
.Item(sUrl & "smtpauthenticate") = 1
.Item(sUrl & "smtpusessl") = true
.Item(sUrl & "sendusername") = sUser
.Item(sUrl & "sendpassword") = sPass
.Update
End With
End If
On Error Resume Next
oMsg.Send
Call LogEvent(Err.Number,Err.Description)
On Error Goto 0
End Sub
'=====イベントログへ処理結果出力==================
Sub LogEventWarn()
oWsh.LogEvent 2, "引数が正しく指定されなかった為、処理を中止しました。" & VbCrLf & _
"m、d、cのいずれか1つを指定して下さい。" & VbCrLf & VbCrLf &_
sSfn
End Sub
Sub LogEvent(iErrNo,sErrMsg)
If iErrNo <> 0 Then
oWsh.LogEvent 1, "予期しないエラーが発生しました。" & vbCrLf & vbCrLf & _
sSfn & " " & oPrm(0) & vbCrLf & _
"ID:" & iErrNo & vbCrLf & _
"内容:" & sErrMsg
Else
oWsh.LogEvent 0, "正常終了しました。" & vbCrLf & _
sSfn & " " & oPrm(0)
End If
End Sub
'=====終了処理==================
Set oWsh = Nothing
Set oFso = Nothing
Set oPrm = Nothing
Set oMsg = Nothing
WScript.Quit
はい、完成。
引数によって処理が変わります。
- 引数「m」 → チェック用ファイル作成
- 引数「d」 → チェック用ファイル削除
- 引数「c」 → チェック用ファイルがなければメール送信
コマンドプロンプトでこんな感じで実行します。
C:\>cscript C:\CheckGoToWork\CheckGoToWork.vbs m
出勤確認の全体の流れとしてはこんなイメージ
- PC自動起動時に引数「d」で実行 → チェック用ファイル削除
- 従業員ログイン時に引数「m」で実行 → チェック用ファイル作成
- 出勤チェック時刻に引数「c」で実行 → チェック用ファイルが無ければメール送信
誰も出勤してこなくて、2番の処理が行われなければメール送信される仕組み。
ほんとはチェック処理に環境変数かレジストリ使おうと思ってたんだけど、なんか権限の関係でうまくいかんかったのでとりあえずファイルの有無で判定。
あと、いちおイベントログに実行ログが吐かれるようにしておいた。
◆正常終了◆

◆警告◆

◆エラー◆

ってか、今気づいたんだけどイベントビュアーって標準のプリントスクリーンだとキャプチャ取れないんだ!!
え、もしかして常識?
まあ、とりあえず置いといて次にタスクの登録です。
タスクスケジューラに登録
そしてタスクスケジューラもプリントスクリーン出来ないし!
マジですか
ではタスクスケジューラにタスクを3つ登録していくよー
- チェック用ファイル作成
タスク名:MakeFile
引数:m
トリガー:ログイン時に起動 - チェック用ファイル削除
タスク名:DelFile
引数:d
トリガー:パソコン起動時と毎日6:00に実行 - チェック用ファイルがなければメール送信
タスク名:Check
引数:c
トリガー:平日の13:00と土日の9:30に実行
Cドライブ直下に「CheckGoToWork」フォルダがあってその中に「CheckGoToWork.vbs」スクリプトがあるのを前提に説明します。
「MakeFile」タスクの登録
タスクの作成をクリック

《名前》を入力し、【ユーザーまたはグループの変更】をクリック

《使用するオブジェクト名を入力して下さい》に「system」と入力し【OK】をクリック

《最上位の特権で実行する》にチェックを入れ、《構成》から任意の環境を選び、[トリガー]タブをクリック

【新規】をクリック

《タスクの開始》にて「ログオン時」を選択
《停止するまでの時間》にチェックを入れ「5」を入力し【OK】をクリック

ログオン時のトリガーが出来ました。
次は[操作]タブに行きます。

【新規】をクリック

《操作》にてプログラムの開始を選択
《プログラム/スクリプト》に「C:\Windows\System32\cscript.exe」と入力
《引数の追加》に「C:\CheckGoToWork\CheckGoToWork.vbs m」と入力し【OK】をクリック

「操作」が作られました。
次は[条件]タブに進みます。

《コンピューターをAC電源で使用している場合のみタスクを開始する》のチェックを外す
《タスクを実行するためにスリープを解除する》にチェックを入れる
[設定]タブをクリック

《タスクを停止するまでの時間》にチェックを入れ「5」を入力
《タスクが既に実行中の場合に適用される規則》にて「既存のインスタンスの停止」を選択し【OK】をクリック

「MakeFile」タスクが登録されました。

同じようにして「DelFile」「Check」タスクを登録していきます。
[トリガー][操作]タブ以外は共通なので省略します。
「DelFile」タスクの登録
【新規】をクリック

《タスクの開始》にて「スタートアップ時」を選択
《停止するまでの時間》にチェックを入れ「5」を入力し【OK】をクリック

あと、PCのシャットダウンを忘れて帰った時用に毎朝6時にも動くようにしておきます。
【新規】をクリック

《タスクの開始》にて「スケジュールに従う」を選択
「毎日」を選択し「6:00」を入力
《停止するまでの時間》にチェックを入れ「5」を入力し【OK】をクリック

「システム起動時」と「毎日6:00」に実行されるようになりました。
次は[操作]タブに行きます。

【新規】をクリック

《操作》にてプログラムの開始を選択
《プログラム/スクリプト》に「C:\Windows\System32\cscript.exe」と入力
《引数の追加》に「C:\CheckGoToWork\CheckGoToWork.vbs d」と入力し【OK】をクリック

「操作」が作られました。
[全般][条件][設定]タブは「MakeFile」タスクと同じです。

「Check」タスクの登録
【新規】をクリック

《タスクの開始》にて「スケジュールに従う」を選択
「毎週」「月~金」を選択し「13:00」を入力
《停止するまでの時間》にチェックを入れ「5」を入力し【OK】をクリック

もっかい【新規】をクリック

《タスクの開始》にて「スケジュールに従う」を選択
「毎週」「土日」「09:30」を選択
《停止するまでの時間》にチェックを入れ「5」を入力し【OK】をクリック

平日用と土日用のトリガーが出来ました。
次は[操作]タブに行きます。

《操作》にてプログラムの開始を選択
《プログラム/スクリプト》に「C:\Windows\System32\cscript.exe」と入力
《引数の追加》に「C:\CheckGoToWork\CheckGoToWork.vbs c」と入力し【OK】をクリック

「操作」が作られました。
[全般][条件][設定]タブは「MakeFile」タスクと同じです。

登録したタスクの確認
これでタスクスケジューラに3つとも登録されました。

しかし、同じような設定を何度も行う作業やってると、やっぱGUIってめんどいわー
と思ってコマンドからタスク操作する方法ないか調べたらいくつかあったし!
中でもPowerShellのScheduledTaskはかなり使えそうな感じだけど、なぜかトリガー設定用のNew-ScheduledTaskTriggerがこけるこける。

原因調べてたら、コミュニティーで環境依存っぽいってなってたのでとりあえず今回は見送った。
Insider Previewでのpowershell – マイクロソフト コミュニティ
あと、ScheduledTask自体がPowerShell V3.0以前のバージョンは標準搭載じゃないらしいし、各店舗のPCがこのコマンド使える環境か分からんので深追いするのはやめておこう。
PowerShellって今まであんま触った事ないけど中々使い勝手は良さそうに感じるので、これからちょいちょいイジっていきます。
BIOSの自動起動設定
最後にBIOSの設定だけど、これはパソコンによって設定方法変わるよなー
うちのパソコンだと、[Power]-[Wake System From S5]にチェック入れて[Wakeup Hour]のトグルで「9」を選べば『毎日9:00に起動』するように設定出来ました

大概は「電源」メニューの「WakeUpなんちゃら」とか「PowerOnなんちゃら」で設定出来ると思うので、毎日9時に起動するようにしておきましょう。
終わりに
本当は祝日も対応してないとだけどなー、めんどい(笑)
またなんかカレンダー的なプログラム書く事があったらその時にこっちも対応させよう。
って事で長々と書きましたが、まだ実際に導入はしていないのでこれでうまくいくかは分からんざますのことよ(笑)
いちお導入したらまた追記します。
そして、設定方法のキャプチャ取りながらブログ書くのってメチャ大変だなー
普段から分からん事あったらすぐ検索して知恵をお借りしまくっているので、今さらながら技術系Webサイトの作成者様に感謝です。
このブログもなんかの役に立ったらうれしいですな
追記 2016/06/09
導入したらやっぱり動かんかったー
うちの環境だと普通に動くけど店舗のPCだとなぜかうまくいかなくて《タスクが既に実行中の場合に適用される規則》を「既存のインスタンスの停止」から「新しいインスタンスを並列で実行」に変えたら動くようになった、理由は謎
あと、MakeFileだけトリガーの遅延時間を1分に設定しておいた。