当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] PowerShell GUI - 如何开始

作者:精品下载站 日期:2024-12-14 03:39:48 浏览:15 分类:玩电脑

PowerShell GUI - 如何开始


过去几年我创建了许多 PowerShell 脚本。所有这些都只有一个目的:尽可能自动化我的 IT 工作。但本周我需要创建一个可由用户自己运行的脚本。用户和命令行并不是最佳组合,所以让我们来看看使用 PowerShell GUI。

我们都喜欢 PowerShell,因为在脚本编写方面简单高效,但对于普通用户来说,他们并不习惯使用 CLI。在本文中,我将解释如何为脚本创建一个简单的 GUI,并帮助您克服基本障碍。

示例项目

在这篇文章中,我将使用我自己的一个项目作为示例,所以让我首先介绍一下我需要解决的问题。

我在一家建筑公司工作,我们的建筑工地通过 4G IPVPN 网络与数据中心连接。由于双重网络,我们无法部署带有打印服务器的打印机。

我们的用户可以自己安装打印机,但由于它们未列在打印服务器上,因此他们可以轻松搜索打印机。他们需要创建 TCP/IP 端口、找到打印机的 IP 地址、选择驱动程序并给出打印机名称。

我创建了一个 PowerShell 脚本,我可以远程运行该脚本以在后台执行此操作,但这需要他们给我打电话,这样我就可以在后台运行该脚本。现在我可以安装所有打印机,但这只会造成混乱并导致打印机列表很长。

所以我想,PowerShell 脚本只需要打印机型号、IP 地址和名称。我们可以查找 IP 地址,因此如果用户可以选择型号并填写名称,我们就完成了。每周为我节省 2 个电话。

PowerShell GUI 的基础知识

在开始创建表单之前,了解 PowerShell 脚本是按顺序运行的很重要。所以你定义你的表单并显示它。但是,在关闭表单之前,显示表单后的任何代码都不会执行。

我花了 30 分钟才弄清楚这个问题……我只是想我可以在 PowerShell 中显示表单并处理其下方的输入。

创建表单

我们从一张空白表格开始。首先,我们添加.Net Windows。表格。另外,我们需要定义表单的大小(宽度、高度)、标题和背景颜色。只需将以下代码复制粘贴到 PowerShell ISE 中,然后单击运行

# Init PowerShell Gui
Add-Type -AssemblyName System.Windows.Forms

# Create a new form
$LocalPrinterForm                    = New-Object system.Windows.Forms.Form

# Define the size, title and background color
$LocalPrinterForm.ClientSize         = '500,300'
$LocalPrinterForm.text               = "LazyAdmin - PowerShell GUI Example"
$LocalPrinterForm.BackColor          = "#ffffff"

# Display the form
[void]$LocalPrinterForm.ShowDialog()

您将看到一个简单的表单,如下所示:

[玩转系统] PowerShell GUI - 如何开始

添加元素到您的表单

在我们的表单上,我们可以添加元素。这些可用于显示信息和收集用户输入。输入的位置基于左侧和顶部的点/像素。因此,位置 20,50 距离左侧 20 个像素,距离顶部 50 个像素。

我们可以在表单上使用以下元素:

  • TextBox(获取用户输入)
  • 标签
  • 按钮
  • 图片框
  • 复选框
  • 组合框(下拉列表)
  • 列表视图
  • 列表框
  • 单选按钮
  • 控制板
  • Groupbox(将元素分组在一起)
  • 进度条
  • 数据网格视图

因此,让我们在表单上创建一些元素。将以下代码添加到您的脚本中。确保 ShowDialog 位于脚本的末尾。

# Create a Title for our form. We will use a label for it.
$Titel                           = New-Object system.Windows.Forms.Label

# The content of the label
$Titel.text                      = "Adding new printer"

# Make sure the label is sized the height and length of the content
$Titel.AutoSize                  = $true

# Define the minial width and height (not nessary with autosize true)
$Titel.width                     = 25
$Titel.height                    = 10

# Position the element
$Titel.location                  = New-Object System.Drawing.Point(20,20)

# Define the font type and size
$Titel.Font                      = 'Microsoft Sans Serif,13'

# Other elemtents
$Description                     = New-Object system.Windows.Forms.Label
$Description.text                = "Add a new construction site printer to your computer. Make sure you are connected to the network of the construction site."
$Description.AutoSize            = $false
$Description.width               = 450
$Description.height              = 50
$Description.location            = New-Object System.Drawing.Point(20,50)
$Description.Font                = 'Microsoft Sans Serif,10'

$PrinterStatus                   = New-Object system.Windows.Forms.Label
$PrinterStatus.text              = "Status:"
$PrinterStatus.AutoSize          = $true
$PrinterStatus.location          = New-Object System.Drawing.Point(20,115)
$PrinterStatus.Font              = 'Microsoft Sans Serif,10,style=Bold'

$PrinterFound                    = New-Object system.Windows.Forms.Label
$PrinterFound.text               = "Searching for printer..."
$PrinterFound.AutoSize           = $true
$PrinterFound.location           = New-Object System.Drawing.Point(75,115)
$PrinterFound.Font               = 'Microsoft Sans Serif,10'

# ADD OTHER ELEMENTS ABOVE THIS LINE

# Add the elements to the form
$LocalPrinterForm.controls.AddRange(@($Titel,$Description,$PrinterStatus,$PrinterFound))

# THIS SHOULD BE AT THE END OF YOUR SCRIPT FOR NOW
# Display the form
[void]$LocalPrinterForm.ShowDialog()

您在这里看到的是每个元素都已创建。这些都是简单的文本或标签元素。您可以定义每个元素的宽度和高度,但如果您的内容比该元素长,它将仅部分显示。因此,通过将自动调整大小设置为true,您可以确保用户可以阅读整个标签。

每个元素都有一个位置,第一个数字是距左侧的像素数,第二个数字是距顶部的像素数。

结果将如下所示:

[玩转系统] PowerShell GUI - 如何开始

使用下拉列表

我们的用户需要选择打印机制造商,我们只使用两个品牌,所以我的单选按钮也可以工作。我们使用通用打印驱动程序,因此我不需要知道打印机的具体型号。

$PrinterType                     = New-Object system.Windows.Forms.ComboBox
$PrinterType.text                = ""
$PrinterType.width               = 170
$printerType.autosize            = $true

# Add the items in the dropdown list
@('Canon','Hp') | ForEach-Object {[void] $PrinterType.Items.Add($_)}

# Select the default value
$PrinterType.SelectedIndex       = 0
$PrinterType.location            = New-Object System.Drawing.Point(20,210)
$PrinterType.Font                = 'Microsoft Sans Serif,10'

我认为上面的代码非常清楚,我们创建组合框并使用单行 foreach 循环将项目添加到列表中。同样,我们还定义了位置,并且我设置了元素的最小宽度。


您可以通过选择索引来设置下拉列表的默认值。确保将元素的变量添加到$LocalPrinterForm.controls.AddRange中,否则不会显示。

添加按钮

我们还将向表单添加一些按钮。按钮可以具有标准操作,例如(
确定、取消、中止、重试、忽略、是或否),或者您可以为其分配自定义功能。

我们要添加的按钮是“取消”和“添加打印机”。 “取消”只会关闭表单,不执行任何其他操作,而“添加打印机”将运行我们的逻辑来添加打印机。使用下面的代码添加按钮,再次确保将按钮的变量添加到 $LocalPrinterForm.controls.AddRange

$AddPrinterBtn                   = New-Object system.Windows.Forms.Button
$AddPrinterBtn.BackColor         = "#a4ba67"
$AddPrinterBtn.text              = "Add Printer"
$AddPrinterBtn.width             = 90
$AddPrinterBtn.height            = 30
$AddPrinterBtn.location          = New-Object System.Drawing.Point(370,250)
$AddPrinterBtn.Font              = 'Microsoft Sans Serif,10'
$AddPrinterBtn.ForeColor         = "#ffffff"

$cancelBtn                       = New-Object system.Windows.Forms.Button
$cancelBtn.BackColor             = "#ffffff"
$cancelBtn.text                  = "Cancel"
$cancelBtn.width                 = 90
$cancelBtn.height                = 30
$cancelBtn.location              = New-Object System.Drawing.Point(260,250)
$cancelBtn.Font                  = 'Microsoft Sans Serif,10'
$cancelBtn.ForeColor             = "#000"
$cancelBtn.DialogResult          = [System.Windows.Forms.DialogResult]::Cancel
$LocalPrinterForm.CancelButton   = $cancelBtn
$LocalPrinterForm.Controls.Add($cancelBtn)

现在其他网站上的很多例子都使用[void]$form.ShowDialog()来丢弃对话框的结果。但是对话框的返回值应该用来告诉用户如何关闭形式。

所以我们要修改 ShowDialog cmd。

$result = $LocalPrinterForm.ShowDialog()

这样我们就可以检查用户是否按下了取消或表单中的任何其他默认按钮

