CDav117
CDav117

Reputation: 15

Powershell - Allow and Parse Multiple Line Paste

I'm working on a PS script that will allow a user to paste a bunch of emails on the command line, then the script will parse each one out and run another function on them.

I've looked around for a solution as well as played around in VS Code, but nothing seems to work how I would like it.

The format of the pasted emails by the user will be as follows, copied from a txt file:

[email protected]
[email protected]
[email protected]

Each email separated by a newline.

Using Read-Host, if I paste multiple lines, it just takes the first line, runs whatever function I have on it, then errors out on the next lines.

Essentially I'd like input/output to look like this:

Paste emails: 
[email protected]
[email protected]
[email protected]

Operation was performed on email [email protected]
Operation was performed on email [email protected]
Operation was performed on email [email protected]

Any help would be much appreciated. Thank you!

Upvotes: 1

Views: 1966

Answers (2)

mklement0
mklement0

Reputation: 439912

Read-Host inherently supports only one line of input, so you have the following options:

  • Make your users copy and paste a single-line list of space-separated email addresses (e.g., [email protected] [email protected] ...)

    • You can then split the Read-Host return value into an array of addresses with
      $addresses = -split (Read-Host ...)
  • Use a GUI-based prompting mechanism that accepts multi-line input - see sample code below.

Alternatively:

  • Make the user specify the path to the file containing the email addresses, which you can then read with Get-Content.

  • If you don't mind having to press Enter twice after typing only one address or pasting one or multiple ones without a trailing newline, consider js2010's simple loop-based alternative.


Using WinForms to create a multi-line input box:

  • Note: For a single-line input box, you can use [Microsoft.VisualBasic.Interaction]::InputBox() - see this answer.

The following creates a sample dialog of fixed size with a multi-line textbox and OK and Cancel buttons (PSv5+, but could be adapted to earlier versions):

# Declare implied namespaces, so that types from
# the loaded assemblies can be referred to by mere name
# (e.g., 'Form' instead of 'System.Windows.Forms')
# Requires PSv5+
using namespace System.Windows.Forms
using namespace System.Drawing

# Load the System.Windows.Forms assembly
# which implicitly loads System.Drawing too.
Add-Type -AssemblyName System.Windows.Forms

# Create the form.
($form = [Form] @{
  Text = "Enter Email Addresses"
  Size = [Size]::new(300,300)
  ControlBox = $false
  FormBorderStyle = 'FixedDialog'
  StartPosition = 'CenterScreen'
}).Controls.AddRange(@(

  ($textBox = [TextBox] @{
    MultiLine = $true
    Location = [Point]::new(10, 10)
    Size = [Size]::new(260, 200)
  })

  ($okButton = [Button] @{
    Location = [Point]::new(100, 220)
    Size = [Size]::new(80,30)
    Text = '&OK'
    DialogResult = 'OK'
    Enabled = $false
  })

  ($cancelButton = [Button] @{
    Location = [Point]::new(190, 220)
    Size = [Size]::new(80,30)
    Text = 'Cancel'
  })

))

# Make Esc click the Cancel button.
# Note: We do NOT use $form.AcceptButton = $okButton,
#       because that would prevent using Enter to enter multiple lines.
$form.CancelButton = $cancelButton

# Make sure that OK can only be clicked if the textbox is non-blank.
$textBox.add_TextChanged({
  $okButton.Enabled = $textBox.Text.Trim().Length -gt 0
})

# Display the dialog modally and evaluate the result.
if ($form.ShowDialog() -ne 'OK') {
  Throw 'Canceled by user request.'
}

# Parse the multi-line string into an array of individual addresses.
$addressesEntered = -split $textBox.Text

# Diagnostic output.
Write-Verbose -Verbose 'The following addresses were entered:'
$addressesEntered

Upvotes: 1

js2010
js2010

Reputation: 27566

Like this? Keep appending to an array until a blank line is entered.

$list = @()
while ($a = read-host) {
  $list += $a}
a
b
c

$list
a
b
c

Upvotes: 2

Related Questions