我尝试使用一堆函数创建一个模块,但我遇到了一个问题:有时我需要运行与当前凭据不同的函数。但问题是:如果我没有指定用户名,我不想要求凭据。像这样:
function MyFunction ($ComputerName='localhost', $UserName) {
if ($UserName) {
Get-WmiObject -Class Win32_OperatingSystem -ComputerName $ComputerName -Credential $UserName
} else {
Get-WmiObject -Class Win32_OperatingSystem -ComputerName $ComputerName
}
}
我可以以某种方式摆脱if
声明吗?我可以让函数使用当前凭据,除非我指定-UserName
吗?
如果我这样离开:
Get-WmiObject -Class Win32_OperatingSystem -ComputerName $ComputerName -Credential $UserName
并在不指定-UserName
的情况下调用函数,它每次都会请求凭证。是的,如果我关闭了“获得信誉”,它会使用当前电话。盒子,但它不是我想要的。
答案 0 :(得分:2)
您可以使用splatting动态构建参数列表,但仍需要if
语句来决定是否添加-Credential
参数:
function MyFunction ($ComputerName='localhost', $UserName) {
$params = @{
Class = 'Win32_OperatingSystem'
ComputerName = $ComputerName
}
if ($UserName) { $params['Credential'] = $UserName }
Get-WmiObject @params
}
答案 1 :(得分:0)
您可以使用in here获取的默认凭据使用当前凭据填充 PSCredential
对象:
if ($UserName) {
$cred = get-credential $username # this prompts for credentials
} else {
$cred=[PSCredential][System.Net.CredentialCache]::DefaultCredentials
}
然后只需使用 -credential $cred
,无需构建if的墙。
编辑:显然,由于当前用户的PSCredential
对象的密码为SecureString
,由同一用户的私钥加密,如果有人能够获得PSCredential
默认凭证对象,他将能够将密码解密为明文,因此这个漏洞存在但最终被关闭。 (也许让这个答案挂在这里,以便人们不会像我那样得到asme错误)This question对这里出现的内容有规范的答案。
另一种方法可能是使用splatting的变体,由Ansgar Wiechers和here详细解释,在单个if语句中仅构造凭证块,然后在任何需要的地方使用该块,而不是写直接-credential
参数。
$creds=@{}
if ($UserName) {
$cred = get-credential $username # this prompts for credentials
$creds['Credential']=$cred
}
然后在需要备用凭据的地方添加@creds:
Get-WmiObject -Class Win32_OperatingSystem -ComputerName $ComputerName @creds
这样,如果提供$UserName
,系统会要求您输入一次用户密码,然后$creds
将为空或包含$UserName
的有效凭据,因此所有后续的if可以通过显式添加@creds
替换。
答案 2 :(得分:0)
你永远不会失去IF
,但你可以动态创建一个字符串,然后将其作为表达式调用:
如果$UserName
为$null
,则不会将凭据参数添加到表达式中。
function MyFunction ([String]$ComputerName='localhost', [String]$UserName) {
Invoke-Expression ("Get-WmiObject -Class Win32_OperatingSystem -ComputerName $ComputerName $(IF($UserName){'-Credential $UserName'})")
}