Use script variable inside textbox form


I’m trying to create a form which contains a message where I want to use some data imported from a CSV file.
The script will read the CSV rows and print a message that will contain data from CSV.

The issue is that the variables inside message textbox is used as text


Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName PresentationFramework

function show_menu {
	[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
	$form = New-Object System.Windows.Forms.Form
	$form.Text = 'menu'
	$form.Size = New-Object System.Drawing.Size(630,370)
	$form.StartPosition = 'CenterScreen'
	$form.FormBorderStyle = 'FixedSingle'
	#$form.Icon = [System.Drawing.Icon]::FromHandle((New-Object System.Drawing.Bitmap -Argument $stream).GetHIcon())
    $okButton = New-Object System.Windows.Forms.Button
	$okButton.Location = New-Object System.Drawing.Point(200,295)
	$okButton.Size = New-Object System.Drawing.Size(75,23)
	$okButton.Text = 'OK'
	$okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
		$form.Tag = $textBox_recipient.Text;
		$form.Tag = $textBox_message.Text;
	$form.AcceptButton = $okButton

	$cancelButton = New-Object System.Windows.Forms.Button
	$cancelButton.Location = New-Object System.Drawing.Point(355,295)
	$cancelButton.Size = New-Object System.Drawing.Size(75,23)
	$cancelButton.Text = 'Cancel'
	$cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
	$form.CancelButton = $cancelButton

	$textBox_recipient = New-Object System.Windows.Forms.TextBox
	$textBox_recipient.Location = New-Object System.Drawing.Point(210,70)
	$textBox_recipient.Size = New-Object System.Drawing.Size(245, 20)
	$textBox_recipient.ReadOnly = $true
	$textBox_recipient_select = New-Object System.Windows.Forms.Button
	$textBox_recipient_select.Location = New-Object System.Drawing.Point(460, 70)
	$textBox_recipient_select.Size = New-Object System.Drawing.Size(100, 20)
	$textBox_recipient_select.Text = "Select CSV file"
			$ofd = New-Object
			#$ofd.Filter = 'Supported file types (*.csv,*.xlsx)|*.csv,*.xlsx'
			$ofd.Filter = 'Supported file types (*.csv, *.xlsx)|*.csv; *.xlsx| All (*.*)|*.*'
			$script:recipient_filename = 'Not found'
			if ($ofd.ShowDialog() -eq 'Ok')	{
				$script:recipient_filename = $textbox_recipient.Text = $ofd.FileName
	#$textBox_recipient.Text = "C:\Users\Ady\Desktop\test.csv"

	$label_message = New-Object System.Windows.Forms.Label
	$label_message.Location = New-Object System.Drawing.Point(10,150)
	$label_message.Size = New-Object System.Drawing.Size(200,20)
	$label_message.BackColor = [System.Drawing.Color]::FromName("Transparent")
	$label_message.Font = [System.Drawing.Font]::new("Microsoft Sans Serif", 10, [System.Drawing.FontStyle]::Bold)
	$label_message.Text = 'Message:'

	$textBox_message = New-Object System.Windows.Forms.TextBox
    $textBox_message.Multiline = $True
    $textBox_message.Scrollbars = "Vertical"
	$textBox_message.Location = New-Object System.Drawing.Point(210,150)
	$textBox_message.Size = New-Object System.Drawing.Size(350, 135)
    $textBox_message.Text = "Insert your text here. HTML format supported"

    $form.Topmost = $true
    $form.Add_Shown({ $textBox_recipient.Select(),$textBox_message.Select() })
	$result = $form.ShowDialog()

    if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
        $script:filename = "$(($textBox_recipient).Text)"

        $recipients = Import-csv -Path "$filename"
	    $total_recipient_nr = get-content "$filename" | select-string "@" | measure-object -line
        $recipient_nr = 0
	    foreach ($recipient in $recipients)	{
		    if (++$recipient_nr % 31 -eq 0)
			    Start-Sleep -Seconds 30
			    echo "waiting 1 minute"
		    $script:user_email = $
		    $script:user_firstname = $recipient.firstname
		    $script:user_lastname = $recipient.lastname
		    $script:user_code = $recipient.code
		    $script:message = $textBox_message.Text
				    Write-Host $message


For example, the following csv:

firstname, lastname, email, code ---- header of csv file
firstname1, lastname1, email1@domain, code1
firstname2, lastname2, email2@domain, code2

What I want to do is to use variables like $user_email, $user_code inside “$textBox_message.Text” field of the form and for each line of the CSV file, the message to use the value of those variables. (recipient is a row from the csv file that contains different values at each foreach run)

$script:user_firstname = $recipient.firstname
$script:user_code = $recipient.code
$script:message = $textBox_message.Text

I run the script, the form appears and I replace the default text “Insert your text here. HTML format supported” of $textBox_message.Text with the following: Hi $user_firstname. This is your code: $user_code

The result (value of $message var) by executing line 96, should be: Hi firstname1. This is your code: code1 - at first run of foreach loop and Hi firstname2. This is your code: code2 - at second run of foreach loop

Instead, the result is: Hi $user_firstname. This is your code: $user_code — plain text (the value) of $message

The problem is that the text in your box is a String literal so the ‘variables’ (not really variables in a String literal) won’t be substitued for their values.

You could, if you really, really, really, really, really, really, trust what’s going to be entered that box use Invoke-Expression.

Invoke-Expression "Write-Host $message"

But I wouldn’t.

1 Like

thanks Matt.
someone gave the a good solution: to use {0}, {1} … inside the textbox and make the message variable something like this:
$script:message = $script:message -f $recipient.firstname,$recipient.code

and it’s working.
I will add some keywords like user_firstname, to be used inside the textbox and replace so will be easy for the person that will write the final message and will do a replace
$script:message = $script:message -replace 'user_firstname', '{0}' -replace 'user_fcode','{1}'