> For the complete documentation index, see [llms.txt](https://docs.nexthink.com/platform/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nexthink.com/platform/ja/user-guide/remote-actions/setting-up-and-managing-remote-actions/creating-remote-actions/writing-scripts-for-remote-actions-on-mac.md).

# Mac 上でリモートアクション用スクリプトを作成する

{% hint style="info" %}
この記事で説明されている操作の実行についてサポートが必要な場合は、Nexthink認定パートナーにお問い合わせください。
{% endhint %}

このページでは、MacでNexthinkリモートアクションスクリプトを準備する方法について説明します。 スクリプトは、多くのUNIX系オペレーティングシステムでサポートされているコマンドラインシェルおよびスクリプト言語であるBashで作成し、セキュリティのために証明書で署名します。

Bashスクリプトは、タスクの自動化および構成管理に適しており、従業員のデバイスでリモートアクションを実行できます。

{% hint style="warning" %}
現在、Mobile Accountsが有効なmacOSデバイスでは、リモートアクションはサポートされていません。 このモードでは、アクションが成功したように見えても、実際には変更が適用されません。
{% endhint %}

リモートアクションの主なユースケースには、デバイスからのオンデマンドデータ収集、自己修復タスク、および構成設定の変更が含まれます。

この記事は、読者がBashスクリプティングに精通していることを前提としています。

詳細については、[CommunityのRemote actionsグループ](https://community.nexthink.com/s/group/0F92p000000kI80CAE)のドキュメントを参照してください。

{% hint style="info" %}
スクリプトを安全に実行する方法の詳細については、Nexthink Securityの[Remote Actionsのセキュリティベストプラクティス](https://docs.nexthink.com/security/security-best-practices/remote-actions-security-best-practices)を参照してください。
{% endhint %}

## スクリプトの作成

### 汎用スクリプトと入力変数

汎用スクリプトは、デジタル署名済みスクリプトをカスタマイズする必要がある場合に役立ちます。 署名済みスクリプトを変更すると署名が無効になりますが、汎用スクリプトは署名を維持したままパラメータでカスタマイズできます。

Bashの位置パラメータ用のパラメータをスクリプトの先頭で宣言し、次のように一対の特別なコメントで囲みます：

```
# NXT_PARAMETERS_BEGIN
Parameter1=$1
Parameter2=$2
Parameter3=$3
# NXT_PARAMETERS_END
```

リモートアクションの設定時にスクリプトをアップロードすると、システムはBashスクリプト内の特別なNexthinkコメントの間にあるパラメータを取得します。 これらはスクリプトテキストの下にある**パラメータ**セクションに一覧表示されます。 各パラメータ名の右側に表示されるテキスト入力ボックスに、パラメータの実際の値を入力します。

{% hint style="info" %}
実際の値は常にテキストとしてスクリプトに渡されます。 スクリプトで**string**以外の型のパラメータを宣言している場合は、スクリプトが想定する型に変換できる値を指定してください。
{% endhint %}

### 出力変数の作成

スクリプトを実行すると、オンデマンドデータとして保存したい出力が生成される場合があります。 Nexthinkは、Collectorと同時に従業員のデバイスにインストールされるBashスクリプト（`nxt_ra_script_output.sh`）を提供します。 このスクリプトには、結果をデータレイヤーに書き込む関数が含まれています。

リモートアクションの出力でNexthinkスクリプトの関数を使用するには、Bashスクリプトの先頭に次のヘッダーを追加します：

```
#!/bin/bash
. "${NEXTHINK}"/bash/nxt_ra_script_output.sh
```

すべての書き込みメソッドは、出力名と書き込む値を引数として受け取ります。 たとえば、ディレクトリ内のファイル数をデータレイヤーに返す場合、スクリプト内の変数`nfiles`にその数が格納されます。 `FileNumber`という名前の出力を介して`nfiles`の値をデータレイヤーに書き込むには、符号なし整数を書き込む関数を呼び出します：

```
nxt_write_output_uint32 'FileNumber' $nfiles
```

Remote Actionsエディタはスクリプト内の出力書き込み呼び出しを認識し、出力変数を「出力」セクションに一覧表示します。 調査およびメトリクスでの参照方法を示すように、出力のラベルを設定します。

各`write`メソッドの末尾は出力の型を示します。 Bashは緩やかな型付けの言語であるため、出力の型はコンテキストに応じて解釈されます。 使用可能なメソッドの一覧は次のとおりです：

| nxt writeメソッド                    | 制約                                                                |
| -------------------------------- | ----------------------------------------------------------------- |
| nxt\_write\_output\_string       | 0 ～ 1024 バイト（大きい場合は出力が切り捨てられます）                                   |
| nxt\_write\_output\_bool         | true / false                                                      |
| nxt\_write\_output\_uint32       | <ul><li>最小: 0</li><li>最大: 4 294 967 295</li></ul>                 |
| nxt\_write\_output\_float        | <ul><li>最小: -3.4E+38</li><li>最大: 3.4E+38</li></ul>                |
| nxt\_write\_output\_size         | <ul><li>最小: 0</li><li>最大: 3.4E+38</li></ul>                       |
| nxt\_write\_output\_ratio        |                                                                   |
| nxt\_write\_output\_bitrate      |                                                                   |
| nxt\_write\_output\_duration     | <ul><li>最小: 0 ms</li><li>最大: 49日</li><li>ミリ秒単位の精度</li></ul>       |
| nxt\_write\_output\_date\_time   | <ul><li>想定値: エポック時刻（整数）</li><li>出力: YYYY-MM-DD HH:MM:SS</li></ul> |
| nxt\_write\_output\_string\_list | 0 ～ 1024 バイト（大きい場合は出力が切り捨てられます）                                   |

### **出力フィールドの定義**

スクリプトを作成するときは、必ず次の点を確認してください:

* **すべての出力フィールド名を事前に定義する:** これにより、スクリプトの実行中に出力テーブルの正しいフィールドが確実に入力されます。 predefined な field 名がない場合、script は output schema が不明なため失敗する可能性があります。
  * 出力フィールド名は常に`string`形式である必要があります。
  * 例: `nxt_write_output_string 'output_field_name' "$output_value"`
* **出力フィールドの数を定義する:** スクリプトでは常に、固定数の出力フィールドを指定する必要があります。 固定スキーマにより、結果の予測可能性と互換性が確保されます。
  * 動的なフィールドを避けてください。 動的な出力構造は、プラットフォームにおける不整合や処理エラーを引き起こす可能性があります。
  * スクリプトを実行する際に、出力フィールドを定義するためにループを使用することは避けてください。

### キャンペーンの実装

リモートアクションとキャンペーンを組み合わせて、従業員が自立して問題を解決できるようにします。 キャンペーンを使用すると、問題が検出されたことを従業員に通知し、その解決に向けて案内できます。

デバイスを操作している従業員のデスクトップにキャンペーンを表示するには：

* キャンペーンには **リモートアクション** のトリガーがあり、公開されている必要があります。
* リモートアクションのスクリプトは、次のいずれかの方法で実行できます。
  * アクションに特別な権限が不要な場合は、従業員のコンテキストで実行されます。
  * ローカル システム アカウントのコンテキストで、アクションに管理者特権が必要な場合。

### **キャンペーン識別子の取得**

リモートアクションからキャンペーンを実行するためのメソッドでは、引数としてキャンペーン識別子を渡す必要があります。 キャンペーンの NQL ID（推奨）とキャンペーンの UID（従来のオプション）の両方を使用できます。

```
NQL ID を識別子として使用するには、Collector バージョン 23.5 以降が必要です。
```

キャンペーン識別子をリモートアクションに渡すには、必要な各キャンペーンごとに、リモートアクションのスクリプト内でパラメーターを宣言します。 リモートアクションを編集する際、パラメーターの実際の値として NQL ID（または UID）を使用します。

NQL IDまたはキャンペーンのUIDの取得方法については、[キャンペーンのトリガー](/platform/ja/user-guide/campaigns/working-with-campaigns/triggering-campaigns.md)のドキュメントを参照してください。

### **リモートアクションのスクリプトからキャンペーンを実行する**

{% hint style="info" %}
エラーログは `/Library/Logs/nxtcod.log` にあります。
{% endhint %}

これはファイル構造によって異なる場合があります。

以下の関数は、リモートアクションのスクリプト機能を拡張します。

```
nxt_run_campaign( id )
```

この関数は、パラメーターとして渡された NQL ID（推奨）または UID に一致するキャンペーンを実行し、回答を内部に保存します。

* キャンペーンのステータスが受信された場合、関数は 0 を返します。
* その他のすべての場合には関数は 1 を返し、エラーはログに記録されます。

この関数を呼び出すと、従業員がキャンペーンを完了するか却下するまで、リモートアクションの実行が一時停止されます。

```
nxt_run_campaign_with_timeout( id timeout)
```

この関数は、パラメーターとして渡されたタイムアウト（秒単位、0 < T < 1 週間）を用いて、NQL ID（推奨）または UID に一致するキャンペーンを実行し、回答を内部に保存します。

* キャンペーンのステータスを受信した場合、関数は 0 を返します。
* 関数はその他のすべての場合に 1 を返し、エラーはログに記録されます。

この関数を呼び出すと、従業員がキャンペーンを完了するか、却下するか、タイムアウトまでにキャンペーンを完了できなかった場合のいずれかになるまで、リモートアクションの実行が一時停止されます。

```
nxt_run_standalone_campaign( id )
```

この関数は、パラメーターとして渡された NQL ID（推奨）または UID に一致するキャンペーンを実行し、回答を内部に保存します。

* キャンペーンのステータスが受信された場合、関数は 0 を返します。
* その他すべての場合には関数は1を返し、エラーはログに記録されます。

関数を呼び出すとキャンペーンが開始され、従業員の回答を待たずにリモートアクションの実行が継続されます。

```
nxt_get_campaign_status( res_var )
```

関数:

* キャンペーンステータスが `res_var` に正常に保存された場合は 0 を返します。
* それ以外の場合は 1 を返します。

その後、キャンペーンのステータスを文字列値として抽出し、指定された変数 `res_var` に保存します。 関数が結果として `0` を返した場合、`res_var` には次のいずれかの値が設定されます。

* **完全**: 従業員はキャンペーンの質問に完全に回答しました。
* **timeout**：ユーザーが回答を終える前にキャンペーンがタイムアウトしました。
* **postponed**：従業員はキャンペーンへの参加に同意しました。
* **declined**：従業員はキャンペーンへの参加を辞退しました。
* **connectionfailed**: スクリプトがキャンペーン通知を制御する Collector コンポーネントに接続できませんでした。
* **notificationfailed**: スクリプトは、次のいずれかの理由によりキャンペーンを正常に表示できませんでした:
  * キャンペーンが存在しない、または未公開のため、プラットフォームからキャンペーン定義を取得できませんでした。
  * 別のキャンペーンが従業員にすでに表示されています。
  * フォーカス保護またはCollectorの「通知しない」ルールにより、非緊急のキャンペーンを表示できません。 詳細については、[キャンペーンの受信率を制限する](/platform/ja/user-guide/campaigns/managing-campaigns/creating-campaigns/limiting-the-reception-rate-of-campaigns.md)ドキュメントを参照してください。
* 最後のキャンペーンが失敗した場合は空になります。

```
nxt_get_response_answer( res_var question_key)
```

質問ラベルを文字列パラメーター `query_key` として使用して、最後のキャンペーンをクエリします。 この関数は回答を文字列値として抽出し、指定された変数 `res_var` に保存します。

* キャンペーンの回答が `res_var` に正常に保存された場合は 0 を返します。
* それ以外の場合は 1 を返します。

### スクリプトのエンコード

リモートアクション用の Bash スクリプトを作成するには:

* スクリプトを含むファイルを UTF-8（BOM なし）でエンコードしてください。
* コード内の各行は、UNIX システムで通常使用される文字「LF」で終わらせてください。

エラーやスクリプトの不具合を防ぐため、適切なエンコードを使用してください。

***

## コード例

<0>キャンペーンの呼び出し\</0>

この例では、リモートアクションが ID を使用して基本的なキャンペーン呼び出しを実行し、成功した場合はステータスメッセージを、失敗した場合はエラーメッセージを出力します。

```bash
if nxt_run_campaign "#my_campaign_nql_id"; then
    nxt_get_campaign_status status
    if [[ status == "fully" ]]; then
        echo "キャンペーンが成功しました"
    else
        echo "ステータスは $status です"
    fi
else
    echo "キャンペーンが失敗しました"
fi
```

<details>

<summary>レスポンスへのアクセス</summary>

この例では、リモートアクションがキャンペーンの回答データを要求し、配列として出力します。 各回答は、それぞれ対応する番号付きオプションで表されます。 Bash は最小の選択肢として 0 を使用しますが、Zsh は 1 を使用します。

```bash
nxt_get_campaign_status status
echo "レスポンスステータスは $status です"
nxt_get_response_answer answersArray key1
echo ${answersArray[1]}
```

</details>

<0>タイムアウト付きでキャンペーンを実行する\</0>

この例では、リモートアクションが、秒を入力として指定した時間後にタイムアウトして終了するキャンペーンを実行するように設定されています。

```bash
# timeout は秒数で指定します (100s または 00:01:40)

if nxt_run_campaign_with_timeout "#my_campaign_nql_id" 100; then
    nxt_get_campaign_status status
    if [[ status == "fully" ]]; then
        echo "キャンペーンが成功しました"
    else
        echo "ステータスは $status です"
    fi
else
    echo "キャンペーンが失敗しました"
fi
```

<0>非ブロッキングキャンペーンの実行\</0>

この例では、リモートアクションはユーザー入力を必要とせず、キャンペーンをトリガーした後も実行を続けます。 ユーザーはいつでもキャンペーンを閉じることができます。 これは主に、データを取得するのではなく、ユーザーに情報を提供するために使用されます。

詳細については、[魅力的なキャンペーンの実施](broken://pages/fww1Z7TuzfBVwY5iW1pf#conductingengagingcampaigns-determinecampaigngoals)ドキュメントを参照してください。

```bash
if nxt_run_standalone_campaign "#my_campaign_nql_id"; then
    nxt_get_campaign_status status
    if [[ status == "fully" ]]; then
        echo "キャンペーンが成功しました"
    else
        echo "ステータスは $status です"
    fi
else
    echo "キャンペーンが失敗しました"
fi
```

***

## スクリプトの署名

Nexthink は、macOS 上で署名されたスクリプトを検証するために、システム証明書ストアに依存する方法と、証明書ピンニングを使用する方法の 2 つのアプローチをサポートしています。 どちらの方法でもスクリプトの完全性は確保されますが、証明書ピンニングを使用することで、macOS の証明書信頼に依存せずに済み、Apple がセキュリティモデルを進化させ続ける中でも、より堅牢なソリューションを提供できます。

macOS で信頼性の高いスクリプト署名を行うには、`login.keychain` に保存された証明書を使用してください。 `System.keychain` 内の証明書は、特に自動化された非対話型環境では、プライベートキーへのアクセスが制限されているために失敗する可能性があります。

{% hint style="info" %}
セキュリティ上の理由から、NexthinkではmacOS上のリモートアクション用Bashスクリプトを`codesign`ツールでデジタル署名する必要があります。 Apple は署名をファイルの拡張属性に保存します。 拡張属性を保持するため、署名済みスクリプトを`tar.gz`ファイルとしてパッケージ化します。 Nexthink の Web インターフェイスは、macOS を対象とするリモートアクション用のスクリプトをインポートする際、`tar.gz` ファイルのみを受け付けます。

Nexthinkでは、本番環境のすべてのスクリプトに署名することを推奨しています。 未署名のスクリプトはテスト環境でのみ使用してください。
{% endhint %}

<details>

<summary>オプション 1：証明書ピンニング（Nexthink 推奨）</summary>

証明書ピンニングが有効な場合、署名されていないスクリプトは実行されません。 Collector は、SHA-256 フィンガープリントが設定済みの `cert_fingerprints` の値と一致する証明書で署名された場合にのみスクリプトを実行します。

サポートされている実行ポリシーには、`signed_pinned` と `signed_pinned_or_nexthink` が含まれます。 後者では、設定内で Nexthink 証明書のフィンガープリントを必要とせずに、Nexthink Library のリモートアクションを実行できるようになります。

{% hint style="info" %}
Collectorバージョン2025.9.1.x以降、MacOS Collectorでは、実行できるスクリプトを制御するための追加の実行ポリシーがサポートされています。 このセクションでは、その詳細について説明します。
{% endhint %}

**新しい実行ポリシー**

macOSには、以下の新しい実行ポリシーが導入されています：

* **signed\_pinned**
* **signed\_pinned\_or\_nexthink**

さらに、新しいインストーラーオプション`cert_fingerprints`が追加されました。

**「**`cert_fingerprints`**」インストーラーオプション**

`cert_fingerprints`オプションでは、スクリプト署名サムプリントの許可リストを定義できます（単一の`,`文字で区切り、前後にスペースを入れません）。 スクリプト署名のサムプリントは **リーフ証明書** のサムプリントと一致している必要があります。

次のスクリプトを使用して、署名済みスクリプトファイルのリーフ証明書のサムプリントを抽出できます：

```
#!/bin/bash
#
# extract_signature_leaf_certificate_thumbprint.sh
#
# Copyright (C) 2025 by Nexthink S.A., Switzerland. Any usage, copy or partial copy of
# this code without the explicit agreement of Nexthink S.A. is prohibited and will be
# pursued to the full extend of the law.
#
# The arguments for the script:
# - input script filename
#

set -euo pipefail

if [ $# -lt 1 ]; then
  echo "Usage: $0 <path-to-signed-binary>" >&2
  exit 1
fi

sigpath="$1"

tmpdir=$(mktemp -d) || { echo "Failed to create temp dir" >&2; exit 1; }

(
  cd "$tmpdir" || exit 1
  codesign -d --extract-certificates "$sigpath" >/dev/null

  leaf=$(ls codesign0* 2>/dev/null | head -n 1)
  if [ -n "$leaf" ] && [ -f "$leaf" ]; then
    openssl x509 -in "$leaf" -inform DER -noout -fingerprint -sha256
  else
    echo "Leaf certificate not found" >&2
    exit 2
  fi
)

rm -rf "$tmpdir"
```

{% hint style="danger" %}
`cert_fingerprints`オプションは、新しい実行ポリシー（`signed_pinned`および`signed_pinned_or_nexthink`）を使用する場合にのみ適用されます。 他の実行ポリシーには影響しません。
{% endhint %}

**ポリシーの動作**

**signed\_pinned**

* 未署名のスクリプトは許可されません。 実行時に失敗し、Collectorは該当するステータスを報告します。
* Nexthink LibraryのRAスクリプト: `cert_fingerprints`に署名のリーフ証明書のサムプリントが含まれている場合にのみ実行が許可されます。 それ以外の場合、実行はブロックされ、ステータスが報告されます。
* その他のスクリプト: `cert_fingerprints`に署名のリーフ証明書のサムプリントが含まれている場合にのみ実行が許可されます。 それ以外の場合、実行はブロックされ、ステータスが報告されます。

**signed\_pinned\_or\_nexthink**

* 未署名のスクリプトは**許可されません**。 実行時に失敗し、Collectorは該当するステータスを報告します。
* Nexthink LibraryのRAスクリプト: 常に実行が許可されます（ポリシーによってブロックされません）。
* その他のスクリプト: `cert_fingerprints`に署名のリーフ証明書のサムプリントが含まれている**場合にのみ**実行が許可されます。 それ以外の場合、実行はブロックされ、ステータスが報告されます。

**実行ポリシーの概要表**

| ポリシー                              | 未署名のスクリプト | Nexthink LibraryのRAスクリプト                    | その他の署名済みスクリプト                               | cert\_fingerprintsの影響 |
| --------------------------------- | --------- | ------------------------------------------- | ------------------------------------------- | --------------------- |
| signed\_trusted（既存）               | ブロック      | ブロック                                        | 信頼された証明書による署名の場合に許可                         | 影響なし                  |
| signed\_trusted\_or\_nexthink（既存） | ブロック      | 常に許可                                        | 信頼された証明書による署名の場合に許可                         | 影響なし                  |
| signed\_pinned                    | ブロック      | 許可リスト（`cert_fingerprints`）にサムプリントが含まれる場合に許可 | 許可リスト（`cert_fingerprints`）にサムプリントが含まれる場合に許可 | 必要                    |
| signed\_pinned\_or\_nexthink      | ブロック      | 常に許可                                        | 許可リスト（`cert_fingerprints`）にサムプリントが含まれる場合に許可 | 必要                    |

**証明書ピン留め用のコード署名証明書を作成する**

証明書ピンニングでは、あらゆる種類のコード署名証明書がサポートされます：

* AppleのDeveloperサイトで作成したコード署名証明書
* AppleのCertificate Assistantで作成したコード署名証明書
* プライベートRoot CAを使用するコード署名証明書
* パブリックRoot CAを使用するコード署名証明書
* その他のあらゆる種類

プライベートRoot CAを使用するコード署名証明書を使用する場合は、具体的な手順を[上記](#option-1-relying-on-the-system-certificate-store)で確認できます。

**署名済みリモートアクションスクリプトのパッケージ化と既知の制限事項**

コード署名証明書を作成したら、それをダブルクリックしてKeychain Accessアプリケーションで開きます。 証明書を右クリックし、「情報を見る」をクリックします。

<figure><img src="/files/AukULdAMUMqmrL6HxPfj" alt="" width="563"><figcaption></figcaption></figure>

下部までスクロールし、そこにあるSHA-1をコピー＆ペーストします。 リモートアクションスクリプトの署名に使用するため、値からスペースを削除します。

<figure><img src="/files/5ZtDtwIqKL5mVhI9csJc" alt="" width="563"><figcaption></figcaption></figure>

コード署名証明書を使用してスクリプトに署名します：

<figure><img src="/files/hAaGyPWyBGnkXVcW2dAn" alt="" width="563"><figcaption></figcaption></figure>

以下のようにコマンドを実行して、前のスクリプト署名手順が成功したことを確認します。

<figure><img src="/files/ecQfVpcVAfiqqRnLsdRN" alt="" width="563"><figcaption></figcaption></figure>

**パッケージ化**

リモートアクションスクリプトを、.tarアーカイブと.gzip圧縮でパッケージ化します。 拡張子「.tar.gz」は必須です。

```
tar -czvf ./<your script name>.tar.gz ./<your script name>.sh
```

スクリプトファイルが署名されている場合、tarユーティリティはその拡張属性もパッケージ化します。 これにより、システムはコード署名とスクリプトファイルを転送できます。

**制限事項**

* 各アーカイブには、スクリプトを1つだけ格納できます。
* スクリプトファイルはルートパッケージフォルダーに配置する必要があります。`./myscript/myscript.sh`のパスは正しくありません。
* スクリプトには.sh拡張子が必要です。
* スクリプトファイル名はUTF-8でエンコードする必要があります。これはmacOSのデフォルトです。

**例**

`test.sh`スクリプトをパッケージ化する例：

```
tar -czvf ./example_ra_script.tar.gz ./example_ra_script.sh
```

生成された`example_ra_script.tar.gz`がリモートアクションスクリプトファイルです。

{% hint style="info" %}
Nexthinkでは、署名とパッケージ化のプロセスを簡略化するために、このスクリプトを使用することを推奨しています。
{% endhint %}

```
#!/bin/bash
#
# script_signing.sh
# 
# Copyright (C) 2023 by Nexthink S.A., Switzerland. Any usage, copy or partial copy of
# this code without the explicit agreement of Nexthink S.A. is prohibited and will be
# pursued to the full extend of the law.
#
# The arguments for the script:
# - input script filename
# - output archive filename
# - Certificate owner
# - Prefix
#
 
 
# Error handling
set -euo pipefail
trap "echo unrecoverable error !" ERR
 
 
# Check codesign
if [[ ! -x /usr/bin/codesign ]]
then
    echo "Error: this script requires that codesign is installed"
    exit 2
fi
 
# Check tar
if [[ ! -x /usr/bin/tar ]]
then
    echo "Error: this script requires that tar is installed"
    exit 2
fi
 
 
# Check arguments
if [[ $# -lt 4 ]]
then
    echo "Usage: script_signing.sh inputScriptFilename outputArchiveFilename CertificateOwner prefix"
    echo "Example: ./script_signing.sh script.sh script.tar.gz \"John Doe\" com.john.remote-action.macos."
    exit 1
fi
 
/usr/bin/codesign -s "$3" --timestamp --prefix="$4" --force "$1"
/usr/bin/tar czf "$2" "$1"
```

**署名証明書のRoot CAをエンドポイントに展開する**

証明書ピン留めでは、証明書をエンドポイントに展開する必要はありません。 上記の説明に従い、すべてのエンドポイントで`cert_fingerprints` Collectorインストーラーオプションを設定するだけです。

</details>

<details>

<summary>オプション 2: システム証明書ストア（Nexthink は推奨しません）</summary>

**署名証明書の作成**

{% hint style="warning" %}
MacOS Sequoia（バージョン15）以降では、Appleによる変更により、（Windowsで行うように）署名証明書自体をすべてのデバイスに信頼済みとして展開するのではなく、署名証明書のルート認証局（CA）を展開する必要があります。 オペレーティングシステムに事前インストールされているパブリックRoot CAは使用できません。
{% endhint %}

リモートアクションを実行するすべてのデバイスに、次のいずれかのオプションを展開できます。

* リモートアクション専用の自己署名Root CA
* 企業のRoot CA

以下は、自己署名Root CAを作成し、それを使用してリモートアクションへの署名用コード署名証明書を生成する例です：

1. MacデバイスでKeychain Accessを起動します。
2. 「Keychain Access」>「Certificate Assistant」> **「証明機関を作成…」** に移動します

<figure><img src="/files/xC1JNiaw6kaYZ1Jfrq3Y" alt="" width="563"><figcaption></figcaption></figure>

3. 認証局の名前を入力します。
4. **ユーザー証明書**として**コード署名**を選択します。
5. メールアドレス（管理目的の連絡先）を入力します。
6. \*\*「作成」\*\*をクリックして証明書を生成します。

<figure><img src="/files/QslvcdqRAhxiHLhpIkuH" alt="" width="563"><figcaption></figcaption></figure>

以下は、コード署名証明書自体を作成する例です：

1. MacデバイスでKeychain Accessを起動します。
2. 「Keychain Access」>「Certificate Assistant」> **「証明書を作成…」** に移動します

<figure><img src="/files/Ze4v57HrribnxXVlFdoc" alt="" width="563"><figcaption></figcaption></figure>

3. 証明書の名前を入力します。

<figure><img src="/files/RcySuTcoinKf1zpocbEA" alt="" width="563"><figcaption></figcaption></figure>

4. この証明書の発行者としてRoot CAを選択します。

<figure><img src="/files/6eCbQUyMsdbWrvVPD9Hj" alt="" width="563"><figcaption></figcaption></figure>

5. \*\*「作成」\*\*をクリックして証明書を生成すると、以下のような確認が表示されます。

<figure><img src="/files/wI3pfOM9vF1KaKszWfG4" alt="" width="563"><figcaption></figcaption></figure>

証明書が作成されると、Keychain Accessアプリケーションで表示されます。 証明書を右クリックし、「情報を見る」をクリックします。

<figure><img src="/files/AukULdAMUMqmrL6HxPfj" alt="" width="563"><figcaption></figcaption></figure>

下部までスクロールし、そこにあるSHA-1をコピー＆ペーストします。 リモートアクションスクリプトの署名に使用するため、値からスペースを削除します。

<figure><img src="/files/5ZtDtwIqKL5mVhI9csJc" alt="" width="563"><figcaption></figcaption></figure>

コード署名証明書を使用してスクリプトに署名します：

<figure><img src="/files/hAaGyPWyBGnkXVcW2dAn" alt="" width="563"><figcaption></figcaption></figure>

以下のようにコマンドを実行して、前のスクリプト署名手順が成功したことを確認します。

<figure><img src="/files/ecQfVpcVAfiqqRnLsdRN" alt="" width="563"><figcaption></figcaption></figure>

**パッケージ化**

リモートアクションスクリプトを、.tarアーカイブと.gzip圧縮でパッケージ化します。 拡張子「.tar.gz」は必須です。

```
tar -czvf ./<your script name>.tar.gz ./<your script name>.sh
```

スクリプトファイルが署名されている場合、tarユーティリティはその拡張属性もパッケージ化します。 これにより、システムはコード署名とスクリプトファイルを転送できます。

**制限事項**

* 各アーカイブには、スクリプトを1つだけ格納できます。
* スクリプトファイルはルートパッケージフォルダーに配置する必要があります。`./myscript/myscript.sh`のパスは正しくありません。
* スクリプトには.sh拡張子が必要です。
* スクリプトファイル名はUTF-8でエンコードする必要があります。これはmacOSのデフォルトです。

**例**

`test.sh`スクリプトをパッケージ化する例：

```
tar -czvf ./example_ra_script.tar.gz ./example_ra_script.sh
```

生成された`example_ra_script.tar.gz`がリモートアクションスクリプトファイルです。

{% hint style="info" %}
Nexthinkでは、署名とパッケージ化のプロセスを簡略化するために、このスクリプトを使用することを推奨しています。
{% endhint %}

```
#!/bin/bash
#
# script_signing.sh
# 
# Copyright (C) 2023 by Nexthink S.A., Switzerland. Any usage, copy or partial copy of
# this code without the explicit agreement of Nexthink S.A. is prohibited and will be
# pursued to the full extend of the law.
#
# The arguments for the script:
# - input script filename
# - output archive filename
# - Certificate owner
# - Prefix
#
 
 
# Error handling
set -euo pipefail
trap "echo unrecoverable error !" ERR
 
 
# Check codesign
if [[ ! -x /usr/bin/codesign ]]
then
    echo "Error: this script requires that codesign is installed"
    exit 2
fi
 
# Check tar
if [[ ! -x /usr/bin/tar ]]
then
    echo "Error: this script requires that tar is installed"
    exit 2
fi
 
 
# Check arguments
if [[ $# -lt 4 ]]
then
    echo "Usage: script_signing.sh inputScriptFilename outputArchiveFilename CertificateOwner prefix"
    echo "Example: ./script_signing.sh script.sh script.tar.gz \"John Doe\" com.john.remote-action.macos."
    exit 1
fi
 
/usr/bin/codesign -s "$3" --timestamp --prefix="$4" --force "$1"
/usr/bin/tar czf "$2" "$1"
```

**Root CAを生成したマシンで署名済みスクリプトをテストする**

Root CAを作成した同じマシンで署名済みスクリプトをテストする場合は、次の手順を実行する必要があります。

**Root CAをシステムキーチェーンにコピーして信頼済みとしてマークする**

Appleはデフォルトで、生成されたRoot CAを\*\*「login」**キーチェーンに配置します。 ただし、適切に機能させるには**「System」\*\*キーチェーンにインストールする必要があります。

証明書をSystemキーチェーンにコピーするには、次の手順に従います：

1. **Keychain Access**を開きます。
2. Root CA証明書を右クリックし、\*\*「書き出す」\*\*を選択してエクスポートします。\
   ポップアップウィンドウで、\*\*Certificate (.cer)\*\*ファイル形式を選択します。<br>

   <figure><img src="/files/z7KtPR8Fvm4wa6fuPZTL" alt="" width="563"><figcaption></figcaption></figure>
3. **Terminal**アプリケーションを開きます。
4. 次のコマンドを実行して、Root CAをSystemキーチェーンにインポートします。\
   `sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain Certificate.cer`
5. インポート後、証明書が**System**キーチェーンに表示されることを確認します：
   * **Keychain Access**に戻ります。
   * 左側のサイドバーで**System**セクションを選択します。
   * 右上隅の検索バーを使用して証明書を探します。
   * 結果テーブルで、**キーチェーン**列に**System**と表示されていることを確認します。
6. Root CA証明書を右クリックし、\*\*「情報を見る」\*\*を選択して、信頼済みとしてマークします。
   * **信頼**セクションで、Root CAを信頼済みとしてマークするよう設定を調整します。<br>

     <figure><img src="/files/g09OzuGqdaNXL7TuW7E6" alt=""><figcaption></figcaption></figure>

**署名証明書のRoot CAをエンドポイントに展開する**

{% hint style="info" %}
MacOS Sequoiaバージョン15以降では、Windowsのように署名証明書をすべてのデバイスに信頼済みとして展開するのではなく、署名証明書のルート認証局（CA）を展開する必要があります。

Collector Cloud 24.10.2.10およびCollectorオンプレミス24.10.30.26では、展開済みの署名証明書に代わる方法として、展開済みRoot CAに基づくリモートアクションスクリプトの信頼済みソース検証がサポートされています。
{% endhint %}

Root CAは複数の方法で展開できますが、主に以下で説明するJAMFを使用した構成プロファイルの作成によって展開します。

**Root CAで作成した証明書をエクスポートする**

1. ポップアップウィンドウで、\_Certificate (.cer)\_ファイル形式を選択します。

<figure><img src="/files/z7KtPR8Fvm4wa6fuPZTL" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="/files/h4AqiINonXXgfGvcfZog" alt="" width="563"><figcaption></figcaption></figure>

2. 上記の構成プロファイルを使用して、すべてのエンドポイントに展開します。 Root CAは自動的に信頼済みとしてマークされます。

<figure><img src="/files/CSxaM8O83Nz8gggSzEa4" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/g09OzuGqdaNXL7TuW7E6" alt="" width="563"><figcaption></figcaption></figure>

**証明書がエンドポイントに正しくインポートされたことを確認する**

署名済みリモートアクションスクリプトをエンドポイントにコピーし、展開します。

```
tar -xzvf example_ra_script.tar.gz
```

署名を検証します。

```
codesign -vvvv -R="anchor trusted" example_ra_script.sh
```

署名証明書のRoot CAが正しくインポートされている場合、次の出力が表示されます：

<figure><img src="/files/7VlLbExxUeYPKXtGf2gA" alt=""><figcaption></figcaption></figure>

</details>

<0>オプション 3: 証明書の生成、署名、デプロイ、検証（非推奨の方法<1>,\</1>macOS Sequoia 以降とは互換性がありません）\</0>

**Root CAを使用しない証明書生成方法**

この証明書生成方法はすべてのデバイスで引き続き機能しますが、デバイスで信頼済みとしてマークするにはユーザー操作が必要です。

* MacデバイスでKeychain Accessを起動します。
* 「Keychain Access」>「Certificate Assistant」> **「証明書を作成…」** に移動します

<img src="/files/Q08eNez3RmEBk29BwikN" alt="" data-size="original">

1. 証明書の名前を入力します。

* **証明書の種類**として**コード署名**を選択します。
* テスト目的の場合、**デフォルトを上書きする**はオフのままにできます。<br>

<img src="/files/bReDxBSBg10dD3SnWCFt" alt="" data-size="original">

* **「作成」**、次に\*\*「完了」\*\*をクリックします。 システムにより証明書が生成されます。

<img src="/files/AfuDULK4iMYl8ctW5bWX" alt="" data-size="original">

**署名**

標準のmacOS codesignユーティリティを使用して、リモートアクションスクリプトに署名します。

```
codesign -s <your certificate identity> --timestamp --prefix=<code signature identifier prefix> --force <script file name>
```

パラメータ：

```
-s <your certificate identity>
```

コード署名証明書のIDはキーチェーンにあります。 通常、証明書サブジェクトの共通名または証明書ハッシュです。 詳細については、SS64の[codesignマニュアルページ](https://ss64.com/mac/codesign.html)を参照してください。

```
--timestamp
```

署名の信頼できるタイムスタンプです。

```
--prefix
```

コード署名識別子のプレフィックスです。 企業IDを識別子に付加し、識別子を一意にするのに役立ちます。 コード署名識別子の生成ルールについては、UNIXの[codesignマニュアルページ](https://www.unix.com/man-page/osx/1/codesign/)のドキュメントを参照してください。

```
--force
```

既存のコード署名がある場合に、強制的に書き換えます。

**例**

\_example\_ra\_script.sh\_リモートアクションスクリプト用テスト証明書の例：

```
codesign -s "RA scripts code signing certificate" --timestamp --prefix=com.my-organisation.remote-action.macos. --force example_ra_script.sh
```

スクリプトファイルの署名は、ファイルに関連付けられたファイルシステムの拡張属性に生成されます。 codesignユーティリティを使用してコード署名の詳細を取得し、署名を検証します：

<img src="/files/g2Q4x7FDBQgsCMaLwSqP" alt="" data-size="original">

**署名証明書をエンドポイントに展開する**

この展開方法は引き続き機能しますが、ユーザー操作が必要です。

<img src="/files/AHKSNM3uLCWNJKL7I4Dj" alt="" data-size="original">

ポップアップウィンドウで、パブリック証明書用の\_Certificate (.cer)\_ファイル形式を選択します。

**エンドポイントのキーチェーンに証明書をインポートする**

* \_Trusted Publisher\_実行ポリシーでリモートアクションスクリプトを使用するには、コード署名証明書をSystemキーチェーンにインポートします。
* .cerファイルをダブルクリックし、**キーチェーン**ドロップダウンメニューで**System**オプションを選択します。

<img src="/files/9xM3QhTcGe7Mc3N5dtHt" alt="" data-size="original">

* ルートパスワードを入力して証明書をインポートします。

<img src="/files/blhhsqFeXsh2u67LQl3Z" alt="" data-size="original">

これらのタスクを自動化するには、[securityユーティリティ](https://ss64.com/mac/security-cert.html)（外部リンク）または自動化フレームワークを使用します。

**証明書がエンドポイントに正しくインポートされたことを確認する**

* 署名済みリモートアクションスクリプトをエンドポイントにコピーし、展開します。

```
tar -xzvf example_ra_script.tar.gz
```

* 署名を検証します。

```
codesign -vvvv -R="certificate leaf trusted" example_ra_script.sh
```

署名が正しくインポートされている場合、次の出力が表示されます：

<img src="/files/chpEKafnx7U1z26uoevY" alt="" data-size="original">

***

## スクリプトの保守

### 比較と検証

リモートアクションスクリプトを展開する前に、Nexthinkが準備した他のスクリプトと比較できます。 この手順は任意ですが、初めてスクリプトを準備する場合は推奨されます。

1. Nexthink Libraryで、**コンテンツ**を選択します。
2. **リモートアクション**でフィルタリングします。
3. **Remote Actions**管理ページに移動します。
4. 対象のオペレーティングシステムに一致し、Nexthink Libraryから直接インストールされた任意のリモートアクションスクリプトを選択します。
5. スクリプトをエクスポートし、構文を自分のスクリプトと比較します。

### スクリプトの終了とタイムアウト

リモートアクションスクリプトからサブプロセスを起動した場合、リモートアクションスクリプトが終了またはタイムアウトすると、Collectorがサブプロセスを自動的に終了します。 リモートアクションの終了後もサブプロセスを実行し続けるには、たとえば次のように、スクリプトで`&`文字を使用してサブプロセスをデタッチしてください：

```
some_script.sh -arg1 -arg2 &
```

#### Zshコマンドインタープリター

Collectorバージョン6.27.2以降では、Zsh Unixシェル用に記述されたスクリプトを実行できます。 シェルスクリプトの先頭に、次のコード行を追加する必要があります：

```
#!/bin/zsh
```

これは[シバン](https://en.wikipedia.org/wiki/Shebang_\(Unix\))（外部リンク）と呼ばれる文字列です。

システムが Mac でリモートアクションをトリガーすると、Collector はコードの先頭行を確認し、指定されたインタープリターを使用して残りの命令を実行します。 \_shebang\_のないスクリプトは、Bashコマンドインタープリターで実行されます。

{% hint style="info" %}
Nexthink では、シェルスクリプトには常に *shebang* を使用し、標準的なインタープリターを利用することを推奨しています。
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.nexthink.com/platform/ja/user-guide/remote-actions/setting-up-and-managing-remote-actions/creating-remote-actions/writing-scripts-for-remote-actions-on-mac.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
