Reputation: 15
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
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] ...
)
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:
[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
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