[玩转系统] 了解 PowerShell CmdletBinding 如何增强功能
作者:精品下载站 日期:2024-12-14 13:10:04 浏览:14 分类:玩电脑
了解 PowerShell CmdletBinding 如何增强功能
您是否曾经想要创建 PowerShell cmdlet,但不了解 C# 或其他 Microsoft .NET Framework 语言?当 PowerShell CmdletBinding
触手可及时,为什么还要“想要”呢?
在本教程中,您将学习如何使用 PowerShell CmdletBinding
属性来增强功能并使它们的行为类似于 cmdlet。
准备好?深入挖掘并让您的函数以前所未有的方式运行!
先决条件
本教程将是一个实践演示。只要您拥有安装了 PowerShell v5.1 或更高版本的 Windows 或 Linux PC,就可以开始使用 — 本教程使用安装了 PowerShell v5.1 的 Windows 10 计算机。
创建使用 PowerShell 组织文件的基本函数
在某些情况下,一个目录中可能有很多不同类型的文件,而没有良好的组织。保持文件井井有条始终是一个好习惯,因此您将创建一个基本函数来按文件扩展名将文件移动到指定文件夹。
基本的 PowerShell 函数并不被定义为只有几行代码。在这种情况下,“基本”意味着该函数缺乏 PowerShell cmdlet 的功能。该函数没有通用参数,并且无法完全控制可用参数。
1. 以管理员身份打开 Windows PowerShell ISE。
2. 将以下代码复制并粘贴到代码编辑器中,然后运行代码。下面的代码将桌面上的所有 .pdf、.doc 和 .txt 文件移动到名为“文档”的单个文件夹中。
从本教程的这一点开始,请务必将桌面文件夹路径 (C:\Users\ADMIN\Desktop\) 中的 ADMIN 替换为您的计算机用户名。
Function Group-Files
{
Param(
[string]$Path,
[string]$Folder
)
# Check if the destination folder exists. If not, then create it
If ((Test-Path -Path ($Path + "\" + $Folder)) -eq $False) {
New-Item -Name $Folder -Path $Path -ItemType Directory
}
# Move Items
Get-ChildItem $Path | ForEach-Object {
# If the last four characters of the filename ends with .pdf, .doc, .txt
If ($_.FullName.Substring($_.FullName.Length -4) -in ".pdf", ".doc", ".txt")
{
Move-Item -Path $_.FullName -Destination ($Path + $Folder)
}
}
}
# Call the Group-Files function
Group-Files -Path C:\Users\ADMIN\Desktop\ -Folder "Documents"
运行上面的代码后,您可能已经注意到所有文件都已移动,而没有要求您确认。此外,该函数没有告诉您如果运行该代码会发生什么。您将在以下部分中了解有关使用 CmdletBinding 增强功能的更多信息。
3. 最后,运行下面的 Get-Command 列出您创建的 Group-Files 函数可用的所有参数。
(Get-Command Group-Files).Parameters
使用 CmdletBinding 属性访问通用参数
您已经看到基本功能运行良好。但也许您更喜欢强制参数或添加确认操作对话框?如果是这样,CmdletBinding
属性就可以解决问题! CmdletBinding
属性允许您使用可用于 PowerShell cmdlet 的常用参数。
以下代码表示 CmdletBinding
属性的语法,包括其所有参数。
{
[CmdletBinding(
ConfirmImpact=<string>,
# Default parameter set name you want PowerShell to use
# if there is no parameter set.
DefaultParameterSetName=<string>,
# uri to online help, must begin with http or https
HelpURI=<uri>,
# Used when you’re trying to return data from a large database suchas MySQL.
SupportsPaging=<boolean>,
# Adds three parameters - First, Skip, and IncludeTotalCount to the function.
SupportsShouldProcess=<boolean>,
# positional binding binds positions to parameters
PositionalBinding=<boolean>) as defined
]
# It's important to use the Param keyword
Param ($Parameter1)
Begin{}
Process{}
End{}
}
现在,运行下面的 Group-Files
函数,添加 CmdletBinding
属性,以使其能够访问常用参数并显示所有可用参数。
Function Group-Files
{
[CmdletBinding()]
Param(
[string]$Path,
[string]$Folder
)
#...
}
# Gets all parameters available for the Group-Files function
(Get-Command Group-Files).Parameters
您现在可以在下面看到 Group-Files
函数具有比您之前定义的更多的参数。所有常用参数现在都可供该函数使用。
添加 -WhatIf
开关以双重检查任务
您已经了解了基本函数的工作原理,但函数还可以用于更令人难以置信的事情。您可以通过多种方式创建高级函数,例如使用开关参数。
PowerShell 中的开关参数允许您向函数添加控件。如果开关为 True,则将运行一个操作;如果开关为 False,则将运行另一个操作。
高级功能的工作方式类似于 PowerShell cmdlet。通过高级功能,您可以访问 cmdlet 可用的所有常用参数。但正如您所见,高级功能是用 PowerShell 语言编写的,而 cmdlet 是用 Microsoft .NET Framework 语言(例如 C#)编写的。
用于风险缓解的高级开关只有两个:WhatIf
和 Confirm
开关。但您将开始使用本教程中的 -WhatIf
开关。通过此开关,您可以检查如果运行影响较大的函数会发生什么情况(空运行)。
要了解该开关的工作原理,请在 PowerShell 上使用 -WhatIf
开关运行以下命令。该命令显示“What if”消息,解释运行 New-Item 命令的操作。
New-Item -Name AdamBertram -Path C:\Users\ADMIN\Desktop -ItemType Directory -WhatIf
现在,运行下面的代码并添加 CmdletBinding
,以便在调用函数时可以访问 -WhatIf
。
从现在开始,您将学习如何逐步增强 Group-Files 功能并使用 Write-Host 命令确认操作。在本教程的最后,您将看到增强功能的最终结构。
Function Group-Files
{ # Set SupportsShouldProcess to True, to make -WhatIf and -Confirm accessible
[CmdletBinding(SupportsShouldProcess=$True)]
Param(
[string]$Path,
[string]$Folder
)
If ($PSCmdlet.ShouldProcess($Path)) {
Write-Host "WhatIf wasn't used, moving files..."
}
Else {
Write-Host "WhatIf has been used! Doing nothing..."
}
}
# Calls the Grou-File function
Group-Files -Path C:\Users\ADMIN\Desktop\ -Folder "Documents" -WhatIf
有一个名为 $WhatIfPreference 的系统变量,默认设置为 false。但是当变量为true时,Group-Files函数将被自动调用 -WhatIf
您可以在下面的屏幕截图中看到,该函数根据您是否使用 -WhatIf
开关打印出两条不同的消息。
使用 -Confirm
开关确认操作
与 -WhatIf
开关类似,-Confirm
开关告诉您特定函数或命令将执行什么操作。但是,在函数中添加 -Confirm
开关的好处是,您将收到确认要执行的操作的提示。
当您的函数需要执行高风险操作(例如移动或删除文件)时,添加 -Confirm
开关会派上用场。
在执行指定操作之前,运行以下代码以提示确认 (-Confirm
)。 -Confirm
参数仅在 SupportsShouldProcess
为 true 时才起作用,类似于 -WhatIf
。
Function Group-Files
{
# Set SupportsShouldProcess to True to make -WhatIf and -Confirm accessibly
[CmdletBinding(SupportsShouldProcess=$True)]
Param([string]$Path, [string]$Folders)
# If the user confirmed Yes, or user didn't use -Confirm
If ($PSCmdlet.ShouldProcess($Path)) {
Write-Host "Files Moved"
}
# If the user confirmed No
Else {
Write-Host "Action Declined"
}
}
# Calls the Group-Files function
Group-Files -Path C:\Users\ADMIN\Desktop\ -Folder "Documents" -Confirm
现在,选择是否执行该操作的选项。 $PSCmdlet 自动变量中的 ShouldProcess 方法将用于控制是否移动文件。
如果您选择确认操作,您将在 PowerShell 终端中看到下面显示的消息。否则,您将收到“操作被拒绝”的消息。
设置功能的影响级别
也许您想为您的函数设置影响级别,而不仅仅是依赖 -Confirm 开关。如果是这样,通过在 CmdletBinding 中添加ConfirmImpact 参数来设置对函数的确认影响即可解决问题。
以下是 CmdletBinding
的语法。 ConfirmImpact
参数的级别决定了函数要执行的操作的“破坏性”。
[CmdletBinding(SupportsShouldProcess=$True, ConfirmImpact='level')]
您可以将 ConfirmImpact
参数的级别设置为以下之一:
None
- PowerShell 不会提示确认任何操作,除非您使用-Confirm
开关。低
- 低、中、高风险的操作将被自动确认。Medium
-ConfirmImpact
参数的默认级别,其中 PowerShell 提示确认具有中度或高风险的操作,例如删除文件。高
- PowerShell 提示用户,就像使用-Confirm
参数调用该函数一样。
现在,运行下面的代码来查看 ConfirmImpact
参数和首选项 $ConfirmPreference
变量如何并行工作。
ConfirmImpact
的操作取决于 $ConfirmPreference
变量的值。如果您将 ConfirmImpact
级别设置为等于或大于 $ConfirmPreference
变量的值,您将收到确认提示。
$ConfirmPreference='High' # Sets confirmation preference
Function Group-Files
{
# Sets -WhatIf, -Confirm and ConfirmImpact accessible
[CmdletBinding(SupportsShouldProcess=$True, ConfirmImpact='High')]
Param([string]$Path, [string]$Folders)
# If the user confirmed Yes, or user didn't use -Confirm
If ($PSCmdlet.ShouldProcess($Path)) {
Write-Host "Files Moved"
}
# If the user confirmed No
Else {
Write-Host "Action Declined"
}
}
# Calls the Group-Files function
Group-Files -Path C:\Users\ADMIN\Desktop\ -Folder "Documents"
由于 ConfimImpact
级别等于 $ConfirmPreference
变量值,因此即使不使用 -Confirm
开关,PowerShell 也会提示确认,如下所示。
使用 Write-Verbose
语句显示更多信息
除了您在前面的示例中看到的参数之外,CmdletBinding
还提供了许多其他常见参数,例如 -Verbose
。
-Verbose
参数显示有关代码中正在执行的操作的更多信息。但是你如何在你的函数中使用它呢?通过在函数中添加 Write-Verbose
语句。
运行下面的代码以查看 Write-Verbose
语句如何在函数上工作以显示消息。
Function Group-Files
{
[CmdletBinding(SupportsShouldProcess=$True)]
Param([string]$Path, [string]$Folder)
Write-Verbose "Creating the folder if it doesn't exist..."
# If the user confirmed Yes, or user didn't use -Confirm switch
If ($PSCmdlet.ShouldProcess($Path)) {
Write-Host "Files will be moved"
Write-Verbose "Moving files..."
}
# If the user confirmed No
Else {
Write-Host "Files will not be moved"
}
}
# Calls the Group-Files function
Group-Files -Path C:\Users\ADMIN\Desktop\ -Folder "Documents"
您可以在下面看到,当使用 -Verbose
参数调用函数时,PowerShell 在输出中显示 VERBOSE 消息。
在函数运行时打印详细消息有助于在出现问题时进行故障排除,因为您事先确切知道函数当前正在执行的操作。
需要注意的一个关键问题是,虽然 cmdlet 随处可用,但高级功能只能在当前会话中访问。并且在高级函数中只能使用少数自动变量。例如,$args 自动变量对于高级函数不可用。
使用 Parameter
属性控制参数
Group-Files 函数只有两个参数,这就是该函数所需的全部内容。但明确定义这两个参数的行为是一种很好的做法。
例如,如果没有参数,运行Group-Files
函数将无法工作,因此您将$Path
参数设置为强制参数。同时,您将为 $Folders
参数设置默认值。
以下是 Parameter
属性及其所有参数的语法。
Param
(
[Parameter(
Mandatory=<Boolean>,
Position=<Integer>,
ParameterSetName=<String>,
ValueFromPipeline=<Boolean>,
ValueFromPipelineByPropertyName=<Boolean>,
ValueFromRemainingArguments=<Boolean>,
HelpMessage=<String>,
)]
[string[]]
$Parameter1
)
现在,运行以下代码以使 $Path
参数成为必需参数。
Function Group-Files
{
[CmdletBinding(
SupportsShouldProcess=$True # Since you're using the common parameters
)]
Param(
[Parameter(
Mandatory=$True,
Position=0,
# Since the Path parameter can also get its value from a pipeline input,
# provide access to the pipeline input
ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True
)]
[string]$Path,
[Parameter(
Mandatory=$False,
Position=1
)]
[string]$Folder = "Documents" # Default value of $Folder parameter
)
# If the user confirmed Yes, or user didn't use -Confirm
If ($PSCmdlet.ShouldProcess($Path)) {
Write-Host "Files will be moved"
Write-Verbose "Moving files..."
}
# If the user confirmed No
Else {Write-Host "Files will not be moved"}
}
# Calls the Group-Files function without the -Path parameter
Group-Files -Folder "Documents"
使用 CmdletBinding
和 Parameter
属性改进功能
到目前为止,您已经尝试了 CmdletBinding
和 Parameter
属性,因此是时候为 Group-Files
添加最后的润色了功能。您将使用所有必要的参数和属性来改进该函数。
此外,您将在下面添加验证属性,以确保用户输入正确的参数值。
ValidateScript
- 用于$Path
参数,以确保路径是文件夹而不是文件。ValidateCount
- 确保$Folder
的最小和最大参数。
运行以下代码,其中包含 Group-Files
函数的所有必要详细信息,使其更像高级函数一样工作。
下面的代码检查您的桌面上是否有以 .doc
、.pdf
或 .txt
结尾的文件,并在将它们移动到 文档文件夹。
Function Group-Files
{
[CmdletBinding(
SupportsShouldProcess=$True, # Allows the use of -Confirm and -Whatif
PositionalBinding=$True, # Binds Path and Folder by their position
ConfirmImpact="Medium" # Confirms before moving files
)]
Param(
[Parameter(
Mandatory=$True,
ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True,
HelpMessage="Enter a source folder path"
)]
# Validate the path is a folder and not a file
[ValidateScript({Test-Path $_ -PathType Container})]
[String]$Path,
[Parameter(
Mandatory=$False,
HelpMessage="Enter a destination path"
)]
[ValidateCount(1,1)] # Must provide 1 argument/folder name
[String]$Folder = "Documents"
)
Begin {
# Uncomment the line below to activate -whatif
# $WhatIfPreference = $True
# Uncomment the line below not to ask for confirmation when moving each file
# $ConfirmPreference = "High"
}
# Contains the main part of the function
Process {
# Check if folders exist. If not, then create them
If ((Test-Path -Path ($Path + "\" + $Folder)) -eq $False) {
#Write-Host ($Path+"\"+$_) does not exist!
Write-Verbose "Creating folder $($Path+"\"+$Folder) since it does not exist."
New-Item -Name $Folder -Path $Path -ItemType Directory
}
# Debug message
Write-Debug "Make sure files are not opened with any program before moving."
# If the user confirmed Yes, or user didn't use -Confirm
If ($PSCmdlet.ShouldProcess($Path)) {
Write-Host "Files will be moved"
# Get all the files in the $Path directory
Write-Verbose "Moving files..."
Get-ChildItem $Path | ForEach-Object {
# Documents
If ($_.FullName.Substring($_.FullName.Length -4) -in ".pdf", ".doc", ".txt") {
Write-Verbose "Moving file $($_.FullName) to $($Path + $Folder)"
Move-Item -Path $_.FullName -Destination ($Path + $Folder)
}
}
}
# If the user confirmed No
Else {
Write-Host "Files will not be moved"
}
}
}
# Call the Group-Files function
Group-Files -Verbose -Debug
结论
本教程旨在教您如何增强基本功能。做得好吗?您已经逐步创建了高级功能并获得了已编译 cmdlet 的功能。此时,您已经可以使用 PowerShell 函数创建自己的 cmdlet。
现在,为什么不增强旧脚本中的功能以使其更先进!
猜你还喜欢
- 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