

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用从 AWS IAM 身份中心更新 AWS CLI 证书 PowerShell
<a name="update-aws-cli-credentials-from-aws-iam-identity-center-by-using-powershell"></a>

*Chad Miles 和 Andy Bowen，Amazon Web Services*

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

如果您想将 AWS IAM 身份中心（AWS Single Sign-On 的继任者）凭证与 AWS 命令行接口 (AWS CLI)、AWS 或 AWS SDKs Cloud Development Kit (AWS CDK) 一起使用，则通常必须将证书从 IAM 身份中心控制台复制并粘贴到命令行界面中。此过程可能需要相当长的时间，并且必须为每个需要访问权限的账户重复此过程。

一种常见的解决方案是使用 AWS CLI `aws sso configure` 命令。此命令在您的 AWS CLI 或 AWS SDK 中添加启用 IAM Identity Center 的配置文件。但是，此解决方案的缺点是，您必须为以这种方式配置的每个 AWS CLI 配置文件或账户运行 `aws sso login` 命令。

作为替代解决方案，此模式描述了如何使用[名为 Profiles](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-using-profiles) 的 AWS CLI 和 AWS 工具 PowerShell 来同时存储和刷新来自单个 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 文档）。
+ 已安装并配置 PowerShell的 AWS 工具。出于性能考虑，我们强烈建议您安装名`AWS.Tools`为的 AWS 工具的 PowerShell模块化版本。每个 Amazon Web Service 都由其自己的小模块提供支持。在 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 的访问权限。然后，脚本会自动继续。

**产品版本**
+ 对于所有操作系统，建议您使用 [7.0 或更高PowerShell 版本](https://github.com/powershell/powershell)。

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

您可以使用此模式中的脚本同时刷新多个 IAM 身份中心证书，也可以创建证书文件以用于 AWS CLI、AWS 或 AWS SDKs CDK。

![\[使用 PowerShell 脚本更新 AWS CLI、AWS CDK 或 AWS SKDs 中的证书。\]](http://docs.aws.amazon.com/zh_cn/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>

**Amazon Web Services**
+ [AWS 命令行界面（AWS CLI）](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)是一种开源工具，它可帮助您通过命令行 Shell 中的命令与 Amazon Web Services 交互。
+ [AWS IAM Identity Center](https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html) 可帮助您集中管理对所有 AWS 账户和云应用程序的单点登录（SSO）访问权限。
+ [AWS 工具 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 上运行的微软自动化和配置管理程序。

## 最佳实践
<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>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 自定义 SSO 脚本。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/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"
```