简体   繁体   中英

How to program a command button to use a string in powershell

I am writing a Powershell script to automate the install of printers on our network. I have overthinking in place however, I cant seem to get my command button to allow the user to select the printer from a list and set it as default.

I have a string setup to define the printers (4 of them) but no matter what way I code the $OKButton.Add_Click it wont go with the users selection.

Here is the code I have. Can someone please tell me what I am missung?

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 

$objForm = New-Object System.Windows.Forms.Form 
$objForm.Text = "Select a Printer"
$objForm.Size = New-Object System.Drawing.Size(400,200) 
$objForm.StartPosition = "CenterScreen"

$objForm.KeyPreview = $True
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter") 
    {$x=$objListBox.SelectedItem;$objForm.Close()}})
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape") 
    {$objForm.Close()}})

#Ok Button
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Add_Click({$x=$objListBox.SelectedItem;$strPrinter,$objForm.Close()})
$objForm.Controls.Add($OKButton)

#Cancel Button
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({$objForm.Close()})
$objForm.Controls.Add($CancelButton)

$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20) 
$objLabel.Size = New-Object System.Drawing.Size(280,20) 
$objLabel.Text = "Please select a printer:"
$objForm.Controls.Add($objLabel) 

#List box showing printer options
$objListBox = New-Object System.Windows.Forms.ListBox 
$objListBox.Location = New-Object System.Drawing.Size(10,40) 
$objListBox.Size = New-Object System.Drawing.Size(360,20) 
$objListBox.Height = 80

[void] $objListBox.Items.Add("HP Color LaserJet CP2020")
[void] $objListBox.Items.Add("Brother DCP-8065DN")
[void] $objListBox.Items.Add("Canon iR-ADV C2220/2230")
[void] $objListBox.Items.Add("HP LJ300-400 color M351-M451")

$objForm.Controls.Add($objListBox) 

$objForm.Topmost = $True

$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()

#String to call printers, each printer is assigned a value (1,2,3,4)
$strPrinter = 1, "HP Color LaserJet CP2020", ((New-Object -ComObject WScript.Network).SetDefaultPrinter('\\PS\PT01')) 
$strPrinter = 2, "Brother DCP-8065DN", ((New-Object -ComObject WScript.Network).SetDefaultPrinter('\\PS\PT02')) 
$strPrinter = 3, "Canon iR-ADV C2220/2230", ((New-Object -ComObject WScript.Network).SetDefaultPrinter('\\PS\PT03'))
$strPrinter = 4, "HP LJ300-400 color M351-M451", ((New-Object -ComObject WScript.Network).SetDefaultPrinter('\PS\PT04'))

$x

There are two problems with your current script.

The first one, that $x appears empty is due to a scoping issue. When inside the scope of the add_Click() event handler, $x is a local variable and its value won't be accessible outside of the event handler.

You could work around this by specifying a parent scope, like (notice the global: scope qualifier):

$global:x = $objListBox.SelectedItem

But still, nothing would happen, leading me to the second issue:

I'm not sure what you mean by "string setup", but your script basically ends up setting the last printer as the default whenever it runs.

You'll want to define the printers up front, before showing the dialog, and wrap the ((New-Object... statements in a scriptblock, something like:

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 

# New array of "printer objects", rather than $strPrinter
$Printers = @(
    New-Object psobject -Property @{
        Name = "HP Color LaserJet CP2020"
        SetCommand = { ((New-Object -ComObject WScript.Network).SetDefaultPrinter('\\PS\PT01')) }
    },
    New-Object psobject -Property @{
        Name = "Brother DCP-8065DN"
        SetCommand = { ((New-Object -ComObject WScript.Network).SetDefaultPrinter('\\PS\PT02')) }
    },
    New-Object psobject -Property @{ 
        Name = "Canon iR-ADV C2220/2230"
        SetCommand = { ((New-Object -ComObject WScript.Network).SetDefaultPrinter('\\PS\PT03')) }
    },
    New-Object psobject -Property @{
        Name = "HP LJ300-400 color M351-M451"
        SetCommand = { ((New-Object -ComObject WScript.Network).SetDefaultPrinter('\PS\PT04')) }
    }
)

$objForm = New-Object System.Windows.Forms.Form 
$objForm.Text = "Select a Printer"
$objForm.Size = New-Object System.Drawing.Size(400,200) 
$objForm.StartPosition = "CenterScreen"

$objForm.KeyPreview = $True
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter") 
    {$x=$objListBox.SelectedItem;$objForm.Close()}})
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape") 
    {$objForm.Close()}})

#Ok Button
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Add_Click({
    # Grab the printer array index
    $index = $objListBox.SelectedIndex

    # Execute the appropriate command
    & $Printers[$index].SetCommand 

    # Exit
    $objForm.Close()
})
$objForm.Controls.Add($OKButton)

#Cancel Button
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({$objForm.Close()})
$objForm.Controls.Add($CancelButton)

$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20) 
$objLabel.Size = New-Object System.Drawing.Size(280,20) 
$objLabel.Text = "Please select a printer:"
$objForm.Controls.Add($objLabel) 

#List box showing printer options
$objListBox = New-Object System.Windows.Forms.ListBox 
$objListBox.Location = New-Object System.Drawing.Size(10,40) 
$objListBox.Size = New-Object System.Drawing.Size(360,20) 
$objListBox.Height = 80

foreach($Printer in $Printers){
    [void] $objListBox.Items.Add($Printer.Name)
}

$objForm.Controls.Add($objListBox) 

$objForm.Topmost = $True

$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()

Since the printers are now added to the listbox in correct order, we can simply use the SelectedIndex property to find the original printer object and invoke the scriptblock that sets it as default

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM