LoginSignup
3
0

ESET PROTECTのレポート機能を使用したPC管理方法

Posted at

はじめに

SI業務で「ESET PROTECT」を利用した経験から、レポート機能を使用したPCの管理方法をまとめました。

概要

「ESET PROTECT」では任意の情報同士で比較することが困難な場合があります。
例えば、PCにインストールされているESETバージョンやコンピューター名、最終接続日を1つの表にまとめることが出来ません。
そのため、私はこれらの情報を1つの表にまとめるシステムを開発しました。
このシステムでは、「ESET PROTECT」のレポートスケジュール機能とGASのスケジュール機能を使用し、最新の表を定期的に作成することが可能です。

「ESET PROTECT」でのレポート作成

作成する一覧表に使用するデータは、「ESET PROTECT」のレポート機能で取得します。レポート機能とは、ESETのインストールしているクライアントから収集した情報やセキュリティ管理ツールの情報を基にレポートを作成する機能です。

作成するレポート一覧

今回作成する一覧表に必要なレポートを以下に示します。

No レポート名 大項目 小項目
1 検出エンジン コンピューター コンピューター名
検出エンジン データベースのバージョン
2 最終検査日表 コンピューター コンピューター名
検査 ユーザー
検査 完了時間
3 最終接続日 コンピューター コンピューター名
コンピューター 前回の接続
コンピューター セキュリティ製品バージョン
4 OS情報 コンピューター コンピューター名
OSエディション OS名
OSエディション OSバージョン
5 アドレス情報 コンピューター コンピューター名
ネットワークIPアドレス MACアドレス
ネットワークIPアドレス アダプタIPアドレス

※レポート名は任意に決めていただいて構いません。
また、新しいデータを追加したい場合は、最初のカラムにコンピューター名を入れた状態でレポートを作成してください。

レポート作成方法

例として、「検出エンジン」のレポートの作成方法を示します。

  1. 「ESET PROTECT」にログインします。

  2. 画面左側にあるメニューバーの「レポート」をクリックし、「新しいレポートのテンプレート」をクリックします。

  3. 名前を任意の名前に変更してください。また、カテゴリも任意のカテゴリを選択してください。
    ここでは例として名前は「検出エンジン」、カテゴリは「監視とライセンス管理」にします。

  4. 「グラフ」をクリックし、「表示テーブル」にチェックします。

  5. 「データ」をクリックし、「列の追加」から使用するデータを追加します。

  6. 検索欄に「コンピューター」と入れ「コンピューター名」を検索して「OK」ボタンで追加します。
    同様に、「データベースのバージョン」も検索して追加します。

  7. 「終了」をクリックし、レポートテンプレートを保存します。

レポートのスケジュール配信方法

「ESET PROTECT」からメールで定期的にレポートを送るように設定します。

  1. 送信したいレポートの歯車マークをクリックしてください。その後、「スケジュール」をクリックします。

  2. 「レポートテンプレートの追加」をクリックしてください。

  3. 下記の画面に遷移したら、今回作成したレポート名を検索欄に入れ「OK」をクリックして追加してください。

  4. 作成したレポートをすべて追加すると、下の画像のようになります。

  5. 毎週送信するように設定するため、「トリガータイプ」を「毎週」に変更してください。

  6. 「終了条件」は「終了なし」に設定しましょう。

  7. この例では、月曜日に送信されるように設定します。

  8. 「レポート配信」の「電子メールを送信」にチェックをいれ、送信先のGmailアドレスに設定してください。

  9. 「+印刷オプションを表示」をクリックし、出力形式をCSV(表データのみ)に変更してください。「終了」をクリックして保存します。

レポートの集計方法

作成したレポートの集計を行います。

※レポートには同じコンピューター名を持つ行が存在してしまっています。
これはESETの再インストール時に、過去のバージョンが残っているためです。
 したがって、レポートの集計をするスクリプトはコンピューター名が重複しているデータのうち、最新のものを取得しするように処理をしています。

レポートの集計処理の実装

手順は以下です。

  1. メール送信先のGoogleアカウントのドライブを開きます。
    空のスプレッドシートを作成します。

  2. スプレッドシートの「拡張機能」、「Apps Script」の順でクリックしてApps Scriptを起動します。

  3. 「コード.gs」のfunction myFunction()...を下記のコードに書き換えてください。

  • SPREADSHEET_ISはご自身のApps Scriptを作成しているスプレッドシートIDを指定してください。
  • DRIVE_FOLDER_IDはご自身のCSVを保存するGoogleドライブフォルダのIDを指定してください。
  • {Your ESET server email address} はご自身のESETサーバーに設定済みの送信元アドレスを指定してください。
// スプレッドシートIDの指定
const SPREADSHEET_IS = "******************************";
// CSVを保存するGoogleドライブフォルダのID
const DRIVE_FOLDER_ID = "******************************";
// 本日の日付を取得
const today = new Date();
//本日の日付を取得
const day = today.getFullYear() + "/" + (today.getMonth()+1) + "/" + today.getDate();
// 検索条件
const query = 'is:unread from:{Your ESET server email address} after:'+ day;


function readCsv(data) {
  const lines = data.split('\n');
  const report = lines.map(line => line.split(';'));
  // データの空欄があった時に空のデータを入れる
  const headers = report[0];
  for(let i = report.length; i < headers.length; i++){
    report.push("");
  }
  return report;
}


