Show-CredentialDialog.ps1

function Show-CredentialDialog
{
  <#
      .SYNOPSIS
      Displays a TUI (terminal user interface) dialog to enter credentials. MUST RUN IN A CONSOLE or VSCode! Does not work in ISE.
      .DESCRIPTION
      Demonstrates using TUI in both WPS and PS7 by implementing a TUI credential dialog
      .EXAMPLE
      Show-CredentialDialog
      shows the credential dialog and returns a user credential
      .EXAMPLE
      Show-CredentialDialog -Title 'Log in to server abc'
      uses a custom dialog title
      .EXAMPLE
      Show-CredentialDialog -Title 'Log in to server abc' -AllowToggle
      uses a custom dialog title and adds button to toggle to clear text password input
  #>

  [CmdletBinding()]
  param
  (
    [Parameter()]
    [string]
    $Title = 'Enter your credentials',
      
    [Parameter()]
    [string]
    $UserName = "$env:userdomain\$env:username",
      
    [Switch]
    $AllowToggle
  )
    
  [Terminal.Gui.Application]::Init()
    
  $canceled = $true
    
  $window = [Terminal.Gui.Window] @{
    Title  = $Title
    Width  = 45
    Height = 9
    X      = [Terminal.Gui.Pos]::Center()
    Y      = [Terminal.Gui.Pos]::Center()
  }
  [Terminal.Gui.Application]::Top.Add($Window)
    
  $labelUserName = [Terminal.Gui.Label] @{
    Text = 'UserName'
    X    = 1
    Y    = 1
  }
  $window.Add($labelUserName)
    
  $txtUserName = [Terminal.Gui.TextField]@{
    Width    = 30
    X        = 10
    Y        = 1
    TabIndex = 1
  }
  $window.Add($txtUserName)
    
  $labelPassword = [Terminal.Gui.Label] @{
    Text = 'Password'
    X    = 1
    Y    = 3
  }
  $window.Add($labelPassword)
    
  $txtPassword = [Terminal.Gui.TextField]@{
    Width    = 30
    X        = 10
    Y        = 3
    TabIndex = 0
    Secret   = $True
  }
  $window.Add($txtPassword)
    
  $btnLogin = [Terminal.Gui.Button]@{
    Text     = '_Login'
    X        = 7
    Y        = 5
    TabIndex = 2
  }
  $window.Add($btnLogin)
    
  $btnCancel = [Terminal.Gui.Button]@{
    Text     = '_Cancel'
    X        = $btnLogin.X + 9
    Y        = 5
    TabIndex = 3
  }
  $window.Add($btnCancel)
    
  $btnShow = [Terminal.Gui.Button]@{
    Text     = '_ShowPwd'
    X        = $btnCancel.X + 12
    Y        = 5
    TabIndex = 4
  }
    
  # show this button only on request
  if ($AllowToggle)
  {
    $window.Add($btnShow)
  }  
    
  #############ADD EVENTS TO UI ELEMENTS#############
    
  # handle custom buttons:
  $btnLogin.add_Clicked({
      $script:canceled = $false
      [Terminal.Gui.Application]::RequestStop()
  })
    
  $btnCancel.add_Clicked({
      [Terminal.Gui.Application]::RequestStop()
  })
    
  $btnShow.add_Clicked({
      if ($txtPassword.Secret) {
        $txtPassword.Secret = $False
        $btnShow.Text = '_HidePwd'
      }
      else {
        $txtPassword.Secret = $True
        $btnShow.Text = '_ShowPwd'
      }
  })
    
  #############ADD EVENTS TO WINDOW ITSELF#############
    
  # handle closing window by pressing ESC (easier way)
  [Terminal.Gui.Application]::QuitKey = 27
    
  # add ability to close window via ENTER:
  [Terminal.Gui.Application]::Top.add_KeyPress({
      param($e)
      if ($e.KeyEvent.Key -eq [Terminal.Gui.Key]::Enter) { 
        $script:canceled = $false
        [Terminal.Gui.Application]::RequestStop()
      }
  })
    
  #############CONFIGURE UI#############
    
  # set default user name:
  $txtUserName.Text = $UserName
    
  # set input focus to password box:
  $txtPassword.SetFocus()
    
  #############SHOW UI##################
    
  [Terminal.Gui.Application]::Run()
    
  # clean up:
  [Terminal.Gui.Application]::Shutdown() 
    
  ###############CREATE RETURN VALUE######################
  # if user has cancelled the dialog, throw an exception:
  if ($script:canceled)
  {
    throw 'User canceled login'
  }
  # else take the user input, create a credential, and return it:
  else
  {
    Try {
      $SecureString = ConvertTo-SecureString -String $txtPassword.Text.ToString() -AsPlainText -Force
        
      $credential = [PSCredential]::New($txtUserName.Text.ToString(), $SecureString)
      return $credential
    }
    Catch {
      Throw 'Failed to create a credential. Did you specify a username AND password?'
    }
  }
}