trim() not working for license key tool - powershell

Personal skill level with PS: Low (Student)
Goal:
Trying to find the Windows 10 license key, display it in a window as well as automatically copy it to the clipboard.
Issue:
My output always results in spaces at the beginning and end of the string. I have tried trim(), trimstart(), etc. Nothing has worked thus far. I would not mind so much by the spaces are then saved with the key to the clipboard - making the functionality kinda useless, or at least tedious.
I laid out some notations in the code to identify the problem.
The code (result is below as well):
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
[void][reflection.assembly]::Load("System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
#Obtain Windows 10 Key
$License = wmic path SoftwareLicensingService get OA3xOriginalProductKey
# FAULT - Used to trim key
$Result = $License.Trim("OA3xOriginalProductKey")
#Used to isolate the spaces in the result. Attempt to see if the spaces occur after the trim, or during the trim.
#The spaces are within the "|" rather than outside of the "|" - meaning that the Trim() is not working properly.
#PLEASE HELP!
$Result = "|" + $Result.Trim() + "|"
#Used to copy key to clipboard
$Result | clip.exe
$form = New-Object System.Windows.Forms.Form
$form.Text = "KeySniffer 1.0"
$form.Size = New-Object System.Drawing.Size(280,140)
$form.StartPosition = "CenterScreen"
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(30,70)
$OKButton.Size = New-Object System.Drawing.Size(60,23)
$OKButton.Text = "OK"
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $OKButton
$form.Controls.Add($OKButton)
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = "Key has been copied to clipboard"
$form.Controls.Add($label)
$textBox = New-Object System.Windows.Forms.TextBox
#Put a trim here as a desperate swing in the dark
#The "-" indicate that the spaces occur within the "$Result"
$textBox.Text = "-" + $Result.Trim() + "-"
$textBox.Location = New-Object System.Drawing.Point(10,40)
$textBox.Size = New-Object System.Drawing.Size(200,20)
$form.Controls.Add($textBox)
$form.Topmost = $True
$form.Add_Shown({$textBox.Select()})
$result = $form.ShowDialog()
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
$x = $textBox.Text
$x
}
The result:
-| ****-*****-*****-*****-***** |-

Seems you already took out text you don't want with this
$Result = $License.Trim("OA3xOriginalProductKey")
Now let's try only keep content we want on top of it by design a pattern, that only keeps numbers, upper case chars, and "-". Also, we need to remove extra lines.
$pattern = '[^0-9A-Z-]'
$Result = ($Result -replace $pattern, '').trim() -ne ""
Now you can check out the result, everything unwanted should be gone
$Result = "|" + $Result + "|"
$Result

Related

PowerShell - Using input from TextBox wont work?

