🚑

Jamf Proの拡張属性にMacBookのバッテリーステータスを表示させたくなったときのお話

2021/06/24に公開

おかしな壊れ方をするやつはいる

2019年の春頃のことだったと思います。
『MacBook Proの電源が入らない』
そんなユーザの声が上がったのでそれは大変だということで状況を確認しました。

幸いにも電源アダプタを繋いだままにすると起動したので、
システム情報 > ハードウェア > 電源 > バッテリー情報 > 状態情報 > 状態
を確認しました。ここは通常正常修理サービス推奨がでてくるのですが、何故か4096になっていました。

いくらググってもこれがどんな状態なのか全然わかりません。OSを再インストールしても直らなかったため、個人的にはバッテリーコントローラの故障ではないかなと思ってます。
こればっかりはもう仕方がないので、Appleのサポートにはバッテリーの状態が見たことない感じになっている旨を伝えつつ修理に出し有償修理となったしまったわけですが、こちらとしてはこの不具合に気づけなかった事が悔やまれます。デバイスの不具合は生産性に直結するため、IT管理者としては早めに気付きたい。

2018年秋にJamf Proを使い始めたばかりだったのですが、初期登録やアプリの配布などは行なっていたものの一人情シスでJamfを使い込む時間もあまり無く、デバイスの不具合を把握するなどの使い方はまだしていませんでした。
そこで、よさげな拡張属性を求めJamf Nationを探してみました。

こんなのあったから使おう

https://www.jamf.com/jamf-nation/third-party-products/files/311/battery-health-status
追記:リンク切れてました
同じものがこちらです
https://github.com/jamf/Jamf-Nation-Extension-Attributes/blob/master/Battery Health Status.xml
このスクリプトは2011年にポストされており、かつてJamf ProにWindowsも登録できていた頃の名残があります。良き。
古い情報でしたが、この部分は普通に使えそうだと思い調べてみました。

result=`ioreg -r -c "AppleSmartBattery" | grep "PermanentFailureStatus" | awk '{print $3}' | sed s/\"//g`

if [ "$result" == "1" ]; then
result="Failure"
elif [ "$result" == "0" ]; then
result="OK"
fi

調べてみるとPermanentFailureStatusはバッテリーのステータスを0か1で返すっぽいということです。おかしいな、うちのブッ壊れたMacは全然違う値出してたけど…。
とはいえresultが0でも1でもないときはコマンドの出力がそのまま拡張属性に入るし何か出るでしょ。
手元のマシンで正常に動作することを確認し、拡張属性に登録してSmart Computer Groupで結果が"OK以外"の場合を抽出してダッシュボードに出すことにしました。

その後

それからはSmart Computer GroupでS.M.A.R.T.ステータスの異常や起動ドライブの残容量が一定以下になっている端末、購入してから一定期間以上経過した端末などをリストしてダッシュボードに表示させて目に付くようにしています。
何かおすすめのハードウェア異常検知項目があれば教えてください。

その後2

あれから4年、ついに同じ症状のMacが現れました。
せっかくだしちょっと調べてみようと思ってググったらこれが出てきました
https://opensource.apple.com/source/PowerManagement/PowerManagement-271.1/AppleSmartBatteryManager/AppleSmartBattery.cpp.auto.html
PermanentFailureStatusの値を入れてるのはここっぽい

my_unsigned_16 = ((uint16_t)transaction->receiveData[1] << 8)
                    | (uint16_t)transaction->receiveData[0];

if (kIOSMBusStatusOK == transaction_status) {
    pfstatus_num = OSNumber::withNumber((unsigned long long)my_unsigned_16, (int)32);
} else {
    pfstatus_num = OSNumber::withNumber((unsigned long long)0, (int)32);
}
if (pfstatus_num)
{
    setPSProperty(_PFStatusSym, pfstatus_num);
    pfstatus_num->release();
}

PermanentFailureStatusを表す_PFStatusSymの値をバッテリーに対してリクエストするときは符号なし16bit。壊れ方によっては1が出ることもあるかもだけど、バッテリーから返ってきた値をそのまま出してそう。
ということは0以外のときはその値をEAに渡して、0じゃない値を持ってるデバイスがリストされるようにするでも良いのかな
他にもfPermanentFailureていうフラグもあって、そっちはErrorConditionPermanent Battery Failureを渡すためのフラグっぽい
ErrorConditionはバッテリーにエラーがあるときにしか出てこないっぽいので、これが出ているかどうかでも判別できそう。
あとはバッテリー修理推奨がでるのはどこなのか知りたい。

Discussion