はじめに
どーもみなさんこんにちは。ねもてぃです。
みなさん、macOSのアップデート管理、できてますか?
Jamf ProでMacを管理されている組織が多いかと思いますが、現状Jamf Proの標準機能では自動的にmacOSをアップデートする機能が弱く、「管理対象ソフトウェアアップデート」機能を利用した管理者プッシュ型のアップデートが主となっています。
そのため、GitHubに公開されている「Nudge」や「S.U.P.E.R.M.A.N」といったツールを利用し、エンドユーザーに通知することでアップデートを促す形をとっている方も多いのではないでしょうか。
今日は昨年末ぐらいにGitHubに公開された「Update_macOS_DDM」というスクリプトが良さそうだったので、こちらのスクリプトを使ってmacOSのアップデート通知および宣言型デバイス管理(Declarative Device Management)を組み合わせたアップデートについて見ていこうと思います!
※Kandjiの場合は「Managed OS」という機能があり、ツールを利用せずともエンドユーザーに通知、アップデート指示を出してくれます。
以下、こんな感じです!という画像を貼っておきます。とりあえずあどみんちゃんからのお知らせ風にしてみました。

宣言型デバイス管理(Declarative Device Management/DDM)とは
その前に少しだけ宣言型デバイス管理について触れようと思います。
Declarative Device Management(DDM)は、Appleが導入した新しいモバイルデバイス管理(MDM)の仕組みです。従来のMDMがサーバー主体で設定を適用するのに対し、DDMではデバイス自身が設定を管理・適用するため、より柔軟でリアルタイムなデバイス管理が可能になります。
主な特徴
- デバイスが主体的に設定を適用し、サーバーの指示待ち不要
- ローカルでの状態管理により、常に適切な設定を維持
- ネットワーク負荷を軽減し、効率的にデバイスを管理
メリット
- 設定の適用がリアルタイムで行われる
- サーバーとの通信が減り、負荷が軽減
- デバイスが自動でポリシーを維持し、管理がスムーズ
対応OS: iOS 15以降、iPadOS 15以降、macOS 12以降 など
~ChatGPTより~
DDMにより、企業や教育機関のデバイス管理がよりシンプルで効率的になります。
とりあえずAppleが近年提供を始めたデバイス管理に関するプロトコルだと思ってもらえればOKです。
MDMコマンドによるソフトウェアアップデートはうまくいかないことが多く、いまいち実行力に欠けていた印象なのですが、このDDMベースのアップデートは旧来より実行力が高いように感じます。(感覚ですが)
※OSのアップデート以外にも様々な機能で置き換えが進んでいるようです。
そのため、このDDMによるアップデートが実装されていることが重要な要素の一つであると思うのと同時に、今回紹介する「Update_macOS_DDM」はDDMを使用したアップデートに対応している、というのが大きな特徴となります。(紹介したくなった理由でもあります)
「Update_macOS_DDM」is なに?
「Update_macOS_DDM」の特徴について挙げていきます。(ChatGPTが)
「Update_macOS_DDM」は、macOSデバイスのソフトウェアアップデートを自動化するためのシェルスクリプトです。このスクリプトを使用することで、管理者は以下の利点を享受できます:
- スケジュール不要:管理者が個別にアップデートのスケジュールを設定する必要がありません。
- DDM(Declarative Device Management)サポート:最新のmacOS 14.0以降で導入されたDDMメソッドをサポートしています。
- 管理者アカウント不要:隠れた管理者アカウントを作成する必要がなく、ユーザーパスワードの入力も不要です。
- カスタマイズ可能なユーザー通知:ユーザーに表示されるダイアログのテキストやウィンドウサイズ、フォントサイズなどを設定プロファイルでカスタマイズできます。
これらの特徴により、組織内のmacOSデバイスを効率的かつ一貫性のある方法で最新の状態に保つことが可能となります
~ChatGPTより~
補足していきます。
このスクリプトはSOFA(Simple Organized Feed for Apple Software Updates)に対応しており、スクリプト実行時に最新バージョンや適格性などをSOFAに確認しにいき、CVEデータに基づいたアップデートの必要性などについて鑑みた上で実行処理を行います。SOFAにはリリース日情報なども含まれているため、〇〇日後に強制アップデート、という設定を施すことで管理者が定期的にアップデートバージョンなどを確認して管理する必要がなくなります。
サードパーティ製ツールの中で最も採用率が高いと思われる「Nudge」ではVer.2にてこのSOFA確認が実装されましたが、それまでは最低OSのバージョンや期限日時の指定などを管理者が都度更新しなければならなかったため非常に手間でした。これが必要ないというのも嬉しいポイントかと思います!
要件とか
- macOS 14 Sonoma 以降
- Jamf Proに登録されていること
- ブートストラップトークンがJamf Proにエスクローされていること
- されていない場合はエンドユーザーにパスワード入力を求めるダイアログが出るだけなのであまり気にしなくていいかもしれません
- Jamf Pro API 認証情報
- クライアントID
- クライアントシークレット
準備
準備するもの
- 構成プロファイル
- 設定は基本的に構成プロファイルで行います
- ポリシー
- 「Update_macOS_DDM」スクリプトを実行するポリシー
- Jamf Pro API 認証情報
- ブートストラップトークンの保存状態の確認やDDMを利用したアップデートの実行をAPI経由でJamf Proに仕掛けるために必要となります
以上です!アプリのインストール等は不要なのでシンプルです!!!
というわけで準備していきましょー
Jamf Pro API 認証情報の作成
とりあえずJamf Pro APIの認証情報から作っていきます。
- Jamf Pro管理コンソール > 設定 > システム > API ロールとクライアント を開きます。
- API ロール タブ にて右上”+新規”より、下記を設定して保存します。
- 表示名:Update_macOS_DDM など任意
- 権限
- Read Computers
- Send Computer Remote Command to Download and Install OS X Update
- Read Managed Software Updates
- Create Managed Software Updates

