Ik wil de gebruiker vragen om een reeks invoer, inclusief een wachtwoord en een bestandsnaam.
Ik heb een voorbeeld van het gebruik van host.ui.prompt
, wat logisch lijkt, maar ik begrijp de terugkeer niet.
Is er een betere manier om gebruikersinvoer in PowerShell te krijgen?
Antwoord 1, autoriteit 100%
Read-Host
is een eenvoudige optie om stringinvoer van een gebruiker te krijgen.
$name = Read-Host 'What is your username?'
Om wachtwoorden te verbergen, kunt u het volgende gebruiken:
$pass = Read-Host 'What is your password?' -AsSecureString
Om het wachtwoord om te zetten in platte tekst:
[Runtime.InteropServices.Marshal]::PtrToStringAuto(
[Runtime.InteropServices.Marshal]::SecureStringToBSTR($pass))
Wat betreft het type geretourneerd door $host.UI.Prompt()
, als u de code uitvoert via de link in de opmerking van @Christian, kunt u het retourtype achterhalen door het naar Get-Member
(bijvoorbeeld $results | gm
). Het resultaat is een Dictionary waarbij de sleutel de naam is van een FieldDescription
-object dat in de prompt wordt gebruikt. Om toegang te krijgen tot het resultaat voor de eerste prompt in het gekoppelde voorbeeld, typt u: $results['String Field']
.
Om toegang te krijgen tot informatie zonder een methode aan te roepen, laat je de haakjes weg:
PS> $Host.UI.Prompt
MemberType : Method
OverloadDefinitions : {System.Collections.Generic.Dictionary[string,psobject] Pr
ompt(string caption, string message, System.Collections.Ob
jectModel.Collection[System.Management.Automation.Host.Fie
ldDescription] descriptions)}
TypeNameOfValue : System.Management.Automation.PSMethod
Value : System.Collections.Generic.Dictionary[string,psobject] Pro
mpt(string caption, string message, System.Collections.Obj
ectModel.Collection[System.Management.Automation.Host.Fiel
dDescription] descriptions)
Name : Prompt
IsInstance : True
$Host.UI.Prompt.OverloadDefinitions
geeft je de definitie(s) van de methode. Elke definitie wordt weergegeven als <Return Type> <Method Name>(<Parameters>)
.
Antwoord 2, autoriteit 21%
Het gebruik van parameterbinding is hier absoluut de beste keuze. Het is niet alleen erg snel om te schrijven (voeg gewoon [Parameter(Mandatory=$true)]
toe boven je verplichte parameters), maar het is ook de enige optie waar je jezelf niet voor later zult haten.
Meer hieronder:
[Console]::ReadLine
is expliciet verboden door de FxCopregels voor PowerShell. Waarom? Omdat het alleen werkt in PowerShell.exe, niet in PowerShell ISE, PowerGUI, enz.
Read-Hostis simpelweg een slechte vorm. Read-Host stopt het script oncontroleerbaar om de gebruiker te vragen, wat betekent dat je nooit een ander script kunt hebben dat het script bevat dat Read-Host gebruikt.
U probeert om parameters te vragen.
U moet het kenmerk [Parameter(Mandatory=$true)]
gebruiken en correct typen om de parameters op te vragen.
Als je dit op een [SecureString]
gebruikt, zal het om een wachtwoordveld vragen. Als u dit gebruikt op een referentietype, ([Management.Automation.PSCredential]
), zal het dialoogvenster met referenties verschijnen als de parameter er niet is. Een string wordt gewoon een gewoon oud tekstvak. Als u een HelpMessage toevoegt aan het parameterkenmerk (dat wil zeggen, [Parameter(Mandatory = $true, HelpMessage = 'New User Credentials')]
), dan wordt het helptekst voor de prompt.
Antwoord 3, autoriteit 4%
Plaats dit bovenaan je script. Het zorgt ervoor dat het script de gebruiker om een wachtwoord vraagt. Het resulterende wachtwoord kan dan elders in je script worden gebruikt via $pw.
Param(
[Parameter(Mandatory=$true, Position=0, HelpMessage="Password?")]
[SecureString]$password
)
$pw = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($password))
Als je fouten wilt opsporen en de waarde wilt zien van het wachtwoord dat je zojuist hebt gelezen, gebruik je:
write-host $pw
Antwoord 4
Als alternatief zou je het kunnen toevoegen als een scriptparameter voor invoer als onderdeel van het uitvoeren van het script
param(
[Parameter(Mandatory = $True,valueFromPipeline=$true)][String] $value1,
[Parameter(Mandatory = $True,valueFromPipeline=$true)][String] $value2
)