

• 2026 年 4 月 30 日之後將不再提供 AWS Systems Manager CloudWatch Dashboard。客戶可以繼續使用 Amazon CloudWatch 主控台來檢視、建立和管理其 Amazon CloudWatch 儀表板，就像現在一樣。如需詳細資訊，請參閱 [Amazon CloudWatch Dashboard 文件](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Dashboards.html)。

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

# `aws:executeScript` – 執行指令碼
<a name="automation-action-executeScript"></a>

執行使用指定的執行時間和處理程序提供的 Python 或 PowerShell 指令碼。每個 `aws:executeScript` 動作最久可執行 600 秒 (10 分鐘)。您可以透過指定 `aws:executeScript` 步驟的 `timeoutSeconds` 參數來限制逾時。

在函數中使用傳回陳述式將輸出加入輸出承載。有關 `aws:executeScript` 動作定義輸出的範例，請參閱 [範例 2：指令碼式 Runbook](automation-authoring-runbooks-scripted-example.md)。您也可以把 Runbook 的 `aws:executeScript` 動作輸出傳送到您指定的 Amazon CloudWatch Logs 日誌群組。如需詳細資訊，請參閱[使用 CloudWatch Logs 記錄自動化動作輸出](automation-action-logging.md)。

如果您想要將`aws:executeScript`動作的輸出傳送至 CloudWatch Logs，或者您為`aws:executeScript`動作指定的指令碼呼叫 AWS API 操作，則一律需要 AWS Identity and Access Management (IAM) 服務角色 （或擔任角色） 才能執行 Runbook。

**注意**  
`aws:executeScript` 動作不支援自動限流重試。如果您的指令碼發出可能會調節的 AWS API 呼叫，您必須在指令碼程式碼中實作自己的重試邏輯。

`aws:executeScript` 動作包含下列預先安裝的 PowerShell Core 模組。
+ Microsoft.PowerShell.Host
+ Microsoft.PowerShell.Management
+ Microsoft.PowerShell.Security
+ Microsoft.PowerShell.Utility
+ PackageManagement
+ PowerShellGet

若要使用未預先安裝的 PowerShell Core 模組，您的指令碼必須使用 `-Force` 旗標安裝模組，如下列命令所示。不支援 `AWSPowerShell.NetCore` 模組。把 *ModuleName* (模組名稱) 取代為您想要安裝的模組。

```
Install-Module ModuleName -Force
```

若要在指令碼中使用 PowerShell Core Cmdlet，建議您使用 `AWS.Tools` 模組，如下列命令所示。將每個*範例資源預留位置*取代為您自己的資訊。
+ Amazon Simple Storage Service (Amazon S3) cmdlet。

  ```
  Install-Module AWS.Tools.S3 -Force
  Get-S3Bucket -BucketName amzn-s3-demo-bucket
  ```
+ Amazon EC2 cmdlet。

  ```
  Install-Module AWS.Tools.EC2 -Force
  Get-EC2InstanceStatus -InstanceId instance-id
  ```
+ 常見 或服務獨立 AWS Tools for Windows PowerShell cmdlet。

  ```
  Install-Module AWS.Tools.Common -Force
  Get-AWSRegion
  ```

如果指令碼除了使用 PowerShell Core Cmdlet 之外，還會初始化新物件，您也必須匯入模組，如下列命令所示。

```
Install-Module AWS.Tools.EC2 -Force
Import-Module AWS.Tools.EC2

$tag = New-Object Amazon.EC2.Model.Tag
$tag.Key = "Tag"
$tag.Value = "TagValue"

New-EC2Tag -Resource i-02573cafcfEXAMPLE -Tag $tag
```

如需在 Runbook 內容中安裝和匯入 `AWS.Tools` 模組，以及使用 PowerShell Core Cmdlet 的範例，請參閱 [Automation 執行手冊的視覺化設計體驗](automation-visual-designer.md)。

**Input**  
提供執行指令碼所需訊息。將每個*範例資源預留位置*取代為您自己的資訊。

**注意**  
Python 指令碼的附件可以是包含指令碼的 .py 檔案或 .zip 檔案。PowerShell 指令碼必須儲存在 .zip 檔案中。

------
#### [ YAML ]

```
action: "aws:executeScript"
inputs: 
 Runtime: runtime
 Handler: "functionName"
 InputPayload: 
  scriptInput: '{{parameterValue}}'
 Script: |-
   def functionName(events, context):
   ...
 Attachment: "scriptAttachment.zip"
```

------
#### [ JSON ]

```
{
    "action": "aws:executeScript",
    "inputs": {
        "Runtime": "runtime",
        "Handler": "functionName",
        "InputPayload": {
            "scriptInput": "{{parameterValue}}"
        },
        "Attachment": "scriptAttachment.zip"
    }
}
```

------

