#凭据与权限
#简介
在自动化脚本中,经常需要使用用户名和密码登录远程计算机或访问受保护的资源。PowerShell 使用 PSCredential 对象表示凭据,其中密码以 SecureString 形式保存。
良好的做法是:不要在脚本中硬编码明文密码,不要让脚本长期以管理员或 root 权限运行,并遵循最小权限原则。
#获取凭据
使用 Get-Credential 交互式获取用户名和密码:
> $cred = Get-Credential
> $cred = Get-Credential -UserName 'alice' -Message '请输入远程登录密码'
返回值是 PSCredential 对象。UserName 是字符串,Password 是 SecureString,因此不会直接暴露明文密码。
#SecureString
可以在终端中安全地读取密码,或从明文临时转换:
> $secure = Read-Host -AsSecureString -Prompt '密码'
> $secure = ConvertTo-SecureString -String 'P@ssw0rd' -AsPlainText -Force
> $cred = [System.Management.Automation.PSCredential]::new('alice', $secure)
#导出与还原 SecureString
ConvertFrom-SecureString 将 SecureString 转换为加密后的字符串,ConvertTo-SecureString 再做还原:
> $key = [byte[]](1..32)
> $encrypted = ConvertFrom-SecureString -SecureString $secure -Key $key
> $secure2 = ConvertTo-SecureString -String $encrypted -Key $key
-Key 使用 AES 加密,密钥长度应为 16、24 或 32 字节。示例中的密钥仅用于演示,实际使用时应生成随机密钥并安全保存,不要与加密数据放在一起。在 Windows 上不指定 -Key 时,通常使用 DPAPI 加密,结果与当前用户和计算机绑定,不能直接复制到其他计算机使用。
#在远程命令中使用凭据
使用 WinRM 时,可以将 PSCredential 传给远程命令或会话:
> $cred = Get-Credential
> Invoke-Command -ComputerName server01 -Credential $cred -ScriptBlock { whoami }
> $session = New-PSSession -ComputerName server01 -Credential $cred
> Remove-PSSession -Session $session
使用 SSH 远程时,通常通过 -UserName 和 -KeyFilePath 指定身份,或由 SSH 自行提示输入密码:
> $session = New-PSSession -HostName server01 -UserName alice -KeyFilePath ~/.ssh/id_ed25519
#最小权限原则
- 为自动化创建专用账户,只授予完成任务所需的最小权限。
- 不要在日常操作中始终使用管理员或 root 账户。
- 定期审查账户权限和凭据的使用范围。
- 密钥和密码应保存在受保护的存储中,而不是脚本或仓库里。
Windows 的权限模型通常通过用户组、访问控制列表(ACL)和 UAC 提权来管理;Linux 则常通过普通用户配合 sudo 临时提权。两者机制不同,远程会话默认使用登录用户的权限,需要提权时必须显式处理。
#SecretManagement 简介
Microsoft.PowerShell.SecretManagement 是 PowerShell 的密钥管理扩展模块,可以配合不同的密钥库(如 Microsoft.PowerShell.SecretStore)统一保存和读取密码、令牌等敏感信息。
> Install-Module Microsoft.PowerShell.SecretManagement -Scope CurrentUser
> Install-Module Microsoft.PowerShell.SecretStore -Scope CurrentUser
> Register-SecretVault -Name SecretStore -ModuleName Microsoft.PowerShell.SecretStore -DefaultVault
> $token = Read-Host -AsSecureString -Prompt 'Token'
> Set-Secret -Name GitHubToken -Secret $token
> Get-Secret -Name GitHubToken
这样脚本中只需引用密钥名称,不必包含明文密码。密钥库本身的保护方式和访问控制仍需单独配置。