Parametry PowerShell

10

W moim skrypcie mam blok 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
)

Czy mogę użyć CmdLet Read-Host w wymaganym polu parametru? jeśli nie, co mogę zrobić, aby upewnić się, że wybrałem poprawny typ zmiennej, aby przekazać ją do procesu tworzenia użytkownika?

TechGuyTJ
źródło

Odpowiedzi:

16

Podanie prawidłowego typu hasła powinno wystarczyć, spróbuj:

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

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

PowerShell „zamaskuje” hasło (takie samo jak w przypadku read-host -asSecureString), a typem wyniku będzie ten, którego mogą wymagać inne cmdlety.

EDYCJA: Po ostatnich komentarzach: rozwiązanie, które daje obu opcję podania hasła w postaci zwykłego tekstu lub zmusza użytkownika do wpisania hasła (ale zamaskuj to w ten sam sposób, co zrobiłby Read-Host -AsSecureString), aw obu przypadkach w końcu otrzymaj [Security.SecureString] . Jako bonus otrzymasz wymyślne zapytanie o swoje tajne hasło. ;)

[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

Użyłem sztuczki Jaykul, aby oszukiwać, prosząc o bezpieczne hasło. ;) Sprawi, że ten parametr będzie bardzo trudny w użyciu w trybie CLI (-Wpisz swoje tajne hasło nie będzie działać zgodnie z oczekiwaniami), więc powinien zmusić użytkowników skryptu do pominięcia hasła (i otrzymania zamaskowanego monitu) lub określenia go za pomocą -password parametr, który akceptuje ciąg normalny i konwertuje go na bezpieczny ciąg w logice skryptu.

Bartek B.
źródło
To powoduje dla mnie błąd.
Ryan Ries,
1
Naprawdę nie mogę pomóc w tak niejasnych informacjach. ;) Jaki masz błąd? Przetestowałem to zarówno na v2, jak i v3 i działało dobrze dla mnie. Nie wiesz, gdzie może być źródło problemu, jeśli nie określisz komunikatu o błędzie ...
BartekB,
Nie nie, masz rację - przepraszam. Twój kod jest poprawny, ale nadal myślę, że OP będzie chciał przekazać metodę SecureString do skryptu w wierszu polecenia, a nie tylko ciąg znaków.
Ryan Ries,
Podczas używania tego bloku Param pojawia się następujący błąd [PS] C: \ Windows \ system32> C: \ Util \ Create-MailboxUsers.ps1 -FileLocation C: \ Util \ Users.csv -password P @ ssword C: \ Util \ Create-MailboxUsers.ps1: Nie można przetworzyć transformacji argumentu parametru „hasło”. Nie można przekonwertować wartości „P @ssword” typu „System.String” na typ „System.Security.SecureString”. W wierszu: 1 znak: 74 + C: \ Util \ Create-MailboxUsers.ps1-FileLocation C: \ Util \ Users.csv -password <<<< H @ sło
TechGuyTJ
1
Wynika to z faktu, że nie można przekonwertować zwykłego łańcucha na taki bezpieczny. Zaktualizowałem odpowiedź o coś, co prawdopodobnie pozwoli ci uzyskać niewiele z obu: maskowane pytanie i opcjonalnie możliwość podania hasła w połączeniu z parametrem -password P @ ssword param.
BartekB
4

Trochę trudno jest odczytać, co próbujesz zrobić ...

Edytować; jak wspomniano Ryan, obecnie określasz go jako ciąg znaków ...

Ale w niektórych kodach użyłem następującej funkcji podczas korzystania z Read-Host i SecureStrings

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

W twoim przypadku zadzwonisz, wykonując następujące czynności;

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

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

EDYCJA: Biorąc pod uwagę komentarze i na wszelki wypadek ... oto alternatywna metoda konwersji powyższego bezpiecznego ciągu na zwykły tekst w programie 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) )
}

Użyłbyś tego w ten sposób;

$PWPlain = ConvertTo-PlainText $password

Podsumowując, zabierasz hasło w postaci zamaskowanej, jest to bezpieczny ciąg znaków, możesz następnie podzielić go na zwykły tekst, aby użyć go gdzie indziej. Przykładem prawdziwego słowa byłoby, gdyby niektóre programy CLI akceptowały hasła przesyłane do nich jako zwykły tekst, to pomaga w automatyzacji, w której nie chcesz na stałe wpisywać hasła do skryptu.

fenneh
źródło
1

Nie jestem pewien, czy rozumiem ... wygląda na to, że już to robisz. Ustawiając parametr na obowiązkowy, Powershell wyświetli monit o podanie go, jeśli nie podasz go w wierszu poleceń, a za pomocą [string] upewnisz się, że jedynym typem danych, który może przejść do tej zmiennej, jest System.string.

EDYCJA: Opierając się na odpowiedzi Bartka, zrób to w swoim skrypcie:

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

Następnie musisz przekazać skryptowi obiekt SecureString, taki jak:

PS:> Read-Host -AsSecureString | .\YourScript.ps1
Ryan Ries
źródło