Powershell-Parameter

10

Ich habe einen Param-Block in meinem Skript

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
)

Kann ich das Read-Host CmdLet in einem erforderlichen Parameterfeld verwenden? Wenn nicht, was kann ich tun, um sicherzustellen, dass ich den richtigen Variablentyp verwende, damit ich ihn an einen Benutzererstellungsprozess übergeben kann?

TechGuyTJ
quelle

Antworten:

16

Geben Sie Folgendes an, um den richtigen Typ für das Kennwort anzugeben:

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

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

PowerShell "maskiert" das Kennwort (wie für read-host -asSecureString) und der Ergebnistyp ist derjenige, den andere Cmdlets möglicherweise benötigen.

BEARBEITEN: Nach den letzten Kommentaren: Lösung, die sowohl die Option bietet, ein Nur-Text-Kennwort anzugeben , als auch den Benutzer zur Eingabe eines Kennworts zu zwingen (es jedoch auf dieselbe Weise zu maskieren, wie es Read-Host -AsSecureString tun würde) und in beiden Fällen am Ende [Security.SecureString] erhält . Und als Bonus erhalten Sie eine ausgefallene Aufforderung zur Eingabe Ihres geheimen Passworts. ;)

[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

Ich habe Jaykuls Trick hier benutzt, um mit der Aufforderung zur Eingabe eines sicheren Passworts zu betrügen. ;) Es macht es sehr schwierig, diesen Parameter im CLI-Modus zu verwenden (- Geben Sie ein, dass Ihr geheimes Passwort nicht wie erwartet funktioniert), sodass Benutzer des Skripts gezwungen werden sollten, das Passwort entweder wegzulassen (und eine maskierte Eingabeaufforderung zu erhalten) oder es mit anzugeben -password-Parameter, der reguläre Zeichenfolgen akzeptiert und in sichere Zeichenfolgen innerhalb der Skriptlogik konvertiert.

BartekB
quelle
Dies führt zu einem Fehler für mich.
Ryan Ries
1
Kann nicht wirklich mit so vagen Informationen helfen. ;) Welchen Fehler bekommst du? Ich habe dies sowohl auf v2 als auch auf v3 getestet und es hat gut für mich funktioniert. Ich bin mir nicht sicher, wo die
Ursache
Nein, nein, du hast recht - sorry. Ihr Code ist korrekt, aber ich denke immer noch, dass das OP eine Möglichkeit haben möchte, einen SecureString an das Skript in der Befehlszeile zu übergeben, und nicht nur eine Zeichenfolge.
Ryan Ries
Bei Verwendung dieses Parameterblocks [PS] C: \ Windows \ system32> C: \ Util \ Create-MailboxUsers.ps1 -FileLocation C: \ Util \ Users.csv -password P @ ssword C: \ wird folgende Fehlermeldung angezeigt Util \ Create-MailboxUsers.ps1: Die Argumenttransformation für den Parameter 'password' kann nicht verarbeitet werden. Der Wert "P @ssword" vom Typ "System.String" kann nicht in den Wert "System.Security.SecureString" konvertiert werden. In Zeile: 1 Zeichen: 74 + C: \ Util \ Create-MailboxUsers.ps1 -FileLocation C: \ Util \ Users.csv -password <<<< P @ ssword
TechGuyTJ
1
Das liegt daran, dass Sie keine regulären Zeichenfolgen in solche sicheren Zeichenfolgen konvertieren können. Ich habe meine Antwort mit etwas aktualisiert, mit dem Sie wahrscheinlich nur wenig von beidem erhalten können: maskierte Eingabeaufforderung und optional die Möglichkeit, das Kennwort inline mit -password P @ ssword param anzugeben.
BartekB
4

Es ist ein wenig schwer zu entziffern, was Sie versuchen zu tun ...

Bearbeiten; Wie von Ryan erwähnt, geben Sie es derzeit bereits als Zeichenfolge an ...

In einigen Codes habe ich jedoch die folgende Funktion verwendet, wenn ich Read-Host und SecureStrings verwendet habe

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

In Ihrem Fall würden Sie es wie folgt aufrufen:

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

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

BEARBEITEN: Gegebene Kommentare, und nur zum Teufel ... hier ist eine alternative Methode, um die obige sichere Zeichenfolge in Powershell in einfachen Text umzuwandeln.

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

Sie würden es so verwenden;

$PWPlain = ConvertTo-PlainText $password

Zusammenfassend lässt sich sagen, dass Sie das Kennwort maskiert verwenden. Es ist eine sichere Zeichenfolge. Sie können es dann zur Verwendung an anderer Stelle in einfachen Text zerlegen. Ein Beispiel für ein echtes Wort wäre, wenn bestimmte CLI-Programme nur Kennwörter akzeptieren, die als einfacher Text an sie übergeben werden Hilft bei der Automatisierung, bei der Sie kein Kennwort fest in Ihr Skript codieren möchten.

Fenneh
quelle
1

Ich bin nicht sicher , ob ich verstehe ... es scheint , dass Sie bereits sind , das zu tun. Wenn Sie den Parameter auf obligatorisch setzen, werden Sie von Powershell dazu aufgefordert, wenn Sie ihn nicht in der Befehlszeile angeben. Mit [string] stellen Sie sicher, dass der einzige Datentyp, der in diese Variable aufgenommen werden kann, System.string ist.

EDIT: Aufbauend auf Barteks Antwort, machen Sie dies in Ihrem Skript:

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

Dann müssen Sie Ihrem Skript ein SecureString-Objekt wie folgt übergeben:

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