hack のためのネタ帳, etc,,,

×

状況

VPN 接続が切断した際に、自動再接続したいので、
  • ログ: Application
  • ソース: RasClient
  • イベントID: 20226
のイベントをタスクスケジューラーで拾い、イベントデータの2,3番目にある
  • Event/EventData/Data[2] の connection-name
  • Event/EventData/Data[3] の err-code
を発火させたタスクに渡したい。

タスクスケジューラーで発生したイベントのパラメータをタスクに渡す方法は 辺りに見つけたので、これに習って、 で作成した schtasks.exe 用の XML をベースとして Task/Triggers/EventTrigger 以下に ValueQueries/Value を追加した以下のような XML を作成した。
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <Settings>
    <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
  </Settings>
  <Triggers>
    <EventTrigger>
      <Subscription>&lt;QueryList&gt;&lt;Query Id="0" Path="Application"&gt;&lt;Select Path="Application"&gt;*[System[Provider[@Name='RasClient'] and EventID=20226]]&lt;/Select&gt;&lt;/Query&gt;&lt;/QueryList&gt;</Subscription>
      <ValueQueries>
        <Value name="user">Event/EventData/Data[1]</Value>
        <Value name="connection-name">Event/EventData/Data[2]</Value>
        <Value name="err-code">Event/EventData/Data[3]</Value>
      </ValueQueries>
    </EventTrigger>
  </Triggers>
  <Actions Context="Author">
    <Exec>
      <Command>%USERPROFILE%\HOME\.local\bin\test.bat</Command>
      <Arguments>$(user) $(connection-name) $(err-code)</Arguments>
    </Exec>
  </Actions>
</Task>
ところが、タスクスケジューラーに登録してみると
$ schtasks.exe /create /TN VPN\ routing /xml:task.xml
警告: タスクは登録されていますが、指定されたすべてのトリガーがこのタスクを開始するわけではありません。詳細については、タスク スケジューラのイベント ログを確認してください。
みたいな警告が出ることに加え、VPN を切断してもタスクが発火してくれない。
阻害要因特定のために、いろいろ削って最小限にしてみたりもしたのだが、さっぱり効果が出ず埒が明かない。
途方に暮れて、「警告: タスクは登録されていますが、指定されたすべてのトリガーがこのタスクを開始するわけではありません。詳細については、タスク スケジューラのイベント ログを確認してください。
でググったりもしてみたが、有用な情報は得られず困り果ててしまった。

XPath の書き方に問題があるのではと思い、「eventdata data value valuequeries」でググった所、たまたま以下のページを見つけた。
前者のページの最後 2015-12-16 のコメント曰く、ValueQueries には name 属性等で命名されてない特定の Data を取り出す手段が欠落してるように見えるとかなんとかで、
  • Event/System/Channel
  • Event/System/EventRecordID
を渡して
wevtutil.exe qe $Channel /q:"Event[System[EventRecordID=$EventRecordID]]" /rd:true /c:1 /f:text
または
wevtutil.exe qe $Channel /q:"Event[System[EventRecordID=$EventRecordID]]" /rd:true /c:1 /f:xml
するくらいが、私が思いついた唯一の一般的な回避策みたいな締めくくりになっていた。
つまり、見事にピンポイントで地雷を踏み抜いたらしい。orz

後者も、ValueQueries の XPath 不完全だ! みたいな話なんだけど、
Event/System/EventID
Event/System/Provider/@Name
Event/EventData/Data[@Name=”SomeValue”]
みたいな書き方は行けるけど
Event/EventData/Data[1]
Event/EventData/Data[position()=1]
Event/EventData/Data[last()]
のような順序指定や
Event/EventData/Data[@Name !=”TargetUserName”]
Event/EventData/Data[@Name !=”Dummy Attribute”]
Event/EventData/Data[. != “Dummy Value”]
のような否定は全滅みたいな話になってた。

微妙なのは、
Event/EventData
Event/EventData/*
Event/EventData/Data
なのだが、明言されてんだかよく分からなくて、
2つ下の段落にある
In all those cases a warning including the following information was generated: “Ensure all the task triggers are valid as configured. Additional Data: Error Value: 2147942487”.
がこいつにも係ってるのかな? と思ったのだが、試してみると
$ schtasks.exe /create /TN VPN\ routing /xml:task.xml
成功: スケジュール タスク "VPN routing" は正しく作成されました。
みたいに正常に登録されて、タスクもきちんと発火してくれた。
ただし、
  • Event/EventData
は、きちんと値が取れず、
  • Event/EventData/*
  • Event/EventData/Data

{********-****-****-****-************},MYHOST\kou,HOME,631
のようにコンマ区切りで各 Data の内容が連結された状態の値が得られるという状況だった。

因みに、err-code 631 は「ユーザーによってポートが切断されました。」

結論

という事で、タスクスケジューラーから直に
  • Event/EventData/Data[n]
のような順序指定で個別の Data 要素を得るのは無理ってことらしい。

コンマ区切りで問題なければ、
  • Event/EventData/Data
より詳細に取りたいなら、
  • Event/System/Channel
  • Event/System/EventRecordID
を渡したタスク内で
wevtutil.exe qe $Channel /q:"Event[System[EventRecordID=$EventRecordID]]" /rd:true /c:1 /f:xml
してイベントの詳細を拾うという方法を取る必要がある。

関連

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Wiki内検索

フリーエリア

管理人/副管理人のみ編集できます