見出し画像

JamfProでデバイス情報を取得して Lookerで可視化する

会社からユーザーへ貸与している全てのMacはJamfProで管理できる状態にしています。ただ、管理下にあっても定期的な状態確認を行っていなかったので、これを行っていくことにしました。

定期的に確認を行う場合、管理画面へログインしてデバイスを一つ一つ確認していくのは現実的ではありません。確認したい項目だけを俯瞰して確認できるのがベストです。

そこで、JamfProのAPIを使って必要な情報だけを取得してまとめたダッシュボードを作ることにしました。



JamfProのAPIについて

JamfProのAPIはBasic認証を行ってBearerトークンを取得し、そのトークンを用いてAPIを実行する方法と、APIクライアントを用いて実行する方法があります。

Bearerトークンでの認証方式だとユーザーのIDとパスワードを送る必要があるのですが、APIクライアントを用いた方法だとクライアントIDとシークレットでAPIを実行できるので、こちらの方法で実行することにします。

APIを利用する準備

APIクライアントの設定については、下記の記事を参考にさせていただきました。JamfProの管理画面から設定を行い、APIロールとAPIクライアントを作成するだけでとても簡単です。


今回はデバイスの情報が参照できれば良いので、APIクライアント作成時に指定するAPIロールには「Read Computers」の権限のみ付与しました。


どのデータを取得するか

下準備が済んだら、どのデータを取得するかを検討します。デバイスの正常性と利用状況がチェックできれば良しとして、下記を取得することにしました。

  • OS

    • 古すぎるバージョンが無いかを把握

  • デバイスの種類

    • 古すぎるデバイスが無いか確認

  • シリアル

  • デバイス名

    • デバイス固有の情報として

  • 最終チェックイン日時

    • しばらくチェックインしていない端末は無いか確認

  • FileVaultの設定状況

    • 念のため暗号化状況の確認

  • ストレージ使用量

    • 不必要にデータを溜め込んでいないか

インストールされているアプリも取得しようか迷いましたが、恐らく量が多く可視化に向かないので今回は無しにしました。

どのエンドポイントを利用するか

欲しい情報が決まったら、JamfProのAPIリファレンスを眺めながらどうやったら欲しい情報を取得できるか考えます。

見たところ、

  • Finds all computers

  • Finds computers by ID

このあたり使えば欲しい情報が取れそうです。「Finds all computers」でJamfProに登録されているデバイスのIDの一覧を取得し、「Finds computers by ID」で各IDを持つデバイスの詳細情報を取得します。

また、「Finds computers by ID」で取得できる情報のうち、下記も取っておくと良さそうだったので追加で取得することにしました。

  • 初回登録日

  • ログインアカウント名

  • 拡張属性の値

ストレージ使用量はAPIからでも取得できますが、拡張属性でストレージ使用率を取っていたので、拡張属性から引っ張ることにします。

APIだと取得できても扱いづらい情報もあるので、欲しい情報によっては拡張属性との組み合わせも検討したほうが良さそうです。

GASで実装

取得したい情報が決まったので、GASで実装していきます。スクリプトプロパティにはJamfProの管理画面で作成したAPIクライアントIDとシークレットを格納しておきます。

// 書き込み先スプレッドーシートをシート名で指定
const ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('data');

// 初期設定
const API_URL = '<https://yourServer.jamfcloud.com/JSSResource/>';
const CLIENT_ID = PropertiesService.getScriptProperties().getProperty('CLIENT_ID');
const CLIENT_SECRET = PropertiesService.getScriptProperties().getProperty('CLIENT_SECRET');

// トークン取得
function getToken() {
  const url='<https://yourServer.jamfcloud.com>';
  const postUrl = url + '/api/oauth/token';
  const options = {
    method: 'post',
    payload: {
        grant_type: 'client_credentials',
        client_id: CLIENT_ID,
        client_secret: CLIENT_SECRET
    }
  };

  const response=JSON.parse(UrlFetchApp.fetch(postUrl, options));
  return response['access_token']
}

// Jamfに登録されたデバイスの情報を取得する
function getDevices() {

  // データ一時格納用配列
  const dataValues = [];

  // トークン取得関数呼び出し
  const authData = getToken();

  const options = {
    'method' : 'GET',
    'contentType': 'application/json',
    'headers': {'Authorization' : 'Bearer ' + authData,
                'accept' : 'application/json'},
  };
  
  // 全てのデバイスを取得
  const response = UrlFetchApp.fetch(API_URL + 'computers', options);
  const cont = JSON.parse(response.getContentText('UTF-8'));
  const computers = cont['computers'];

  // IDから詳細情報を取得する
  for (let i = 0; i < computers.length; i++) {

      // エンドポイントにアクセス
      let response_c = UrlFetchApp.fetch(API_URL + 'computers/id/' + computers[i]['id'], options);
      let res_c = JSON.parse(response_c.getContentText('UTF-8'));

      // デバイス情報を変数に格納
      let id = res_c['computer']['general']['id']; //jamfのID
      let name = res_c['computer']['general']['name']; //端末名
      let account = res_c['computer']['groups_accounts']['local_accounts'][0]['realname']; //ログインアカウント名
      let serial = res_c['computer']['general']['serial_number']; //シリアル
      let entry = res_c['computer']['general']['initial_entry_date']; //初回登録日
      let contact = res_c['computer']['general']['last_contact_time']; //最後に疎通を取った日
      let model = res_c['computer']['hardware']['model']; //デバイスのモデル
      let os = res_c['computer']['hardware']['os_version']; //OSバージョン    
      let encryption = res_c['computer']['hardware']['disk_encryption_configuration']; //ディスク暗号化構成
      let extension = res_c['computer']['extension_attributes']; //拡張属性
      let storage = extension.find(item => item.name === "ストレージ使用率");
      storage = storage.value;

      // 書き込み用に配列にデータを入れておく
      let values = [id, name, account, serial, entry, contact, model, os, encryption, storage];
      dataValues.push(values);

  }
  
  // 出力用ヘッダ
  const heading = ["ID", "デバイス名", "アカウント名", "シリアル", "初回登録日", "最終疎通時間", "モデル", "OS", "ディスク暗号化構成", "ストレージ使用率"];

  // シートを初期化してから配列のデータを書き込む
  ss.clear();
  ss.getRange(1, 1, 1, heading.length).setValues([heading]);
  ss.getRange(2, 1, dataValues.length, dataValues[0].length).setValues(dataValues);
  
}


データを可視化する

結果はスプレッドシートに書き出します。試しに取得してみたところ、ちゃんと全てのデバイスの情報を取得することができました。ただ、FV2が有効化されてないデバイスがあるのが気になるところ。

更に手軽に扱えるように、Lookerで可視化してみます。コントロールを追加して、条件に一致するデバイスのみを抽出できるようにしておきます。

また、追加で最終疎通確認から30日経過しているかどうかチェックするカラムを追加し、長期間疎通が取れていないデバイスを認識できるようにしました。


あとはGASを1日1回実行するようにしておけば、あとは定期的にダッシュボードをチェックするだけ。


今後は定期チェックします

ひとまず手軽にチェックできる環境整備ができました。仕組み化しないと都度ポチポチしなくちゃいけなくて時間がかかるし面倒ですが、ページを開いて見るだけなら数分で済みますし、昼食のあとのルーチンにでもすれば時間の無駄にもなりません。

しばらくこれで運用してみたいと思います。ただ、これだと見れるだけなので、異常が見つかった場合のオペレーションも検討したいと思います。

この記事が気に入ったらサポートをしてみませんか?