

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 當使用使用者資料輸入啟動 EC2 執行個體時執行命令
<a name="user-data"></a>

當您啟動 Amazon EC2 執行個體時，您可以將使用者資料傳遞到用於執行自動化設定任務或在執行個體啟動後執行指令碼的執行個體。

如果您對更複雜的自動化案例感興趣，可以考慮 CloudFormation。如需詳細資訊，請參閱「AWS CloudFormation 使用者指南」**中的[使用 CloudFormation在 Amazon EC2 部署應用程式](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/deploying.applications.html)。

在 Linux 執行個體，您可以將兩種類型的使用者資料傳遞給 Amazon EC2：shell 指令碼和 cloud-init 指示詞。您也可以將這項資料以純文字、檔案 (在使用命令列工具啟動執行個體時很有用) 或 Base64 編碼文字 (適用於 API 呼叫) 傳遞給啟動執行個體精靈。

在 Windows 執行個體，啟動代理程式會處理您的使用者資料指令碼。

**考量事項**
+ 使用者資料或會做為不透明資料處理：您給予的即為您取回的。是否要解譯則取決於執行個體。
+ 使用者資料必須為 base64 編碼形式。Amazon EC2 主控台可為您執行 base64 編碼，或是接受 base64 編碼輸入。如果您使用執行個體中繼資料或主控台擷取使用者資料，將會自動為您進行 base64 解碼。
+ 使用者資料在 base64 編碼之前限制為 16 KB (原始形式)。長度為 *n* 的字串在 base64 編碼之後的大小為 ceil(*n*/3)\$14。
+ 使用者資料是執行個體屬性。如果您從執行個體建立 AMI，執行個體使用者資料不會包含在 AMI 中。

## 中的使用者資料 AWS 管理主控台
<a name="user-data-console"></a>

您可以在啟動執行個體時指定執行個體使用者資料。若執行個體的根磁碟區為 EBS 磁碟區，您也可以停止執行個體並更新其使用者資料。

### 使用啟動精靈在啟動時指定執行個體使用者資料
<a name="user-data-launch-instance-wizard"></a>

