仅在指定的情况下才要求信用

Ask for creds only if some specified

我正在尝试创建一个包含大量函数的模块,但我遇到了一个问题:有时我需要 运行 具有不同于当前凭据的函数。但问题是:如果我没有指定用户名,我不想询问凭据。像这样:

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 的情况下调用函数,它每次都要求提供凭据。是的,如果我关闭 'get-cred' 框,它会使用电流,但这不是我想要的。

您可以使用像 in here:

这样获取的默认凭据,用当前凭据填充 PSCredential 对象
if ($UserName) {
   $cred = get-credential $username # this prompts for credentials
} else {
   $cred=[PSCredential][System.Net.CredentialCache]::DefaultCredentials
}

然后只要你需要就使用 -credential $cred 而无需建造一堵 if's 墙。

编辑:显然,由于当前用户的 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.

来替换

您永远不会真正丢失 IF,但您可以即时创建一个字符串,然后将其作为表达式调用:

如果 $UserName$null,则不会将凭据参数添加到表达式中。

function MyFunction ([String]$ComputerName='localhost', [String]$UserName) {

    Invoke-Expression ("Get-WmiObject -Class Win32_OperatingSystem -ComputerName $ComputerName $(IF($UserName){'-Credential $UserName'})")

}

您可以使用 splatting 来动态构建参数列表,但您仍然需要一个 if 语句来决定是否添加 -Credential 参数:

function MyFunction ($ComputerName='localhost', $UserName) {
    $params = @{
      Class        = 'Win32_OperatingSystem'
      ComputerName = $ComputerName
    }
    if ($UserName) { $params['Credential'] = $UserName }

    Get-WmiObject @params
}