Parámetros de Powershell

10

Tengo un bloque Param en mi 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
)

¿Puedo usar Read-Host CmdLet en un campo de parámetro requerido? Si no, ¿qué puedo hacer para asegurarme de tomar el tipo correcto de variable para poder pasarlo a un proceso de creación de usuario?

TechGuyTJ
fuente

Respuestas:

16

Especificar el tipo correcto de contraseña debería ser suficiente, intente:

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

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

PowerShell "enmascarará" la contraseña (igual que para read-host -asSecureString) y el tipo de resultado será el que otros cmdlets puedan requerir.

EDITAR: después de los comentarios recientes: solución, que ofrece ambas opciones para proporcionar una contraseña de texto sin formato, o forzar al usuario a escribir la contraseña (pero enmascararla de la misma manera que lo haría Read-Host -AsSecureString) y en ambos casos obtener [Security.SecureString] al final . Y, como beneficio adicional, obtienes un aviso rápido para tu contraseña secreta. ;)

[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

He usado el truco de Jaykul aquí para hacer trampa al solicitar una contraseña segura. ;) Hará que este parámetro sea muy difícil de usar en el modo CLI (-Escriba su contraseña secreta no funcionará como se esperaba), por lo que debería obligar a los usuarios de la secuencia de comandos a omitir la contraseña (y obtener una solicitud enmascarada) o especificarla con -parámetro de contraseña que acepta una cadena normal y la convierte en una cadena segura dentro de la lógica del script.

BartekB
fuente
Esto resulta en un error para mí.
Ryan Ries
1
Realmente no puedo ayudar con información tan vaga. ;) ¿Qué error obtienes? He probado esto tanto en v2 como en v3 y funcionó bien para mí. No estoy seguro de dónde puede estar la fuente de su problema si no especifica un mensaje de error ...
BartekB
No, no, tienes razón, lo siento. Su código es correcto, pero sigo pensando que el OP querrá una forma de pasar un SecureString al script en la línea de comando, y no solo una cadena.
Ryan Ries
Recibo el siguiente error cuando uso este bloque de parámetros [PS] C: \ Windows \ system32> C: \ Util \ Create-MailboxUsers.ps1 -FileLocation C: \ Util \ Users.csv -password P @ ssword C: \ Util \ Create-MailboxUsers.ps1: no se puede procesar la transformación de argumentos en el parámetro 'contraseña'. No se puede convertir el valor "P @ssword" del tipo "System.String" al tipo "System.Security.SecureString". En la línea: 1 char: 74 + C: \ Util \ Create-MailboxUsers.ps1 -FileLocation C: \ Util \ Users.csv -password <<<< P @ ssword
TechGuyTJ
1
Esto se debe a que no puede convertir una cadena normal en una cadena segura como esa. He actualizado mi respuesta con algo que probablemente le permitirá obtener poco de ambos: solicitud enmascarada y, opcionalmente, posibilidad de especificar la contraseña en línea con -password P @ ssword param.
BartekB
4

Es un poco difícil descifrar lo que estás tratando de hacer ...

Editar; como mencionó Ryan, actualmente ya lo estás especificando como una cadena ...

Pero en algunos códigos, he usado la siguiente función cuando uso Read-Host y SecureStrings

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

En su caso, lo llamaría haciendo lo siguiente;

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

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

EDITAR: Comentarios dados, y solo por el placer de hacerlo ... aquí hay un método alternativo utilizado para convertir la cadena segura anterior en texto sin formato dentro de 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) )
}

Lo usarías así;

$PWPlain = ConvertTo-PlainText $password

Resumiendo, tomas la contraseña enmascarada, es una cadena segura, luego puedes dividirla en texto sin formato para usarla en otra parte, un ejemplo de una palabra real sería si ciertos programas de CLI solo aceptan que se pasen contraseñas como texto sin formato, esto ayuda con la automatización donde no desea codificar una contraseña en su script.

fenneh
fuente
1

No estoy seguro de entender ... parece que ya lo estás haciendo. Al establecer el parámetro como obligatorio, Powershell lo solicitará si no lo proporciona en la línea de comando, y con [cadena] se asegurará de que el único tipo de datos que pueda entrar en esa variable sea System.string.

EDITAR: Basándose en la respuesta de Bartek, haga esto en su script:

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

Luego debe pasar su script a un objeto SecureString de esta manera:

PS:> Read-Host -AsSecureString | .\YourScript.ps1
Ryan Ries
fuente