Add password confirmation in Get-Credential (#12782)

* Add parameter -ReEnterPassword to prompt user to re-enter the password for confirmation

* Add new public overload function PromptForCredential
This commit is contained in:
Shri Ram K S
2020-07-22 19:13:42 +05:00
committed by GitHub
parent 9c396aa0ea
commit a6bd47f031
11 changed files with 329 additions and 79 deletions
@@ -47,7 +47,7 @@ namespace Microsoft.PowerShell
}
/// <summary>
/// PromptForChoice.
/// Prompt for choice.
/// </summary>
/// <param name="caption"></param>
/// <param name="message"></param>
@@ -60,7 +60,7 @@ namespace Microsoft.PowerShell
}
/// <summary>
/// PromptForCredential.
/// Prompt for credential.
/// </summary>
/// <param name="caption"></param>
/// <param name="message"></param>
@@ -73,7 +73,7 @@ namespace Microsoft.PowerShell
}
/// <summary>
/// PromptForCredential.
/// Prompt for credential.
/// </summary>
/// <param name="caption"></param>
/// <param name="message"></param>
@@ -88,7 +88,23 @@ namespace Microsoft.PowerShell
}
/// <summary>
/// ReadLine.
/// Prompt for credential.
/// </summary>
/// <param name="caption"></param>
/// <param name="message"></param>
/// <param name="userName"></param>
/// <param name="confirmPassword"></param>
/// <param name="targetName"></param>
/// <param name="allowedCredentialTypes"></param>
/// <param name="options"></param>
/// <returns></returns>
public override PSCredential PromptForCredential(string caption, string message, string userName, bool confirmPassword, string targetName, PSCredentialTypes allowedCredentialTypes, PSCredentialUIOptions options)
{
throw new PSNotImplementedException();
}
/// <summary>
/// Read line.
/// </summary>
/// <returns></returns>
public override string ReadLine()
@@ -303,10 +303,10 @@ namespace Microsoft.PowerShell
PSCredential credential = null;
credential =
PromptForCredential(
null, // caption already written
null, // message already written
null,
string.Empty);
caption: null, // caption already written
message: null, // message already written
userName: null,
targetName: string.Empty);
convertedObj = credential;
cancelInput = (convertedObj == null);
if ((credential != null) && (credential.Password.Length == 0) && listInput)
@@ -3,10 +3,11 @@
using System;
using System.Globalization;
using System.Linq;
using System.Management.Automation;
using System.Management.Automation.Internal;
using System.Runtime.InteropServices;
using System.Security;
using Microsoft.Win32;
namespace Microsoft.PowerShell
@@ -24,21 +25,17 @@ namespace Microsoft.PowerShell
/// this function will be modified to prompt using secure-path
/// if so configured.
/// </summary>
/// <param name="userName">Name of the user whose creds are to be prompted for. If set to null or empty string, the function will prompt for user name first.</param>
/// <param name="targetName">Name of the target for which creds are being collected.</param>
/// <param name="message">Message to be displayed.</param>
/// <param name="caption">Caption for the message.</param>
/// <param name="message">Message to be displayed.</param>
/// <param name="userName">Name of the user whose credentials are to be prompted for. If set to null or empty string, the function will prompt for user name first.</param>
/// <param name="targetName">Name of the target for which credentials are being collected.</param>
/// <returns>PSCredential object.</returns>
public override PSCredential PromptForCredential(
string caption,
string message,
string userName,
string targetName)
public override PSCredential PromptForCredential(string caption, string message, string userName, string targetName)
{
return PromptForCredential(caption,
message,
userName,
confirmPassword: false,
targetName,
PSCredentialTypes.Default,
PSCredentialUIOptions.Default);
@@ -47,31 +44,62 @@ namespace Microsoft.PowerShell
/// <summary>
/// Prompt for credentials.
/// </summary>
/// <param name="userName">Name of the user whose creds are to be prompted for. If set to null or empty string, the function will prompt for user name first.</param>
/// <param name="targetName">Name of the target for which creds are being collected.</param>
/// <param name="message">Message to be displayed.</param>
/// <param name="caption">Caption for the message.</param>
/// <param name="allowedCredentialTypes">What type of creds can be supplied by the user.</param>
/// <param name="options">Options that control the cred gathering UI behavior.</param>
/// <param name="message">Message to be displayed.</param>
/// <param name="userName">Name of the user whose credentials are to be prompted for. If set to null or empty string, the function will prompt for user name first.</param>
/// <param name="targetName">Name of the target for which credentials are being collected.</param>
/// <param name="allowedCredentialTypes">What type of credentials can be supplied by the user.</param>
/// <param name="options">Options that control the credential gathering UI behavior.</param>
/// <returns>PSCredential object, or null if input was cancelled (or if reading from stdin and stdin at EOF).</returns>
public override PSCredential PromptForCredential(
string caption,
string message,
string userName,
string targetName,
PSCredentialTypes allowedCredentialTypes,
PSCredentialUIOptions options)
{
return PromptForCredential(
caption,
message,
userName,
confirmPassword: false,
targetName,
allowedCredentialTypes,
options);
}
/// <summary>
/// Prompt for credentials.
/// </summary>
/// <param name="caption">Caption for the message.</param>
/// <param name="message">Message to be displayed.</param>
/// <param name="userName">Name of the user whose credentials are to be prompted for. If set to null or empty string, the function will prompt for user name first.</param>
/// <param name="confirmPassword">Prompts user to re-enter the password for confirmation.</param>
/// <param name="targetName">Name of the target for which credentials are being collected.</param>
/// <param name="allowedCredentialTypes">What type of credentials can be supplied by the user.</param>
/// <param name="options">Options that control the credential gathering UI behavior.</param>
/// <returns>PSCredential object, or null if input was cancelled (or if reading from stdin and stdin at EOF).</returns>
public override PSCredential PromptForCredential(
string caption,
string message,
string userName,
bool confirmPassword,
string targetName,
PSCredentialTypes allowedCredentialTypes,
PSCredentialUIOptions options)
{
PSCredential cred = null;
SecureString password = null;
SecureString reenterPassword = null;
string userPrompt = null;
string passwordPrompt = null;
string confirmPasswordPrompt = null;
string passwordMismatch = null;
if (!string.IsNullOrEmpty(caption))
{
// Should be a skin lookup
WriteLineToConsole();
WriteLineToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(caption));
}
@@ -85,9 +113,7 @@ namespace Microsoft.PowerShell
{
userPrompt = ConsoleHostUserInterfaceSecurityResources.PromptForCredential_User;
//
// need to prompt for user name first
//
do
{
WriteToConsole(userPrompt, true);
@@ -100,25 +126,95 @@ namespace Microsoft.PowerShell
while (userName.Length == 0);
}
passwordPrompt = StringUtil.Format(ConsoleHostUserInterfaceSecurityResources.PromptForCredential_Password, userName
);
passwordPrompt = StringUtil.Format(ConsoleHostUserInterfaceSecurityResources.PromptForCredential_Password, userName);
//
// now, prompt for the password
//
WriteToConsole(passwordPrompt, true);
password = ReadLineAsSecureString();
if (password == null)
do
{
return null;
WriteToConsole(passwordPrompt, true);
password = ReadLineAsSecureString();
if (password == null)
{
return null;
}
}
while (password.Length == 0);
if (confirmPassword)
{
confirmPasswordPrompt = StringUtil.Format(ConsoleHostUserInterfaceSecurityResources.PromptForCredential_ReenterPassword, userName);
passwordMismatch = StringUtil.Format(ConsoleHostUserInterfaceSecurityResources.PromptForCredential_PasswordMismatch);
// now, prompt to re-enter the password.
WriteToConsole(confirmPasswordPrompt, true);
reenterPassword = ReadLineAsSecureString();
if (reenterPassword == null)
{
return null;
}
if (!SecureStringEquals(password, reenterPassword))
{
WriteToConsole(ConsoleColor.Red, ConsoleColor.Black, passwordMismatch, false);
return null;
}
}
WriteLineToConsole();
cred = new PSCredential(userName, password);
return cred;
}
private static bool SecureStringEquals(SecureString password, SecureString confirmPassword)
{
if (password.Length != confirmPassword.Length)
{
return false;
}
IntPtr pwd_ptr = IntPtr.Zero;
IntPtr confirmPwd_ptr = IntPtr.Zero;
try
{
pwd_ptr = Marshal.SecureStringToBSTR(password);
if (pwd_ptr == IntPtr.Zero)
{
return false;
}
confirmPwd_ptr = Marshal.SecureStringToBSTR(confirmPassword);
if (confirmPwd_ptr == IntPtr.Zero)
{
return false;
}
int pwdLength = Marshal.ReadInt32(pwd_ptr, -4);
int equal = 0;
for (int i = 0; i < pwdLength; i++)
{
byte c1 = Marshal.ReadByte(pwd_ptr, i);
byte c2 = Marshal.ReadByte(confirmPwd_ptr, i);
equal = c1 ^ c2;
if (equal != 0)
{
return false;
}
}
return true;
}
finally
{
if (pwd_ptr != IntPtr.Zero)
{
Marshal.ZeroFreeBSTR(pwd_ptr);
}
if (confirmPwd_ptr != IntPtr.Zero)
{
Marshal.ZeroFreeBSTR(confirmPwd_ptr);
}
}
}
}
}
@@ -123,4 +123,10 @@
<data name="PromptForCredential_Password" xml:space="preserve">
<value>Password for user {0}: </value>
</data>
<data name="PromptForCredential_ReenterPassword" xml:space="preserve">
<value>Re-enter password for user {0}:</value>
</data>
<data name="PromptForCredential_PasswordMismatch" xml:space="preserve">
<value>Passwords do not match.</value>
</data>
</root>
@@ -79,6 +79,12 @@ namespace Microsoft.PowerShell.Commands
private string _title = UtilsStrings.PromptForCredential_DefaultCaption;
/// <summary>
/// Gets or sets the confirm password prompt.
/// </summary>
[Parameter(ParameterSetName = messageSet)]
public SwitchParameter ConfirmPassword { get; set; }
/// <summary>
/// Initializes a new instance of the GetCredentialCommand
/// class.
@@ -100,7 +106,14 @@ namespace Microsoft.PowerShell.Commands
try
{
Credential = this.Host.UI.PromptForCredential(_title, _message, _userName, string.Empty);
Credential = this.Host.UI.PromptForCredential(
_title,
_message,
_userName,
ConfirmPassword,
string.Empty,
PSCredentialTypes.Default,
PSCredentialUIOptions.Default);
}
catch (ArgumentException exception)
{
@@ -56,6 +56,7 @@ namespace System.Management.Automation.Host
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.ReadLineAsSecureString"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, string)"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, string, System.Management.Automation.PSCredentialTypes, System.Management.Automation.PSCredentialUIOptions)"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, bool, string, System.Management.Automation.PSCredentialTypes, System.Management.Automation.PSCredentialUIOptions)"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForChoice"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.Prompt"/>
public abstract string ReadLine();
@@ -94,10 +95,12 @@ namespace System.Management.Automation.Host
/// Note that credentials (a user name and password) should be gathered with
/// <see cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, string)"/>
/// <see cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, string, System.Management.Automation.PSCredentialTypes, System.Management.Automation.PSCredentialUIOptions)"/>
/// <see cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, bool, string, System.Management.Automation.PSCredentialTypes, System.Management.Automation.PSCredentialUIOptions)"/>
/// </remarks>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.ReadLine"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, string)"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, string, System.Management.Automation.PSCredentialTypes, System.Management.Automation.PSCredentialUIOptions)"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, bool, string, System.Management.Automation.PSCredentialTypes, System.Management.Automation.PSCredentialUIOptions)"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForChoice"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.Prompt"/>
public abstract SecureString ReadLineAsSecureString();
@@ -825,8 +828,9 @@ namespace System.Management.Automation.Host
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.ReadLine"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.ReadLineAsSecureString"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForChoice"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, string)"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string,string)"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, string, System.Management.Automation.PSCredentialTypes, System.Management.Automation.PSCredentialUIOptions)"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, bool, string, System.Management.Automation.PSCredentialTypes, System.Management.Automation.PSCredentialUIOptions)"/>
public abstract Dictionary<string, PSObject> Prompt(string caption, string message, Collection<FieldDescription> descriptions);
/// <summary>
@@ -859,9 +863,12 @@ namespace System.Management.Automation.Host
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.Prompt"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForChoice"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, string, System.Management.Automation.PSCredentialTypes, System.Management.Automation.PSCredentialUIOptions)"/>
public abstract PSCredential PromptForCredential(string caption, string message,
string userName, string targetName
);
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, bool, string, System.Management.Automation.PSCredentialTypes, System.Management.Automation.PSCredentialUIOptions)"/>
public abstract PSCredential PromptForCredential(
string caption,
string message,
string userName,
string targetName);
/// <summary>
/// Prompt for credential.
@@ -883,7 +890,7 @@ namespace System.Management.Automation.Host
/// Types of credential can be supplied by the user.
/// </param>
/// <param name="options">
/// Options that control the credential gathering UI behavior
/// Options that control the credential gathering UI behavior.
/// </param>
/// <returns>
/// User input credential.
@@ -893,10 +900,57 @@ namespace System.Management.Automation.Host
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.Prompt"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForChoice"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, string)"/>
public abstract PSCredential PromptForCredential(string caption, string message,
string userName, string targetName, PSCredentialTypes allowedCredentialTypes,
PSCredentialUIOptions options
);
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, bool, string, System.Management.Automation.PSCredentialTypes, System.Management.Automation.PSCredentialUIOptions)"/>
public abstract PSCredential PromptForCredential(
string caption,
string message,
string userName,
string targetName,
PSCredentialTypes allowedCredentialTypes,
PSCredentialUIOptions options);
/// <summary>
/// Prompt for credential.
/// </summary>
/// <param name="caption">
/// Caption for the message.
/// </param>
/// <param name="message">
/// Text description for the credential to be prompt.
/// </param>
/// <param name="userName">
/// Name of the user whose credential is to be prompted for. If set to null or empty
/// string, the function will prompt for user name first.
/// </param>
/// <param name="confirmPassword">
/// Prompts user to re-enter the password for confirmation.
/// </param>
/// <param name="targetName">
/// Name of the target for which the credential is being collected.
/// </param>
/// <param name="allowedCredentialTypes">
/// Types of credential can be supplied by the user.
/// </param>
/// <param name="options">
/// Options that control the credential gathering UI behavior.
/// </param>
/// <returns>
/// User input credential.
/// </returns>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.ReadLine"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.ReadLineAsSecureString"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.Prompt"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForChoice"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, string)"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, string, System.Management.Automation.PSCredentialTypes, System.Management.Automation.PSCredentialUIOptions)"/>
public abstract PSCredential PromptForCredential(
string caption,
string message,
string userName,
bool confirmPassword,
string targetName,
PSCredentialTypes allowedCredentialTypes,
PSCredentialUIOptions options);
/// <summary>
/// Presents a dialog allowing the user to choose an option from a set of options.
@@ -922,6 +976,7 @@ namespace System.Management.Automation.Host
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.Prompt"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, string)"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, string, System.Management.Automation.PSCredentialTypes, System.Management.Automation.PSCredentialUIOptions)"/>
/// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForCredential(string, string, string, bool, string, System.Management.Automation.PSCredentialTypes, System.Management.Automation.PSCredentialUIOptions)"/>
public abstract int PromptForChoice(string caption, string message, Collection<ChoiceDescription> choices, int defaultChoice);
#endregion Dialog-oriented interaction
@@ -14,38 +14,52 @@ namespace System.Management.Automation.Internal.Host
/// <summary>
/// See base class.
/// </summary>
public override
PSCredential
PromptForCredential
(
string caption,
string message,
string userName,
string targetName
)
public override PSCredential PromptForCredential(string caption, string message, string userName, string targetName)
{
return PromptForCredential(caption, message, userName,
targetName,
PSCredentialTypes.Default,
PSCredentialUIOptions.Default);
return PromptForCredential(
caption,
message,
userName,
confirmPassword: false,
targetName,
PSCredentialTypes.Default,
PSCredentialUIOptions.Default);
}
/// <summary>
/// See base class.
/// </summary>
public override
PSCredential
PromptForCredential
(
public override PSCredential PromptForCredential(
string caption,
string message,
string userName,
string targetName,
PSCredentialTypes allowedCredentialTypes,
PSCredentialUIOptions options
)
PSCredentialUIOptions options)
{
return PromptForCredential(
caption,
message,
userName,
confirmPassword: false,
targetName,
allowedCredentialTypes,
options);
}
/// <summary>
/// See base class.
/// </summary>
public override
PSCredential
PromptForCredential(
string caption,
string message,
string userName,
bool confirmPassword,
string targetName,
PSCredentialTypes allowedCredentialTypes,
PSCredentialUIOptions options)
{
if (_externalUI == null)
{
@@ -55,7 +69,7 @@ namespace System.Management.Automation.Internal.Host
PSCredential result = null;
try
{
result = _externalUI.PromptForCredential(caption, message, userName, targetName, allowedCredentialTypes, options);
result = _externalUI.PromptForCredential(caption, message, userName, confirmPassword, targetName, allowedCredentialTypes, options);
}
catch (PipelineStoppedException)
{
@@ -233,5 +233,15 @@ namespace System.Management.Automation.Remoting
return _serverMethodExecutor.ExecuteMethod<PSCredential>(RemoteHostMethodId.PromptForCredential2,
new object[] { caption, message, userName, targetName, allowedCredentialTypes, options });
}
/// <summary>
/// Prompt for credential.
/// </summary>
public override PSCredential PromptForCredential(string caption, string message, string userName, bool confirmPassword, string targetName, PSCredentialTypes allowedCredentialTypes, PSCredentialUIOptions options)
{
return _serverMethodExecutor.ExecuteMethod<PSCredential>(
RemoteHostMethodId.PromptForCredential2,
new object[] { caption, message, userName, confirmPassword, targetName, allowedCredentialTypes, options });
}
}
}
@@ -32,6 +32,7 @@ namespace System.Management.Automation
PSCredential cred = null;
string userName = null;
bool shouldPrompt = false;
bool confirmPassword = false;
if ((engineIntrinsics == null) ||
(engineIntrinsics.Host == null) ||
@@ -74,10 +75,13 @@ namespace System.Management.Automation
prompt = CredentialAttributeStrings.CredentialAttribute_Prompt;
cred = engineIntrinsics.Host.UI.PromptForCredential(
caption,
prompt,
userName,
string.Empty);
caption,
prompt,
userName,
confirmPassword,
string.Empty,
PSCredentialTypes.Default,
PSCredentialUIOptions.Default);
}
return cred;
@@ -102,4 +102,21 @@ Describe "Get-Credential Test" -Tag "CI" {
$netcred.UserName | Should -Be "John"
$netcred.Password | Should -Be "CredTest"
}
It "Get-credential Joe -ConfirmPassword set to false"{
$cred = $ps.AddScript("Get-Credential Joe -ConfirmPassword:`$false").Invoke() | Select-Object -First 1
$cred | Should -BeOfType System.Management.Automation.PSCredential
$netcred = $cred.GetNetworkCredential()
$netcred.UserName | Should -Be "Joe"
$netcred.Password | Should -Be "This is a test"
$th.ui.Streams.Prompt[-1] | Should -Match "Credential:[^:]+:[^:]+"
}
It "Get-Credential with only -ConfirmPassword" {
$cred = $ps.AddScript("Get-Credential -ConfirmPassword").Invoke() | Select-Object -First 1
$cred | Should -BeOfType System.Management.Automation.PSCredential
$netcred = $cred.GetNetworkCredential()
$netcred.UserName | Should -Be "John"
$netcred.Password | Should -Be "This is a test"
$th.ui.Streams.Prompt[-2] | Should -Match "Credential:[^:]+:[^:]+"
$th.ui.Streams.Prompt[-1] | Should -Match "Credential@[^@]+@[^@]+"
}
}
@@ -10,6 +10,7 @@ using System.Globalization;
using System.Collections.ObjectModel;
using System.Security;
using System.Collections;
using System.Runtime.InteropServices;
namespace TestHost
{
@@ -145,18 +146,36 @@ namespace TestHost
public override PSCredential PromptForCredential(string caption, string message, string userName, string targetName)
{
Streams.Prompt.Add("Credential:" + caption + ":" + message);
SecureString ss = ReadLineAsSecureString();
string userNameToUse = string.IsNullOrEmpty(userName) ? UserNameForCredential : userName;
return new PSCredential(userNameToUse, ss);
return PromptForCredential(caption,
message,
userName,
confirmPassword: false,
targetName,
PSCredentialTypes.Default,
PSCredentialUIOptions.Default);
}
public override PSCredential PromptForCredential(string caption, string message, string userName, string targetName, PSCredentialTypes allowedCredentialTypes, PSCredentialUIOptions options)
{
return PromptForCredential(caption,
message,
userName,
confirmPassword: false,
targetName,
allowedCredentialTypes,
options);
}
public override PSCredential PromptForCredential(string caption, string message, string userName, bool confirmPassword, string targetName, PSCredentialTypes allowedCredentialTypes, PSCredentialUIOptions options)
{
Streams.Prompt.Add("Credential:" + caption + ":" + message);
SecureString ss = ReadLineAsSecureString();
SecureString password = ReadLineAsSecureString();
if(confirmPassword)
{
Streams.Prompt.Add("Credential@" + caption + "@" + message);
}
string userNameToUse = string.IsNullOrEmpty(userName) ? UserNameForCredential : userName;
return new PSCredential(userNameToUse, ss);
return new PSCredential(userNameToUse, password);
}
public override string ReadLine()