ユーザが使いやすいようにサポートメニューを作る

デバイス

ユーザへ操作を促すのが大変なときがある

企業でmacOSを使っていて、サポートするときにたまにコンピュータ名知りたいとか、IPアドレス知りたいとか、シリアル番号知りたいっていうタイミングがあったりします。

そんなときに、GUIでパっと出せたらなと思うのです。頻度は高くないけど、ちょっとコマンド打たないと出てこないものをGUIでパッと出せるようにしておくことで、ユーザにコマンド打ってっていうより、GUIのこの操作してって促すことができ、サポートが楽になる、そんなツールを触っていきます。

Hello-ITで専用メニューをつくる

Hello-ITというサポート専用のメニューをつくるコードがあるので、それを利用します。

これを使うことでこのようなメニューを作る事ができます。
下記の画像は、すでにカスタマイズ済みです。

コンピュータ情報がサッと分かるようにする

ネットワーク情報がサッと分かるようにする

ユーザがよく使いそうなURLを作成する

普通に導入してみる

導入はカンタンです。githubのリリースのところにアプリケーションがありますので、それを普通にインストールしてください。

企業で複数台に導入するときは、みんな大好きなJamfなどのMDMを使いましょう。

導入時はこんなメニュー画面になっているはずです。これをベースにカスタマイズしてきます。

カスタマイズしてみる

カスタマイズは2つやっていきます。メニューの変更とメニューに対応したスクリプト作成です。デフォルトだとメニューが少なく寂しいので、カスタマイズ必須です。

メニューの設定ファイル

メニューは構成プロファイルで変更可能です。ソースコードの中にサンプルが入っているので、そのサンプルを参考に作成していきます。

構成プロファイルのサンプルはexampleフォルダに入ってます。仕組みを理解するためにいったんこの構成プロファイルをインストールして、どのようになるか確認してみるのもおすすめです。

参考までに私がカスタマイズした構成プロファイル(冒頭の画像のようになる)を本記事の最後に付けておきます(200行以上あります)

サブメニューの設定

下記がサブメニュー一つ分の内容です。
scriptのところにスクリプト名を入れ、titleはメニューに表示されるタイトルになります。タイトルは、起動直後、まだ値が取れていない状態のときに表示され、値が取れると切り替わります。

例を上げると、起動直後はSNinfoという文字がメニューに表示されますが、シリアル番号が取得できると実際のシリアル番号が表示されます。

  <dict>
	<key>functionIdentifier</key>
	<string>public.script.item</string>
	<key>settings</key>
	<dict>
	  <key>script</key>
	  <string>com.github.ygini.hello-it.computerdetails.serialnumber.sh</string>
	  <key>title</key>
	  <string>SNInfo</string>
	</dict>
  </dict>

メニューに対応したスクリプト作成

メニューを作成したら、それに対応したスクリプトを作成する必要があります。
これもソースコードの中にサンプルが入っているので、このサンプルを参考に作成していきます。

メニューに対応したスクリプトは下記のフォルダに入れます。Pluginsフォルダを使う設定もあるらしいのですが、使い分け方がいまいちわかりません。もともとは全部、root:wheelなので、これに合わせるのが良さそうです。

# pwd             
/Library/Application Support/com.github.ygini.hello-it/CustomScripts
pocky@XXXXXXXXX:/Library/Application Support/com.github.ygini.hello-it/CustomScripts# ll
total 96
-rwxr-xr-x  1 root   wheel   611 10 24 08:45 com.github.ygini.hello-it.computerdetails.macOSversion.sh
-rwxr-xr-x  1 pocky  staff   603 10 24 08:45 com.github.ygini.hello-it.computerdetails.modelinfo.sh
-rwxr-xr-x  1 pocky  staff   463 10 24 08:45 com.github.ygini.hello-it.computerdetails.raminfo.sh
-rwxr-xr-x  1 pocky  staff   610 10 24 08:45 com.github.ygini.hello-it.computerdetails.serialnumber.sh
-rwxr-xr-x  1 pocky  staff   685 10 24 08:45 com.github.ygini.hello-it.computerdetails.smartstatus.sh
-rwxr-xr-x  1 pocky  staff  1321 10 24 08:45 com.github.ygini.hello-it.computerdetails.storagespace.sh
-rwxr-xr-x  1 root   wheel  1067 10  1 23:34 com.github.ygini.hello-it.controlstrip.presenter.sh
-rwxr-xr-x  1 root   wheel  1247 10  1 23:34 com.github.ygini.hello-it.hide-desktop.sh
-rwxr-xr-x  1 root   wheel  1141 10  1 23:34 com.github.ygini.hello-it.hostname.sh
-rwxr-xr-x  1 root   wheel  2008 10  1 23:34 com.github.ygini.hello-it.ip.sh
-rwxr-xr-x  1 root   wheel  1936 10  1 23:34 com.github.ygini.hello-it.public-ip.sh
-rwxr-xr-x  1 root   wheel   341 10  1 23:34 com.github.ygini.hello-it.sleep.sh

