PowerShell'de kullanıcı girişi istemi


209

Kullanıcıdan şifre ve dosya adı da dahil olmak üzere bir dizi girdi istemek istiyorum.

Kullandığım bir örnek var host.ui.promptmantıklı görünüyor, ama dönüşü anlayamıyorum.

PowerShell'de kullanıcı girişi almanın daha iyi bir yolu var mı?

Yanıtlar:


333

Read-Host bir kullanıcıdan dize girdisi almak için basit bir seçenektir.

$name = Read-Host 'What is your username?'

Şifreleri gizlemek için şunları kullanabilirsiniz:

$pass = Read-Host 'What is your password?' -AsSecureString

Parolayı düz metne dönüştürmek için:

[Runtime.InteropServices.Marshal]::PtrToStringAuto(
    [Runtime.InteropServices.Marshal]::SecureStringToBSTR($pass))

Döndürülen türe gelince $host.UI.Prompt(), kodu @ Christian'ın yorumunda yayınlanan bağlantıda çalıştırırsanız, dönüş türünü Get-Member(örneğin, $results | gm) ile borulandırarak öğrenebilirsiniz . Sonuç, anahtarın FieldDescriptionbilgi isteminde kullanılan bir nesnenin adı olduğu bir Sözlüktür. Bağlantılı örnekte ilk istemi sonucunu erişmek için şunları yazın: $results['String Field'].

Bir yöntemi çağırmadan bilgilere erişmek için parantezleri kapalı bırakın:

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.OverloadDefinitionssize yöntemin tanımlarını verecektir. Her tanım olarak görüntülenir <Return Type> <Method Name>(<Parameters>).


Teşekkürler @Rynant. Asıl sorumu cevaplayan tek kişi olduğum için kabul edilen cevap! ;) Diğer tüm bilgiler de gerçekten yararlıdır, özellikle de PS'de yolumu tutuyorum.
AJ.

Sorun değil, @AJ. Bir yöntem hakkında bilgi almanın başka bir yolu da parantezleri bırakmaktır. Cevabıma bir örnek ekleyeceğim.
Rynant

3
Kullanıcı adları ve parolalar alıyorsanız Get-Credential'ı da kullanabilirsiniz.
Matt Lyons

75

Parametre bağlama kullanmak kesinlikle buraya gitmek için bir yoldur. Sadece yazmak çok hızlı değil (sadece [Parameter(Mandatory=$true)]zorunlu parametrelerinizin üzerine ekleyin), aynı zamanda daha sonra kendinizden nefret etmeyeceğiniz tek seçenektir.

Aşağıda daha fazlası:

[Console]::ReadLinePowerShell için FxCop kuralları tarafından açıkça yasaklanmıştır . Neden? Çünkü yalnızca PowerShell.exe'de çalışır, PowerShell ISE , PowerGUI vb.

Read-Host oldukça basit bir şekilde kötü bir formdur. Read-Host, komut istemini komut isteminden durdurarak kullanıcıdan sormasını sağlar, bu da Read-Host kullanan komut dosyasını içeren başka bir komut dosyasına sahip olamayacağınız anlamına gelir.

Parametreler istemeye çalışıyorsunuz.

[Parameter(Mandatory=$true)]Parametreleri istemek için niteliği kullanmanız ve doğru yazmayı kullanmanız gerekir .

Bunu a'da kullanırsanız [SecureString], bir şifre alanı ister. Bunu Kimlik Bilgisi türünde ( [Management.Automation.PSCredential]) kullanırsanız, parametre yoksa, kimlik bilgileri iletişim kutusu açılır. Bir dize sadece düz eski bir metin kutusu haline gelir. Parametre özniteliğine (yani [Parameter(Mandatory = $true, HelpMessage = 'New User Credentials')]) bir HelpMessage eklerseniz , bilgi istemi için yardım metni olur.


5
Bu en esnek ve kullanıcı dostu çözümdür, ancak tavsiyenizi neredeyse göz ardı ettim, çünkü Rynant'ın cevabı gibi açık kod örnekleri yoktu . Güzel biçimlendirilmiş bazı örnekler verebilir misiniz?
Iain Samuel McLean Elder

4
"Read-Host, oldukça basit bir şekilde kötü bir form" ... birisi komut dosyanızı HERHANGİ parametrelere çağırmadığı için dışarıda bırakılan girdileri koşullu olarak kabul etmek için kullanmıyorsanız. BOOM.

2
Hayır: o zaman hala kötü bir form. Bu yüzden parametreleri zorunlu olarak işaretlersiniz.
Start-

2
Etkileşimli bir komut dosyası yazmak isterseniz ne olur ? Bunun, yalnızca belirli koşullar karşılandığında kullanıcı girişi gerektiren bir komut dosyası olduğunu varsayalım. Örneğin, komut dosyanız bir SDK için hedef dizin oluşturacaksa, kullanıcının dizini zaten varsa silmek istediğini onaylamak isteyebilirsiniz.
Mart'ta Jason Goemaat

6
Bence user1499731 iyi bir noktaya sahipti ... Kullanıcıdan yalnızca bazı bilgiler gösterildikten veya başka bir işlem yapıldıktan sonra anlamlı olarak sağlanabilen girdi almanız gerektiğinde zamanlar vardır . Bu durumda, bir parametre kullanamazsınız ve burada Read-Host"kötü form" olma nedenleri geçerli değildir. Dahası, sadece birkaç cevapla sınırlı olmak gibi .ShouldProcess()kısıtlamalara Read-Hostsahip değildir. Ancak .ShouldProcess()uygulanabilir olduğunda daha iyi olduğunu kabul ediyorum .
LarsH

14

Bunu betiğinizin en üstüne yerleştirin. Komut dosyasından kullanıcıdan parola istenmesine neden olur. Ortaya çıkan parola daha sonra $ pw aracılığıyla betiğinizin başka bir yerinde kullanılabilir .

   Param(
     [Parameter(Mandatory=$true, Position=0, HelpMessage="Password?")]
     [SecureString]$password
   )

   $pw = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($password))

Hata ayıklamak ve az önce okuduğunuz parolanın değerini görmek istiyorsanız, şunu kullanın:

   write-host $pw

3

Alternatif olarak, komut dosyasını yürütmenin bir parçası olarak girdi için komut dosyası parametresi olarak ekleyebilirsiniz

 param(
      [Parameter(Mandatory = $True,valueFromPipeline=$true)][String] $value1,
      [Parameter(Mandatory = $True,valueFromPipeline=$true)][String] $value2
      )
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.