I'm trying to make a GUI for an easy tool I need to check if a specific certificate is included in the file and Output the current and next line. This already works.
If I set the variables $INT1 and $Serial1 manually within the code it also works as intended.
e.g. $INT1=31 and $Serial1="5AA61E07726DAC13".
I always get an Error that the variable is empty when inputing the same values into the GUI and clicking OK. What am I doing wrong?
The code:
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$objForm = New-Object System.Windows.Forms.Form
$objForm.StartPosition = "CenterScreen"
$objForm.Size = New-Object System.Drawing.Size(400,250)
$objForm.Topmost = $True
#Label+Textbox first question
$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,30)
$objLabel.Size = New-Object System.Drawing.Size(800,20)
$objLabel.Text = "INT of certificate"
$objForm.Controls.Add($objLabel)
$objTextBox = New-Object System.Windows.Forms.TextBox
$objTextBox.Location = New-Object System.Drawing.Size(10,50)
$objTextBox.Size = New-Object System.Drawing.Size(200,20)
$objForm.Controls.Add($objTextBox)
#Label+Textbox second question
$objLabel2 = New-Object System.Windows.Forms.Label
$objLabel2.Location = New-Object System.Drawing.Size(10,130)
$objLabel2.Size = New-Object System.Drawing.Size(800,20)
$objLabel2.Text = "Serialnumber of the certificate"
$objForm.Controls.Add($objLabel2)
$objTextBox2 = New-Object System.Windows.Forms.TextBox
$objTextBox2.Location = New-Object System.Drawing.Size(10,150)
$objTextBox2.Size = New-Object System.Drawing.Size(200,20)
$objForm.Controls.Add($objTextBox2)
$INT1 = $objTextBox.Text;
$Serial1 = $objTextBox2.Text;
#OK Button
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(100,175)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Name = "OK"
#$OKButton.DialogResult = "OK"
$OKButton.Add_Click({Invoke-WebRequest -Uri http://CENSORED.crl -OutFile crl.crl;
$test=certutil.exe -dump crl.crl |Out-String -stream | Select-String -pattern "$Serial1" -Context 0,1
[void] [Windows.Forms.MessageBox]::Show($test)})
$objForm.Controls.Add($OKButton)
[void] $objForm.ShowDialog()
Thank you!
Here's a rewrite of your code.
I'm assuming that you want variables $INT1 and $Serial1 to be available after the windows closes.
In that case, fill them inside the Click() scriptblock and refer to them using $script: scoping, otherwise they are just new variables local to the scriptblock.
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# these variables need to visible inside the Click scriptblock of the button
# and be also available after the windows closes
$INT1 = $null
$Serial1 = $null
$objForm = New-Object System.Windows.Forms.Form
$objForm.StartPosition = "CenterScreen"
$objForm.Size = New-Object System.Drawing.Size(400,250)
$objForm.Topmost = $True
#Label+Textbox first question
$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,30)
$objLabel.Size = New-Object System.Drawing.Size(800,20)
$objLabel.Text = "INT of certificate"
$objForm.Controls.Add($objLabel)
$objTextBox = New-Object System.Windows.Forms.TextBox
$objTextBox.Location = New-Object System.Drawing.Size(10,50)
$objTextBox.Size = New-Object System.Drawing.Size(200,20)
$objForm.Controls.Add($objTextBox)
#Label+Textbox second question
$objLabel2 = New-Object System.Windows.Forms.Label
$objLabel2.Location = New-Object System.Drawing.Size(10,130)
$objLabel2.Size = New-Object System.Drawing.Size(800,20)
$objLabel2.Text = "Serialnumber of the certificate"
$objForm.Controls.Add($objLabel2)
$objTextBox2 = New-Object System.Windows.Forms.TextBox
$objTextBox2.Location = New-Object System.Drawing.Size(10,150)
$objTextBox2.Size = New-Object System.Drawing.Size(200,20)
$objForm.Controls.Add($objTextBox2)
#OK Button
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(100,175)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Name = "OK"
#$OKButton.DialogResult = "OK"
$OKButton.Add_Click({
# you never seem to use variable $INT1, but if you do, refer to it as $script:INT1
# set the variables defined OUTSIDE the scriptblock using script-scoping
$script:INT1 = $objTextBox.Text
$script:Serial1 = $objTextBox2.Text
# create a full path and filename for the output of the Invoke-WebRequest call
$crlFile = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath 'crl.crl'
Invoke-WebRequest -Uri 'http://CENSORED.crl' -OutFile $crlFile
$test = certutil.exe -dump $crlFile | Out-String -Stream | Select-String -Pattern $script:Serial1 -Context 0,1
[void] [Windows.Forms.MessageBox]::Show($test)
# delete the temporary file
$crlFile | Remove-Item -Force
})
$objForm.Controls.Add($OKButton)
[void] $objForm.ShowDialog()
# clean up the form from memory'
$objForm.Dispose()
# here you can again see what is inside variables $INT1 and $Serial1
Write-Host "Last entered values: $INT1 $Serial1"
All user interaction with your form happens in this, blocking call:
[void] $objForm.ShowDialog()
See the ShowDialog() method.
Therefore, if you want to store results from that user interaction in variables, place the assignments after the call, and reference the controls of interest.
# ... form setup
# Show the form modally (as a dialog).
# The call blocks until the form is closed.
# Note:
# You may want to examine the return value in case there
# are multiple ways to close your form, and one of those ways
# signals having *canceled*, for instance.
$null = $objForm.ShowDialog()
# Now you can get values from the controls and assign them to (script) variables.
$INT1 = $objTextBox.Text
$Serial1 = $objTextBox2.Text
Note: If you need to set script-level variables - i.e., variables visible after a .ShowDialog() call - from inside script blocks serving as event delegates (e.g., the script block passed to $OKButton.Add_Click()), you need to use the $script: scope, given that such script blocks run in a child scope too - see this answer.

