[玩转系统] 向 PowerShell 函数添加凭据支持
作者:精品下载站 日期:2024-12-14 03:03:47 浏览:11 分类:玩电脑
向 PowerShell 函数添加凭据支持
笔记
本文的原始版本出现在@joshduffney 撰写的博客上。本文已被编辑以包含在本网站上。 PowerShell 团队感谢 Josh 与我们分享这些内容。请查看他的博客:duffney.io。
本文向您展示如何向 PowerShell 函数添加凭据参数以及为什么要这样做。凭据参数允许您以不同用户身份运行该函数或 cmdlet。最常见的用途是以提升的用户帐户身份运行该函数或 cmdlet。
例如,cmdlet New-ADUser
有一个 Credential 参数,您可以提供域管理员凭据以在域中创建帐户。假设运行 PowerShell 会话的普通帐户尚不具有该访问权限。
创建凭证对象
PSCredential 对象表示一组安全凭证,例如用户名和密码。该对象可以作为参数传递给作为该凭证对象中的用户帐户运行的函数。您可以通过多种方式创建凭证对象。创建凭据对象的第一种方法是使用 PowerShell cmdlet Get-Credential
。当您不带参数运行时,它会提示您输入用户名和密码。或者,您可以使用一些可选参数调用 cmdlet。
要提前指定域名和用户名,您可以使用Credential或UserName参数。当您使用 UserName 参数时,您还需要提供 Message 值。下面的代码演示了如何使用 cmdlet。您还可以将凭证对象存储在变量中,以便可以多次使用该凭证。在下面的示例中,凭证对象存储在变量 $Cred
中。
$Cred = Get-Credential
$Cred = Get-Credential -Credential domain\user
$Cred = Get-Credential -UserName domain\user -Message 'Enter Password'
有时,您无法使用上例中所示的交互式方法来创建凭据对象。大多数自动化工具需要非交互式方法。要创建无需用户交互的凭据,请创建包含密码的安全字符串。然后将安全字符串和用户名传递给 System.Management.Automation.PSCredential()
方法。
使用以下命令创建包含密码的安全字符串:
ConvertTo-SecureString "MyPlainTextPassword" -AsPlainText -Force
AsPlainText 和 Force 参数都是必需的。如果没有这些参数,您将收到一条消息,警告您不应将纯文本传递到安全字符串中。 PowerShell 返回此警告是因为纯文本密码被记录在各种日志中。创建安全字符串后,您需要将其传递给 PSCredential()
方法来创建凭证对象。在以下示例中,变量 $password
包含安全字符串 $Cred
包含凭证对象。
$password = ConvertTo-SecureString "MyPlainTextPassword" -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential ("username", $password)
现在您已经知道如何创建凭据对象,您可以将凭据参数添加到 PowerShell 函数中。
添加凭证参数
就像任何其他参数一样,您首先将其添加到函数的 param
块中。建议您将参数命名为 $Credential
,因为这是现有 PowerShell cmdlet 使用的名称。参数的类型应为[System.Management.Automation.PSCredential]
。
以下示例显示了名为 Get-Something
的函数的参数块。它有两个参数:$Name
和 $Credential
。
function Get-Something {
param(
$Name,
[System.Management.Automation.PSCredential]$Credential
)
本示例中的代码足以拥有一个有效的凭据参数,但是您可以添加一些内容以使其更加健壮。
添加
[ValidateNotNull()]
验证属性以检查是否传递给Credential 的值。如果参数值为 null,则此属性会阻止函数使用无效凭据执行。添加
[System.Management.Automation.Credential()]
。这允许您以字符串形式传入用户名,并有输入密码的交互式提示。-
将
$Credential
参数的默认值设置为[System.Management.Automation.PSCredential]::Empty
。您的函数可能会将此$Credential
对象传递给现有的 PowerShell cmdlet。向函数内调用的 cmdlet 提供 null 值会导致错误。提供空凭证对象可以避免此错误。
有用的提示
某些接受凭据参数的 cmdlet 不支持 [System.Management.Automation.PSCredential]::Empty
,因为它们应该支持。请参阅处理旧版 Cmdlet 部分以获取解决方法。
使用凭证参数
以下示例演示了如何使用凭据参数。此示例显示了一个名为 Set-RemoteRegistryValue
的函数,该函数来自 The Pester Book。该函数使用上一节中描述的技术定义凭证参数。该函数使用该函数创建的 $Credential
变量调用 Invoke-Command
。这允许您更改运行 Invoke-Command
的用户。由于 $Credential
的默认值是空凭据,因此该函数可以在不提供凭据的情况下运行。
function Set-RemoteRegistryValue {
param(
$ComputerName,
$Path,
$Name,
$Value,
[ValidateNotNull()]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential = [System.Management.Automation.PSCredential]::Empty
)
$null = Invoke-Command -ComputerName $ComputerName -ScriptBlock {
Set-ItemProperty -Path $using:Path -Name $using:Name -Value $using:Value
} -Credential $Credential
}
以下部分展示了向 Set-RemoteRegistryValue
提供凭据的不同方法。
提示输入凭据
在运行时使用括号 ()
中的 Get-Credential
会导致 Get-credential
首先运行。系统会提示您输入用户名和密码。您可以使用 Get-credential
的 Credential 或 UserName 参数来预填充用户名和域。以下示例使用称为 splatting 的技术将参数传递给 Set-RemoteRegistryValue
函数。有关 splatting 的更多信息,请查看 about_Splatting 文章。
$remoteKeyParams = @{
ComputerName = $env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams -Credential (Get-Credential)
使用 (Get-Credential)
似乎很麻烦。通常,当您仅使用带有用户名的 Credential 参数时,cmdlet 会自动提示输入密码。 [System.Management.Automation.Credential()]
属性启用此行为。
$remoteKeyParams = @{
ComputerName = $env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams -Credential duffney
笔记
要设置显示的注册表值,这些示例假设您安装了 Windows 的Web 服务器功能。如果需要,运行 Install-WindowsFeature Web-Server
和 Install-WindowsFeature web-mgmt-tools
。
在变量中提供凭据
您还可以提前填充凭据变量并将其传递给 Set-RemoteRegistryValue
函数的 Credential 参数。将此方法与持续集成/持续部署 (CI/CD) 工具(例如 Jenkins、TeamCity 和 Octopus Deploy)结合使用。有关使用 Jenkins 的示例,请查看 Hodge 的博客文章在 Windows 上使用 Jenkins 和 PowerShell 实现自动化 - 第 2 部分。
此示例使用 .NET 方法创建凭据对象和用于传入密码的安全字符串。
$password = ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential ("duffney", $password)
$remoteKeyParams = @{
ComputerName = $env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams -Credential $Cred
对于本示例,安全字符串是使用明文密码创建的。前面提到的所有 CI/CD 都有一种在运行时提供密码的安全方法。使用这些工具时,请将纯文本密码替换为您使用的 CI/CD 工具中定义的变量。
无需凭据即可运行
由于 $Credential
默认为空凭据对象,因此您可以在没有凭据的情况下运行该命令,如本示例所示:
$remoteKeyParams = @{
ComputerName = $env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams
处理旧版 cmdlet
并非所有 cmdlet 都支持凭据对象或允许空凭据。相反,cmdlet 需要用户名和密码参数作为字符串。有几种方法可以解决此限制。
使用 if-else 处理空凭据
在这种情况下,您要运行的 cmdlet 不接受空凭据对象。仅当 Credential 参数不为空时,此示例才会将其添加到 Invoke-Command
中。否则,它将运行不带 Credential 参数的 Invoke-Command
。
function Set-RemoteRegistryValue {
param(
$ComputerName,
$Path,
$Name,
$Value,
[ValidateNotNull()]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential = [System.Management.Automation.PSCredential]::Empty
)
if($Credential -ne [System.Management.Automation.PSCredential]::Empty) {
Invoke-Command -ComputerName:$ComputerName -Credential:$Credential {
Set-ItemProperty -Path $using:Path -Name $using:Name -Value $using:Value
}
} else {
Invoke-Command -ComputerName:$ComputerName {
Set-ItemProperty -Path $using:Path -Name $using:Name -Value $using:Value
}
}
}
使用 splatting 处理空凭据
此示例使用参数展开来调用旧版 cmdlet。 $Credential
对象有条件地添加到哈希表中以进行展开,并避免需要重复 Invoke-Command
脚本块。要了解有关函数内部展开的更多信息,请参阅高级函数内部展开参数博客文章。
function Set-RemoteRegistryValue {
param(
$ComputerName,
$Path,
$Name,
$Value,
[ValidateNotNull()]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential = [System.Management.Automation.PSCredential]::Empty
)
$Splat = @{
ComputerName = $ComputerName
}
if ($Credential -ne [System.Management.Automation.PSCredential]::Empty) {
$Splat['Credential'] = $Credential
}
$null = Invoke-Command -ScriptBlock {
Set-ItemProperty -Path $using:Path -Name $using:Name -Value $using:Value
} @splat
}
使用字符串密码
Invoke-Sqlcmd
cmdlet 是接受字符串作为密码的 cmdlet 示例。 Invoke-Sqlcmd
允许您运行简单的 SQL 插入、更新和删除语句。 Invoke-Sqlcmd
需要明文用户名和密码,而不是更安全的凭据对象。此示例演示如何从凭证对象中提取用户名和密码。
本示例中的 Get-AllSQLDatabases
函数调用 Invoke-Sqlcmd
cmdlet 来查询 SQL Server 的所有数据库。该函数定义了一个 Credential 参数,其属性与前面示例中使用的属性相同。由于用户名和密码存在于 $Credential
变量中,因此您可以提取这些值以与 Invoke-Sqlcmd
一起使用。
用户名可从 $Credential
变量的 UserName 属性获取。要获取密码,您必须使用 $Credential
对象的 GetNetworkCredential()
方法。这些值被提取到变量中,这些变量被添加到哈希表中,用于将参数分配给 Invoke-Sqlcmd
。
function Get-AllSQLDatabases {
param(
$SQLServer,
[ValidateNotNull()]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential = [System.Management.Automation.PSCredential]::Empty
)
$UserName = $Credential.UserName
$Password = $Credential.GetNetworkCredential().Password
$splat = @{
UserName = $UserName
Password = $Password
ServerInstance = 'SQLServer'
Query = "Select * from Sys.Databases"
}
Invoke-Sqlcmd @splat
}
$credSplat = @{
TypeName = 'System.Management.Automation.PSCredential'
ArgumentList = 'duffney',('P@ssw0rd' | ConvertTo-SecureString -AsPlainText -Force)
}
$Credential = New-Object @credSplat
Get-AllSQLDatabases -SQLServer SQL01 -Credential $Credential
继续学习证书管理
安全地创建和存储凭证对象可能很困难。以下资源可以帮助您维护 PowerShell 凭据。
- BetterCredentials
- Azure 密钥保管库
- 避难所项目
- 秘密管理模块
猜你还喜欢
- 03-30 [玩转系统] 如何用批处理实现关机,注销,重启和锁定计算机
- 02-14 [系统故障] Win10下报错:该文件没有与之关联的应用来执行该操作
- 01-07 [系统问题] Win10--解决锁屏后会断网的问题
- 01-02 [系统技巧] Windows系统如何关闭防火墙保姆式教程,超详细
- 12-15 [玩转系统] 如何在 Windows 10 和 11 上允许多个 RDP 会话
- 12-15 [玩转系统] 查找 Exchange/Microsoft 365 中不活动(未使用)的通讯组列表
- 12-15 [玩转系统] 如何在 Windows 上安装远程服务器管理工具 (RSAT)
- 12-15 [玩转系统] 如何在 Windows 上重置组策略设置
- 12-15 [玩转系统] 如何获取计算机上的本地管理员列表?
- 12-15 [玩转系统] 在 Visual Studio Code 中连接到 MS SQL Server 数据库
- 12-15 [玩转系统] 如何降级 Windows Server 版本或许可证
- 12-15 [玩转系统] 如何允许非管理员用户在 Windows 中启动/停止服务
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[影视] 黑道中人 Alto Knights(2025)剧情 犯罪 历史 电影
[古装剧] [七侠五义][全75集][WEB-MP4/76G][国语无字][1080P][焦恩俊经典]
[实用软件] 虚拟手机号 电话 验证码 注册
[电视剧] 安眠书店/你 第五季 You Season 5 (2025) 【全10集】
[电视剧] 棋士(2025) 4K 1080P【全22集】悬疑 犯罪 王宝强 陈明昊
[软件合集] 25年6月5日 精选软件22个
[软件合集] 25年6月4日 精选软件36个
[短剧] 2025年06月04日 精选+付费短剧推荐33部
[短剧] 2025年06月03日 精选+付费短剧推荐25部
[软件合集] 25年6月3日 精选软件44个
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电视剧] 欢乐颂.5部全 (2016-2024)
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[影视] 【稀有资源】香港老片 艺坛照妖镜之96应召名册 (1996)
[剧集] 神经风云(2023)(完结).4K
[剧集] [BT] [TVB] [黑夜彩虹(2003)] [全21集] [粤语中字] [TV-RMVB]
[实用软件] 虚拟手机号 电话 验证码 注册
[资源] B站充电视频合集,包含多位重量级up主,全是大佬真金白银买来的~【99GB】
[影视] 内地绝版高清录像带 [mpg]
[书籍] 古今奇书禁书三教九流资料大合集 猎奇必备珍藏资源PDF版 1.14G
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电影] 美国队长4 4K原盘REMUX 杜比视界 内封简繁英双语字幕 49G
[电影] 死神来了(1-6)大合集!
[软件合集] 25年05月13日 精选软件16个
[精品软件] 25年05月15日 精选软件18个
[绝版资源] 南与北 第1-2季 合集 North and South (1985) /美国/豆瓣: 8.8[1080P][中文字幕]
[软件] 25年05月14日 精选软件57个
[短剧] 2025年05月14日 精选+付费短剧推荐39部
[短剧] 2025年05月15日 精选+付费短剧推荐36部
- 最新评论
-
- 热门tag