LoginSignup
5
6

More than 5 years have passed since last update.

JScriptでWMI(その2)

Posted at

はじめに

以前、JScriptでWMI(その1)でプロパティの一覧を取得しました。
そこで作ったメソッドを利用するにあたり、特殊な挙動をするもの、クエリの記述方法について記述します。

Ping

WMIのクラスに「Win32_PingStatus」があります。
これは、クエリに「SELECT * FROM Win32_PingStatus」を設定しても何もおこりません。
(結果は、1行も帰ってきません。)

WHERE句に「Address」を指定してみると、Pingの結果が返されます。

var query = "SELECT Address,StatusCode FROM Win32_PingStatus WHERE Address = '192.168.0.1'";
var props = wmiProps(query);
var csv = props2csv(props);
WScript.Echo(csv);

結果は、「StatusCode」に入ってきます。
結果コードは以下のとおりです。(原文のまま記載してます。)

Value Meaning Value Meaning
0 Success 11011 Bad Request
11001 Buffer Too Small 11012 Bad Route
11002 Destination Net Unreachable 11013 TimeToLive Expired Transit
11003 Destination Host Unreachable 11014 TimeToLive Expired Reassembly
11004 Destination Protocol Unreachable 11015 Parameter Problem
11005 Destination Port Unreachable 11016 Source Quench
11006 No Resources 11017 Option Too Big
11007 Bad Option 11018 Bad Destination
11008 Hardware Error 11032 Negotiating IPSEC
11009 Packet Too Big 11050 General Failure
11010 Request Timed Out

WQL

構文

WMIで設定するクエリは、WQL(WMI Query Language)というものです。
SQLのクエリと似ていますが、異なる部分があります。
(SQLの機能制限版みたいな感じです。)

WQL構文
SELECT properties FROM class [WHERE conditions]


properties

この部分で使えるのは、各クラスのプロパティ名と「」です。
サンプルコードでも使っていますが、「
」は全てのプロパティを出力します。
SQLと異なる点として、内部での演算は出来ません。

OK
SELECT * FROM Win32_Process
SELECT Caption,ProcessID,WorkingSetSize FROM Win32_Process
NG
SELECT Caption,FileSystem,Size - FreeSpace FROM Win32_LogicalDisk WHERE DriveType = '3'


class

クラスの部分は、WMIクラスを指定します。
主に使うのが「Win32 Provider」に属するクラスです。
SQLと異なる点として、1つのクラスしか指定できません。


conditions

条件を指定する部分です。
条件の接続は、括弧「()」、かつ「AND」、または「OR」が使えます。

また、値の条件式は
演算子として、等しい「=」、未満「<」、以下「<=」、より大きい「>」、以上「>=」、等しくない「<>」
が利用できます。

また、「IS NOT NULL」「IS NULL」「LIKE」も利用出来ます。

ドライブCとDの情報
SELECT * FROM Win32_LogicalDisk WHERE DeviceID = 'C:' OR DeviceID = 'D:'

ドライブCとDで空き容量が1G未満の情報
SELECT * FROM Win32_LogicalDisk WHERE (DeviceID = 'C:' OR DeviceID = 'D:') AND FreeSpace < 1048576

SQL関連のサービス情報
SELECT * FROM Win32_Service WHERE Name LIKE '%SQL%'

datetime

WMIで利用するdatetime型のフォーマットは、yyyymmddHHMMSS.xxxxxx±UUUとなっています。
そこで、JScriptのDate型から、datetime型の生成、datetime型フォーマットで出力の2メソッドを作成しました。
UUUの±が通常とは逆に設定するようで、わかりづらくなりそうなのでUTCを設定しています。

function wmiDate(date) {
    var datetime = null;
    if (date && date instanceof Date) {
        // 「SWbemDateTime」オブジェクト生成
        datetime = new ActiveXObject("WbemScripting.SWbemDateTime");
        datetime.Year = date.getUTCFullYear();                     // 年
        datetime.Month = date.getUTCMonth() + 1;                   // 月
        datetime.Day = date.getUTCDate();                          // 日
        datetime.Hours = date.getUTCHours();                       // 時
        datetime.Minutes = date.getUTCMinutes();                   // 分
        datetime.Seconds = date.getUTCSeconds();                   // 秒
        datetime.Microseconds = date.getUTCMilliseconds() * 1000;  // ミリ秒
    }
    return datetime;
}

function wmiDateFormat(date) {
    var ret = null;
    if (date && date instanceof Date) {
        ret = date.getUTCFullYear()                         // 年
            + ("0" + (date.getUTCMonth() + 1)).slice(-2)    // 月
            + ("0" + date.getUTCDate()).slice(-2)           // 日
            + ("0" + date.getUTCHours()).slice(-2)          // 時
            + ("0" + date.getUTCMinutes()).slice(-2)        // 分
            + ("0" + date.getUTCSeconds()).slice(-2) + "."  // 秒
            + ("00" + date.getUTCMilliseconds()).slice(-3)  // ミリ秒
            + "000+000";                                    // ナノ秒+UTC
    }
    return ret;
}

これを利用すると、本日0時以降のイベントデータの取得などが出来ます。

var now = new Date();
var date = new Date(now.getYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0);
var wmidate = wmiDateFormat(date);
// var wmidate = wmiDate(date);
var query = "SELECT Category,EventCode,Message,TimeWritten FROM Win32_NTLogEvent WHERE TimeWritten >= '" + wmidate + "'";
var props = wmiProps(query);
var csv = props2csv(props);
WScript.Echo(csv);

一応、WMIのdatetime型からJScriptのDate型へ戻すメソッドも作成しました。

function wmiDate2date(datetime) {
    var date = null;
    try {
        // 変換
        date = new Date(Date.parse(datetime.GetVarDate()));
    } catch (e) {
        // エラーの場合
        date = null;
        // throw e;
    }
    return date;
}
5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6