JamfからiPadを再起動させてみる。誰がそんなこと必要とすんねん！ え？うちだけど？

# まえがき

どもです。Gzockです。前回記事の如く本名は名乗りません。
早々に2回目の[アドカレ](https://qiita.com/advent-calendar/2023/bitkey-corp-eng)が回ってきました。これをチャンスと呼びましょう。
年の瀬が迫った今、ネガティブな気持ちなんて持ちたくありません。
諸事情により時間がないので、誰の役にも立たないであろう話を書きます。
はい、Jamfを使ってiPadを遠隔再起動させてみようぜっていう話です。
そんなの誰の役に立つんでしょうね？ えぇ、弊社です。

# そもそもの話

- 私は情シス所属ではありません
- 普段はIoTの開発やってます
    - [2023 AWS Summit Tokyoで弊社が登壇](https://speakerdeck.com/bitkey/yuzati-yan-woxiang-shang-saserukagiha-fen-duan-nojie-xiao-jue-dui-nizhi-merarenaisumatorotukuwoxi-usisutemunoli-ce)させてもらいましたが、その中で言及しているプラットフォームを担当しています
    - その他、登壇資料を見てもらえるとどんなヤツか大体わかると思います
        - [ビットキーのIoT基盤におけるAWS IoT Rule Action活用](https://www.slideshare.net/ryosasaki376695/iotaws-iot-rule-action)
        - [Okta Workflowsによるノーコード業務改善](https://www.slideshare.net/ryosasaki376695/okta-x-jamf-okta-workflows-jamf-apimacpdf)
        - [たまにはオンプレもいいぞ？GKEとArmadillo IoTで実現するハイブリッドクラウド](https://www.slideshare.net/ryosasaki376695/cloud-native-days-tokyo-2022-gke-armadillo-iot)
        - [Datadog Agent on CloudRunによるGCPトレーサビリティの向上](https://www.slideshare.net/ryosasaki376695/datadog-agent-on-cloudrungcp)
- なのになんで[情シスアドベントカレンダー](https://qiita.com/advent-calendar/2023/bitkey-corp-eng)で早々に2回目の記事を書いてるのって？
- わかりません, ボス(@h_r_w_t_r)に聞いてください
    - ちょっとした経緯は上述のOkta WFsの記事で言及しています

# この記事は何？

- Jamfを導入し、macOSのみならず、iPhoneやiPadを管理している場合において、それらを遠隔で再起動させる話
- 前提としてJamfの導入が必須
- その上でJamfのAPIを使って実現させます
- ダレデモ デキルヨ

# なぜiPadを再起動させたい？

- 弊社のプロダクトの1つとして”顔認証”を提供している
- その顔認証のアプリはiOSアプリとして実現されており、稼働のためiPhoneあるいはiPadが必ず必要
- 自社オフィス内でも顔認証による入退室が利用できるようになっており、オフィス内に100台近くのiOSデバイスが設置されている
- 現在では、Jamfを用いて、それらのiOS端末を一括管理している
- そんな折、たまにそれらのiOS端末を再起動させたくなる機会がたまーーーーーにある
    - 弊社提供アプリの都合上、毎日深夜に再起動させたい
    - iOSの問題で週末に一度再起動させたい
    - などなど
- 当初は人力で頑張ったりしていたのだが、くっそ面倒くさいそんなことずっとはやっていられない
- あれ？Jamfでなんかそういうことできんじゃね？

# 方法

- JamfのAPIでそういうのがサポートされている
    - **[Creates a new mobile device command](https://developer.jamf.com/jamf-pro/reference/createmobiledevicecommand)**
- 基本的には以下のようなAPIエンドポイントの `command` の次のパスとして実際の各種コマンドを差し込む

```bash
https://your-domain.jamfcloud.com/JSSResource/mobiledevicecommands/command/do-something
```

- あとはそれでContent-type: xmlな感じでPOSTすればOK
- サポートしているコマンドも上述のAPIリファレンスページに載っているが、その中に`RestartDevice`がある

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80163/36e9ceea-b75f-cfa5-1a7e-5eaa6c0f8def.png)

- このRestartDeviceコマンドを用いて、さらにデバイスIDを指定すれば、もうめっちゃ簡単に再起動させることが可能

# 注意点

- HTTPリクエストヘッダーとして `Content-type: application/xml`は入れておいたほうがいい
    - ただしリクエストボディを持たないなら別になくても通るは通る
    - RestartDeviceコマンドの場合はリクエストボディはなくてもOK
- Credentialとして、事前にアクセストークンをとって、それをBearerトークンとしてヘッダーに盛り込んでPOSTする必要がある
    - 以前は直接的なBASIC認証でいけたけど、もうダメ？っぽい (詳しくない
    - 公式ガイドとしてはこちらをどうぞ
        - [Authentication and Authorization](https://developer.jamf.com/jamf-pro/docs/jamf-pro-api-overview)
- デバイスIDは以下のようにデバイスの詳細ページから特定することが可能
    - 他にも至るところにIDは入ってるのでもっと楽な確認方法もあると思う
        
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80163/2ee9601d-b6fb-cf13-e78a-c83491a05397.png)

        
- この値もまたインベントリ検索のAPIを使って特定することは可能なので、再起動オペレーションを完全に自動化する際には、そういう別APIを組み合わせて実現することになる

# スクリプト

- 古い人間である私はcurl大好きマンです
- ざっとこんな感じで！
    
    ```bash
    #!/bin/bash
    
    readonly USER=your_name
    readonly PASSWD=your_password
    readonly TARGET_DEVICE_ID=your_device_number
    
    token=$(curl -s -X POST -u "${USER}:${PASSWD}" "https://your-domain.jamfcloud.com/api/v1/auth/token" | jq -r .token)
    
    curl -s \
    	-H "Authorization: Bearer ${token}" \
    	-X POST \
    	"https://your-domain.jamfcloud.com/JSSResource/mobiledevicecommands/command/RestartDevice/id/${TARGET_DEVICE_ID}" 
    ```
    

- 成功すると以下のようにレスポンスがxmlでもらえる
    
    ```xml
    <?xml version="1.0" encoding="UTF-8"?>
    <mobile_device_command>
       <uuid>your-device-uuid</uuid>
       <command>RestartDevice</command>
       <mobile_devices>
          <mobile_device>
             <id>159</id>
             <management_id>your-device-id</management_id>
             <status />
          </mobile_device>
       </mobile_devices>
    </mobile_device_command>
    ```
    

# あとがき

- 実はこのネタをやったのはもう1年以上前の話になる
- よってもしかしたらもう情報として古いとかもっと良い方法があるかも？
- その場合は是非教えてください！
- 一応、載せたスクリプトで再起動かけることができるのは、この記事を執筆した時点で確認しております