執行時期  
用於執行所提供指令碼的執行時間語言。 `aws:executeScript`支援下表中的執行時間。      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/systems-manager/latest/userguide/automation-action-executeScript.html)
類型：字串  
必要：是  
對於 python 執行時期，該環境提供 512 MB 的記憶體與 512 MB 的磁碟空間。對於 PowerShell 執行時期，該環境提供 1024 MB 的記憶體與 512 MB 的磁碟空間。

處理常式  
函數名稱。您必須確保處理常式中定義的函數有兩個參數，`events` 和 `context`。PowerShell 執行階段不支援此參數。  
類型：字串  
必要：是 (Python) \$1 不支援 (PowerShell)

InputPayload  
將傳遞給處理程序的第一個參數的 JSON 或 YAML 物件。這可以用來將輸入資料傳入至指令碼。  
類型：字串  
必要：否  

```
description: Tag an instance
schemaVersion: '0.3'
assumeRole: '{{AutomationAssumeRole}}'
parameters:
    AutomationAssumeRole:
        type: String
        description: '(Required) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.'
    InstanceId:
        type: String
        description: (Required) The ID of the EC2 instance you want to tag.
mainSteps:
  - name: tagInstance
    action: 'aws:executeScript'
    inputs:
        Runtime: "python3.11"
        Handler: tagInstance
        InputPayload:
            instanceId: '{{InstanceId}}'
        Script: |-
          def tagInstance(events,context):
            import boto3

            #Initialize client
            ec2 = boto3.client('ec2')
            instanceId = events['instanceId']
            tag = {
                "Key": "Env",
                "Value": "ExamplePython"
            }
            print(f"Adding tag {tag} to instance id {instanceId}")
            ec2.create_tags(
                Resources=[instanceId],
                Tags=[tag]
            )
            return tag
    outputs:
      - Type: String
        Name: TagKey
        Selector: $.Payload.Key
outputs:
  - tagInstance.TagKey
```

```
description: Tag an instance
schemaVersion: '0.3'
assumeRole: '{{AutomationAssumeRole}}'
parameters:
  AutomationAssumeRole:
    type: String
    description: (Required) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.
  InstanceId:
    type: String
    description: (Required) The ID of the EC2 instance you want to tag.
mainSteps:
  - name: tagInstance
    action: aws:executeScript
    isEnd: true
    inputs:
      Runtime: PowerShell 7.4
      InputPayload:
        instanceId: '{{InstanceId}}'
      Script: |-
        Install-Module AWS.Tools.EC2 -Force
        Import-Module AWS.Tools.EC2

        $input = $env:InputPayload | ConvertFrom-Json

        $tag = New-Object Amazon.EC2.Model.Tag
        $tag.Key = "Env"
        $tag.Value = "ExamplePowerShell"

        Write-Information "Adding tag key: $($tag.Key) and value: $($tag.Value) to instance id $($input.instanceId)"
        New-EC2Tag -Resource $input.instanceId -Tag $tag

        return $tag
    outputs:
      - Type: String
        Name: TagKey
        Selector: $.Payload.Key
outputs:
  - tagInstance.TagKey
```

指令碼  
您想要在自動化期間執行的內嵌指令碼。  
類型：字串  
必要：No (Python) \$1 Yes (PowerShell)

