Hi All, newbie here. Trying to create a powershell script to add network printers.
All works well except that when the Install Printer button is clicked, the GUI freezes and can’t be closed. The printer installs successfully though. I need the process to end cleanly and the button enabled back to install another printer.
Pls help. thank you.
# Import necessary assemblies
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# Function to read INI file
function Read-INIFile {
param ([string]$path)
$ini = @{}
$currentSection = $null
foreach ($line in Get-Content $path) {
$line = $line.Trim()
if ($line -match '^\[(.+?)\]$') {
$currentSection = $matches[1]
$ini[$currentSection] = @{}
} elseif ($line -match '^(.+?)=(.+)$' -and $currentSection) {
$ini[$currentSection][$matches[1].Trim()] = $matches[2].Trim()
}
}
return $ini
}
# Function to install TCP/IP printer
function Install-Printer {
param (
[string]$printerName,
[string]$ipAddress,
[string]$portName,
[string]$driverName
)
try {
# Create a new TCP/IP printer port if it doesn't already exist
if (-not (Get-PrinterPort -Name $portName -ErrorAction SilentlyContinue)) {
Add-PrinterPort -Name $portName -PrinterHostAddress $ipAddress
}
# Install the printer with the specified driver
if (-not (Get-Printer -Name $printerName -ErrorAction SilentlyContinue)) {
Add-Printer -Name $printerName -PortName $portName -DriverName $driverName
return "Printer $printerName installed successfully."
} else {
return "Printer $printerName already exists."
}
} catch {
# Log the detailed error message
$errorMessage = "Error while installing printer: $_"
Write-Host $errorMessage # You can also log this to a file if needed
return $errorMessage
}
}
# Load printer configurations from the INI file
$iniFilePath = "C:\Printers.ini"
$printersConfig = Read-INIFile -path $iniFilePath
# Check if the INI file has data
if ($printersConfig.Count -eq 0) {
[System.Windows.Forms.MessageBox]::Show("No printers found in configuration.", "Warning", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Warning)
exit
}
# Create GUI
$form = New-Object System.Windows.Forms.Form
$form.Text = "TCP/IP Printer Installer"
$form.Size = New-Object System.Drawing.Size(500, 280)
$form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
$form.BackColor = [System.Drawing.Color]::FromArgb(117, 192, 199)
# ComboBox for Printer selection
$comboBox = New-Object System.Windows.Forms.ComboBox
$comboBox.Location = New-Object System.Drawing.Point(20, 20)
$comboBox.Size = New-Object System.Drawing.Size(440, 40)
$comboBox.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList
$comboBox.DisplayMember = 'DisplayText'
# Add printers to ComboBox
foreach ($printerName in $printersConfig.Keys) {
$printerConfig = $printersConfig[$printerName]
if ($printerConfig -and $printerConfig['PrinterName'] -and $printerConfig['IPAddress'] -and $printerConfig['PortName'] -and $printerConfig['DriverName']) {
$printerObject = New-Object PSObject -Property @{
PrinterName = $printerConfig['PrinterName']
PrinterModel = $printerConfig['PrinterModel']
IPAddress = $printerConfig['IPAddress']
PortName = $printerConfig['PortName']
Location = $printerConfig['Location']
DriverName = $printerConfig['DriverName']
DisplayText = "$($printerConfig['PrinterName']) - $($printerConfig['Location'])"
}
$comboBox.Items.Add($printerObject)
}
}
$form.Controls.Add($comboBox)
# Label to display selected printer details
$detailsLabel = New-Object System.Windows.Forms.Label
$detailsLabel.Location = New-Object System.Drawing.Point(70, 70)
$detailsLabel.Size = New-Object System.Drawing.Size(340, 80)
$detailsLabel.TextAlign = [System.Drawing.ContentAlignment]::MiddleCenter
$form.Controls.Add($detailsLabel)
# Button to Install Printer
$installButton = New-Object System.Windows.Forms.Button
$installButton.Text = "Install Selected Printer"
$installButton.Location = New-Object System.Drawing.Point(120, 160)
$installButton.Size = New-Object System.Drawing.Size(250, 40)
$installButton.Font = New-Object System.Drawing.Font("Microsoft Sans Serif", 10, [System.Drawing.FontStyle]::Bold)
$form.Controls.Add($installButton)
# ComboBox Selection Event to show printer details
$comboBox.Add_SelectedIndexChanged({
$selectedPrinter = $comboBox.SelectedItem
if ($selectedPrinter) {
$detailsLabel.Text = "Model: $($selectedPrinter.PrinterModel)`n" +
"Location: $($selectedPrinter.Location)`n" +
"IP Address: $($selectedPrinter.IPAddress)`n" +
"Driver: $($selectedPrinter.DriverName)"
} else {
$detailsLabel.Text = ""
}
})
$installButton.Add_Click({
$selectedPrinter = $comboBox.SelectedItem
if ($selectedPrinter) {
Write-Host "Selected Printer Name: $($selectedPrinter.PrinterName)"
Write-Host "Selected Printer IP: $($selectedPrinter.IPAddress)"
Write-Host "Selected Printer Port: $($selectedPrinter.PortName)"
Write-Host "Selected Printer Driver: $($selectedPrinter.DriverName)"
Install-Printer -driverName $($selectedPrinter.DriverName) -ipAddress $($selectedPrinter.IPAddress) -portName $($selectedPrinter.PortName) -printerName $($selectedPrinter.PrinterName)
# Ensure values are not empty
if (-not $selectedPrinter.IPAddress -or -not $selectedPrinter.PortName -or -not $selectedPrinter.DriverName) {
Write-Host "One or more properties are missing for the selected printer."
return
}
# After starting the job, re-enable the button and reset text after a short delay
$installButton.Text = "Install Selected Printer"
$installButton.Enabled = $true
# Optionally display a message that installation has started
[System.Windows.Forms.MessageBox]::Show("Printer installation has started.", "Info", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Information)
# Close the form if desired
$form.Close() # Close the form after installation starts
} else {
[System.Windows.Forms.MessageBox]::Show("Please select a printer to install.", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Warning)
}
})
# Show the form
$form.Add_Shown({ $form.Activate() })
[void]$form.ShowDialog()