if ($result -eq [System.Windows.Forms.DialogResult]::Cancel)
{
    write-output 'User pressed cancel'
}

向按钮添加自定义功能

当用户单击添加打印机时,应执行自定义脚本。我们可以用我们的逻辑创建一个函数,并使用以下命令将该函数分配给按钮

$AddPrinterBtn.Add_Click({ AddPrinter })

还有我们的函数

function AddPrinter { 
	# ADDING PRINTER LOGIC GOES HERE
}

结果

因此,在添加所有元素并添加一些额外标签后,我们最终的 PowerShell GUI 表单如下所示:

[玩转系统] PowerShell GUI - 如何开始

现在我们只需完成脚本即可添加打印机。

添加逻辑

因此,表单就位后,我们可以从添加逻辑开始。在脚本执行期间,您可能想要更改文本、显示或删除字段或执行特定操作。让我们首先概述我们的 PowerShell 脚本。

#------------[Initialisations]------------

# Init PowerShell Gui
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing


#---------------[Form]-------------------

# Our form goes here

[System.Windows.Forms.Application]::EnableVisualStyles()

$LocalPrinterForm                    = New-Object system.Windows.Forms.Form
$LocalPrinterForm.ClientSize         = '480,300'
$LocalPrinterForm.text               = "LazyAdmin - PowerShell GUI Example"
$LocalPrinterForm.BackColor          = "#ffffff"
$LocalPrinterForm.TopMost            = $false
$Icon                                = New-Object system.drawing.icon ("./form.ico")
$LocalPrinterForm.Icon               = $Icon

# THE REST OF THE FORM

$LocalPrinterForm.controls.AddRange(@( "<ALL FORM ELEMENTS>" ))

#------------[Functions]------------

function AddPrinter { 
    # Function that is triggered with the add printer button
}

#------------[Script]------------

$AddPrinterBtn.Add_Click({ AddPrinter })

# REST OF YOUR SCRIPT


#------------[Show form]------------

# Show the form
$result = $LocalPrinterForm.ShowDialog()

# Catch any output of the form
if ($result -eq [System.Windows.Forms.DialogResult]::Cancel)
{
    write-output 'User pressed cancel'
}

在函数或脚本部分,您可能希望向用户提供一些反馈或使用输入字段中的数据。

读取和更改 PowerShell GUI 元素

从文本框中读取数据非常简单。在我们的示例中,我们希望使用用户输入的名称并检查打印机名称是否已存在。如果该名称存在,我们希望显示错误。

if (Get-Printer -Name $printerName.text) {
	$PrinterStatus.ForeColor = "#D0021B"
	$PrinterStatus.Text = 'Printer name already exists.'
}

在上面的示例中,我们检查给定的打印机名称,如果存在,我们更改标签“PrinterStatus”的字体颜色以读取并更改标签的文本以向用户显示消息。

无需刷新表单或输入,您只需随时更改文本即可。

显示和隐藏字段

在加载表单之前,我检查预期的网络地址上是否有可用的打印机。如果不是,则用户无需继续。因此,当我初始化表单元素时,我隐藏了一些元素。

如果我们有连接,那么我会显示元素或更改按钮的标签。可以使用以下代码来隐藏和显示 PowerShell GUI 中的元素:

$PrinterNameLabel.Visible = $false # or $true of course ?

在线 PowerShell GUI 编辑器 PoshGUI

仅从命令行创建更大或复杂的表单可能有点具有挑战性。您必须将所有元素放置在正确的位置,创建所有必要的代码。幸运的是,有一个在线 PowerShell GUI 编辑器 PoshGUI。

[玩转系统] PowerShell GUI - 如何开始

这是创建初始表单布局的绝佳工具。您可以下载 PS1 文件并继续在您喜欢的编辑器中处理表单。

结论

因此,我希望本文可以帮助您开始创建您的第一个 PowerShell 表单。虽然 PowerShell 并不是真正用于创建表单,但它可以是使脚本对用户或同事更有用的好方法。

订阅新闻通讯以在邮箱中接收有关 PowerShell 或 Office 365 的最新文章。

完整的代码如下所示:

#---------------------------------------------------------[Initialisations]--------------------------------------------------------
# Init PowerShell Gui
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing


#---------------------------------------------------------[Form]--------------------------------------------------------

[System.Windows.Forms.Application]::EnableVisualStyles()

