英文:
How do I configure help and usage statements in a powershell script?
问题 {#heading}
核心方法是在 PowerShell 脚本中使用 CmdletBinding 和 Param 块来定义参数和帮助信息。以下是示例 PowerShell 脚本 foo.ps1
,其中定义了参数和帮助信息:
<# test foo.ps1 #>
param(
[CmdletBinding()]
[Switch]$foo,
[Switch]$bar
)
<#
.SYNOPSIS
This is a sample PowerShell script with custom parameters.
.DESCRIPTION
This script demonstrates the usage of custom parameters in PowerShell.
.PARAMETER foo
The -foo switch parameter does something.
.PARAMETER bar
The -bar switch parameter does something else.
.EXAMPLE
.\foo.ps1 -foo
This example shows how to use the -foo parameter.
.EXAMPLE
.\foo.ps1 -bar
This example shows how to use the -bar parameter.
.NOTES
File Name : foo.ps1
Author : Your Name
Prerequisite : PowerShell
Copyright 2023 - Your Company
#>
# Rest of your script code goes here
在这个示例中,我们使用了 param
块来定义了 -foo
和 -bar
参数,并使用了 [CmdletBinding()]
来启用高级的参数处理功能,如 -Debug
和 -Verbose
。帮助信息放在 <# ... #>
注释块中,可以通过 --help
或 Get-Help
命令来查看。
这样做可以使你的脚本更加用户友好,让用户可以轻松地查看和理解脚本的参数和功能。 英文:
Suppose I have the powershell script foo.ps1
:
<# test foo.ps1 #>
param(
[CmdletBinding()]
[Switch]$foo,
[Switch]$bar
)
Which has a few automatic parameters like -Debug
and -Verbose
in addition to the custom parameters -foo
and -bar
.
I should be able to see all of these parameters when I do something like .\foo.ps1 --help
, or I should be able to configure that somehow.
What is the core way to do this in powershell?
答案1 {#1}
得分: 2
Get-Command
会返回完整的参数列表,包括常见参数:
$myScript = Get-Command .\foo.ps1
# 这是一个包含所有参数的字典
$myScript.Parameters
# 我们可以像处理其他字典一样检查给定参数的参数元数据
$myScript.Parameters['bar']
关于Get-Help
,这部分已经为您处理了 - 当您添加了CmdletBinding
后,在执行Get-Help .\foo.ps1
或.\foo -?
时,PowerShell将自动将[<CommonParameters>]
添加到命令语法字符串中,以指示接受常见参数:
没有[CmdletBinding()]
装饰器:
f [-foo] [-bar]
使用了[CmdletBinding()]
装饰器(或任何参数属性装饰器):
f [-foo] [-bar] [<CommonParameters>]
如果您想要显示更丰富的帮助内容,则需要提供它 英文:
Get-Command
will return you the full list of parameters, including common parameters:
$myScript = Get-Command .\foo.ps1
this is a dictionary containing all the parameters
==================================================
$myScript.Parameters
we can index into it like any other dictionary to inspect the parameter metadata for a given parameter
======================================================================================================
`$myScript.Parameters['bar']
`
With regards to Get-Help
, that part is already taken care of for you - when you do Get-Help .\foo.ps1
or .\foo -?
after adding a CmdletBinding, PowerShell will automatically add [<CommonParameters>]
to the command syntax string to indicate that common parameters are accepted:
Without [CmdletBinding()]
decorator:
f [-foo] [-bar]
With [CmdletBinding()]
decorator (or any parameter attribute decorators) specified:
f [-foo] [-bar] [<CommonParameters>]
If you want richer help content displayed, then you'll need to provide it
答案2 {#2}
得分: 0
为了补充Mathias的有用回答:
-
概念性的about_Command_Syntax帮助主题讨论了PowerShell的_语法图表_,这是PowerShell用于记录命令支持的参数、它们的数据类型、它们是否是强制的以及它们是否可以被绑定位置的符号表示法。
-
通用参数 (如
-Debug
和-Verbose
)是由编译的cmdlet和高级函数和脚本<sup>[1]</sup>_隐式支持的,它们在概念性的about_CommonParameters帮助主题中有文档。 -
通用参数在语法图表中从不单独显示,只显示为集体占位符
[<CommonParameters>]
,如Mathias的回答中所示。 -
由于一个_bug_,至少在PowerShell(Core)7.3.6之前,如果非高级函数和脚本恰好定义了_基于注释的帮助_,则此占位符也会错误地显示为非高级函数和脚本的支持,详细信息请参阅概念性的about_Comment_Based_Help帮助主题;这里有一个最小的示例:
# !! 输出错误地建议Get-Foo支持通用参数。 function Get-Foo { <#.SYNOPSIS #> }; Get-Foo -?
- 相关的bug报告是GitHub问题#17312
-
语法图表可以通过参数
-?
(适用于cmdlet和_高级_函数和脚本以及具有基于注释的帮助的函数和脚本,即使非高级的情况下也适用),Get-Help
(适用于任何命令,除了外部程序),以及Get-Command
-Syntax
来显示,后者直接从命令的定义中获取信息,而Get-Help
可能会从外部帮助文件中获取信息,如果存在的话;由于帮助文件可能与实际实现不同步,Get-Command -Syntax
是更可靠的来源。 -
语法图表从不单独显示通用参数有点不幸:
-
以下两个通用参数不受所有cmdlet /高级函数和脚本的支持,因为它们需要通过
[CmdletBinding()]
属性的ShouldProcess
属性进行选择: -
正如Mathias所指出的,
(Get-Command ...).Parameters
允许您枚举给定命令的_所有_参数 - 但您不能以编程方式告诉哪些是_通用_参数 - 您将不得不通过它们的名称来识别它们。-
作为列出_只有_命令的通用参数的_近似_方法 - 这还将告诉您是否支持
-WhatIf
和-Confirm
,您可以使用以下方法,但请注意它可能会产生误报(使用Remove-Item
作为示例命令):# 列出Remove-Item支持的所有通用参数。 (Get-Command Remove-Item).Parameters.Values | Where { $_.Aliases[0] -like '??' -or $_.Name -eq 'InformationAction' } | ForEach-Object Name
- 以上利用了所有通用参数都有_两个字母的别名_的事实,例如
-wi
代表-WhatIf
- 唯一的例外是InformationAction
,其别名为-infa
。
- 以上利用了所有通用参数都有_两个字母的别名_的事实,例如
-
-
英文:
To complement Mathias' helpful answer:
-
The conceptual about_Command_Syntax help topic discusses PowerShell's syntax diagrams, which is PowerShell's notation for documenting a command's supported parameters, their data types, whether they are mandatory, and whether they can be bound positionally.
-
The common parameters (such as
-Debug
and-Verbose
) that are implicitly supported by compiled cmdlets and advanced functions and scripts<sup>[1]</sup> are documented in the conceptual about_CommonParameters help topic. -
Common parameters are never shown individually in syntax diagrams, only with the collective placeholder
[<CommonParameters>]
, as shown in Mathias' answer. -
Due to a bug , present up to at least PowerShell (Core) 7.3.6, this placeholder is mistakenly also shown for non -advanced functions and scripts, if they happen to define comment-based help , as documented in the conceptual about_Comment_Based_Help help topic; here's a minimal example:
# !! Output mistakenly suggests that Get-Foo supports common parameters. function Get-Foo { <#.SYNOPSIS #> }; Get-Foo -?
- The relevant bug report is GitHub issue #17312
-
Syntax diagrams can be shown with parameter
-?
(for cmdlets and advanced functions and scripts as well as functions and scripts with comment-based help, even if non-advanced),Get-Help
(for any command except external programs), and, in isolation, withGet-Command
-Syntax
, which takes its information directly from the command's definition, whereasGet-Help
may take its information from an external help file, if present; since a help file may get out of sync with the actual implementation,Get-Command -Syntax
is a more reliable source. -
That syntax diagrams never show enumerate the common parameters individually is somewhat unfortunate:
-
The following two common parameters aren't supported by all cmdlets / advanced functions and scripts, as they require opt-in via the
ShouldProcess
property of the[CmdletBinding()]
attribute: -
As Mathias notes,
(Get-Command ...).Parameters
allows you to enumerate all parameters of a given command - but you cannot programmatically tell which of those are common parameters - you'll have to recognize them by their names.-
As an approximation of listing only a command's common parameters - which will also tell you whether
-WhatIf
and-Confirm
is supported, you can use the following, but note that it can yield false positives (usingRemove-Item
as a sample command):# List all common parameters supported by Remove-Item. (Get-Command Remove-Item).Parameters.Values | Where { $_.Aliases[0] -like '??' -or $_.Name -eq 'InformationAction' } | ForEach-Object Name
- The above takes advantage of the fact that all common parameters have two-letter aliases , such as
-wi
for-WhatIf
- the only exception beingInformationAction
, whose alias is-infa
.
- The above takes advantage of the fact that all common parameters have two-letter aliases , such as
-
-
<sup>[1] In short: It is the use of a [CmdletBinding()]
attribute and/or of at least one parameter-individual [Parameter()]
attribute that makes a function or script and advanced one.</sup>