在您的 Windows 執行個體啟動時執行命令 - Amazon Elastic Compute Cloud

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

在您的 Windows 執行個體啟動時執行命令

當您使用 Amazon EC2 啟動 Windows 執行個體時,您可以將使用者資料傳遞給執行個體,以便在執行個體啟動後執行自動化設定任務或執行指令碼。執行個體的使用者資料將被視為不透明的資料,並由執行個體來解譯。使用者資料由 Windows Server 2022 上的 EC2Launch v2、Windows Server 2016 和 2019 上的 EC2Launch 以及 Windows Server 2012 R2 及更早版本上的 EC2Config 來處理。

如需範 AWS CloudFormation 本中UserData屬性組件的範例,請參閱 Base64 編碼內 UserData 容Base64 編碼 UserData 屬性與與 AccessKey 。 SecretKey

如需有關啟動時在 Linux 執行個體上執行命令的資訊,請參閱 Linux 執行個體的 Amazon EC2 使用者指南啟動時,在您的 Linux 執行個體上執行命令

有關在使用 lifecycle hook 之 Auto Scaling 中的執行個體上執行命令的範例,請參閱《Amazon EC2 Auto Scaling 使用者指南》中的教學課程:設定使用者資料來透過執行個體中繼資料擷取目標生命週期狀態

使用者資料指令碼

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

如果您同時指定批次指令碼和 Windows 指 PowerShell 令碼,則會先執行批次指令碼,然後再執行 Windows 指 PowerShell 令碼,而不論它們在執行個體使用者資料中出現的順序為何。

如果您在使用者資料指令碼中使用 AWS API (包括),則在啟動執行個體時必須使用執行個體設定檔。 AWS CLI執行個體設定檔會提供使用者資料指令碼進行 API 呼叫所需的適當 AWS 憑證。如需詳細資訊,請參閱 執行個體描述檔。您指派給 IAM 角色的許可取決於您使用 API 呼叫的服務。如需詳細資訊,請參閱 Amazon EC2 的 IAM 角色

批次指令碼的語法

使用 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 階段中的 EC2Launch v2 executeScript 任務,將 XML 使用者資料指令碼作為以分離的程序執行,請將下列標籤新增至您的使用者資料。

<detach>true</detach>

注意

舊版啟動代理程式不支援分離標籤。

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

語法視窗 PowerShell指令碼

AWS Windows AMI 包含 AWS Tools for Windows PowerShell,因此您可以在使用者資料中指定這些指令程式。如果將 IAM 角色與執行個體建立關聯,則不需要為指令程式指定登入資料,因為在執行個體上執行的應用程式會使用角色的登入資料來存取 AWS 資源 (例如,Amazon S3 儲存貯體)。

使用標記指定 Windows 指 PowerShell 令<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>
EC2Launch v2 代理程式

若要透過 UserData 階段中的 EC2Launch v2 executeScript 任務,將 XML 使用者資料指令碼作為以分離的程序執行,請將下列標籤新增至您的使用者資料。

<detach>true</detach>

注意

舊版啟動代理程式不支援分離標籤。

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

YAML 組態指令碼的語法

如果您使用 EC2Launch v2 來執行指令碼,則可以使用 YAML 格式。若要檢視 EC2Launch v2 的組態任務、詳細資料和範例,請參閱 EC2Launch v2 任務組態

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

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

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 編碼

如果您使用 Amazon EC2 API 或不會為您執行使用者資料的 base64 編碼的工具,就必須自行編碼使用者資料。若否,系統就會記錄一則錯誤,指出找不到要執行的 scriptpowershell 標籤。以下是使用 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://www.ietf.org/rfc/rfc4648.txt

使用者資料執行

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

注意

在預設情況下,初始啟動後不會執行使用者資料。若要在重新開機或啟動執行個體後執行使用者資料,請參閱 後續的重新開機或啟動

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

執行個體啟動

執行個體使用者資料中的指令碼僅會在執行個體初次啟動時執行。如果找到 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 - 如果執行使用者資料指令碼,則會記錄其輸出

後續的重新開機或啟動

當您更新執行個體使用者資料時,使用者資料指令碼並未在您重新開機或啟動執行個體時自動執行。不過,您可以啟用使用者資料執行,以讓使用者資料指令碼在您重新開機或啟動執行個體時執行一次,或每次重新開機或啟動執行個體時都執行。