スクリプトを1から作成してはいないのですが、構造をみるとカンタンに作成できそうです。メニューに表示するだけの動きのときは、setTitleActionに掛けば良さそう。クリック時の処理やCronでの処理ができそうですね。

# cat com.github.ygini.hello-it.computerdetails.macOSversion.sh
#!/bin/bash
. "$HELLO_IT_SCRIPT_SH_LIBRARY/com.github.ygini.hello-it.scriptlib.sh"

function onClickAction {
  setTitleAction "$@"
}

function fromCronAction {
   setTitleAction "$@"
}

function setTitleAction {
  osversion="$(sw_vers | grep "ProductVersion" | awk '{print $2}')"
  buildversion="$(sw_vers | grep "Build" | awk '{print $2}')"
  updateTitle "macOS Version: $osversion"
  updateState "${STATE[4]}"
  updateTooltip "macOS Build: $buildversion"
  setEnabled YES
}

### The only things to do outside of a bash function is to call the main function defined by the Hello IT bash lib.
main "$@"

exit 0

活用できそうなシーン

冒頭にも書きましたが、ユーザサポートするときに促すことが楽になるという課題は解決できます。またユーザが定型的に必要な作業をするときに、操作をシンプルにする(サポートサイトへのリンクとか)こともできます。

ただ、macOSアップデートによるメンテナンスが最低限必要になってきますので、それなりの大規模環境、もしくは潤沢に情シスを用意できる企業でないと難しそうという印象です。

メリットはあるものの、メンテナンスを考えると、よりメリットが大きくなるような使い方もしくは環境が必要かなと思っています。

