

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

# 使用 PowerShell 從 AWS IAM Identity Center 更新 AWS CLI 憑證
<a name="update-aws-cli-credentials-from-aws-iam-identity-center-by-using-powershell"></a>

*ChadMiles 和 Andy Bowen，Amazon Web Services*

## 總結
<a name="update-aws-cli-credentials-from-aws-iam-identity-center-by-using-powershell-summary"></a>

如果您想要搭配 AWS 命令列界面 (AWS CLI)、AWS SDKs或 AWS 雲端開發套件 (AWS CDK) 使用 AWS IAM Identity Center (AWS Single Sign-On 的後續產品） 登入資料，您通常必須將登入資料從 IAM Identity Center 主控台複製並貼到命令列界面。此程序可能需要相當長的時間，而且必須針對每個需要存取的帳戶重複。

一個常見的解決方案是使用 AWS CLI `aws sso configure`命令。此命令會將啟用 IAM Identity Center 的設定檔新增至您的 AWS CLI 或 AWS 開發套件。不過，此解決方案的缺點是，您必須`aws sso login`對以這種方式設定的每個 AWS CLI 設定檔或帳戶執行 命令。

做為替代解決方案，此模式說明如何使用 AWS CLI [命名設定檔](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-using-profiles)和適用於 PowerShell 的 AWS 工具，同時從單一 IAM Identity Center 執行個體存放和重新整理多個帳戶的登入資料。指令碼也會將 IAM Identity Center 工作階段資料存放在記憶體中，以重新整理登入資料，而無需再次登入 IAM Identity Center。

## 先決條件和限制
<a name="update-aws-cli-credentials-from-aws-iam-identity-center-by-using-powershell-prereqs"></a>

**先決條件**
+ PowerShell，已安裝並設定。如需詳細資訊，請參閱[安裝 PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell?view=powershell-7.3) (Microsoft 文件）。
+ 已安裝和設定的 AWS Tools for PowerShell。基於效能考量，強烈建議您安裝名為 的 AWS Tools for PowerShell 模組化版本`AWS.Tools`。每個 AWS 服務都由其個別的小型模組支援。在 PowerShell 提示中，輸入下列命令來安裝此模式所需的模組：`AWS.Tools.Installer`、 `SSO`和 `SSOIDC`。

  ```
  Install-Module AWS.Tools.Installer
  Install-AWSToolsModule SSO, SSOOIDC
  ```

  如需詳細資訊，請參閱[在 Windows 上安裝 AWS.Tools](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up-windows.html#ps-installing-awstools) 或[在 Linux 或 macOS 上安裝 AWS.Tools](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up-linux-mac.html#install-aws.tools-on-linux-macos)。
+ AWS CLI 或 AWS 開發套件先前必須使用工作登入資料進行設定，方法為執行下列其中一項：
  + 使用 AWS CLI `aws configure`命令。如需詳細資訊，請參閱[快速組態](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config) (AWS CLI 文件）。
  + 設定 AWS CLI 或 AWS CDK 以透過 IAM 角色取得暫時存取權。如需詳細資訊，請參閱[取得 CLI 存取的 IAM 角色登入](https://docs.aws.amazon.com/singlesignon/latest/userguide/howtogetcredentials.html)資料 (IAM Identity Center 文件）。

**限制**
+ 此指令碼無法用於管道或全自動化解決方案。部署此指令碼時，您必須從 IAM Identity Center 手動授權存取。然後指令碼會自動繼續。

**產品版本**
+ 對於所有作業系統，建議您使用 [PowerShell 7.0 版或更新版本。](https://github.com/powershell/powershell)

## Architecture
<a name="update-aws-cli-credentials-from-aws-iam-identity-center-by-using-powershell-architecture"></a>

您可以使用此模式中的指令碼，同時重新整理多個 IAM Identity Center 登入資料，也可以建立登入資料檔案，以搭配 AWS CLI、AWS SDKs或 AWS CDK 使用。

![\[使用 PowerShell 指令碼更新 AWS CLI、AWS CDK 或 AWS SKDs。\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/images/pattern-img/6d54a6bb-01ac-4736-9b78-40921fcc9056/images/01e0fcb6-3b48-422c-8868-07a7de83b3e3.png)


## 工具
<a name="update-aws-cli-credentials-from-aws-iam-identity-center-by-using-powershell-tools"></a>

**AWS 服務**
+ [AWS Command Line Interface (AWS CLI)](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) 是一種開放原始碼工具，可協助您透過命令列 shell 中的命令與 AWS 服務互動。
+ [AWS IAM Identity Center](https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html) 可協助您集中管理所有 AWS 帳戶和雲端應用程式的單一登入 (SSO) 存取。
+ [AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-welcome.html) 是一組 PowerShell 模組，可協助您從 PowerShell 命令列對 AWS 資源執行指令碼操作。

**其他工具**
+ [PowerShell](https://learn.microsoft.com/en-us/powershell/) 是在 Windows、Linux 和 macOS 上執行的 Microsoft 自動化和組態管理程式。

## 最佳實務
<a name="update-aws-cli-credentials-from-aws-iam-identity-center-by-using-powershell-best-practices"></a>

為每個 IAM Identity Center 執行個體保留一份此指令碼的副本。不支援將一個指令碼用於多個執行個體。

## 史詩
<a name="update-aws-cli-credentials-from-aws-iam-identity-center-by-using-powershell-epics"></a>

### 執行 SSO 指令碼
<a name="run-the-sso-script"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 自訂 SSO 指令碼。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/update-aws-cli-credentials-from-aws-iam-identity-center-by-using-powershell.html) | 雲端管理員 | 
| 執行 SSO 指令碼。 | 建議您使用下列命令，在 PowerShell shell 中執行自訂指令碼。<pre>./Set-AwsCliSsoCredentials.ps1</pre>或者，您也可以輸入下列命令，從另一個 shell 執行指令碼。<pre>pwsh Set-AwsCliSsoCredentials.ps1</pre> | 雲端管理員 | 

## 疑難排解
<a name="update-aws-cli-credentials-from-aws-iam-identity-center-by-using-powershell-troubleshooting"></a>


| 問題 | 解決方案 | 
| --- | --- | 
| `No Access` 錯誤 | 您使用的 IAM 角色沒有存取您在 `RoleName` 參數中定義之角色或許可集的許可。更新您正在使用之角色的許可，或在指令碼中定義不同的角色或許可集。 | 

## 相關資源
<a name="update-aws-cli-credentials-from-aws-iam-identity-center-by-using-powershell-resources"></a>
+ [組態設定存放在哪裡？](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-where) (AWS CLI 文件）
+ [設定 AWS CLI 以使用 AWS IAM Identity Center](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html) (AWS CLI 文件）
+ [使用具名設定檔](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-using-profiles) (AWS CLI 文件）

## 其他資訊
<a name="update-aws-cli-credentials-from-aws-iam-identity-center-by-using-powershell-additional"></a>

**SSO 指令碼**

在下列指令碼中，將角括號 (<>) 中的預留位置取代為您自己的資訊，並移除角括號。

```
Set-AwsCliSsoCredentials.ps1
Param(
    $DefaultRoleName = '<AWSAdministratorAccess>',
    $Region          = '<us-west-2>',
    $StartUrl        = "<https://d-12345abcde.awsapps.com/start/>",
    $EnvironmentName = "<CompanyName>"
) 
Try {$SsoAwsAccounts = (Get-Variable -name "$($EnvironmentName)SsoAwsAccounts" -Scope Global -ErrorAction 'SilentlyContinue').Value.Clone()} 
Catch {$SsoAwsAccounts = $False}
if (-not $SsoAwsAccounts) { $SsoAwsAccounts = @(    
# Add your account information in the list of hash tables below, expand as necessary, and do not forget the commas 
    @{Profile = "<Account1>"      ; AccountId = "<012345678901 >"; RoleName = $DefaultRoleName },
    @{Profile = "<Account2>"      ; AccountId = "<123456789012>"; RoleName = "<AWSReadOnlyAccess>" }
)}
$ErrorActionPreference = "Stop"
if (-not (Test-Path ~\.aws))      { New-Item ~\.aws -type Directory }
if (-not (Test-Path ~\.aws\credentials)) { New-Item ~\.aws\credentials -type File }
$CredentialFile = Resolve-Path ~\.aws\credentials 
$PsuedoCreds    = @{AccessKey = 'AKAEXAMPLE123ACCESS';SecretKey='PsuedoS3cret4cceSSKey123PsuedoS3cretKey'} # Pseudo Creds, do not edit.
Try {$SSOTokenExpire = (Get-Variable -Scope Global -Name "$($EnvironmentName)SSOTokenExpire" -ErrorAction 'SilentlyContinue').Value} Catch {$SSOTokenExpire = $False}
Try {$SSOToken       = (Get-Variable -Scope Global -Name "$($EnvironmentName)SSOToken" -ErrorAction 'SilentlyContinue').Value }      Catch {$SSOToken       = $False}
if ( $SSOTokenExpire -lt (Get-Date) ) {
    $SSOToken = $Null
    $Client   = Register-SSOOIDCClient -ClientName cli-sso-client -ClientType public -Region $Region @PsuedoCreds
    $Device   = $Client | Start-SSOOIDCDeviceAuthorization -StartUrl $StartUrl -Region $Region @PsuedoCreds
    Write-Host "A Browser window should open. Please login there and click ALLOW." -NoNewline
    Start-Process $Device.VerificationUriComplete
    While (-Not $SSOToken){
        Try {$SSOToken = $Client | New-SSOOIDCToken -DeviceCode $Device.DeviceCode -GrantType "urn:ietf:params:oauth:grant-type:device_code" -Region $Region @PsuedoCreds}
        Catch {If ($_.Exception.Message -notlike "*AuthorizationPendingException*"){Write-Error $_.Exception} ; Start-Sleep 1}
    }
    $SSOTokenExpire = (Get-Date).AddSeconds($SSOToken.ExpiresIn)
    Set-Variable -Name "$($EnvironmentName)SSOToken" -Value $SSOToken -Scope Global
    Set-Variable -Name "$($EnvironmentName)SSOTokenExpire" -Value $SSOTokenExpire -Scope Global
}
$CredsTime     = $SSOTokenExpire - (Get-Date)
$CredsTimeText = ('{0:D2}:{1:D2}:{2:D2} left on SSO Token' -f $CredsTime.Hours, $CredsTime.Minutes, $CredsTime.Seconds).TrimStart("0 :")
for ($i = 0; $i -lt $SsoAwsAccounts.Count; $i++) {
    if (([DateTimeOffset]::FromUnixTimeSeconds($SsoAwsAccounts[$i].CredsExpiration / 1000)).DateTime -lt (Get-Date).ToUniversalTime()) {
        Write-host "`r                                                                     `rRegistering Profile $($SsoAwsAccounts[$i].Profile)" -NoNewline
        $TempCreds = $SSOToken | Get-SSORoleCredential -AccountId $SsoAwsAccounts[$i].AccountId -RoleName $SsoAwsAccounts[$i].RoleName -Region $Region @PsuedoCreds
        [PSCustomObject]@{AccessKey = $TempCreds.AccessKeyId; SecretKey = $TempCreds.SecretAccessKey; SessionToken = $TempCreds.SessionToken
        } | Set-AWSCredential -StoreAs $SsoAwsAccounts[$i].Profile -ProfileLocation $CredentialFile 
        $SsoAwsAccounts[$i].CredsExpiration = $TempCreds.Expiration
    }
} 
Set-Variable -name "$($EnvironmentName)SsoAwsAccounts" -Value $SsoAwsAccounts.Clone() -Scope Global
Write-Host "`r$($SsoAwsAccounts.Profile) Profiles registered, $CredsTimeText"
```