Vraag om gebruikersinvoer in PowerShell

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-Hostis 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.OverloadDefinitionsgeeft 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]::ReadLineis 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
      )

Other episodes