参考 – 構成プロファイル

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>PayloadContent</key>
    <array>
      <dict>
        <key>PayloadContent</key>
        <dict>
          <key>com.github.ygini.hello-it</key>
          <dict>
            <key>Forced</key>
            <array>
              <dict>
                <key>mcx_preference_settings</key>
                <dict>
                  <key>content</key>
                  <array>
                    <dict>
                      <key>functionIdentifier</key>
                      <string>public.submenu</string>
                      <key>settings</key>
                      <dict>
                        <key>content</key>
                        <array>
                          <dict>
                            <key>functionIdentifier</key>
                            <string>public.script.item</string>
                            <key>settings</key>
                            <dict>
                              <key>script</key>
                              <string>com.github.ygini.hello-it.computerdetails.serialnumber.sh</string>
                              <key>title</key>
                              <string>SNInfo</string>
                            </dict>
                          </dict>
                          <dict>
                            <key>functionIdentifier</key>
                            <string>public.script.item</string>
                            <key>settings</key>
                            <dict>
                              <key>script</key>
                              <string>com.github.ygini.hello-it.computerdetails.modelinfo.sh</string>
                              <key>title</key>
                              <string>modelinfo</string>
                            </dict>
                          </dict>
                          <dict>
                            <key>functionIdentifier</key>
                            <string>public.script.item</string>
                            <key>settings</key>
                            <dict>
                              <key>script</key>
                              <string>com.github.ygini.hello-it.computerdetails.macOSversion.sh</string>
                              <key>title</key>
                              <string>macOSversion</string>
                            </dict>
                          </dict>
                          <dict>
                            <key>functionIdentifier</key>
                            <string>public.script.item</string>
                            <key>settings</key>
                            <dict>
                              <key>script</key>
                              <string>com.github.ygini.hello-it.computerdetails.raminfo.sh</string>
                              <key>title</key>
                              <string>raminfo</string>
                            </dict>
                          </dict>
                          <dict>
                            <key>functionIdentifier</key>
                            <string>public.script.item</string>
                            <key>settings</key>
                            <dict>
                              <key>script</key>
                              <string>com.github.ygini.hello-it.computerdetails.smartstatus.sh</string>
                              <key>title</key>
                              <string>smartstatus</string>
                            </dict>
                          </dict>
                          <dict>
                            <key>functionIdentifier</key>
                            <string>public.script.item</string>
                            <key>settings</key>
                            <dict>
                              <key>script</key>
                              <string>com.github.ygini.hello-it.computerdetails.storagespace.sh</string>
                              <key>title</key>
                              <string>storagespace</string>
                              <key>repeat</key>
                              <integer>3600</integer>
                            </dict>
                          </dict>
                          <dict>
                            <key>functionIdentifier</key>
                            <string>public.separator</string>
                          </dict>
                        </array>
                        <key>title</key>
                        <string>Computer Details</string>
                      </dict>
                    </dict>
                    <dict>
                      <key>functionIdentifier</key>
                      <string>public.submenu</string>
                      <key>settings</key>
                      <dict>
                        <key>content</key>
                        <array>
                          <dict>
                            <key>functionIdentifier</key>
                            <string>public.test.http</string>
                            <key>settings</key>
                            <dict>
                              <key>URL</key>
                              <string>https://raw.githubusercontent.com/ygini/Hello-IT/master/staticfiles/internet_test.txt</string>
                              <key>imageBaseName</key>
                              <string>network</string>
                              <key>mode</key>
                              <string>md5</string>
                              <key>originalString</key>
                              <string>ccf41dc8262810b99142b5627d27c25e</string>
                              <key>repeat</key>
                              <integer>60</integer>
                              <key>title</key>
                              <string>Internet</string>
                            </dict>
                          </dict>
                          <dict>
                            <key>functionIdentifier</key>
                            <string>public.script.item</string>
                            <key>settings</key>
                            <dict>
                              <key>script</key>
                              <string>com.github.ygini.hello-it.ip.sh</string>
                              <key>repeat</key>
                              <integer>60</integer>
                            </dict>
                          </dict>
                          <dict>
                            <key>functionIdentifier</key>
                            <string>public.script.item</string>
                            <key>settings</key>
                            <dict>
                              <key>script</key>
                              <string>com.github.ygini.hello-it.hostname.sh</string>
                            </dict>
                          </dict>
                        </array>
                        <key>title</key>
                        <string>Network Details</string>
                      </dict>
                    </dict>
                    <dict>
                      <key>functionIdentifier</key>
                      <string>public.submenu</string>
                      <key>settings</key>
                      <dict>
                        <key>title</key>
                        <string>Help</string>
                        <key>content</key>
                        <array>
                          <dict>
                            <key>functionIdentifier</key>
                            <string>public.open.resource</string>
                            <key>settings</key>
                            <dict>
                              <key>URL</key>
                              <string>https://www.example.com/</string>
                              <key>title</key>
                              <string>Support Page</string>
                            </dict>
                          </dict>
                          <dict>
                            <key>functionIdentifier</key>
                            <string>public.open.resource</string>
                            <key>settings</key>
                            <dict>
                              <key>URL</key>
                              <string>https://www.google.com/a/example.com/</string>
                              <key>title</key>
                              <string>Password変更</string>
                            </dict>
                          </dict>
                        </array>
                      </dict>
                    </dict>
                  </array>
                </dict>
              </dict>
            </array>
          </dict>
        </dict>
        <key>PayloadEnabled</key>
        <true/>
        <key>PayloadIdentifier</key>
        <string>MCXToProfile.a560c8ba-01eb-486a-a7f6-f2b208218cd4.alacarte.customsettings.06be8416-6831-401c-95b3-889610b35feb</string>
        <key>PayloadType</key>
        <string>com.apple.ManagedClient.preferences</string>
        <key>PayloadUUID</key>
        <string>06be8416-6831-401c-95b3-889610b35feb</string>
        <key>PayloadVersion</key>
        <integer>1</integer>
      </dict>
    </array>
    <key>PayloadDescription</key>
    <string>Included custom settings:com.github.ygini.hello-itGit revision: a0e04c60fc</string>
    <key>PayloadDisplayName</key>
    <string>Hello IT Configuration</string>
    <key>PayloadIdentifier</key>
    <string>org.example.techserv.helloit.config</string>
    <key>PayloadOrganization</key>
    <string>Bozeman School District #7</string>
    <key>PayloadRemovalDisallowed</key>
    <true/>
    <key>PayloadScope</key>
    <string>System</string>
    <key>PayloadType</key>
    <string>Configuration</string>
    <key>PayloadUUID</key>
    <string>a560c8ba-01eb-486a-a7f6-f2b208218cd4</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
  </dict>
</plist>
タイトルとURLをコピーしました