4

My Powershell Script asks for credentials using the following syntax, and it works all right:

$credentials = (Get-Credential -Message "Enter Password")

But the problem is that the window that pops to enter the user name and password has very little space and it is uncomfortable for the user to enter large user names (large server name backslash large user names), and that windows does not allow resizing.

I would like to give my users the ability to enter usernames and passwords in another bigger window. Any Idea?

3
  • 4
    Probably you would have to design a custom form yourself. It's not that hard to do. Commented Jul 3, 2021 at 23:01
  • 3
    take a look at using Read-Host to get secure strings. that would let you work in the entire console ... [grin] Commented Jul 3, 2021 at 23:12
  • Take a look at the output of the cmdlet in PowerShell v7.xx! It does not open a graphical pop up. Commented Jul 4, 2021 at 0:57

1 Answer 1

4

I had something similar to this so I thought why not share it. Give it a try, it does not look as pretty as Get-Credential but you can resize it.

It will return a PSCredential object, same as Get-Credential.
The OK button only becomes Enabled if Username and Password have text.

example

using namespace System.Windows.Forms using namespace System.Drawing Add-Type -AssemblyName System.Windows.Forms, System.Drawing Add-Type -TypeDefinition ' public class DPIAware { [System.Runtime.InteropServices.DllImport("user32.dll")] public static extern bool SetProcessDPIAware(); } ' [System.Windows.Forms.Application]::EnableVisualStyles() [void] [DPIAware]::SetProcessDPIAware() function Get-CustomCredential { [Application]::EnableVisualStyles() #$DPI = [math]::round([dpi]::scaling(), 2) * 100 $bounds = [Screen]::PrimaryScreen.WorkingArea #$bounds.Width = $bounds.Width / 100 * $DPI #$bounds.Height = $bounds.Height / 100 * $DPI $mainForm = [Form]@{ StartPosition = 'CenterScreen' FormBorderStyle = 'Sizable' Text = 'Get Custom Credential' WindowState = 'Normal' KeyPreview = $true Font = [Font]::new('Calibri', 11, [FontStyle]::Regular) Icon = [Icon]::ExtractAssociatedIcon((Get-Process -Id $PID).Path) MinimumSize = [Size]::new($bounds.Width / 3.5, $bounds.Height / 4) MaximumSize = [Size]::new($bounds.Width, $bounds.Height / 4) MaximizeBox = $false } $mainForm.Size = $mainForm.MinimumSize $credentialMsg = [Label]@{ Location = [Point]::new(10, 10) Size = [Size]::new($mainForm.Width - 30, 30) Text = 'Supply values for the following parameters:' } $mainForm.Controls.Add($credentialMsg) $userLbl = [Label]@{ Location = [Point]::new(10, 60) Size = [Size]::new(120, 30) Text = 'Username' } $mainForm.Controls.Add($userLbl) $userTxtBox = [TextBox]@{ Location = [Point]::new($userLbl.Width + 10, 60) Size = [Size]::new($mainForm.Width - 160, 60) } $mainForm.Controls.Add($userTxtBox) $passwordLbl = [Label]@{ Location = [Point]::new(10, $userLbl.Location.Y + 40) Size = [Size]::new(120, 30) Text = 'Password' } $mainForm.Controls.Add($passwordLbl) $passwordTxtBox = [TextBox]@{ Location = [Point]::new($passwordLbl.Width + 10, $userTxtBox.Location.Y + 40) Size = [Size]::new($mainForm.Width - 160, 60) UseSystemPasswordChar = $true Anchor = 'top, left' } $mainForm.Controls.Add($passwordTxtBox) $cancelBtn = [Button]@{ Location = [Point]::new($mainForm.Width - 130, $passwordTxtBox.Location.Y + 50) Size = [Size]::new(100, 45) Text = '&Cancel' Anchor = 'right, bottom' } $cancelBtn.Add_Click({ $mainForm.DialogResult = 'Cancel' }) $mainForm.Controls.Add($cancelBtn) $okBtn = [Button]@{ Location = [Size]::new($cancelBtn.Location.X - $cancelBtn.Width - 5, $passwordTxtBox.Location.Y + 50) Size = $cancelBtn.Size Text = '&OK' Anchor = $cancelBtn.Anchor Enabled = $false } $okBtn.Add_Click({ $mainForm.DialogResult = 'OK' }) $mainForm.Controls.Add($okBtn) $okBtnEnableEvent = { if([string]::IsNullOrWhiteSpace($userTxtBox.Text) -or [string]::IsNullOrWhiteSpace($passwordTxtBox.Text)) { $okBtn.Enabled = $false return } $okBtn.Enabled = $True } $userTxtBox.Add_TextChanged($okBtnEnableEvent) $passwordTxtBox.Add_Textchanged($okBtnEnableEvent) $mainForm.Add_Resize({ $userTxtBox.Size = [Size]::new($this.Width - 160, 60) $passwordTxtBox.Size = [Size]::new($this.Width - 160, 60) }) $mainForm.AcceptButton = $okBtn $mainForm.CancelButton = $cancelBtn $mainForm.Add_Shown({ $this.Activate() }) if('OK' -eq $mainForm.ShowDialog()) { $passw = ConvertTo-SecureString $passwordTxtBox.Text.Trim() -AsPlainText -Force [System.Management.Automation.PSCredential]::new($userTxtBox.Text.Trim(), $passw) } $mainForm.Dispose() } $creds = Get-CustomCredential 

Props to mklement0 for his nice feedback and help with code improvements.

Sign up to request clarification or add additional context in comments.

9 Comments

Thank you very much @SantiagoSquerzon for your so complete code. It will help me not only with this problema but as a template to generate a lot more forms.. Thank You!!
Nicely done; a few tips: System.Drawing doesn't need to be loaded separately, and instead of [void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms') it's better to use Add-Type -Assembly System.Windows.Forms. If you also want it to work in PowerShell Core, replace [System.Drawing.Icon]::ExtractAssociatedIcon("$PSHOME\PowerShell.exe") with [System.Drawing.Icon]::ExtractAssociatedIcon((Get-Process -Id $PID).Path).
You can make do without OK/Cancel button events as follows: $okBtn.DialogResult = 'OK' and $cancelBtn.DialogResult = 'Cancel', combined with $mainForm.AcceptButton = $okBtn and $mainForm.CancelButton = $cancelBtn. This also implicitly enables ESC / Enter support.
Thanks for the DPI code; I've never had to deal with it, but it sounds like in v4.7+ .NET helper methods are now available - see High DPI support in Windows Forms. Yes, you need to create the button control first, and then assign them to the form's .AcceptButton and .CancelButton properties. I wouldn't create the credential object in an event handler, I'd check the .ShowDialog() result for 'OK' and create the object then (see next comment).
if ('OK' -eq $mainForm.ShowDialog()) { # Construct and output a PSCredential instance. [System.Management.Automation.PSCredential]::new( $userTxtBox.Text.Trim(), (ConvertTo-SecureString $passwordTxtBox.Text.Trim() -AsPlainText -Force) ) } $mainForm.Dispose()
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.