$LocalPrinterForm                    = New-Object system.Windows.Forms.Form
$LocalPrinterForm.ClientSize         = '480,300'
$LocalPrinterForm.text               = "Printers"
$LocalPrinterForm.BackColor          = "#ffffff"
$LocalPrinterForm.TopMost            = $false
$Icon                                = New-Object system.drawing.icon ("//thunnissen.local/netlogon/printer.ico")
$LocalPrinterForm.Icon               = $Icon

$Titel                           = New-Object system.Windows.Forms.Label
$Titel.text                      = "Add new printer"
$Titel.AutoSize                  = $true
$Titel.width                     = 25
$Titel.height                    = 10
$Titel.location                  = New-Object System.Drawing.Point(20,20)
$Titel.Font                      = 'Microsoft Sans Serif,13'

$Description                     = New-Object system.Windows.Forms.Label
$Description.text                = "To add a printer, make sure you are connected to the same network as the printer.."
$Description.AutoSize            = $false
$Description.width               = 450
$Description.height              = 50
$Description.location            = New-Object System.Drawing.Point(20,50)
$Description.Font                = 'Microsoft Sans Serif,10'

$PrinterStatus                   = New-Object system.Windows.Forms.Label
$PrinterStatus.text              = "Status:"
$PrinterStatus.AutoSize          = $true
$PrinterStatus.width             = 25
$PrinterStatus.height            = 10
$PrinterStatus.location          = New-Object System.Drawing.Point(20,115)
$PrinterStatus.Font              = 'Microsoft Sans Serif,10,style=Bold'

$PrinterFound                    = New-Object system.Windows.Forms.Label
$PrinterFound.text               = "Searching for printer..."
$PrinterFound.AutoSize           = $true
$PrinterFound.width              = 25
$PrinterFound.height             = 10
$PrinterFound.location           = New-Object System.Drawing.Point(100,115)
$PrinterFound.Font               = 'Microsoft Sans Serif,10'

$PrinterDetails                  = New-Object system.Windows.Forms.Label
$PrinterDetails.text             = "Printer details"
$PrinterDetails.AutoSize         = $true
$PrinterDetails.width            = 25
$PrinterDetails.height           = 10
$PrinterDetails.location         = New-Object System.Drawing.Point(20,150)
$PrinterDetails.Font             = 'Microsoft Sans Serif,12'
$PrinterDetails.Visible          = $false

$PrinterNameLabel                = New-Object system.Windows.Forms.Label
$PrinterNameLabel.text           = "Name:"
$PrinterNameLabel.AutoSize       = $true
$PrinterNameLabel.width          = 25
$PrinterNameLabel.height         = 20
$PrinterNameLabel.location       = New-Object System.Drawing.Point(20,180)
$PrinterNameLabel.Font           = 'Microsoft Sans Serif,10,style=Bold'
$PrinterNameLabel.Visible        = $false

$PrinterName                     = New-Object system.Windows.Forms.TextBox
$PrinterName.multiline           = $false
$PrinterName.width               = 314
$PrinterName.height              = 20
$PrinterName.location            = New-Object System.Drawing.Point(100,180)
$PrinterName.Font                = 'Microsoft Sans Serif,10'
$PrinterName.Visible             = $false

$PrinterTypeLabel                = New-Object system.Windows.Forms.Label
$PrinterTypeLabel.text           = "Brand:"
$PrinterTypeLabel.AutoSize       = $true
$PrinterTypeLabel.width          = 25
$PrinterTypeLabel.height         = 20
$PrinterTypeLabel.location       = New-Object System.Drawing.Point(20,210)
$PrinterTypeLabel.Font           = 'Microsoft Sans Serif,10,style=Bold'
$PrinterTypeLabel.Visible        = $false

$PrinterType                     = New-Object system.Windows.Forms.ComboBox
$PrinterType.text                = ""
$PrinterType.width               = 170
$PrinterType.height              = 20
@('Canon','Hp') | ForEach-Object {[void] $PrinterType.Items.Add($_)}
$PrinterType.SelectedIndex       = 0
$PrinterType.location            = New-Object System.Drawing.Point(100,210)
$PrinterType.Font                = 'Microsoft Sans Serif,10'
$PrinterType.Visible             = $false

$AddPrinterBtn                   = New-Object system.Windows.Forms.Button
$AddPrinterBtn.BackColor         = "#ff7b00"
$AddPrinterBtn.text              = "Add"
$AddPrinterBtn.width             = 90
$AddPrinterBtn.height            = 30
$AddPrinterBtn.location          = New-Object System.Drawing.Point(370,250)
$AddPrinterBtn.Font              = 'Microsoft Sans Serif,10'
$AddPrinterBtn.ForeColor         = "#ffffff"
$AddPrinterBtn.Visible           = $false