您可以在使用 EC2 主控台的啟動精靈啟動執行個體時指定使用者資料。若要在啟動時指定使用者資料，請遵循[啟動執行個體](ec2-launch-instance-wizard.md)的程序。此 **User data** (使用者資料) 欄位位於啟動執行個體精靈的 [進階詳細資訊](ec2-instance-launch-parameters.md#liw-advanced-details) 區段中。在**使用者資料**欄位輸入 PowerShell 指令碼，然後完成執行個體啟動程序。

在以下**使用者資料**欄位的螢幕擷取畫面中，範例指令碼會在 Windows 暫時資料夾中建立一個檔案，並在檔名中使用目前日期和時間。當您包括 `<persist>true</persist>` 時，指令碼會在您每次重新開機或啟動執行個體時執行。如果您將**使用者資料已使用 base64 編碼**核取方塊留白，Amazon EC2 主控台會為您執行 base64 編碼。

![\[Advanced Details (進階詳細資訊) 使用者資料文字欄位。\]](http://docs.aws.amazon.com/zh_tw/AWSEC2/latest/UserGuide/images/configure_ec2config_userdata.png)


如需詳細資訊，請參閱[使用啟動精靈在啟動時指定執行個體使用者資料](#user-data-launch-instance-wizard)。如需使用 的 Linux 範例 AWS CLI，請參閱 [使用者資料和 AWS CLI](#user-data-api-cli)。如需使用 Tools for Windows PowerShell 的 Windows 範例，請參閱 [使用者資料與 Tools for Windows PowerShell](#user-data-powershell)。

### 檢視及更新執行個體使用者資料
<a name="user-data-view-change"></a>

您可以檢視任何執行個體的執行個體使用者資料，並更新已終止之執行個體的執行個體使用者資料。

**使用主控台更新執行個體的使用者資料**

1. 在 [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/) 開啟 Amazon EC2 主控台。

1. 在導覽窗格中，選擇 **Instances** (執行個體)。

1. 選取執行個體，並選取 **Actions (動作)**、**Instance state (執行個體狀態)**、**Stop instance (停止執行個體)**。
**警告**  
當您停止執行個體時，執行個體存放磁碟區上的資料會遺失。若要保留此資料，請將其備份至持久性儲存。

1. 出現確認提示時，請選擇 **Stop (停止)**。停止執行個體可能需要幾分鐘。

1. 在仍然選取執行個體的情況下，選取**動作** > **執行個體設定** > **編輯使用者資料**。您無法在執行個體仍在執行中時變更使用者資料，但您可以檢視它。

1. 在 **Edit user data (編輯使用者資料)** 對話方塊中，更新使用者資料，然後選擇 **Save (儲存)**。若要在每次重新開機或啟動執行個體時執行使用者資料指令碼，請新增 `<persist>true</persist>`，如下範例所示：  
![\[Edit User Data (編輯使用者資料) 對話方塊。\]](http://docs.aws.amazon.com/zh_tw/AWSEC2/latest/UserGuide/images/view-change-user-data.png)

1. 啟動實例。若您已為後續的重新開機或啟動啟用使用者資料執行，即會在執行個體啟動程序期間執行更新的使用者資料指令碼。

## Amazon EC2 如何處理 Linux 執行個體的使用者資料
<a name="userdata-linux"></a>

以下範例利用使用者資料來執行命令，可在啟用執行個體時設定 LAMP 伺服器。在每個範例中，都會執行以下任務：
+ 更新分佈軟體套件。
+ 安裝 Web 伺服器、`php` 和 `mariadb` 套件。
+ 啟動並開啟 `httpd` 服務。
+ 使用者 `ec2-user` 即會新增至 apache 群組。
+ 接著便會為 Web 目錄和其中包含的檔案設定適當的所有權和檔案許可。
+ 一的簡單的網頁便會建立，用於測試 Web 伺服器和 PHP 引擎。

**Topics**
+ [先決條件](#user-data-requirements)
+ [使用者資料與 Shell 指令碼](#user-data-shell-scripts)
+ [更新執行個體使用者資料](#user-data-modify)
+ [使用者資料與 cloud-init 指示詞](#user-data-cloud-init)
+ [使用者資料和 AWS CLI](#user-data-api-cli)
+ [結合 shell 指令碼與 cloud-init 指令](#user-data-mime-multi)

### 先決條件
<a name="user-data-requirements"></a>

此主題中的範例假設如下內容：
+ 您的執行個體具有公有 DNS 名稱，且可從網際網路連線。
+ 與執行個體相關聯的安全群組已設定為允許 SSH (連接埠 22) 流量，以便您可以連線到執行個體以檢視輸出日誌檔案。
+ 您的執行個體使用 Amazon Linux 2 AMI 啟動。命令與指令可能不適用於其他 Linux 發行版本。如需其他發行版本的詳細資訊，例如支援 cloud-init 的情形，請參閱特定發行版本的相關文件。

### 使用者資料與 Shell 指令碼
<a name="user-data-shell-scripts"></a>

如果您熟悉 Shell 指令碼，這是在啟動時將指令傳送至執行個體的最簡單且最完整的方式。在開機階段新增這些任務也會增加開機執行個體所需要的時間長度。任務完成需要多花幾分鐘的時間，接著您便可以測試使用者指令碼是否已成功完成。

**重要**  
依預設，使用者資料指令碼和 cloud-init 指令只會在您第一次啟動執行個體時的開機週期過程中執行。您可以更新設定，以確保每次重新啟動執行個體時，您的使用者資料指令碼和 cloud-init 指令都會執行。如需詳細資訊，請參閱 AWS 知識中心中的[如何利用使用者資料在每次重新啟動 Amazon EC2 Linux 執行個體時自動執行指令碼？](https://repost.aws/knowledge-center/execute-user-data-ec2)。

使用者資料 shell 指令碼必須以 `#!` 字元，以及您希望讀取指令碼 (通常是 **/bin/bash)**) 的解譯器路徑做為開頭。如需 shell 指令碼的介紹，請參閱 GNU 作業系統**網站的 [Bash 參考手冊](https://www.gnu.org/software/bash/manual/bash.html)。

做為使用者資料輸入的指令碼會以根使用者的身分執行，因此請不要在指令碼中使用 **sudo** 命令。請記得，您建立的任何檔案都會由根使用者擁有；若您需要讓非超級使用者擁有檔案存取權，建議您根據需求在指令碼中修改許可。此外，因為指令碼不會以互動方式執行，您無法包含需要使用者意見回饋的命令 (例如不帶有 `-y` 標記的 **yum update**)。

如果您在使用者資料指令碼中使用 AWS API，包括 AWS CLI，則必須在啟動執行個體時使用執行個體描述檔。執行個體描述檔提供使用者資料指令碼發出 API 呼叫所需的適當 AWS 登入資料。如需詳細資訊，請參閱《IAM 使用者指南》中的[使用執行個體設定檔](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html)。您指派給 IAM 角色的許可取決於您使用 API 呼叫的服務。如需詳細資訊，請參閱[Amazon EC2 的 IAM 的角色](iam-roles-for-amazon-ec2.md)。

cloud-init 輸出日誌檔案會擷取主控台輸出，因此，若執行個體在啟動後未以您想要的方式運作，則可輕鬆地對您的指令碼進行除錯。若要檢視日誌檔案，[連線到執行個體](connect-to-linux-instance.md)並開啟 `/var/log/cloud-init-output.log`。

處理使用者資料指令碼時，會將其複製到 `/var/lib/cloud/instances/instance-id/` 並從中執行。在執行指令碼之後，不會將其刪除。務必從 `/var/lib/cloud/instances/instance-id/` 中刪除使用者資料指令碼，然後再從執行個體中建立 AMI。否則，從 AMI 啟動任何執行個體時，指令碼將存在於這個目錄中。

### 更新執行個體使用者資料
<a name="user-data-modify"></a>

若要更新執行個體使用者資料，您必須先停止執行個體。如果執行個體正在執行，您可以檢視使用者資料，但無法進行修改。

**警告**  
當您停止執行個體時，執行個體存放磁碟區上的資料會遺失。若要保留此資料，請將其備份至持久性儲存。

**修改執行個體使用者資料**

1. 在 [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/) 開啟 Amazon EC2 主控台。

1. 在導覽窗格中，選擇 **Instances** (執行個體)。

1. 選取執行個體，並選取 **Instance state (執行個體狀態)**、**Stop instance (停止執行個體)**。如果此選項已停用，則執行個體已停止或其根磁碟區是執行個體儲存體磁碟區。

1. 出現確認提示時，請選擇 **Stop (停止)**。停止執行個體可能需要幾分鐘。

1. 在仍然選取執行個體的情況下，選取**動作** > **執行個體設定** > **編輯使用者資料**。

1. 視需要修改使用者資料，然後選擇**儲存**。

1. 啟動實例。新的使用者資料便會在執行個體啟動之後出現在執行個體上；但不會執行使用者資料指令碼。

### 使用者資料與 cloud-init 指示詞
<a name="user-data-cloud-init"></a>

cloud-init 套件會在啟動時設定新 Amazon Linux 執行個體的特定部分；最明顯的是，它會設定 ec2-user 的 `.ssh/authorized_keys` 檔案，讓您可以使用自己的私有金鑰登入。如需有關 cloud-init 套件為 Amazon Linux 執行個體執行的組態任務的詳細資訊，請參閱下列文件：
+ **Amazon Linux 2023** – [自訂 cloud-init](https://docs.aws.amazon.com/linux/al2023/ug/cloud-init.html)
+ **Amazon Linux 2** – [使用 Amazon Linux 2 上的 cloud-init](https://docs.aws.amazon.com/linux/al2/ug/amazon-linux-cloud-init.html)

cloud-init 使用者指示詞可在啟動時，以傳遞指令碼相同的方式傳遞到執行個體，雖然語法不同。如需 cloud-init 的詳細資訊，請參閱 https：//[https://cloudinit.readthedocs.org/en/latest/index.html](https://cloudinit.readthedocs.org/en/latest/index.html)。

**重要**  
依預設，使用者資料指令碼和 cloud-init 指令只會在您第一次啟動執行個體時的開機週期過程中執行。您可以更新設定，以確保每次重新啟動執行個體時，您的使用者資料指令碼和 cloud-init 指令都會執行。如需詳細資訊，請參閱 AWS 知識中心中的[如何利用使用者資料在每次重新啟動 Amazon EC2 Linux 執行個體時自動執行指令碼？](https://repost.aws/knowledge-center/execute-user-data-ec2)。

在開機階段新增這些任務也會增加開機執行個體所需要的時間長度。任務完成需要多花幾分鐘的時間，接著您便可以測試您的使用者資料指示詞是否已完成。

**如需傳遞 cloud-init 指令至 Amazon Linux 執行個體**

1. 請遵循[啟動執行個體](ec2-launch-instance-wizard.md)的程序。此 **User data** (使用者資料) 欄位位於啟動執行個體精靈的 [進階詳細資訊](ec2-instance-launch-parameters.md#liw-advanced-details) 區段中。在 **User data** (使用者資料) 欄位中輸入您的 cloud-init 指示詞文字，然後完成執行個體啟動程序。

   在以下範例中，指令會在 Amazon Linux 上建立及設定 Web 伺服器。頂端的 `#cloud-config` 為將命令識別為 cloud-init 指示詞的必要項目。

------
#### [ AL2023 ]

   ```
   #cloud-config
   package_update: true
   package_upgrade: all
   	
   packages:
   - httpd
   - mariadb105-server
   - php8.1
   - php8.1-mysqlnd
   
   runcmd:
   - systemctl start httpd
   - systemctl enable httpd
   - [ sh, -c, "usermod -a -G apache ec2-user" ]
   - [ sh, -c, "chown -R ec2-user:apache /var/www" ]
   - chmod 2775 /var/www
   - [ find, /var/www, -type, d, -exec, chmod, 2775, {}, \; ]
   - [ find, /var/www, -type, f, -exec, chmod, 0664, {}, \; ]
   - [ sh, -c, 'echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.php' ]
   ```

------
#### [ AL2 ]

   ```
   #cloud-config
   package_update: true
   package_upgrade: all
   	
   packages:
   - httpd
   - mariadb-server
   	
   runcmd:
   - [ sh, -c, "amazon-linux-extras install -y lamp-mariadb10.2-php7.2 php7.2" ]
   - systemctl start httpd
   - systemctl enable httpd
   - [ sh, -c, "usermod -a -G apache ec2-user" ]
   - [ sh, -c, "chown -R ec2-user:apache /var/www" ]
   - chmod 2775 /var/www
   - [ find, /var/www, -type, d, -exec, chmod, 2775, {}, \; ]
   - [ find, /var/www, -type, f, -exec, chmod, 0664, {}, \; ]
   - [ sh, -c, 'echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.php' ]
   ```

------

1. 給予執行個體充分的時間啟動及執行您使用者資料中的指示詞，然後檢查您的指示詞是否已完成您預計執行的任務。

   針對此範例，在 Web 瀏覽器中，輸入指示詞建立之 PHP 測試檔案的 URL。此 URL 為您執行個體的公有 DNS 地址，其後跟隨斜線和檔案名稱。

   ```
   http://my.public.dns.amazonaws.com/phpinfo.php
   ```

   您現在應該會看見 PHP 資訊頁面。如果您未看見 PHP 資訊頁面，請檢查您使用的安全群組是否包含允許 HTTP (連接埠 80) 流量的規則。如需詳細資訊，請參閱[設定安全群組規則](changing-security-group.md#add-remove-security-group-rules)。

1. (選用) 若您的指令並未完成您預期執行的任務，或您只希望確認您的指令已順利完成，而沒有發生任何錯誤，請[連線到執行個體](connect-to-linux-instance.md)，檢查 cloud-init 輸出日誌檔案 (`/var/log/cloud-init-output.log`)，並在輸出中查看是否有錯誤訊息。如需其他偵錯資訊，您可以為您的指示詞新增下行：

   ```
   output : { all : '| tee -a /var/log/cloud-init-output.log' }
   ```

   這個指示詞會將 **runcmd** 的輸出傳送到 `/var/log/cloud-init-output.log`。

### 使用者資料和 AWS CLI
<a name="user-data-api-cli"></a>

您可以使用 AWS CLI 來指定、修改和檢視執行個體的使用者資料。如需使用執行個體中繼資料檢視您執行個體中使用者資料的資訊，請參閱[存取 EC2 執行個體的執行個體中繼資料](instancedata-data-retrieval.md)。

在 Windows 上，您可以使用 ， AWS Tools for Windows PowerShell 而不是使用 AWS CLI。如需詳細資訊，請參閱 [使用者資料與 Tools for Windows PowerShell](#user-data-powershell)。

**範例：在啟動時指定使用者資料**  
若要在啟動您的執行個體時指定使用者資料，請搭配 `--user-data` 參數使用 [run-instances](https://docs.aws.amazon.com/cli/latest/reference/ec2/run-instances.html) 命令。使用 **run-instances**， 會為您 AWS CLI 執行使用者資料的 base64 編碼。

以下範例顯示如何在命令列上將指令碼指定為字串：

```
aws ec2 run-instances --image-id ami-abcd1234 --count 1 --instance-type m3.medium \
    --key-name my-key-pair --subnet-id subnet-abcd1234 --security-group-ids sg-abcd1234 \
    --user-data echo user data
```

以下範例顯示如何使用文字檔案指定指令碼。請確認使用 `file://` 前綴來指定檔案。

```
aws ec2 run-instances --image-id ami-abcd1234 --count 1 --instance-type m3.medium \
    --key-name my-key-pair --subnet-id subnet-abcd1234 --security-group-ids sg-abcd1234 \
    --user-data file://my_script.txt
```

以下是具有 shell 指令碼的範例文字檔案。

```
#!/bin/bash
yum update -y
service httpd start
chkconfig httpd on
```

**範例：修改已停止執行個體的使用者資料**  
您可以使用 [modify-instance-attribute](https://docs.aws.amazon.com/cli/latest/reference/ec2/modify-instance-attribute.html) 命令修改已停止執行個體的使用者資料。使用 時**modify-instance-attribute**， AWS CLI 不會為您執行使用者資料的 base64 編碼。
+ 在 **Linux** 電腦上，請使用 base64 命令來編碼使用者資料。

  ```
  base64 my_script.txt >my_script_base64.txt
  ```
+ 在 **Windows** 電腦上，請使用 certutil 命令編碼使用者資料。您必須先移除第一行 (BEGIN CERTIFICATE) 和最後一行 (END CERTIFICATE) AWS CLI，才能將此檔案與 搭配使用。

  ```
  certutil -encode my_script.txt my_script_base64.txt
  notepad my_script_base64.txt
  ```

請使用 `--attribute` 和 `--value` 參數，使用已編碼的文字檔案來指定使用者資料。請確認使用 `file://` 前綴來指定檔案。

```
aws ec2 modify-instance-attribute --instance-id i-1234567890abcdef0 --attribute userData --value file://my_script_base64.txt
```

**範例：清除已停止執行個體的使用者資料**  
若要刪除現有的使用者資料，請使用 [modify-instance-attribute](https://docs.aws.amazon.com/cli/latest/reference/ec2/modify-instance-attribute.html) 命令，如下所示：

```
aws ec2 modify-instance-attribute --instance-id i-1234567890abcdef0 --user-data Value=
```

**範例：檢視使用者資料**  
若要擷取執行個體的使用者資料，請使用 [describe-instance-attribute](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instance-attribute.html) 命令。使用 時**describe-instance-attribute**， AWS CLI 不會為您執行使用者資料的 base64 解碼。

```
aws ec2 describe-instance-attribute --instance-id i-1234567890abcdef0 --attribute userData
```

下列為已使用 base64 編碼之使用者資料的範例輸出。

```
{
    "UserData": {
        "Value": "IyEvYmluL2Jhc2gKeXVtIHVwZGF0ZSAteQpzZXJ2aWNlIGh0dHBkIHN0YXJ0CmNoa2NvbmZpZyBodHRwZCBvbg=="
    },
    "InstanceId": "i-1234567890abcdef0"
}
```
+ 在 **Linux** 上，請使用 `--query` 選項取得已編碼的使用者資料，並使用 base64 命令將其解碼。

  ```
  aws ec2 describe-instance-attribute --instance-id i-1234567890abcdef0 --attribute userData --output text --query "UserData.Value" | base64 --decode
  ```
+ 在 **Windows** 電腦上，使用 `--query` 選項以取得已編碼的使用者資料，並使用 certutil 命令將其解碼。請注意，編碼輸出會存放在檔案中，解碼輸出則會存放在另一個檔案中。

  ```
  aws ec2 describe-instance-attribute --instance-id i-1234567890abcdef0 --attribute userData --output text --query "UserData.Value" >my_output.txt
  certutil -decode my_output.txt my_output_decoded.txt
  type my_output_decoded.txt
  ```

以下為範例輸出。

```
#!/bin/bash
yum update -y
service httpd start
chkconfig httpd on
```

### 結合 shell 指令碼與 cloud-init 指令
<a name="user-data-mime-multi"></a>

根據預設，您一次只能在使用者資料中包含一種內容類型。不過，您可以使用 MIME 多部分檔案中的 `text/cloud-config` 和 `text/x-shellscript` 內容類型，以在使用者資料中包含 shell 指令碼和 cloud-init 指令。

以下展示 MIME 多部分格式。

```
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0
	
--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"
	
#cloud-config
cloud-init directives
	
--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"
	
#!/bin/bash
shell script commands
--//--
```

例如，下列使用者資料包含 cloud-init 指令和 bash shell 指令碼。cloud-init 指令會建立檔案 (`/test-cloudinit/cloud-init.txt`)，並將 `Created by cloud-init` 寫入到該檔案。bash shell 指令碼會建立檔案 (`/test-userscript/userscript.txt`) 並將 `Created by bash shell script` 寫入到該檔案。

```
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0
	
--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"
	
#cloud-config
runcmd:
- [ mkdir, /test-cloudinit ]
write_files:
- path: /test-cloudinit/cloud-init.txt
content: Created by cloud-init
	
--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"
	
#!/bin/bash
mkdir test-userscript
touch /test-userscript/userscript.txt
echo "Created by bash shell script" >> /test-userscript/userscript.txt
--//--
```

## Amazon EC2 如何處理 Windows 執行個體的使用者資料
<a name="ec2-windows-user-data"></a>

在 Windows 執行個體，啟動代理程式會執行與使用者資料相關的任務。如需詳細資訊，請參閱下列內容：
+ [EC2Launch v2](ec2launch-v2.md) 
+ [EC2Launch](ec2launch.md) 
+ [EC2Config 服務](ec2config-service.md)

如需 CloudFormation 範本中`UserData`屬性組合的範例，請參閱 [Base64 編碼 UserData 屬性](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/quickref-general.html#scenario-userdata-base64)和 [Base64 編碼 UserData 屬性與 AccessKey 和 SecretKey](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/quickref-general.html#scenario-userdata-base64-with-keys)。

有關與 lifecycle hook 搭配運作之 Auto Scaling 群組內的執行個體上執行命令的範例，請參閱「Amazon EC2 Auto Scaling 使用者指南」**中的[教學課程：設定使用者資料來透過執行個體中繼資料擷取目標生命週期狀態](https://docs.aws.amazon.com/autoscaling/ec2/userguide/tutorial-lifecycle-hook-instance-metadata.html)。

**Topics**
+ [使用者資料指令碼](#user-data-scripts)
+ [壓縮版使用者資料](#user-data-compressed)
+ [使用者資料執行](#user-data-execution)
+ [使用者資料與 Tools for Windows PowerShell](#user-data-powershell)

### 使用者資料指令碼
<a name="user-data-scripts"></a>

若要讓 `EC2Config` 或 `EC2Launch` 執行指令碼，您必須在新增指令碼至使用者資料時將其括在特殊標籤內。該使用何種標籤，取決於您是在命令提示視窗 (批次命令) 中執行命令，或是使用 Windows PowerShell 來執行命令。

如果您同時指定了批次指令碼和 Windows PowerShell 指令碼，則不論在執行個體使用者資料中的出現順序為何，都會先執行批次指令碼，接著才執行 Windows PowerShell 指令碼。

如果您在使用者資料指令碼中使用 AWS API AWS CLI，包括 ，則必須在啟動執行個體時使用執行個體描述檔。執行個體描述檔提供使用者資料指令碼進行 API 呼叫所需的適當 AWS 登入資料。如需詳細資訊，請參閱[執行個體描述檔](iam-roles-for-amazon-ec2.md#ec2-instance-profile)。您指派給 IAM 角色的許可取決於您使用 API 呼叫的服務。如需詳細資訊，請參閱[Amazon EC2 的 IAM 的角色](iam-roles-for-amazon-ec2.md)。

**Topics**
+ [批次指令碼的語法](#user-data-batch-scripts)
+ [Windows PowerShell 指令碼的語法](#user-data-powershell-scripts)
+ [YAML 組態指令碼的語法](#user-data-yaml-scripts)
+ [Base64 編碼](#user-data-base64-encoding)

#### 批次指令碼的語法
<a name="user-data-batch-scripts"></a>

使用 `script` 標籤指定批次指令碼。使用換行符號分隔命令，如下列範例所示。

```
<script>
    echo Current date and time >> %SystemRoot%\Temp\test.log
    echo %DATE% %TIME% >> %SystemRoot%\Temp\test.log
</script>
```

在預設情況下，使用者資料指令碼僅會在您啟動執行個體時執行一次。若要在每次重新開機或啟動執行個體時執行使用者資料指令碼，請將 `<persist>true</persist>` 新增至使用者資料。

```
<script>
    echo Current date and time >> %SystemRoot%\Temp\test.log
    echo %DATE% %TIME% >> %SystemRoot%\Temp\test.log
</script>
<persist>true</persist>
```

**EC2Launch v2 代理程式**  
若要在 `UserData` 階段將 XML 使用者資料指令碼做為分離的程序與 EC2Launch v2 **executeScript** 任務一起執行，請將 `<detach>true</detach>` 新增至使用者資料。

**注意**  
舊版啟動代理程式不支援 detach 標籤。

```
<script>
    echo Current date and time >> %SystemRoot%\Temp\test.log
    echo %DATE% %TIME% >> %SystemRoot%\Temp\test.log
</script>
<detach>true</detach>
```

#### Windows PowerShell 指令碼的語法
<a name="user-data-powershell-scripts"></a>

 AWS Windows AMIs 包含 [AWS Tools for Windows PowerShell](https://aws.amazon.com/powershell/)，因此您可以在使用者資料中指定這些 cmdlet。如果您將 IAM 角色與執行個體建立關聯，則不需要指定 cmdlet 的登入資料，因為在執行個體上執行的應用程式會使用角色的登入資料來存取 AWS 資源 （例如 Amazon S3 儲存貯體）。

使用 `<powershell>` 標籤指定 Windows PowerShell 指令碼。使用分行符號來區隔命令。`<powershell>` 標籤區分大小寫。

例如：

```
<powershell>
    $file = $env:SystemRoot + "\Temp\" + (Get-Date).ToString("MM-dd-yy-hh-mm")
    New-Item $file -ItemType file
</powershell>
```

在預設情況下，使用者資料指令碼僅會在您啟動執行個體時執行一次。若要在每次重新開機或啟動執行個體時執行使用者資料指令碼，請將 `<persist>true</persist>` 新增至使用者資料。

```
<powershell>
    $file = $env:SystemRoot + "\Temp\" + (Get-Date).ToString("MM-dd-yy-hh-mm")
    New-Item $file -ItemType file
</powershell>
<persist>true</persist>
```

您可以使用 `<powershellArguments>` 標籤指定一或多個 PowerShell 引數。如果未傳遞引數，EC2Launch 和 EC2Launch v2 預設會新增下列引數：`-ExecutionPolicy Unrestricted`。

**範例**：

```
<powershell>
    $file = $env:SystemRoot + "\Temp" + (Get-Date).ToString("MM-dd-yy-hh-mm")
    New-Item $file -ItemType file
</powershell>
<powershellArguments>-ExecutionPolicy Unrestricted -NoProfile -NonInteractive</powershellArguments>
```

**EC2Launch v2 代理程式**  
若要在 `UserData` 階段將 XML 使用者資料指令碼做為分離的程序與 EC2Launch v2 **executeScript** 任務一起執行，請將 `<detach>true</detach>` 新增至使用者資料。

**注意**  
舊版啟動代理程式不支援 detach 標籤。

```
<powershell>
    $file = $env:SystemRoot + "\Temp\" + (Get-Date).ToString("MM-dd-yy-hh-mm")
    New-Item $file -ItemType file
</powershell>
<detach>true</detach>
```

#### YAML 組態指令碼的語法
<a name="user-data-yaml-scripts"></a>

如果您使用 EC2Launch v2 來執行指令碼，則可以使用 YAML 格式。若要檢視 EC2Launch v2 的組態任務、詳細資料和範例，請參閱 [EC2Launch v2 任務組態](ec2launch-v2-settings.md#ec2launch-v2-task-configuration)。

指定具有 `executeScript` 任務的 YAML 指令碼。

**執行 PowerShell 指令碼的 YAML 語法範例** 

```
version: 1.0
tasks:
- task: executeScript
  inputs:
  - frequency: always
    type: powershell
    runAs: localSystem
    content: |-
      $file = $env:SystemRoot + "\Temp\" + (Get-Date).ToString("MM-dd-yy-hh-mm")
      New-Item $file -ItemType file
```

**執行批次指令碼的 YAML 語法範例**

```
version: 1.1
tasks:
- task: executeScript
  inputs:
  - frequency: always
    type: batch
    runAs: localSystem
    content: |-
      echo Current date and time >> %SystemRoot%\Temp\test.log
      echo %DATE% %TIME% >> %SystemRoot%\Temp\test.log
```

#### Base64 編碼
<a name="user-data-base64-encoding"></a>

如果您使用 Amazon EC2 API 或不會為您執行使用者資料的 base64 編碼的工具，就必須自行編碼使用者資料。若否，系統就會記錄一則錯誤，指出找不到要執行的 `script` 或 `powershell` 標籤。以下是使用 Windows PowerShell 的編碼範例。

```
$UserData = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($Script))
```

以下是使用 PowerShell 的解碼範例。

```
$Script = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($UserData))
```

如需 base64 編碼的詳細資訊，請參閱 https：//[https://www.ietf.org/rfc/rfc4648.txt](https://www.ietf.org/rfc/rfc4648.txt)。

### 壓縮版使用者資料
<a name="user-data-compressed"></a>

EC2Launch v2 支援壓縮版使用者資料，做為提交超過 IMDS 所設 16 KB 限制的使用者資料的方法。如需使用此功能，請將您的使用者資料指令碼壓縮成 `.zip` 封存，然後傳遞至 EC2 執行個體。若 EC2Launch v2 偵測到壓縮版使用者資料，可自動對壓縮版使用者資料指令碼解壓縮，然後執行該指令碼。

對於標準使用者資料，如果您使用 Amazon EC2 API 或不會為您執行使用者資料的 base64 編碼的工具，就必須自行編碼壓縮版使用者資料。若要了解使用者資料大小限制及 base64 編碼的相關資訊，請參閱 [存取 EC2 執行個體的執行個體中繼資料](instancedata-data-retrieval.md)。

### 使用者資料執行
<a name="user-data-execution"></a>

根據預設，所有 AWS Windows AMIs都會為初始啟動啟用使用者資料執行。您可以指定在下一次重新開機或重新啟動執行個體時執行使用者資料指令碼。或者，您可以指定每次重新開機或重新啟動執行個體時都執行使用者資料指令碼。

**注意**  
在預設情況下，初始啟動後不會執行使用者資料。若要在重新開機或啟動執行個體後執行使用者資料，請參閱 [在後續重新啟動或啟動期間執行指令碼](#user-data-scripts-subsequent)。

產生隨機密碼時，會透過本機管理員帳戶來執行使用者資料指令碼。否則，會透過系統帳戶執行使用者資料指令碼。

#### 執行個體啟動指令碼
<a name="user-data-scripts-launch"></a>

執行個體使用者資料中的指令碼僅會在執行個體初次啟動時執行。如果找到 `persist` 標籤，即會為後續的重新開機或啟動啟用使用者資料執行。EC2Launch v2、EC2Launch 和 EC2Config 的日誌檔案包含來自標準輸出和標準錯誤串流的輸出。

**EC2Launch v2**  
EC2Launch v2 的記錄檔是 `C:\ProgramData\Amazon\EC2Launch\log\agent.log`。

**注意**  
`C:\ProgramData` 資料夾可能隱藏不見。若要檢視此資料夾，您必須顯示隱藏的檔案和資料夾。

以下資訊會在執行使用者資料時記錄：
+ `Info: Converting user-data to yaml format` - 如果使用者資料是以 XML 格式提供
+ `Info: Initialize user-data state` - 開始執行使用者資料時
+ `Info: Frequency is: always` - 如果使用者資料工作在每次開機時執行
+ `Info: Frequency is: once` - 如果使用者資料任務只執行一次
+ `Stage: postReadyUserData execution completed` - 使用者資料執行結束時

**EC2Launch**  
EC2Launch 的日誌文件是 `C:\ProgramData\Amazon\EC2-Windows\Launch\Log\UserdataExecution.log`。

`C:\ProgramData` 資料夾可能隱藏不見。若要檢視此資料夾，您必須顯示隱藏的檔案和資料夾。

以下資訊會在執行使用者資料時記錄：
+ `Userdata execution begins` - 開始執行使用者資料時
+ `<persist> tag was provided: true` - 如果找到 persist 標籤
+ `Running userdata on every boot` - 如果找到 persist 標籤
+ `<powershell> tag was provided.. running powershell content` - 如果找到 powershell 標籤
+ `<script> tag was provided.. running script content` - 如果找到指令碼標籤
+ `Message: The output from user scripts` - 如果執行使用者資料指令碼，則會記錄其輸出

**EC2Config**  
EC2Config 的日誌文件是 `C:\Program Files\Amazon\Ec2ConfigService\Logs\Ec2Config.log`。以下資訊會在執行使用者資料時記錄：
+ `Ec2HandleUserData: Message: Start running user scripts` - 開始執行使用者資料時
+ `Ec2HandleUserData: Message: Re-enabled userdata execution` - 如果找到 persist 標籤
+ `Ec2HandleUserData: Message: Could not find <persist> and </persist>` - 如果沒有找到 persist 標籤
+ `Ec2HandleUserData: Message: The output from user scripts` - 如果執行使用者資料指令碼，則會記錄其輸出

#### 在後續重新啟動或啟動期間執行指令碼
<a name="user-data-scripts-subsequent"></a>

若更新執行個體使用者資料，下次您重新啟動或啟動執行個體時，執行個體中繼資料會自動反映更新的使用者資料內容。然而，視乎安裝的啟動代理程式，可能需要額外組態，方可設定使用者資料指令碼在後續重新啟動或啟動時執行。

如果您選擇**透過 Sysprep 關閉**選項，使用者資料指令碼會在下次執行個體啟動或重新開機時執行，即使您並沒有為後續的重新開機或啟動啟用使用者資料執行亦同。

若要了解啟用使用者資料執行的說明，選取與您的啟動代理程式相符的標籤。

------
#### [ EC2Launch v2 ]

與 EC2Launch v1 不同，EC2Launch v2 在每次啟動時都會評估使用者資料任務。您不必手動排程使用者資料任務。依據包括的頻率或保存選項來執行使用者資料。

若是 XML 使用者資料指令碼  
如需在每次啟動時執行使用者資料指令碼，可新增 `<persist>true</persist>` 標記至使用者資料。若不包括保存標記，則僅在初始啟動時執行使用者資料指令碼。

若是 YAML 使用者資料  
+ 如需初始啟動時在使用者資料中執行任務，可設定任務 `frequency` 為 `once`。
+ 如需每次啟動時在使用者資料中執行工作，可設定任務 `frequency` 為 `always`。

------
#### [ EC2Launch ]

1. 連接至 Windows 執行個體。

1. 開啟 PowerShell 命令視窗並執行下列其中一項命令：

**執行一次**  
如需下次啟動時執行使用者資料一次，可使用 `-Schedule` 標記。

   ```
   C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance.ps1 -Schedule
   ```

**在所有後續啟動時執行**  
如需在所有後續啟動時執行使用者資料，可使用 `-SchedulePerBoot` 標記。

   ```
   C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance.ps1 -SchedulePerBoot
   ```

1. 中斷連線您的 Windows 執行個體。若要在下一次啟動執行個體時執行更新的指令碼，請停止執行個體並更新使用者資料。

------
#### [ EC2Config ]

1. 連接至 Windows 執行個體。

1. Open `C:\Program Files\Amazon\Ec2ConfigService\Ec2ConfigServiceSetting.exe`.

1. 針對 **User Data (使用者資料)**，選取 **Enable UserData execution for next service start (啟用下一次服務啟動時的使用者資料執行)**。

1. 中斷連線您的 Windows 執行個體。若要在下一次啟動執行個體時執行更新的指令碼，請停止執行個體並更新使用者資料。

------

### 使用者資料與 Tools for Windows PowerShell
<a name="user-data-powershell"></a>

您可以使用 Tools for Windows PowerShell 指定、修改和檢視您執行個體的使用者資料。如需使用執行個體中繼資料檢視您執行個體中使用者資料的資訊，請參閱[存取 EC2 執行個體的執行個體中繼資料](instancedata-data-retrieval.md)。如需使用者資料和 的相關資訊 AWS CLI，請參閱 [使用者資料和 AWS CLI](#user-data-api-cli)。

**範例：在啟動時指定執行個體使用者資料**  
使用執行個體使用者資料建立文字檔案。若要在每次重新開機或啟動執行個體時執行使用者資料指令碼，請新增 `<persist>true</persist>`，如下範例所示。

```
<powershell>
    $file = $env:SystemRoot + "\Temp\" + (Get-Date).ToString("MM-dd-yy-hh-mm")
    New-Item $file -ItemType file
</powershell>
<persist>true</persist>
```

若要在啟動您的執行個體時指定執行個體使用者資料，請使用 [New-EC2Instance](https://docs.aws.amazon.com/powershell/latest/reference/items/New-EC2Instance.html) 命令。此命令不會為您執行使用者資料的 base64 編碼。使用以下命令，將使用者資料編碼至名為 `script.txt` 的文字檔案：

```
PS C:\> $Script = Get-Content -Raw script.txt
PS C:\> $UserData = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($Script))
```

使用 `-UserData` 參數，將使用者資料傳遞到 **New-EC2Instance** 命令。

```
PS C:\> New-EC2Instance -ImageId ami-abcd1234 -MinCount 1 -MaxCount 1 -InstanceType m3.medium \
    -KeyName my-key-pair -SubnetId subnet-12345678 -SecurityGroupIds sg-1a2b3c4d \
    -UserData $UserData
```

**範例：更新已停止之執行個體的執行個體使用者資料**  
您可以使用 [Edit-EC2InstanceAttribute](https://docs.aws.amazon.com/powershell/latest/reference/items/Edit-EC2InstanceAttribute.html) 命令修改已停止之執行個體的使用者資料。

使用新的指令碼建立文字檔案。使用以下命令，將使用者資料編碼至名為 `new-script.txt` 的文字檔案：

```
PS C:\> $NewScript = Get-Content -Raw new-script.txt
PS C:\> $NewUserData = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($NewScript))
```

使用 `-UserData` 和 `-Value` 參數指定使用者資料。

```
PS C:\> Edit-EC2InstanceAttribute -InstanceId i-1234567890abcdef0 -Attribute userData -Value $NewUserData
```

**範例：檢視執行個體使用者資料**  
若要擷取執行個體的使用者資料，請使用 [Get-EC2InstanceAttribute](https://docs.aws.amazon.com/powershell/latest/reference/items/Get-EC2InstanceAttribute.html) 命令。

```
PS C:\> (Get-EC2InstanceAttribute -InstanceId i-1234567890abcdef0 -Attribute userData).UserData
```

下列為範例輸出。請注意使用者資料已編碼。

```
PHBvd2Vyc2hlbGw+DQpSZW5hbWUtQ29tcHV0ZXIgLU5ld05hbWUgdXNlci1kYXRhLXRlc3QNCjwvcG93ZXJzaGVsbD4=
```

使用以下命令，將已編碼的使用者資料存放至變數中，然後加以解碼。

```
PS C:\> $UserData_encoded = (Get-EC2InstanceAttribute -InstanceId i-1234567890abcdef0 -Attribute userData).UserData
PS C:\> [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($UserData_encoded))
```

下列為範例輸出。

```
<powershell>
    $file = $env:SystemRoot + "\Temp\" + (Get-Date).ToString("MM-dd-yy-hh-mm")
    New-Item $file -ItemType file
</powershell>
<persist>true</persist>
```

**範例：重新命名執行個體以符合標籤值**  
使用 [Get-EC2Tag](https://docs.aws.amazon.com/powershell/latest/reference/items/Get-EC2Tag.html) 命令讀取標籤值，在第一次開機時重新命名執行個體以符合標籤值，然後重新開機。若要成功執行此命令，您必須有連接至執行個體的角色具備 `ec2:DescribeTags` 許可，因為由 API 呼叫擷取標籤資訊。如需使用 IAM 角色設定許可的詳細資訊，請參閱 [將 IAM 角色連接至執行個體](attach-iam-role.md)。

------
#### [ IMDSv2 ]

```
<powershell>
    [string]$token = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token-ttl-seconds" = "21600"} -Method PUT -Uri 'http://169.254.169.254/latest/api/token' -UseBasicParsing
    $instanceId = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri 'http://169.254.169.254/latest/meta-data/instance-id' -UseBasicParsing
	$nameValue = (Get-EC2Tag -Filter @{Name="resource-id";Value=$instanceid},@{Name="key";Value="Name"}).Value
	$pattern = "^(?![0-9]{1,15}$)[a-zA-Z0-9-]{1,15}$"
	#Verify Name Value satisfies best practices for Windows hostnames
	If ($nameValue -match $pattern) 
	    {Try
	        {Rename-Computer -NewName $nameValue -Restart -ErrorAction Stop} 
	    Catch
	        {$ErrorMessage = $_.Exception.Message
	        Write-Output "Rename failed: $ErrorMessage"}}
	Else
	    {Throw "Provided name not a valid hostname. Please ensure Name value is between 1 and 15 characters in length and contains only alphanumeric or hyphen characters"}
</powershell>
```

------
#### [ IMDSv1 ]

```
<powershell>
	$instanceId = (Invoke-WebRequest http://169.254.169.254/latest/meta-data/instance-id -UseBasicParsing).content
	$nameValue = (Get-EC2Tag -Filter @{Name="resource-id";Value=$instanceid},@{Name="key";Value="Name"}).Value
	$pattern = "^(?![0-9]{1,15}$)[a-zA-Z0-9-]{1,15}$"
	#Verify Name Value satisfies best practices for Windows hostnames
	If ($nameValue -match $pattern) 
	    {Try
	        {Rename-Computer -NewName $nameValue -Restart -ErrorAction Stop} 
	    Catch
	        {$ErrorMessage = $_.Exception.Message
	        Write-Output "Rename failed: $ErrorMessage"}}
	Else
	    {Throw "Provided name not a valid hostname. Please ensure Name value is between 1 and 15 characters in length and contains only alphanumeric or hyphen characters"}
</powershell>
```

------

如果您的執行個體設定為從執行個體中繼資料存取標籤，則還可以使用執行個體中繼資料中的標籤重新命名執行個體，。如需詳細資訊，請參閱[使用執行個體中繼資料檢視 EC2 執行個體的標籤](work-with-tags-in-IMDS.md)。

------
#### [ IMDSv2 ]

```
<powershell>
    [string]$token = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token-ttl-seconds" = "21600"} -Method PUT -Uri 'http://169.254.169.254/latest/api/token' -UseBasicParsing
	$nameValue = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri 'http://169.254.169.254/latest/meta-data/tags/instance/Name' -UseBasicParsing
	$pattern = "^(?![0-9]{1,15}$)[a-zA-Z0-9-]{1,15}$"
	#Verify Name Value satisfies best practices for Windows hostnames
	If ($nameValue -match $pattern) 
	    {Try
	        {Rename-Computer -NewName $nameValue -Restart -ErrorAction Stop} 
	    Catch
	        {$ErrorMessage = $_.Exception.Message
	        Write-Output "Rename failed: $ErrorMessage"}}
	Else
	    {Throw "Provided name not a valid hostname. Please ensure Name value is between 1 and 15 characters in length and contains only alphanumeric or hyphen characters"}
</powershell>
```

------
#### [ IMDSv1 ]

```
<powershell>
	$nameValue = Get-EC2InstanceMetadata -Path /tags/instance/Name
	$pattern = "^(?![0-9]{1,15}$)[a-zA-Z0-9-]{1,15}$"
	#Verify Name Value satisfies best practices for Windows hostnames
	If ($nameValue -match $pattern) 
	    {Try
	        {Rename-Computer -NewName $nameValue -Restart -ErrorAction Stop} 
	    Catch
	        {$ErrorMessage = $_.Exception.Message
	        Write-Output "Rename failed: $ErrorMessage"}}
	Else
	    {Throw "Provided name not a valid hostname. Please ensure Name value is between 1 and 15 characters in length and contains only alphanumeric or hyphen characters"}
</powershell>
```

------