Powershell参数


10

我的脚本中有一个Param块

Param (
    [Parameter(Mandatory=$True)]
    [string]$FileLocation,

    [Parameter(Mandatory=$True)]
    [string]$password = Read-Host "Type the password you would like to set all the users to" -assecurestring
)

我可以在必填的“参数”字段中使用“读取主机CmdLet”吗?如果不是,我该怎么做才能确保输入正确的变量类型,以便将其传递给用户创建过程?

Answers:


16

为密码指定正确的类型就足够了,请尝试:

Param (
    [Parameter(Mandatory=$True)]
    [string]$FileLocation,

    [Parameter(Mandatory=$True)]
    [Security.SecureString]$password
)

PowerShell将“屏蔽”密码(与读取主机-asSecureString相同),结果类型将是其他cmdlet可能需要的一种。

编辑:最近的评论后:解决方案,给出了两个选项,以提供纯文本密码,或用户输入密码(但掩盖它同样的方式读主机-AsSecureString会),并在这两种情况下得到[Security.SecureString]到底。并且,作为奖励,您会收到一些提示您输入密码的提示。;)

[CmdletBinding(
    DefaultParameterSetName = 'Secret'
)]
Param (
    [Parameter(Mandatory=$True)]
    [string]$FileLocation,

    [Parameter(
        Mandatory = $True,
        ParameterSetName = 'Secret'
    )]
    [Security.SecureString]${Type your secret password},
    [Parameter(
        Mandatory = $True,
        ParameterSetName = 'Plain'
    )]
    [string]$Password
)

if ($Password) {
    $SecretPassword = $Password | ConvertTo-SecureString -AsPlainText -Force
} else {
    $SecretPassword = ${Type your secret password}
}

Do-Stuff -With $SecretPassword

我在这里使用了Jaykul的把戏来提示输入安全密码。;)这将使此参数在CLI模式下非常难以使用(-键入您的秘密密码将无法正常工作),因此它应强制脚本用户忽略密码(或获得带掩码的提示)或使用-password参数,它接受常规字符串并将其转换为脚本逻辑中的安全字符串。


这对我来说是一个错误。
瑞安·里斯

1
真的无法提供如此模糊的信息。;)您会遇到什么错误?我已经在v2和v3上对此进行了测试,对我来说效果很好。如果您不指定错误消息,则不确定问题的根源可能在哪里……
BartekB 2012年

不,不,您是对的-对不起。您的代码是正确的,但是我仍然认为OP将需要一种将SecureString传递给命令行上的脚本的方法,而不仅仅是字符串。
瑞安·里斯

使用此参数块[PS] C:\ Windows \ system32> C:\ Util \ Create-MailboxUsers.ps1 -FileLocation C:\ Util \ Users.csv -password P @ ssword C:\时,出现以下错误Util \ Create-MailboxUsers.ps1:无法处理参数“密码”上的参数转换。无法将类型“ System.String”的“ P @ssword”值转换为类型“ System.Security.SecureString”。在第1行:char:74 + C:\ Util \ Create-MailboxUsers.ps1 -FileLocation C:\ Util \ Users.csv -password <<<< P @ ssword
TechGuyTJ 2012年

1
那是因为您不能将常规字符串转换为安全字符串。我已经用一些可能使您几乎都无法获得的东西更新了我的答案:掩码提示和(可选)使用-password P @ ssword param指定内联密码的可能性。
BartekB

4

破译您要尝试的工作有点困难...

编辑; 就像Ryan提到的那样,您目前已经将其指定为字符串...

但是在某些代码中,使用Read-Host和SecureStrings时使用了以下功能

function AskSecureQ ([String]$Question, [String]$Foreground="Yellow", [String]$Background="Blue") {
    Write-Host $Question -ForegroundColor $Foreground -BackgroundColor $Background -NoNewLine
    Return (Read-Host -AsSecureString)
}

在您的情况下,可以通过执行以下操作来调用它;

Param (
    [Parameter(Mandatory=$True)]
    [string]$FileLocation,

    [Parameter(Mandatory=$True)]
    [string]$password = AskSecureQ "Type the password you would like to set all the users to"
)

编辑:给定注释,仅此而已...这是用于在Powershell中将上述安全字符串转换为纯文本的另一种方法;

# Taking a secure password and converting to plain text
Function ConvertTo-PlainText( [security.securestring]$secure ) {
    $marshal = [Runtime.InteropServices.Marshal]
    $marshal::PtrToStringAuto( $marshal::SecureStringToBSTR($secure) )
}

您将像这样使用它;

$PWPlain = ConvertTo-PlainText $password

概括地说,您将密码屏蔽了,这是一个安全字符串,然后可以将其分解为纯文本以供其他地方使用,一个真实的单词示例是,如果某些CLI程序仅接受以纯文本形式传递给他们的密码,当您不想将密码硬编码到脚本中时,可以帮助实现自动化。


1

我不确定我是否了解...看来您已经这样做了。通过将参数设置为强制,如果您未在命令行上提供该参数,Powershell会提示您输入该参数,并使用[string]来确保可以进入该变量的唯一数据类型是System.string。

编辑:基于Bartek的答案,在您的脚本中执行此操作:

Param ([Parameter(Mandatory=$true,ValueFromPipeline=$true)][Security.SecureString]$Password)       

然后,您必须像这样将脚本传递给SecureString对象:

PS:> Read-Host -AsSecureString | .\YourScript.ps1
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.