GUI for my auto installer keeps going blank

I am currently working on an auto installer for newly configured computers where I work. It has a GUI which allows you to choose which programs will be installed. When the file paths are correct the GUI is blank but when I purposefully mess up the file paths the checkboxes will pop back up.
Sorry if this seems like a very dumb question. I am extremely new to this and have gotten a lot of help from various different websites. This is basically me working off of another auto installer script that I found on this website.
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object System.Windows.Forms.Form
$Form.Size = New-Object System.Drawing.Size(600,700)
$Form.text ="Software Installer"
############################################## Start group boxes
$groupBox = New-Object System.Windows.Forms.GroupBox
$groupBox.Location = New-Object System.Drawing.Size (10,20)
$groupBox.text = "Available Software to Install:"
$Form.Controls.Add($groupBox)
$Checkboxes += New-Object System.Windows.Forms.CheckBox
$Checkboxes = New-Object System.Drawing.Size (10,20)
$Button1 = New-Object System.Windows.Forms.Button
$Button1.text = "Install"
$Button1.width = 100
$Button1.height = 30
$Button1.location = New-Object System.Drawing.Point(245,585)
$Button1.Font = 'Microsoft Sans Serif,10'
$apps = [PSCustomObject]#{
Name = ''
Path = ''
PreTransfer = ''
}
$apps = Import-Csv -Path C:\Users\Zach\Desktop\Installers\appslist.csv
$groupBox.Controls.Add($Button1)
$Checkboxes = #()
$y = 20
foreach ($a in $apps)
{
$Checkbox = New-Object System.Windows.Forms.CheckBox
$Checkbox.name = $a.Name
$Checkbox.Text = $a.Name
$Checkbox.Location = New-Object System.Drawing.Size(10,$y)
$y += 30
$groupBox.Controls.Add($Checkbox)
$Checkboxes += $Checkbox
}
$groupbox.size = New-Object System.Drawing.Size(564,(624*$checkboxes.Count))
#to look at each box
$Button1.Add_Click({
foreach ($i in $Checkboxes){
if ($i.checked -eq $true) {
Start-Process $i.AccessibleDescription
}
}
})
$form.ShowDialog()| Out-Null

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 it.
The issue is that the variables inside message textbox is not used instead a plain text is filled.
I think that this is related to System.Windows.Forms.TextBox but I can't figure it out
Any idea how I can resolve this?
Regards,
Adrian
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
$okButton.Add_Click({
$form.Tag = $textBox_recipient.Text;
$form.Tag = $textBox_message.Text;
$form.Close()
})
$form.AcceptButton = $okButton
$form.Controls.Add($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
$form.Controls.Add($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
$form.Controls.Add($textBox_recipient)
##
$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"
$textBox_recipient_select.add_Click({
$ofd = New-Object system.windows.forms.Openfiledialog
#$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"
$form.Controls.Add($textBox_recipient_select)
$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:'
$form.Controls.Add($label_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.Controls.Add($textBox_message)
$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 = $recipient.email
$script:user_firstname = $recipient.firstname
$script:user_lastname = $recipient.lastname
$script:user_code = $recipient.code
$script:message = $textBox_message.Text
Write-Host $message
}
}
}
show_menu
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
This is from what I have observed from Powershell when trying to writing a simple string with variables:
if you use single quotes i.e.
$firstName = "John"
write-host 'First name is $firstName'
The output is going to be:
First name is $firstName
However if you use double quotes, you should get the variable value instead of variable being displayed as plain text. i.e.
$firstName = "John"
write-host "First name is $firstName" or write-host "First name is $($firstName)"
you should get the desired output:
First name is John

Powershell Form With Two Text Inputs and drop down selection

I'm very rusty in the area of powershell and trying to pick it back up but I have something bothering me that I can't seem to figure out. I've created a form that has two text inputs for file locations and a drop down list. What I'm attempting to do is compare the two files received in a text input. I've got the script already for the compare but what I'm trying to figure out is how I distinguish the script to be run from the selection of the drop down list and also parse the two text inputs from the form to the relevant compare script. Below is the generic form created. Any help would be much appreciated.
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object system.Windows.Forms.Form
$Form.Size = New-Object System.Drawing.Size(700,700)
#You can use the below method as well
#$Form.Width = 400
#$Form.Height = 200
$form.MaximizeBox = $false
$Form.StartPosition = "CenterScreen"
$Form.FormBorderStyle = 'Fixed3D'
$Form.Text = "IAM Application Comparison Tool"
#application Drop down list
$Label = New-Object System.Windows.Forms.Label
$Label.Text = "Please select the application being compared"
$Label.AutoSize = $true
$Label.Location = New-Object System.Drawing.Size(10,10)
$Font = New-Object System.Drawing.Font("Arial",15,[System.Drawing.FontStyle]::Bold)
$form.Font = $Font
$Form.Controls.Add($Label)
#list of applications
$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10,50)
$listBox.Size = New-Object System.Drawing.Size(260,20)
$listBox.Height = 80
[void] $listBox.Items.Add('Terradata')
[void] $listBox.Items.Add('')
[void] $listBox.Items.Add('')
[void] $listBox.Items.Add('')
[void] $listBox.Items.Add('')
[void] $listBox.Items.Add('')
[void] $listBox.Items.Add('')
$form.Controls.Add($listBox)
#File path of previous months file
$Label = New-Object System.Windows.Forms.Label
$Label.Text = "Enter file path of previous months file"
$Label.AutoSize = $true
$Label.Location = New-Object System.Drawing.Size(20,200)
$Font = New-Object System.Drawing.Font("Arial",15,[System.Drawing.FontStyle]::Bold)
$form.Font = $Font
$Form.Controls.Add($Label)
#Input file path
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(20,300)
$textBox.Size = New-Object System.Drawing.Size(450,20)
$form.Controls.Add($textBox)
#$formIcon = New-Object system.drawing.icon ("$env:USERPROFILE\desktop\Blog\v.ico")
#$form.Icon = $formicon
#File path of current month
$Label = New-Object System.Windows.Forms.Label
$Label.Text = "Enter file path of current months file"
$Label.AutoSize = $true
$Label.Location = New-Object System.Drawing.Size(20,400)
$Font = New-Object System.Drawing.Font("Arial",15,[System.Drawing.FontStyle]::Bold)
$form.Font = $Font
$Form.Controls.Add($Label)
#Input file path
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(20,500)
$textBox.Size = New-Object System.Drawing.Size(450,20)
$form.Controls.Add($textBox)
#Run Required Compare script
$Okbutton = New-Object System.Windows.Forms.Button
$Okbutton.Location = New-Object System.Drawing.Size(170,600)
$Okbutton.Size = New-Object System.Drawing.Size(200,30)
$Okbutton.Text = "Compare Files"
$Okbutton.Add_Click()
$Form.Controls.Add($Okbutton)
$Form.ShowDialog()
Create a function that will run whenever the button is clicked.
for instance, your button event will be:
$Okbutton.Add_Click({ BtnClick })
then add the function that will do the compare, whenever the button is clicked the function will be called:
function BtnClick{
# do something / compare your texts
#compare $TextBox1.Text $TextBox2.Text
}
you have to give a different variable name for each textbox, this how you'll be able to access the values:
$input1 = $TextBox1.Text
$input2 = $TextBox2.Text
$input3 = $ComboBox1.Text
The easiest way to have your code distinguish between the different objects is to name them upon creation, so use different variable names for the textboxes and the like.
To act on the button click, you already started by writing $Okbutton.Add_Click(), but since there is no scriptblock to actually do something there, nothing would happen.
The listbox can also react on an event, in this case that would be the SelectedIndexChanged event.
Please see the revised code below that shows how to implement these event handlers
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
[void] [System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object system.Windows.Forms.Form
$Form.Size = New-Object System.Drawing.Size(700,700)
$Form.MaximizeBox = $false
$Form.StartPosition = "CenterScreen"
$Form.FormBorderStyle = 'Fixed3D'
$Form.Text = "IAM Application Comparison Tool"
$Font = New-Object System.Drawing.Font("Arial",15,[System.Drawing.FontStyle]::Bold)
$Form.Font = $Font
#application Drop down list
$LabelDropDown = New-Object System.Windows.Forms.Label
$LabelDropDown.Text = "Please select the application being compared"
$LabelDropDown.AutoSize = $true
$LabelDropDown.Location = New-Object System.Drawing.Size(10,10)
$Form.Controls.Add($LabelDropDown)
# list of applications
$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10,50)
$listBox.Size = New-Object System.Drawing.Size(260,20)
$listBox.Height = 80
# add the items to the listbox
$null = $listBox.Items.AddRange(#('Terradata','SomeApp','MyApp','ThirdPartyApp'))
# set the current selected item to be the first
$listBox.SelectedIndex = 0
# add functionality to react on index changed
$listBox.Add_SelectedIndexChanged({
# do something when the user chose a different app in the listbox
# for demo, just write the currently selected item in the console
Write-Host "Currently selected app in the listbox: $($this.SelectedItem)"
})
$Form.Controls.Add($listBox)
# File path of previous months file
$LabelPrevious = New-Object System.Windows.Forms.Label
$LabelPrevious.Text = "Enter file path of previous months file"
$LabelPrevious.AutoSize = $true
$LabelPrevious.Location = New-Object System.Drawing.Size(20,200)
$Form.Controls.Add($LabelPrevious)
# first Input file path
$textBoxFile1 = New-Object System.Windows.Forms.TextBox
$textBoxFile1.Location = New-Object System.Drawing.Point(20,300)
$textBoxFile1.Size = New-Object System.Drawing.Size(450,20)
$Form.Controls.Add($textBoxFile1)
# File path of current month
$LabelCurrent = New-Object System.Windows.Forms.Label
$LabelCurrent.Text = "Enter file path of current months file"
$LabelCurrent.AutoSize = $true
$LabelCurrent.Location = New-Object System.Drawing.Size(20,400)
$Form.Controls.Add($LabelCurrent)
# second Input file path
$textBoxFile2 = New-Object System.Windows.Forms.TextBox
$textBoxFile2.Location = New-Object System.Drawing.Point(20,500)
$textBoxFile2.Size = New-Object System.Drawing.Size(450,20)
$Form.Controls.Add($textBoxFile2)
# Run Required Compare script
$Okbutton = New-Object System.Windows.Forms.Button
$Okbutton.Location = New-Object System.Drawing.Size(170,600)
$Okbutton.Size = New-Object System.Drawing.Size(200,30)
$Okbutton.Text = "Compare Files"
# add functionality for comparing files
$Okbutton.Add_Click({
# your compare function comparing the file in $textbox1 against the file in $textbox2
# IF both fields contain a valid file path and name of course ;)
# for demo just output in console
Write-Host "Compare file '$($textBoxFile1.Text)' to '$($textBoxFile2.Text)'"
})
$Form.Controls.Add($Okbutton)
$Form.ShowDialog()
# important! dispose of the form when done
$Form.Dispose()
P.S. Inside the scriptblocks for the Click and the SelectedIndexChanged events, you can use automatic variable $this, which refers to the current form control object.

Process locking temporary file. How can i get around this?

As part of looking into creating a GUI for handling certain repetitive tasks i made for for a eight ball function. As part of this function i use an background image and an icon that is embedded in the script and written to $env:tmp.
Upon exit from the GUI i have a cleanup to remove the temporary files. However the script is unable to delete the background image while PowerShell is running even when the form has been terminated.¨
Remove-Item : Cannot remove item C:\Users\USERNAME\AppData\Local\Temp\11a8093b2817a3e1ff135fec4fe01320.jpg: The process cannot access the file 'C:\Users\USERNAME\AppData\Local\Temp\1
1a8093b2817a3e1ff135fec4fe01320.jpg' because it is being used by another process.
At C:\Users\USERNAME\Desktop\8ball.ps1:89 char:1
+ Remove-Item "$env:temp\11a8093b2817a3e1ff135fec4fe01320.jpg"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (C:\Users\USERN~...fec4fe01320.jpg:FileInfo) [Remove-Item], IOException
+ FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
Is there any "simple" way i can get around this?
$MagicEightBallPicture = ""
$ContentPicture = [System.Convert]::FromBase64String($MagicEightBallPicture)
(Set-Content -Path $env:temp\11a8093b2817a3e1ff135fec4fe01320.jpg -Value $ContentPicture -Encoding Byte)
$MagicEightBallIcon = ""
$ContentIcon = [System.Convert]::FromBase64String($MagicEightBallIcon)
(Set-Content -Path $env:temp\11a8093b2817a3e1ff135fec4fe01320.ico -Value $ContentIcon -Encoding Byte)
$PossibleAnswers = #("It is certain",`
"It is decidedly so",`
"Without a doubt",`
"Yes, definitely",`
"You may rely on it",`
"As I see it, yes",`
"Most likely",`
"Outlook good",`
"Yes",`
"Signs point to yes",`
"Reply hazy try again",`
"Ask again later",`
"Better not tell you now",`
"Cannot predict now",`
"Concentrate and ask again",`
"Dont count on it",`
"My reply is no",`
"My sources say no",`
"Outlook not so good",`
"Very doubtful")
Function RollTheBall {
$TheAnswer = Get-Random -Count 1 -InputObject $PossibleAnswers
$TheAnswerBox.Text = $TheAnswer
}
Try {
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$Image = [System.Drawing.Image]::Fromfile("$($env:temp)\11a8093b2817a3e1ff135fec4fe01320.jpg")
$Icon = New-Object System.Drawing.Icon ("$($env:temp)\11a8093b2817a3e1ff135fec4fe01320.ico")
$Form = New-Object System.Windows.Forms.Form
$Form.Text = "Magic Eight Ball"
$Form.MinimizeBox = $False
$Form.MaximizeBox = $False
$Form.FormBorderStyle = 'Fixed3D'
$Form.SizeGripStyle = "Hide"
$Form.ShowInTaskbar = $False
$Form.StartPosition = "CenterScreen"
$Form.Icon = $Icon
$Form.BackgroundImage = $Image
$Form.BackgroundImageLayout = "None"
$Form.Width = $Image.Width
$Form.Height = $Image.Hight
$Form.Size = New-Object System.Drawing.Size(300,200)
$TheAnswerBox = New-Object System.Windows.Forms.TextBox
$TheAnswerBox.Location = New-Object System.Drawing.Size(10,10)
$TheAnswerBox.Size = New-Object System.Drawing.Size(270,20)
$TheAnswerBox.TextAlign = [System.Windows.Forms.HorizontalAlignment]::Center
$TheAnswerBox.add_GotFocus({[System.Windows.Forms.SendKeys]::Send("{tab}")})
$Form.Controls.Add($TheAnswerBox)
$ButtonRollTheBall = New-Object System.Windows.Forms.Button
$ButtonRollTheBall.Location = New-Object System.Drawing.Size(10,40)
$ButtonRollTheBall.Size = New-Object System.Drawing.Size(130,20)
$ButtonRollTheBall.Text = "Help?!"
$ButtonRollTheBall.Add_Click({RollTheBall})
$Form.Controls.Add($ButtonRollTheBall)
$ButtonExit = New-Object System.Windows.Forms.Button
$ButtonExit.Location = New-Object System.Drawing.Size(150,40)
$ButtonExit.Size = New-Object System.Drawing.Size(130,20)
$ButtonExit.Text = "Exit"
$ButtonExit.Add_Click({$Form.Close()})
$Form.Controls.Add($ButtonExit)
$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog()
} Finally {
Remove-Item "$env:temp\11a8093b2817a3e1ff135fec4fe01320.jpg"
Remove-Item "$env:temp\11a8093b2817a3e1ff135fec4fe01320.ico"
}
I've removed the embedded pictures due to possible copyright and shear size.
Since the Image returned from [System.Drawing.Image]::Fromfile is disposable, you have to Dispose it to clean up the ressources before you delete it:
$Image.Dispose()