- 続いてAPI クライアント タブに移動し、右上”+新規”より、下記を設定して保存します。
- 表示名:Update_macOS_DDM など任意
- API ロール:先ほど作成したAPI ロールを選択
- アクセストークンの有効期限:任意(デフォルトでOK)
- API クライアントの有効化/無効化:Enable API clientをクリックし、有効化します
- ここで表示される「クライアント ID」と「クライアントシークレット」は後でスクリプトに使用しますので、どこかにコピーしておきます。

以上でAPIロールとクライアントの設定は完了です。
構成プロファイルの作成
続いて設定用の構成プロファイルを作成していきます。
- Jamf Proで設定する用のJSONテンプレートが用意されているため、それを入手します。
- Update_macOS_DDMのGitHubページにアクセスし、右側”Releases”より最新版の「Source code」をダウンロードし、内包されている”macOS_Updates_DDM_Profile.json”を見つけておきます。
- Jamf Pro管理コンソール > コンピュータ > 構成プロファイル > 右上”+ 新規” より新規プロファイルを作成し、下記設定をしていきます。
- 一般ペイロード
- 名称:Update_macOS_DDM など任意のもの
- アプリケーションとカスタム設定 ペイロード にて「外部アプリケーション」を選択し、右上”+ 追加” > ソースとして カスタムスキーマ を選択します。
- 環境設定ドメイン:it.next.macOS.update
- “+ スキーマを追加” > アップロード より入手した「macOS_Updates_DDM_Profile.json」をアップロードし、”保存”します。
- 各種設定パラメータが追加されますので必要に応じて変更していきます。(解説については次の項で行います)
- Scope タブに移動し、配布したい対象のMacまたはグループを選択し、保存します。
- 一般ペイロード

