[玩转系统] 使用 PowerShell ValidateScript 验证参数 [演练]
作者:精品下载站 日期:2024-12-14 20:52:02 浏览:17 分类:玩电脑
使用 PowerShell ValidateScript 验证参数 [演练]
创建 PowerShell 函数时,验证参数的输入非常重要。参数验证允许您限制传递给函数的内容。在本文中,您将学习如何在问题成为 PowerShell ValidateScript 验证属性之前发现问题。
使用参数验证,您不仅可以确保函数运行后不会出现问题,而且还可以提高代码的简洁性,因为验证逻辑没有放置在函数体内。
Powershell 中提供了多种高级参数验证属性。但在本文中,您将了解最灵活的参数验证之一:PowerShell ValidateScript 验证。
您将了解它的工作原理,并查看如何使用它的示例。
参数验证(类比)
我正在吃午饭,突然想喝一杯苏打水。我走到汽水机前,从口袋里掏出一张 100 比索的钞票,将其插入钞票投币口。机器立刻吐出来。
然后我注意到,就在投币口上方,写着只接受 20 比索和 50 比索的钞票。我最终没有喝到苏打水,因为我身上只有那张 100 比索的钞票。
这个故事与 PowerShell 参数验证有何关系?让我们来分解一下。
- 汽水机作为功能
- 账单就是参数
- 50 比索和 20 比索钞票是有效参数值
- ₱100 被拒绝,因为它是错误的参数值
- 结果机器因为输入错误而没有处理我的请求。因此,我没有苏打水。 ……我也渴了!
上面的汽水机场景只是描述参数验证概念的一种类比。
参数验证逻辑流程
参数验证的概念遵循一个粗略的工作流程。下图显示了参数验证如何工作的概述。
- 该函数通过调用其名称并提供参数值在 PowerShell 中执行
- PowerShell 评估提供的值。
- 如果验证结果为真,PowerShell 将允许该函数在退出之前继续其进程。
- 如果验证结果为 false,PowerShell 将显示错误并且该函数将终止。
演练要求
本文的其余部分不仅仅讨论 PowerShell 函数参数验证,还将提供一些示例,您可以复制并自行尝试。为了跟进,您需要遵循一些事情。
- 具有以下任何 PowerShell 版本的 Windows 10 计算机:
- Windows PowerShell 5.1
- PowerShell 核心 6.2
- PowerShell Core 7(本文的最新版本是预览版 4)
- 您选择的脚本编辑器。例如,Notepad++、PowerShell ISE 或 Visual Studio Code。
了解ValidateScript验证属性
ValidateScript 是 PowerShell 3.0 中引入的可在 PowerShell 中使用的参数验证属性之一。它可以添加到函数的参数定义块内,也可以直接在PowerShell控制台中使用。
ValidateScript用于验证您输入的参数值。如果验证结果为$true
,则脚本将继续运行。另一方面,如果结果为 $false
,该函数将抛出终止错误。
让我们深入看看它是如何工作的。
在函数中使用 ValidateScript
ValidateScript 属性最常见的用途是附加到函数参数。在本部分中,您将创建一个虚拟函数并应用 ValidateScript 参数验证。
虚拟函数将执行以下操作:
- 接受金额输入。
- 验证输入的金额是否等于接受的值。
- 如果验证通过,则运行该流程。
- 如果验证失败,则显示错误。
您将在下一节中逐步学习如何构建此函数。启动脚本编辑器并开始编码!
构建函数
首先,创建一个函数并为其命名。这可以是您选择的任何名称。最佳实践是遵循动词-名词命名约定,使您的函数具有描述性。对于本示例,请使用名称 Get-Soda
。
Function Get-Soda {
[CmdletBinding()]
param ()
}
在 param()
块内,插入您将使用的参数名称,即 Bill
。
Function Get-Soda {
[CmdletBinding()]
param (
$Bill
)
}
此时,该函数除了接受 Bill
参数的任何值之外,尚未执行任何操作。
确保您已将 Get-Soda
函数复制到 PowerShell 控制台中。将函数导入 PowerShell 会话后,通过运行命令来测试函数:Get-Soda -Bill 100
。
当您运行 Get-Soda
函数时,您会注意到没有抛出任何错误,并且它什么也不做。这是目前预计的情况。
添加参数验证
也许您不想允许将所有值传递给 Bill
参数。使用本文顶部解释的类比,该函数不应允许 100 比索的钞票。它应该只允许 50 比索和 20 比索的钞票。
通过在 Bill
参数之前插入 [ValidateScript()]
添加 ValidateScript 参数验证。您的函数应该类似于下面的代码。
Function Get-Soda {
[CmdletBinding()]
param (
[ValidateScript()]
$Bill
)
}
在[ValidateScript()]
块内部,插入验证代码{$_ -eq 20}
。此验证代码检查提供给 bill 参数的值是否等于 20。下面的代码片段是代码的样子。
注意:$_
表示作用域中当前参数的值。在此示例中,$_
的值是参数 Bill
的值。
Function Get-Soda {
[CmdletBinding()]
param (
[ValidateScript({$_ -eq 20})]
$Bill
)
}
现在再次运行此函数,通过运行以下命令来确认参数验证是否正常工作:
PS51> Get-Soda -Bill 20
PS51> Get-Soda -Bill 30
下面您可以看到,当 20 作为值传递时,不会发生任何事情,但当传递 20 以外的任何值时,它会引发错误。
当Get-Soda
函数没有抛出错误时,意味着函数执行成功。为了演示这一点,请在函数内添加以下代码,以简单地将消息返回到控制台。
Write-Host "$Bill is an accepted value. Please select your soda."
Get-Soda
函数将如下所示:
Function Get-Soda {
[CmdletBinding()]
param (
[ValidateScript({$_ -eq 20})]
$Bill
)
Write-Host "$Bill is an accepted value. Please select your soda."
}
现在将一个接受的值(例如 20)传递给 Bill
参数。您应该看到下面的结果。
显示更有意义的错误消息
相信你现在已经注意到,当参数值没有通过验证时返回的错误消息不是很直观,而且很难看。
遗憾的是,您对错误的外观无能为力。在发布支持验证错误格式的功能(希望如此)之前,您将不得不使用它。
但是,可以对其进行一点改进,并赋予错误更多含义,这可以使您的用户受益。接下来您将看到如何执行此操作的示例。
使用 Windows PowerShell 添加自定义验证错误 (5.1)
扩展 Get-Soda
函数,当值不符合验证时,可以抛出特定的错误消息。为此,您可以在 ValidateScript 块内添加 if/then 构造。
创建一个简单的 if/then 结构,如下例所示。在此示例中,如果 Bill
参数值不等于 20,它将返回您选择的错误消息(X 无效。有效值为 20。
) 。
您可以在下面看到一个示例:
Function Get-Soda {
[CmdletBinding()]
param (
[ValidateScript({
if ($_ -eq 20) {
$true
} else {
throw "$_ is invalid. Valid value is 20 only."
}
})]
$bill
)
process {
Write-Host "$bill is an accepted value. Please select your soda."
}
}
下面的屏幕截图显示了正在运行的自定义错误消息。该错误看起来仍然很难看,但这次消息清晰易懂。
使用 PowerShell Core 添加自定义验证错误 (6+)
从 PowerShell Core 6 开始,已经内置了向 ValidateScript 参数验证添加自定义错误消息的功能。我们将其称为ErrorMessage 技术。
在下面修改后的 Get-Soda
函数代码中,[ValidateScript()]
块现在包含一个 ErrorMessage
属性,可以在以下位置使用 ErrorMessage
属性:代码>抛出。现在,您可以使用 {0}
来代替 $_
变量,它代表传递的参数值。
Function Get-Soda {
[CmdletBinding()]
param (
[ValidateScript({
$_ -eq 20
},
ErrorMessage = "{0} is invalid. Valid value is 20 only."
)]
$Bill
)
Write-Host "$Bill is an accepted value. Please select your soda."
}
下面的屏幕截图显示预期输出与使用 if-else 和 throw 技术完全相同。
PowerShell ValidateScript 用法示例
这些是一些可以应用 ValidateScript 的实际用例场景。查看并测试这些示例,然后尝试使用您在上一节中学到的技术自行改进错误消息。
日期参数验证
此代码片段是一个接受开始日期和结束日期的函数。它会验证输入的日期不是将来的日期且不早于 90 天。
<#
Dummy function to search logs.
Accepts the following parameters.
* startDate
- date must not be older than 90 days.
- date must not be in the future.
* endDate
- date must not be older than 90 days.
- date must not be in the future.
#>
Function Search-Log {
[CmdletBinding()]
param (
[parameter(Mandatory)]
[ValidateScript({
($_ -gt (Get-Date -Hour 0 -Minute 0 -Second 0).AddDays(-90) -and $_ -le (Get-Date))
})]
[datetime]$startDate,
[parameter(Mandatory)]
[ValidateScript({
($_ -gt (Get-Date -Hour 0 -Minute 0 -Second 0).AddDays(-90) -and $_ -le (Get-Date))
})]
[datetime]$endDate
)
process {
Write-Host "I will search the logs between [$startDate] and [$endDate"]
}
}
使用这些命令测试该功能。您可以指定自己的 startDate
和 endDate
值
#TEST: Dates are valid
$startDate = (Get-Date).AddDays(-90) #Today - 90 days
$endDate = (Get-Date) # Today
search-log -startDate $startDate -endDate $endDate
下面的示例输出是输入有效日期值时的输出。
现在使用超过 90 天的 startDate
再次测试它。然后确认是否显示错误消息。
Windows 进程参数验证
下一个代码片段是一个接受进程名称的函数。它确认进程正在内存中运行,然后根据验证结果杀死该进程的所有正在运行的实例或退出。
<#
A function to kill all instances of a process.
Usage: Kill-Process -name <process name>
Example: Kill-Process -name notepad
#>
Function Kill-Process {
[CmdletBinding()]
param (
[parameter(Mandatory)]
[ValidateScript(
{
if (Get-Process -Name $_) {
$true
}
else {
throw "A process with name $_ is not found."
}
}
)]
[string]$Name
)
process {
Write-Host "Killing Process: $Name"
Stop-Process -Name $Name -Force
}
}
使用以下命令进行测试:Kill-Process -Name
下面的示例输出假设您正在使用名为 notepad 的进程进行测试。
- 第一个命令成功运行,因为它发现 notepad 进程正在运行并继续终止它。
- 第二个命令失败,因为 notepad 不再运行,并且该函数以您创建的自定义错误消息结束。
通过另一个参数值验证参数
现在您应该了解在函数中使用 ValidateScript 的价值。但有一个限制值得一提。 ValidateScript的范围仅在使用的参数内。这意味着一个参数不能使用其他参数的值。
作为解决方法,可以通过访问 $PSBoundParameters
自动变量来完成跨参数值检查。
也许您有一个名为 Send-Spam
的函数。该函数有三个参数:
发件人
- 发件人的电子邮件地址。 (例如[电子邮件受保护])。不是强制性的。To
- 收件人的电子邮件地址。 (例如[电子邮件受保护])。不是强制性的。SendEmail
- 不需要值的开关参数。但如果使用,则需要From
和To
参数值。
如果使用 SendEmail
开关,将运行验证代码以确认使用了 From
和 To
参数。然后它将返回True
值。另一方面,如果 From
和 To
未使用,该函数将抛出错误并退出。
将以下代码复制并粘贴到您的 PowerShell 会话中。
<#
Dummy function to send spam
Accepts the parameters
From
- sender email address
- cannot be null or empty
To
- recipient email address
- cannot be null or empty
SendEmail
- a switch (on/off) parameter.
- it will validate if 'To' and 'From' values are present.
Usage: Send-Spam -From [email -To [email -SendEmail
#>
Function Send-Spam {
[CmdletBinding()]
param (
[parameter()]
[ValidateNotNullOrEmpty()] #Ensure From is not equal to $null or ""
[mailaddress]$From,
[parameter()]
[ValidateNotNullOrEmpty()] #Ensure To is not equal to $null or ""
[mailaddress]$To,
[parameter()]
[ValidateScript(
{
# Check if the From and To parameters are specified
if ($PSBoundParameters.Keys -contains 'From' -AND
$PSBoundParameters.Keys -contains 'To') {
$true
}
else {
throw "From and To parameters are required when using SendEmail"
}
}
)]
[switch]$SendEmail
)
process {
Write-Host "From: $From" -ForegroundColor Yellow
Write-Host "To: $To" -ForegroundColor Cyan
if ($SendEmail) {
Write-Host "Sending Spam from '$From' to '$To'" -ForegroundColor Green
}
}
}
下面显示的命令将导致验证成功。因为 From
和 To
参数与 SendEmail
开关一起使用。
PS51> Send-Spam -From [email -To [email -SendEmail
现在,不使用 From
或 To
参数进行测试。这应该会导致错误,因为验证脚本将失败。请参阅下面的示例结果。
在控制台中使用 ValidateScript
尽管 ValidateScript 属性最常见的用途是用于验证函数参数,但它也可以直接从 PowerShell 控制台使用。 ValidateScript 对于测试您的验证代码非常有用,甚至在将其合并到脚本或函数之前也是如此。
以下是在函数外部使用 ValidateScript 的一些示例。
验证整数值
下面的示例验证给定的整数值是否大于 5。
[ValidateScript({$_ -gt 5})]$i=4
运行上述代码后,预期结果失败,因为给定值为 4,小于 5。下面的示例屏幕截图就是您期望看到的内容。
验证日期值
下面的下一个示例代码显示如何验证给定日期是否晚于或等于当前日期。
[DateTime][ValidateScript({$_ -ge (Get-Date)})]$date = (Get-Date)
[DateTime][ValidateScript({$_ -ge (Get-Date)})]$date = (Get-Date).AddHours(-1)
运行上述代码片段中的第一行代码后,预期结果已通过 (True),因为提供的 DateTime 值相同或稍大几秒。
第二行代码将产生失败的结果,因为 DateTime 值比当前时间少一小时。请参阅下面的屏幕截图以获取示例输出。
概括
在本文中,您了解了参数验证是什么以及如何使用 ValidateScript 参数验证属性。
您还了解了如何扩展其功能以显示更具描述性的错误消息。在遵循示例时,您已经体验了成功和失败验证的结果。
您现在应该了解 ValidateScript 在跨参数引用方面的限制,以及如何利用 $PSBoundParameters
自动变量来解决该限制。
我希望您在本文中学到了足够的知识,可以在您的 PowerShell 工具制作之旅中应用!
进一步阅读
- Powershell功能介绍
- 了解和构建 PowerShell 模块
- ValidateScript 验证属性
- 关于投掷
猜你还喜欢
- 03-30 [玩转系统] 如何用批处理实现关机,注销,重启和锁定计算机
- 02-14 [系统故障] Win10下报错:该文件没有与之关联的应用来执行该操作
- 01-07 [系统问题] Win10--解决锁屏后会断网的问题
- 01-02 [系统技巧] Windows系统如何关闭防火墙保姆式教程,超详细
- 12-15 [玩转系统] 如何在 Windows 10 和 11 上允许多个 RDP 会话
- 12-15 [玩转系统] 查找 Exchange/Microsoft 365 中不活动(未使用)的通讯组列表
- 12-15 [玩转系统] 如何在 Windows 上安装远程服务器管理工具 (RSAT)
- 12-15 [玩转系统] 如何在 Windows 上重置组策略设置
- 12-15 [玩转系统] 如何获取计算机上的本地管理员列表?
- 12-15 [玩转系统] 在 Visual Studio Code 中连接到 MS SQL Server 数据库
- 12-15 [玩转系统] 如何降级 Windows Server 版本或许可证
- 12-15 [玩转系统] 如何允许非管理员用户在 Windows 中启动/停止服务
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[影视] 黑道中人 Alto Knights(2025)剧情 犯罪 历史 电影
[古装剧] [七侠五义][全75集][WEB-MP4/76G][国语无字][1080P][焦恩俊经典]
[实用软件] 虚拟手机号 电话 验证码 注册
[电视剧] 安眠书店/你 第五季 You Season 5 (2025) 【全10集】
[电视剧] 棋士(2025) 4K 1080P【全22集】悬疑 犯罪 王宝强 陈明昊
[软件合集] 25年6月5日 精选软件22个
[软件合集] 25年6月4日 精选软件36个
[短剧] 2025年06月04日 精选+付费短剧推荐33部
[短剧] 2025年06月03日 精选+付费短剧推荐25部
[软件合集] 25年6月3日 精选软件44个
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电视剧] 欢乐颂.5部全 (2016-2024)
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[影视] 【稀有资源】香港老片 艺坛照妖镜之96应召名册 (1996)
[剧集] 神经风云(2023)(完结).4K
[剧集] [BT] [TVB] [黑夜彩虹(2003)] [全21集] [粤语中字] [TV-RMVB]
[实用软件] 虚拟手机号 电话 验证码 注册
[资源] B站充电视频合集,包含多位重量级up主,全是大佬真金白银买来的~【99GB】
[影视] 内地绝版高清录像带 [mpg]
[书籍] 古今奇书禁书三教九流资料大合集 猎奇必备珍藏资源PDF版 1.14G
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电影] 美国队长4 4K原盘REMUX 杜比视界 内封简繁英双语字幕 49G
[电影] 死神来了(1-6)大合集!
[软件合集] 25年05月13日 精选软件16个
[精品软件] 25年05月15日 精选软件18个
[绝版资源] 南与北 第1-2季 合集 North and South (1985) /美国/豆瓣: 8.8[1080P][中文字幕]
[软件] 25年05月14日 精选软件57个
[短剧] 2025年05月14日 精选+付费短剧推荐39部
[短剧] 2025年05月15日 精选+付费短剧推荐36部
- 最新评论
-
- 热门tag