function getLatestComputerInfo(report) {
  const pcNameReportDict = {};
  const len = report[0].length;

  for (let row of report.slice(1)) {
    const pcName = row[0];
    
    if (len === 2) {
      const item = row[1];
      if (!pcNameReportDict.hasOwnProperty(pcName)) {
        pcNameReportDict[pcName] = item;
      } else {
        if (item === '' || pcNameReportDict[pcName] === '') continue;
        
        if (parseInt(pcNameReportDict[pcName].split('(')[0]) > parseInt(item.split('(')[0])) {
          continue;
        } else {
          pcNameReportDict[pcName] = item;
        }
      }
    } else if (len === 3) {
      const item1 = row[1];
      const item2 = row[2];
      if (!pcNameReportDict.hasOwnProperty(pcName)) {
        pcNameReportDict[pcName] = [item1, item2];
      } else {
        if (item1 === '' || item2 === '' || pcNameReportDict[pcName].length === 0) continue;
        
        if (pcNameReportDict[pcName][0] === '') {
          pcNameReportDict[pcName][0] = item1;
        }
        
        if (pcNameReportDict[pcName][1] === '') {
          pcNameReportDict[pcName][1] = item2;
        } else {
          if (pcNameReportDict[pcName][1] > item2) {
            continue;
          } else {
            pcNameReportDict[pcName] = [item1, item2];
          }
        }
      }
    }
  }
  const newReport = [report[0]];
  if (len === 2) {
    for (let key in pcNameReportDict) {
      newReport.push([key, pcNameReportDict[key]]);
    }
  } else if (len === 3) {
    for (let key in pcNameReportDict) {
      newReport.push([key, pcNameReportDict[key][0], pcNameReportDict[key][1]]);
    }
  }
  return newReport;
}


// ファイル名を指定してGoogleドライブからCSVファイルを取得する
function getCSVFileByName(fileName) {
  const files = DriveApp.getFilesByName(fileName);
  if (files.hasNext()) {
    return files.next();
  }
  return null;
}


function mergeReports(report1, report2){
  const headers = [...report1[0], ...report2[0].slice(1)];
  const rows = {};

  report1.slice(1).forEach(row => {
    const newRow = new Array(report2[0].length - 1).fill('');
    rows[row[0]] = [...row, ...newRow];
  });

  report2.slice(1).forEach(row => {
    if(rows.hasOwnProperty(row[0])){
      rows[row[0]] = [...rows[row[0]].slice(0, report1[0].length), ...row.slice(1)];
    }else{
      const newRow = new Array(report1[0].length - 1).fill('');
      rows[row[0]] =[row[0], ...newRow, ...row.slice(1)];
    }
  });
  const result = [headers, ...Object.values(rows)];
  return result;
}


function myFunction() {
  const threads = GmailApp.search(query);
  const messages = GmailApp.getMessagesForThreads(threads);

  // メールを既読にする
  for (thread in threads) {threads[thread].markRead()}

  let i = 0;
  for(const message of messages){
    for(const msg of message){
      const attachments = msg.getAttachments();
      for(const attachment of attachments){
        if(attachment.getContentType() === 'text/csv'){
          // CSVをGoogleドライブに保存
          const file = DriveApp.getFolderById(DRIVE_FOLDER_ID).createFile(attachment);

          // CSVデータを取得
          const reportFile = getCSVFileByName(file.getName());
          const report_Data = reportFile.getBlob().getDataAsString('UTF-8');
          const report = getLatestComputerInfo(readCsv(report_Data))
          if (report) {
              if (i === 0) {
                baseReport = report;
                i = 1;
              } else {
                baseReport = mergeReports(baseReport, report)
              }
            } else {
              console.error(`The file ${reportName} does not exist.`);
            }          
          // 一時ファイルの削除
          file.setTrashed(true)
        }
      }
      // 結果を現在のスプレッドシートに書き込む
      const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
      sheet.getRange(1, 1, baseReport.length, baseReport[0].length).setValues(baseReport);
    }
  }
}

処理のスケジュール実行方法

処理をスケジュールする手順は以下の通りです。

  1. 作成したGASのスクリプト画面にアクセスします。

  2. 左側のメニューバーの「トリガー」をクリックして、「トリガーを追加」を選択します。

  3. 「ESET PROTECT」から送信される定期メールの頻度に合わせて、トリガーの設定を行います。
    これにより、毎週自動的にレポートを集計することが出来ます。

出力例

スクリプト実行後、スプレッドシートは以下のような内容になります。

コンピューター名 データベースのバージョン ユーザー 完了時間 最終接続 セキュリティ製品バージョン OS名 OSバージョン MACアドレス アダプタIPアドレス
desktop1 27017 (20230404) hoge 2023/4/5 13:33 2023/4/5 16:33 10.0.2034.1 Microsoft Windows 11 Pro 10.0.22621.1413 AA-AA-AA-AA-AA-AA 192.192.192.192
desktop2 27017 (20230404) hoge 2023/4/5 13:33 2023/4/5 16:33 10.0.2045.1 Microsoft Windows 10 Pro 10.0.19044.2728 AA-AA-AA-AA-AA-AA 192.192.192.192
desktop3 27017 (20230404) hoge 2023/4/5 13:33 2023/4/5 16:33 10.0.2034.1 Microsoft Windows 10 Pro 10.0.19044.2728 AA-AA-AA-AA-AA-AA 192.192.192.192

補足

  • 更新時にスプレッドシートが上書きされないように、実行日ごとにシートを分ける機能を追加すれば、より使いやすい一覧表になると思います。
  • 作成した一覧表は、すべての情報を網羅しているわけではないので、必要に応じてカスタマイズするとよいでしょう。

参考

3
0
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
3
0