如果您選擇 Shutdown with Sysprep (使用 Sysprep 關機) 選項,使用者資料指令碼會在下次執行個體啟動或重新開機時執行,即使您並沒有為後續的重新開機或啟動啟用使用者資料執行亦同。使用者資料指令碼將不會在後續的重新開機或啟動時執行。

若要使用 EC2Launch v2 (預覽 AMI) 啟用使用者資料執行
  • 若要在第一次開機時在使用者資料中執行工作,請將 frequency 設定為 once

  • 若要在每次開機時在使用者資料中執行工作,請將 frequency 設定為 always

透過 EC2Launch 啟用使用者資料執行 (Windows Server 2016 或更新版本)
  1. 連接至 Windows 執行個體。

  2. 開啟命 PowerShell 令視窗並執行下列命令:

    C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance.ps1 -Schedule
  3. 中斷連線您的 Windows 執行個體。若要在下一次啟動執行個體時執行更新的指令碼,請停止執行個體並更新使用者資料。如需詳細資訊,請參閱 檢視及更新執行個體使用者資料

透過 EC2Config 啟用使用者資料執行 (Windows Server 2012 R2 或更早版本)
  1. 連接至 Windows 執行個體。

  2. Open C:\Program Files\Amazon\Ec2ConfigService\Ec2ConfigServiceSetting.exe.

  3. 對於使用者資料,請選取啟用下次服務啟動時 UserData執行

  4. 中斷連線您的 Windows 執行個體。若要在下一次啟動執行個體時執行更新的指令碼,請停止執行個體並更新使用者資料。如需詳細資訊,請參閱 檢視及更新執行個體使用者資料

使用者資料與主控台

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

在啟動時指定執行個體使用者資料

請遵循啟動執行個體的程序。此 User data (使用者資料) 欄位位於啟動執行個體精靈的 進階詳細資訊 區段中。在 [使用者資料] 欄位中輸入您的 PowerShell 指令碼,然後完成執行個體啟動程序。

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


					Advanced Details (進階詳細資訊) 使用者資料文字欄位。

檢視及更新執行個體使用者資料

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

使用主控台更新執行個體的使用者資料
  1. https://console.aws.amazon.com/ec2/ 開啟 Amazon EC2 主控台。

  2. 在導覽窗格中,選擇 Instances (執行個體)。

  3. 選取執行個體,並選取 Actions (動作)Instance state (執行個體狀態)Stop instance (停止執行個體)

    警告

    停止執行個體時,在任何執行個體存放區磁碟區的資料都會清除。若要保留執行個體存放區磁碟區的資料,請將資料備份至持久性儲存。

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

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

  6. Edit user data (編輯使用者資料) 對話方塊中,更新使用者資料,然後選擇 Save (儲存)。若要在每次重新開機或啟動執行個體時執行使用者資料指令碼,請新增 <persist>true</persist>,如下範例所示:

    
							Edit User Data (編輯使用者資料) 對話方塊。
  7. 啟動實例。若您已為後續的重新開機或啟動啟用使用者資料執行,即會在執行個體啟動程序期間執行更新的使用者資料指令碼。

使用者資料和視窗工具 PowerShell

您可以使用 Windows 專用的工具 PowerShell 來指定、修改和檢視執行個體的使用者資料。如需使用執行個體中繼資料檢視您執行個體中使用者資料的資訊,請參閱從執行個體擷取執行個體使用者資料。如需使用者資料和的相關資訊 AWS CLI,請參閱《使用者資料》和Amazon EC2 Linux 執行個體使用者指南》 AWS 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令。此命令不會為您執行使用者資料的 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指令修改已停止執行個體的使用者資料。

使用新的指令碼建立文字檔案。使用以下命令,將使用者資料編碼至名為 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指令。

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令讀取標籤值、在第一次開機時重新命名執行個體以符合標籤值,然後重新啟動。若要成功執行此命令,您必須有連接至執行個體的角色具備 ec2:DescribeTags 許可,因為由 API 呼叫擷取標籤資訊。如需使用 IAM 角色設定許可的詳細資訊,請參閱將 IAM 角色連接至執行個體

注意

此指令碼在 2008 以前的 Windows Server 版本上失敗。

<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>

如果您的執行個體設定為從執行個體中繼資料存取標籤,則還可以使用執行個體中繼資料中的標籤重新命名執行個體,。

注意

此指令碼在 2008 以前的 Windows Server 版本上失敗。

<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>