Parâmetros do PowerShell

10

Eu tenho um bloco Param no meu 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
)

Posso usar o CmdLet do host de leitura em um campo de parâmetro obrigatório? caso contrário, o que posso fazer para garantir que eu digite o tipo correto de variável para que eu possa passá-lo para um processo de criação de usuário?

TechGuyTJ
fonte

Respostas:

16

Especificar o tipo correto de senha deve ser suficiente, tente:

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

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

O PowerShell "mascarará" a senha (igual à do host de leitura comoSecureString) e o tipo de resultado será o que outros cmdlets podem exigir.

EDIT: Após comentários recentes: solução, que oferece as duas opções para fornecer senha de texto sem formatação ou forçar o usuário a digitar a senha (mas mascarar da mesma maneira que Read-Host -AsSecureString faria) e, em ambos os casos, obter [Security.SecureString] no final . E, como bônus, você recebe um prompt sofisticado para sua senha 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

Eu usei o truque de Jaykul aqui para enganar solicitando uma senha segura. ;) Tornará esse parâmetro muito difícil de usar no modo CLI (-Digite sua senha secreta não funcionará conforme o esperado), portanto, deve forçar os usuários do script a omitir a senha (e obter prompt mascarado) ou especificá-lo com -password parâmetro que aceita string regular e o converte em string segura dentro da lógica do script.

BartekB
fonte
Isso resulta em um erro para mim.
Ryan Ries
1
Realmente não posso ajudar com informações tão vagas. ;) Que erro você recebe? Eu testei isso na v2 e na v3 e funcionou bem para mim. Não tenho certeza onde a fonte de seu problema pode ser se você não especificar mensagem de erro ...
BartekB
Não, não, você está certo - desculpe. Seu código está correto, mas ainda estou pensando que o OP desejará uma maneira de passar um SecureString para o script na linha de comando, e não apenas uma string.
21912 Ryan Ries
Estou recebendo o seguinte erro ao usar este bloco Param [PS] C: \ Windows \ system32> C: \ Util \ Create-MailboxUsers.ps1 -Localização do arquivo C: \ Util \ Users.csv -password P @ ssword C: \ Util \ Create-MailboxUsers.ps1: Não é possível processar a transformação de argumento no parâmetro 'senha'. Não é possível converter o valor "P @ssword" do tipo "System.String" para o tipo "System.Security.SecureString". Na linha: 1 de char: 74 + C: \ util \ Criar-MailboxUsers.ps1 -FileLocation C: \ Util \ Users.csv -senha <<<< P @ ssword
TechGuyTJ
1
Isso ocorre porque você não pode converter cadeias regulares em cadeias seguras como essa. Atualizei minha resposta com algo que provavelmente permitirá que você obtenha pouco de ambos: prompt mascarado e, opcionalmente, a possibilidade de especificar a senha embutida com o parâmetro -password P @ ssword.
BartekB
4

É um pouco difícil decifrar o que você está tentando fazer ...

Editar; como mencionado por Ryan, você já o está especificando como uma sequência ...

Mas, em algum código, usei a seguinte função ao usar o Read-Host e o SecureStrings

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

No seu caso, você chamaria assim:

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: Dado comentários, e apenas para o inferno ... aqui está um método alternativo usado para converter a string segura acima em texto sem formatação no 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) )
}

Você usaria assim;

$PWPlain = ConvertTo-PlainText $password

Resumindo demais, você pega a senha em mascarada, é uma string segura, e pode ser dividida em texto sem formatação para uso em outros lugares; um exemplo de palavra real seria se certos programas CLI aceitassem apenas senhas passadas para eles como texto sem formatação, isso ajuda na automação onde você não deseja codificar uma senha no seu script.

fenneh
fonte
1

Não sei se entendi ... parece que você já está fazendo isso. Ao definir o parâmetro como obrigatório, o Powershell solicitará se você não o fornecer na linha de comando, e com [string] você garantirá que o único tipo de dados que pode entrar nessa variável seja System.string.

EDIT: Com base na resposta de Bartek, faça isso no seu script:

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

Então você deve passar ao seu script um objeto SecureString da seguinte maneira:

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