🍎

plutilがJamf Proの拡張属性スクリプト書くのに便利そうでした

2023/05/28に公開

拡張属性スクリプト

Jamf Proの拡張属性は、Macのローカルで実行されたスクリプトの結果を入れることが出来るので大変便利です。
ただスクリプトを実行するのがユーザーのローカル環境なので、基本的にはmacOSデフォルトの機能でスクリプトを書くことになります。
特に拡張属性スクリプトで使われがちな(と個人的に思っている)ioregsystem_profilerの結果から特定の値が欲しい場合、grepawksedを使って抽出・整形する必要があります。

plutilを使えるケースがある

plutilは文字通りplistを操作するためのutilityです。plistは基本的にXMLなので、XMLにも使えます。
そしてioregsystem_profilerは出力をXMLにするオプションがあるため、結果をplutilに渡すことでシンプルな書き方ができるようになります。

また、macOS Monterey以降ではJSONの値を読む事ができます。
https://derflounder.wordpress.com/2023/04/15/using-the-plutil-command-line-tool-to-work-with-json-on-macos-monterey-and-later/

plutilを使ってみる

バッテリーの最大容量を取得してみる

Apple Silicon搭載のMacでは、system_profilerコマンドでバッテリーの最大容量を取得できます。
このコマンドはIntel Macだと動かないのでご注意下さい。

plutilを使わない場合

system_profilerの結果から、grepawkで必要な値を取り出す必要があります

plutilを使わずバッテリーの最大容量を取得
system_profiler SPPowerDataType | \
grep "Maximum Capacity" | awk '{print $3}'
88%

やりたいことは出来ているのでこれでも良いのですが、もう少し何をやってるのかわかりやすいと嬉しいですね

plutilを使う場合

system_profiler-xmlオプションで出力をxmlで出力できるので、それをパイプでplutilに渡します
plutilでファイルではなく標準入力で受け取りたい場合は-オプションを使います

plutilを使いバッテリーの最大容量を取得
system_profiler SPPowerDataType -xml | \
plutil -extract 0._items.0.sppower_battery_health_info.sppower_battery_health_maximum_capacity raw -
88%

-extractオプションを使い、抽出したい値のキーと出力する形式(raw)を指定しています。
欲しい情報のキーまでのパスを全て書く必要がありますが、どの情報を参照しているのかが分かりやすくなりました。

キーボードレイアウトを取得してみる

plutilを使わない場合

plutilを使わない場合はgrepawksedで必要な情報を取り出します。

plutilを使わずキーボードレイアウトを取得
ioreg -rln AppleHIDKeyboardEventDriverV2 | \
grep -m1 KeyboardLanguage | awk '{print $4,$5}' | sed s/\"//g
Japanese Keyboard

JapaneseKeyboardの間にスペースがあるため、awk '{print $4,$5}'としています。
またそのままだとダブルクオーテーションが付いてしまうため、sedで取り除いています。

plutilを使う場合

ioreg-aオプションを付けることでxmlで出力できるので、その結果をplutilに渡します

plutilを使いキーボードレイアウトを取得
ioreg -arln AppleHIDKeyboardEventDriverV2 | \
plutil -extract 0.KeyboardLanguage raw -
Japanese Keyboard

指定したキーに対応した値を取り出すのでスペースが入っていても気にする必要がありませんし、ダブルクオーテーションが付かないのも良いです。

目的のキーのパスを調べる

(XMLファイルの中の一つのキーのパスを簡単に一発でバシッと調べる方法を知らないので、どなたかご存知でしたら教えて下さい。)

plutil-pオプションを付けると、XMLを人間にも比較的読みやすい形に変換してくれます。

system_profiler SPPowerDataType -xml | plutil -p -
[
  0 => {
    "_dataType" => "SPPowerDataType"
    "_detailLevel" => "0"
    "_items" => [
      0 => {
        "_name" => "spbattery_information"
        "sppower_battery_charge_info" => {
          "sppower_battery_at_warn_level" => "FALSE"
          "sppower_battery_fully_charged" => "TRUE"
          "sppower_battery_is_charging" => "FALSE"
          "sppower_battery_state_of_charge" => 100
        }
        "sppower_battery_health_info" => {
          "sppower_battery_cycle_count" => 38
          "sppower_battery_health" => "Good"
          "sppower_battery_health_maximum_capacity" => "88%"
        }
		############以下略############

これでsppower_battery_health_maximum_capacityのパスが0._items.0.sppower_battery_health_info.sppower_battery_health_maximum_capacity
だということがわかります。

plutilをJSONで使ってみる

Jamf Proのスクリプト内で何かしらのAPIを叩いて返ってきたJSONをどうにかしたいみたいなケースがありますが、クライアント端末に勝手にjqを入れるのも微妙なので、パイプと各種コマンドで頑張ることになります。
plutilを使えばシンプルで読みやすく書けるので、未来の自分が過去の自分にイライラする事も減るのかなと思います。

ただ手元にBig SurなMacが無いので試せていないのですが、JSONの読み込みはMontery以降でしか対応していないらしいので環境にBig Sur端末がある方はご注意下さい。

JSONを使った良い例が思い浮かばなかったので、ひとまず今回はGoogle ChromeのVersionHistory APIを使って、macOS用のstableチャンネルのGoogle Chromeの最新バージョン情報を取得してみます。
https://developer.chrome.com/docs/versionhistory/

plutilを使わない場合

curl -s https://versionhistory.googleapis.com/v1/chrome/platforms/mac/channels/stable/versions | \
grep version | sed -n 3p | awk '{print $2}' | sed s/\"//g
114.0.5735.45

力技感があって良いですね、温かみを感じます。

plutilを使う場合

curl -s https://versionhistory.googleapis.com/v1/chrome/platforms/mac/channels/stable/versions | \
plutil -extract versions.0.version raw -
114.0.5735.45

だいぶシンプルに書くことができました。

Discussion