以上で構成プロファイルの作成は完了です。
それでは肝心のパラメータについて上から見ていこうと思います。
- Deferral_and_scriptLog セクション
- Maximum Deferral (non-critical)
- 重要でないアップデートの最大延期日数を指定します
- デフォルト:5日
- Maximum Deferral (critical)
- 重要なアップデートの最大延期日数を指定します
- デフォルト:2日
- Script Log
- スクリプトのログファイルの保存場所を指定します
- デフォルト:/var/log/it.next.macOS.Update.log
- Maximum Deferral (non-critical)
- Updates セクション
- macOS Update Selection
- 適用するアップデートの種類を選択します
- Latest version based on device eligibility
- そのMacに適合する最新バージョンを適用します
- Latest major version
- 最新のメジャーバージョンを適用します
- Latest minor version
- 最新のマイナーバージョンを適用します
- Specific version
- 指定したバージョンのmacOSを適用します(15.2 など)
- Latest version based on device eligibility
- 適用するアップデートの種類を選択します
- Specific macOS Version
- macOS Update Selection にて Specific version を指定した場合にのみ、適用するmacOSバージョンを入力します(15.2 など)
- Don’t Run Updates on Days
- 実行したくない曜日があればtrueに変更します
- デフォルト:月〜金がfalse、土日がtrue
- Run Updates on Time
- 特定の時刻にアップデートを実行させたい場合は時刻を指定できます
- macOS Update Selection
- Dialog_Settings セクション
- Banner Image
- 表示される画面に特定の画像を利用したい場合はそのファイルが保存されているディレクトリのパスを入力します
- 例:/usr/local/kaishadetukaugazou/kaishanochara.png
- テストではあどみんちゃんの画像を配布し、その配布先のパスを指定しています
- 例:/usr/local/kaishadetukaugazou/kaishanochara.png
- 表示される画面に特定の画像を利用したい場合はそのファイルが保存されているディレクトリのパスを入力します
- Dialog Update Width / Dialog Update Height
- 表示される画面の縦横を指定します
- デフォルト:740 x 540
- テストではあどみんちゃんの画像がいい感じの縦横に変更しました(デバックモードで数値を確認できるので後から変更するといいかもです)
- Dialog Update Title Font / Dialog Update Message Font
- 表示されるタイトルとメインメッセージのフォントサイズを指定します
- デフォルト:20 / 14
- テストではタイトルサイズがデフォルトだと小さく感じたので32ぐらいにしました
- デフォルト:20 / 14
- 表示されるタイトルとメインメッセージのフォントサイズを指定します
- Banner Image
- Buttontimer セクション
- Timer for Buttons in Final Message
- エンドユーザーがちゃんとメッセージを読んでからアップデートをするかあとでやるかを選択できるように非アクティブ時間が設けられています
- デフォルト:30(秒)
- テストでは30秒は長いと思ったので5秒に変更しました
- Timer for Buttons in Final Message
- Messanges セクション
- Timeout for Message
- 表示される画面が自動的に閉じるまでの秒数を指定します
- デフォルト:300
- Install Button Label
- 「インストールを続ける」ボタンに表示させるテキストです
- デフォルト:Now
- テストでは「いますぐやる!」に変更しました
- Defer Button Label
- 「インストールを延期する」ボタンに表示されるテキストです
- テストでは「あとでやる!」に変更しました
- 「インストールを延期する」ボタンに表示されるテキストです
- Standard Update Message
- エンドユーザーに表示させるメッセージをここで設定します。1行で指定しなければならないので少しやっかいですが、サンプルを置いておきます。(英語のサンプルテキストはダウンロードしたフォルダに含まれていますのでそちらもご参考ください)
- Timeout for Message
- 提供されているサンプル
Hello %REAL_NAME%,\n\nA system update is available for your Mac.\n\nClick **%Install_Button_Custom%** to proceed with the software update and install the update.\n\nIf you are unable to start the process at this time, you have the option to defer it.\n\nThe update will be automatically enforced by **%forceInstallLocalDateTime%** at the latest. The process takes about 30 minutes.\nYou can install the macOS software update at any time yourself.\n\nTo do so, please go to:\n\n > System Preferences > Software Update\n\nOr click **%Install_Button_Custom%** to open System Preferences.\n\nIn System Preferences, you can then click **Update Now**, and the device will restart.
- テストで作成したサンプル
こんにちは!あどみんだよ!\n\nMacのアップデートがあるよ!\n\n**%Install_Button_Custom%** をクリックしてソフトウェアアップデートを進め、アップデートをインストールしてね!\n\nいますぐにできない場合は、延期することもできるよ!\n\nアップデートは、遅くとも **%forceInstallLocalDateTime%** までに自動的に実施されて、約 30 分かかるよ!\nmacOSソフトウェア・アップデートはいつでも自分でインストールできるからね!\n\nその場合は、以下の設定に移動してね!:\n\n > システム設定 > ソフトウェアアップデート\n\nまたは、**%Install_Button_Custom%** をクリックしてシステム設定を開いてね!\n\nシステム設定で、**今すぐアップデート**をクリックすると、デバイスが再起動するよ!
ポリシーの作成
次で最後です。スクリプトを実行するポリシーを作成していきます。
- Jamf Proで設定する用のJSONテンプレートが用意されているため、それを入手します。
- Update_macOS_DDMのGitHubページにアクセスし、右側”Releases”より最新版の「Source code」をダウンロードし、内包されている”macOS_Update.sh”を見つけておきます。(GitHubページからコピペでもOKです)
- Jamf Pro管理コンソール > 設定 > コンピュータ管理 > スクリプト > 右上”+ 新規”より下記設定を行い、保存します
- 一般 タブ
- 表示名:Update_macOS_DDM など任意のもの
- 注記などに追加日、入手したGitHubのリンクなどを記載しておくと良いと思います
- スクリプト タブ
- 入手、またはコピペした”macOS_Update.sh”の内容をペーストします
- オプション タブ
- わかりやすいようにパラメータにラベルをつけておきます(ここはあくまでラベルなのでこのままでOKです)
- パラメータ4:Jamf API Client ID
- パラメータ5:Jamf API Client Secret
- パラメータ6:Debug Mode(Possible values: verbose, true, or false. Default: “verbose”
- わかりやすいようにパラメータにラベルをつけておきます(ここはあくまでラベルなのでこのままでOKです)
- 一般 タブ


3. Jamf Pro管理コンソール > コンピュータ > ポリシー > 右上”+ 新規” より下記を設定し、保存します。
- General ペイロード
- 表示名:Update_macOS_DDM など任意のもの
- トリガー:Recurring Check-in
- 実行頻度:Once every day
- ここでは毎日アップデートを促す通知を表示するように構成しています。テストする場合に限りOngoingに設定し、Self Service タブより「Self Service でポリシーを使用可能にする」をONにし、Self Serviceから複数回実行できるようにしておいても良いかと思います(本番展開の際に戻し忘れ注意)
- スクリプト ペイロード
- 先ほど追加したスクリプトを選択(Add)します
- パラメータ4(Jamf API Client ID)に「Jamf Pro API 認証情報の作成」の手順で作成したクライアント IDを入力します
- パラメータ5(Jamf API Client Secret)に「Jamf Pro API 認証情報の作成」の手順で作成したクライアントシークレットを入力します
- パラメータ6(Debug Mode(Possible values: verbose, true, or false. Default: “verbose”))にまずはverboseと入力しておきます
- 本番利用する場合はここをfalseに変更します
- 先ほど追加したスクリプトを選択(Add)します
- Scope タブ
- 展開したい対象のMacまたはグループを選択し、保存します。

以上でポリシーの設定も完了です!
動作確認
それでは実際の動作を見ていきましょー。
まず、ブートストラップトークンがJamf Proにエスクローされていない場合はこのような画面が表示され、エンドユーザーのパスワードが求められます。

英語が・・・という場合はmacOS_Update.shの「function Enable_BootstrapToken_with_currentUser」のあたりで表示するテキストメッセージを設定しているのでその辺りを変更すると日本語にすることができると思います。
続いて宣言型デバイス管理によるmacOSのアップデートが設定されたよ、という通知が右上に表示されます。

3月26日に検証を行ったので5日後の3月31日にスケジュールされています。
Jamf Pro管理コンソール > コンピュータ > インベントリ検索 > 該当Macのインベントリ > 管理タブ > オペレーティングシステム でも宣言型デバイス管理によってスケジュールされていることが確認できます。

続いて表示されるメッセージ画面です。まずはデバッグモードが有効になっている状態だと・・・

このように赤枠に囲まれた状態で表示されます。角にカーソルを当てることで縦横サイズの変更ができ、左上にwidthとheightの値が表示されるので、変更したい場合はこの数値を構成プロファイルの「Dialog Update Width / Dialog Update Height」にて調整してください。

縦横サイズを調整してみました。** なにがし ** でメッセージを太字にできますが、上記のようにうまく行っていない場合は**の前後に半角スペースを入れると反映されると思います。
というわけでスクリプトのパラメータ6(Debug Mode(Possible values: verbose, true, or false. Default: “verbose”))をverboseからfalseに変更すると・・・

こんな感じでいい感じになりました!
どうです?あどみんちゃんに言われたらちゃんとアップデートしますよね・・・?
ということで、動作確認もおわりです!!!
おわりに
個人的な感想としては、準備や検証にあまり時間がかからなかったので「Nudge」や「S.U.P.E.R.M.A.N」より導入しやすいのでは?と思いました。(ブログ書く時間のほうが長かったレベル)
アップデート通知の仕組み、必要だけど実装めんどくさいな〜と常々思ってた部分ではあるので、これぐらいであれば試してみても良いのでは!!!と思います!!!
それでは!