連接  
動作可呼叫的獨立指令碼檔案或 .zip 檔案的名稱。指定與您在 `Attachments` 請求參數中指定的文件附件檔案的 `Name` 相同的數值。如須詳細資訊，請參閱《*AWS Systems Manager API 參考*》的[附件](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_CreateDocument.html#systemsmanager-CreateDocument-request-Attachments)。如果您使用附件提供指令碼，還必須定義 Runbook 頂層元素的 `files` 區段。如需詳細資訊，請參閱[結構描述版本 0.3](documents-schemas-features.md#automation-doc-syntax-examples)。  
若要為 Python 呼叫檔案，請在 `Handler` 中使用 `filename.method_name` 格式。  
Python 指令碼的附件可以是包含指令碼的 .py 檔案或 .zip 檔案。PowerShell 指令碼必須儲存在 .zip 檔案中。
當在附件中包含 Python 庫時，建議在每個模組目錄中新增空的 `__init__.py` 檔案。這允許您從指令碼內容中的附件庫匯入模組。例如：`from library import module`  
類型：字串  
必要：否Output

酬載  
由函數傳回之物件的 JSON 表示法。最多會傳回 100 KB。如果輸出清單，則最多只能傳回 100 個項目。

## 搭配 aws:executeScript 使用附件
<a name="automation-action-executeScript-attachments"></a>

附件提供了一種強大的方法，可將複雜的指令碼、多個模組和外部相依性與您的 `aws:executeScript` 動作一起封裝並重複使用。當您需要進行下列操作時，請使用附件：
+ 將多個 Python 模組或 PowerShell 指令碼封裝在一起。
+ 在多個執行手冊中，重複使用相同的指令碼邏輯。
+ 在您的指令碼中包含外部程式庫或相依性。
+ 分隔複雜的指令碼邏輯，保持執行手冊定義明確清晰。
+ 在團隊或自動化工作流程中共用指令碼套件。

### 附件結構和封裝
<a name="automation-action-executeScript-attachment-structure"></a>

您可以連接單一檔案或是包含多個檔案的 zip 套件。結構取決於您的使用案例：

**單一檔案附件**  
對於簡單的指令碼，您可以連接單一 `.py` 檔案 (Python) 或包含單一 PowerShell 指令碼的 `.zip` 檔案。

**多模組套件**  
對於需要多個模組的複雜自動化，請以下列建議的結構建立 zip 套件：

```
my-automation-package.zip
├── main.py                    # Entry point script
├── utils/
│   ├── __init__.py           # Required for Python module imports
│   ├── helper_functions.py   # Utility functions
│   └── aws_operations.py     # AWS-specific operations
├── config/
│   ├── __init__.py
│   └── settings.py           # Configuration settings
└── requirements.txt          # Optional: document dependencies
```

**重要**  
對於 Python 套件，您必須在包含 Python 模組的每個目錄中包含空白的 `__init__.py` 檔案。這可讓您使用標準的 Python 匯入語法 (例如 `from utils import helper_functions`) 來匯入模組。

**PowerShell 套件結構**  
PowerShell 附件必須使用下列結構，封裝在 zip 檔案中：

```
my-powershell-package.zip
├── Main.ps1                  # Entry point script
├── Modules/
│   ├── HelperFunctions.ps1   # Utility functions
│   └── AWSOperations.ps1     # AWS-specific operations
└── Config/
    └── Settings.ps1          # Configuration settings
```

### 建立含有附件的執行手冊
<a name="automation-action-executeScript-attachment-workflow"></a>

請依照下列步驟建立使用附件的執行手冊：

1. **將您的附件上傳至 Amazon S3**

   將您的指令碼檔案或 zip 套件上傳至自動化角色可存取的 S3 儲存貯體。請記下 S3 URI，以便在下一個步驟中使用。

   ```
   aws s3 cp my-automation-package.zip s3://my-automation-bucket/scripts/
   ```

1. **計算附件檢查總和**

   計算附件檔案的 SHA-256 檢查總和，以進行安全性驗證：

   ```
   # Linux/macOS
   shasum -a 256 my-automation-package.zip
   
   # Windows PowerShell
   Get-FileHash -Algorithm SHA256 my-automation-package.zip
   ```

1. **定義執行手冊中的檔案區段**

   在執行手冊的頂層新增 `files` 區段，以參考您的附件：

   ```
   files:
     my-automation-package.zip:
       checksums:
         sha256: "your-calculated-checksum-here"
   ```

1. **參考 executeScript 步驟中的附件**

   使用 `Attachment` 參數來參考您已上傳的檔案：

   ```
   - name: runMyScript
     action: aws:executeScript
     inputs:
       Runtime: python3.11
       Handler: main.process_data
       Attachment: my-automation-package.zip
       InputPayload:
         inputData: "{{InputParameter}}"
   ```

## aws:executeScript 附件範例
<a name="automation-action-executeScript-examples"></a>

下列範例示範搭配 `aws:executeScript` 動作使用附件的不同方式。

### 範例 1：單一檔案附件
<a name="automation-action-executeScript-single-file-example"></a>

此範例說明如何使用單一 Python 檔案作為附件來處理 EC2 執行個體資料。

**附件檔案：process\$1instance.py**  
使用下列內容建立 Python 檔案：

```
import boto3
import json

def process_instance_data(events, context):
    """Process EC2 instance data and return formatted results."""
    try:
        instance_id = events.get('instanceId')
        if not instance_id:
            raise ValueError("instanceId is required")
        
        ec2 = boto3.client('ec2')
        
        # Get instance details
        response = ec2.describe_instances(InstanceIds=[instance_id])
        instance = response['Reservations'][0]['Instances'][0]
        
        # Format the response
        result = {
            'instanceId': instance_id,
            'instanceType': instance['InstanceType'],
            'state': instance['State']['Name'],
            'availabilityZone': instance['Placement']['AvailabilityZone'],
            'tags': {tag['Key']: tag['Value'] for tag in instance.get('Tags', [])}
        }
        
        print(f"Successfully processed instance {instance_id}")
        return result
        
    except Exception as e:
        print(f"Error processing instance: {str(e)}")
        raise
```

**完成執行手冊**  
下方是使用單一檔案附件的完整執行手冊：

```
description: Process EC2 instance data using single file attachment
schemaVersion: '0.3'
assumeRole: '{{AutomationAssumeRole}}'
parameters:
  AutomationAssumeRole:
    type: String
    description: (Required) IAM role for automation execution
  InstanceId:
    type: String
    description: (Required) EC2 instance ID to process

files:
  process_instance.py:
    checksums:
      sha256: "abc123def456..."

mainSteps:
  - name: processInstance
    action: aws:executeScript
    inputs:
      Runtime: python3.11
      Handler: process_instance.process_instance_data
      Attachment: process_instance.py
      InputPayload:
        instanceId: '{{InstanceId}}'
    outputs:
      - Type: StringMap
        Name: InstanceData
        Selector: $.Payload

outputs:
  - processInstance.InstanceData
```

### 範例 2：多模組套件
<a name="automation-action-executeScript-multi-module-example"></a>

此範例示範如何使用包含多個 Python 模組的 zip 套件進行複雜的 S3 儲存貯體操作。

**套件結構**  
使用下列結構建立 zip 套件：

```
s3-operations.zip
├── main.py
├── utils/
│   ├── __init__.py
│   ├── s3_helper.py
│   └── validation.py
└── config/
    ├── __init__.py
    └── settings.py
```

**main.py (進入點)**  
協調操作的主要指令碼：

```
from utils.s3_helper import S3Operations
from utils.validation import validate_bucket_name
from config.settings import get_default_settings

def cleanup_s3_bucket(events, context):
    """Clean up S3 bucket based on specified criteria."""
    try:
        bucket_name = events.get('bucketName')
        max_age_days = events.get('maxAgeDays', 30)
        
        # Validate inputs
        if not validate_bucket_name(bucket_name):
            raise ValueError(f"Invalid bucket name: {bucket_name}")
        
        # Initialize S3 operations
        s3_ops = S3Operations()
        settings = get_default_settings()
        
        # Perform cleanup
        deleted_objects = s3_ops.delete_old_objects(
            bucket_name, 
            max_age_days,
            settings['dry_run']
        )
        
        result = {
            'bucketName': bucket_name,
            'deletedCount': len(deleted_objects),
            'deletedObjects': deleted_objects[:10],  # Return first 10 for brevity
            'dryRun': settings['dry_run']
        }
        
        print(f"Cleanup completed for bucket {bucket_name}")
        return result
        
    except Exception as e:
        print(f"Error during S3 cleanup: {str(e)}")
        raise
```

## 對 aws:executeScript 附件進行疑難排解
<a name="automation-action-executeScript-troubleshooting"></a>

使用以下指引來解決 `aws:executeScript` 附件的常見問題：

**模組匯入錯誤**  
如果您在使用多模組套件時收到匯入錯誤：
+ 請確保您已在每個包含 Python 模組的目錄中包含空白 `__init__.py` 檔案。
+ 驗證您的匯入陳述式是否符合 zip 套件中的實際檔案與目錄結構。
+ 一致地使用相對匯入 (例如 `from .utils import helper`) 或絕對匯入 (例如 `from utils import helper`)。

**找不到附件錯誤**  
如果您的 Automation 無法找到附件：
+ 驗證 `Attachment` 參數值是否與 `files` 區段中的索引鍵完全相符。
+ 檢查 `files` 區段中的 S3 儲存貯體路徑與檔案名稱是否正確。
+ 確保您的自動化角色具有附件 S3 位置的 `s3:GetObject` 許可。
+ 驗證執行手冊中的檢查總和是否符合實際檔案檢查總和。

**處理常式函數錯誤**  
如果您收到與處理常式相關的錯誤：
+ 對於 Python：在 `Handler` 參數中使用 `filename.function_name` 格式 (例如 `main.process_data`)。
+ 確保您的處理常式函數只接受兩個參數：`events` 和 `context`。
+ 對於 PowerShell：請勿指定 `Handler` 參數；指令碼會直接執行。

**指令碼執行失敗**  
如果您的指令碼在執行期間失敗：
+ 檢查自動化執行歷史記錄，以取得詳細的錯誤訊息和堆疊追蹤。
+ 使用 `print()` 陳述式 (Python) 或 `Write-Information` (PowerShell) 新增偵錯輸出。
+ 確認所有必要的 AWS 許可都授予您的自動化角色。
+ 將指令碼邏輯封裝為附件之前，先在本機測試指令碼邏輯。

**結束程式碼和錯誤處理**  
若要正確處理錯誤並傳回結束程式碼：
+ 在 Python 中：使用 `raise Exception("error message")` 指出指令碼失敗。
+ 在 PowerShell 中：使用 `throw "error message"` 或 `Write-Error` 指出失敗。
+ 從函數傳回結構化資料，以提供詳細的成功/失敗資訊。
+ 使用 try-catch 區塊，以正常方式處理例外狀況，並提供有意義的錯誤訊息。