Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have a Param block in my script

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
)

Can I use the Read-Host CmdLet in a required Parameter field? if not what can I do to make sure I take in the correct type of variable type so I can pass it to a user creation process?

share|improve this question
add comment

3 Answers

up vote 3 down vote accepted

Specifying correct type for password should be enough, try:

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

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

PowerShell will "mask" password (same as for read-host -asSecureString) and result type will be the one that other cmdlets may require.

EDIT: After recent comments: solution, that gives both option to provide plain text password, or force user to type password (but mask it same way Read-Host -AsSecureString would) and in both cases get [Security.SecureString] in the end. And, as a bonus, you get some fancy prompt for your secret password. ;)

[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

I've used Jaykul's trick here to cheat with prompting for secure password. ;) It will make this parameter very hard to use in CLI mode (-Type your secret password won't work as expect), so it should force users of the script to either omit password (and get masked prompt) or specify it with -password parameter that accepts regular string and converts it to secure string inside script logic.

share|improve this answer
    
This results in an error for me. –  Ryan Ries Jul 11 '12 at 21:34
1  
Can't really help with so vague info. ;) What error do you get? I've tested this both on v2 and v3 and it worked fine for me. Not sure where the source of your issue may be if you don't specify error message... –  BartekB Jul 11 '12 at 21:49
    
No no, you're right - sorry. Your code is correct, but I'm still thinking the OP is going to want a way to pass a SecureString to the script on the command line, and not just a string. –  Ryan Ries Jul 11 '12 at 21:53
    
I am getting the following error when I use this Param block [PS] C:\Windows\system32>C:\Util\Create-MailboxUsers.ps1 -FileLocation C:\Util\Users.csv -password P@ssword C:\Util\Create-MailboxUsers.ps1 : Cannot process argument transformation on parameter 'password'. Cannot convert the "P @ssword" value of type "System.String" to type "System.Security.SecureString". At line:1 char:74 + C:\Util\Create-MailboxUsers.ps1 -FileLocation C:\Util\Users.csv -password <<<< P@ssword –  TechGuyTJ Jul 12 '12 at 13:58
1  
That's because you can not convert regular string to secure string like that. I've updated my answer with something that will probably allow you to get little of both: masked prompt and optionally possibility to specify password inline with -password P@ssword param. –  BartekB Jul 12 '12 at 19:33
add comment

It's a little hard to decipher what you're trying to do...

Edit; like mentioned by Ryan, you currently already are specifying it as a string...

But in some code, I've used the following function when using Read-Host and SecureStrings

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

In your case you'd call it by doing the following;

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

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

EDIT: Given comments, and just for the hell of it... here's an alternative method used to convert the above secure string into plain text within 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) )
}

You'd use it like this;

$PWPlain = ConvertTo-PlainText $password

Too summarise, you take the password in masked, it's a secure string, you can then break this down into plain text for use elsewhere, a real word example would be if certain CLI programs only accept passwords being passed into them as plain text, this helps with automation where you don't want to hard code a password into your script..

share|improve this answer
add comment

I'm not sure I understand... it appears that you already are doing that. By setting the parameter to mandatory, Powershell will prompt you for it if you don't provide it on the command line, and with [string] you are ensuring that the only data type that can go into that variable is System.string.

EDIT: Building on Bartek's answer, do this in your script:

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

Then you have to pass your script a SecureString object like so:

PS:> Read-Host -AsSecureString | .\YourScript.ps1
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.