$cancelBtn                       = New-Object system.Windows.Forms.Button
$cancelBtn.BackColor             = "#ffffff"
$cancelBtn.text                  = "Cancel"
$cancelBtn.width                 = 90
$cancelBtn.height                = 30
$cancelBtn.location              = New-Object System.Drawing.Point(260,250)
$cancelBtn.Font                  = 'Microsoft Sans Serif,10'
$cancelBtn.ForeColor             = "#000"
$cancelBtn.DialogResult          = [System.Windows.Forms.DialogResult]::Cancel
$LocalPrinterForm.CancelButton   = $cancelBtn
$LocalPrinterForm.Controls.Add($cancelBtn)

$LocalPrinterForm.controls.AddRange(@($Titel,$Description,$PrinterStatus,$PrinterFound,$PrinterName,$PrinterNameLabel,$PrinterType,$AddPrinterBtn,$cancelBtn,$PrinterTypeLabel,$PrinterDetails))

#-----------------------------------------------------------[Functions]------------------------------------------------------------

function AddPrinter { 
	$PrinterFound.ForeColor = "#000000"
	$PrinterFound.Text = 'Adding printer...'
	# Check printer port
	$portName = "TCPPort:"+$printerIp
	$portExists = Get-Printerport -Name $portname -ErrorAction SilentlyContinue

	# Create port if it not exists
	if (-not $portExists) {
		$PrinterFound.Text = 'Creating printer port...'
		Add-PrinterPort -name $portName -PrinterHostAddress $printerIp
	}

	# Select the correct driver
	if ($PrinterType.SelectedItem -eq 'Canon') {
		$printerDriverName = "Canon Generic Plus PCL6"
	}else{
		$printerDriverName = "HP LaserJet M227-M231 PCL-6"
	}

	# Check if printer driver exists
	$printDriverExists = Get-PrinterDriver -name $printerDriverName -ErrorAction SilentlyContinue

	# Install printer or printer driver and printer
	if ($printDriverExists) {
		$PrinterFound.Text = 'Installing printer...'
		Add-Printer -Name $printerName.text -PortName $portName -DriverName $printerDriverName 
	}else{
		$PrinterFound.Text = 'Installing printer driver...'
		Add-PrinterDriver -name $printerDriverName

		$PrinterFound.Text = 'Installing printer...'
		Add-Printer -Name $printerName.text -PortName $portName -DriverName $printerDriverName
	}

	if (Get-Printer -Name $printerName.text) {
		$PrinterFound.ForeColor = "#7ed321"
		$PrinterFound.Text = 'The printer is installed'
	}
	else {
		$PrinterFound.ForeColor = "#D0021B"
		$PrinterFound.Text = 'Installation failed'
	}
	$PrinterNameLabel.Visible = $false
	$PrinterName.Visible = $false
	$PrinterType.Visible = $false
	$AddPrinterBtn.Visible = $false
	$PrinterDetails.Visible = $false
	$PrinterTypeLabel.Visible = $false
	$cancelBtn.text = "Close"
}

#---------------------------------------------------------[Script]--------------------------------------------------------
# Get printers IP Address
$clientIP = (
    Get-NetIPConfiguration |
    Where-Object {
        $_.IPv4DefaultGateway -ne $null -and
        $_.NetAdapter.Status -ne "Disconnected"
    }
).IPv4Address.IPAddress

$networkAddress = $clientIP.Split('.')
$networkAddress = $networkAddress[0]+"."+$networkAddress[1]+"."+$networkAddress[2]

# Check if printer is online
$printerIp =  $networkAddress + ".31" 
$testConnection = Test-Connection $printerIp -count 1 -Quiet

If ($testConnection) {
	$PrinterFound.text = "Printer found"
	$PrinterFound.ForeColor = "#7ed321"
	$PrinterNameLabel.Visible = $true
	$PrinterName.Visible = $true
	$PrinterType.Visible = $true
	$AddPrinterBtn.Visible = $true
	$PrinterDetails.Visible = $true
	$PrinterTypeLabel.Visible = $true
}else{
	$PrinterFound.text = "No printers found"
	$PrinterFound.ForeColor = "#D0021B"
	$cancelBtn.text = "Sluiten"
}

$AddPrinterBtn.Add_Click({ AddPrinter })

[void]$LocalPrinterForm.ShowDialog()

您还可以查看以下文章:

  • 使用 PowerShell 添加打印机和打印机端口
  • 使用 PowerShell 将主文件夹迁移到 OneDrive
  • Microsoft Flow 入门

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