下面我将从最简单到最复杂,详细讲解 PowerShell 接收参数的各种方式。

(图片来源网络,侵删)
使用位置参数 (Positional Parameters)
这是最直接、最简单的方式,参数的顺序决定了它们的值。
直接使用变量
在脚本中,任何以 开头的变量,如果前面没有声明,都可以直接作为参数接收,变量的名就是参数名,变量的值就是传入的值。
脚本示例 Get-UserInfo.ps1:
# 脚本直接使用 $UserName 和 $Age 变量
# 如果脚本运行时没有提供这两个值,它们会是 $null
Write-Host "用户名: $UserName"
Write-Host "年龄: $Age"
# 可以对参数进行一些逻辑判断
if ($Age -gt 18) {
Write-Host "$UserName 是成年人。"
} else {
Write-Host "$UserName 是未成年人。"
}
如何运行:

(图片来源网络,侵删)
# 按顺序传入值,$UserName 得到 "张三",$Age 得到 25 .\Get-UserInfo.ps1 "张三" 25 # 输出: # 用户名: 张三 # 年龄: 25 # 张三是成年人。
注意: 这种方式虽然简单,但缺点是:
- 调用时必须严格按照参数顺序。
- 如果脚本逻辑变了,参数顺序也变了,所有调用脚本的地方都需要修改,非常不健壮。
使用 param 关键字 (推荐)
这是 PowerShell 最标准、最推荐 的方式,它将所有参数集中定义在脚本的开头,使脚本结构更清晰,功能也更强大。
1 基本用法
param 关键字定义了一个参数块,你可以在其中声明参数及其类型。
脚本示例 Get-UserInfo-Param.ps1:

(图片来源网络,侵删)
param(
[string]$UserName, # 定义一个名为 UserName 的字符串参数
[int]$Age # 定义一个名为 Age 的整数参数
)
Write-Host "用户名: $UserName"
Write-Host "年龄: $Age"
如何运行:
# 使用位置参数调用(顺序与 param 块中定义的顺序一致) .\Get-UserInfo-Param.ps1 "李四" 30 # 输出: # 用户名: 李四 # 年龄: 30
2 指定参数名调用
使用 param 定义后,就可以通过 参数名=值 的方式调用,不再受顺序限制,这大大提高了脚本的可读性和健壮性。
# 使用参数名调用,顺序可以任意 .\Get-UserInfo-Param.ps1 -Age 30 -UserName "李四" # 也可以使用等号 .\Get-UserInfo-Param.ps1 -UserName="李四" -Age=30
3 为参数添加属性 (Attributes)
param 块中的每个参数都可以附加多个属性,来控制其行为。
- Mandatory (强制): 如果标记为
[Mandatory()],运行脚本时必须提供该参数,否则会报错。 - HelpMessage (帮助信息): 当用户只提供参数名而不提供值时,会显示这条帮助信息。
- ValueFromPipeline (管道输入): 允许将对象通过管道传递给此参数。
- ValueFromRemainingArguments (剩余参数): 将所有未匹配的参数收集到一个数组中。
- ValidateSet (验证集合): 参数的值必须是集合中指定的一个。
- ValidateRange (验证范围): 参数的值必须在指定的数值范围内。
- Default (默认值): 如果参数未提供,则使用此默认值。
脚本示例 Get-UserInfo-Advanced.ps1:
param(
[Parameter(Mandatory=$true, HelpMessage="请输入用户名")]
[string]$UserName,
[Parameter(Mandatory=$true)]
[ValidateRange(1, 120)]
[int]$Age,
[Parameter(HelpMessage="请输入用户所在的部门")]
[string]$Department = "未指定" # 提供默认值
)
Write-Host "--- 用户信息 ---"
Write-Host "姓名: $UserName"
Write-Host "年龄: $Age"
Write-Host "部门: $Department"
Write-Host "-----------------"
如何运行:
# 正确调用 .\Get-UserInfo-Advanced.ps1 -UserName "王五" -Age 28 -Department "研发部" # 输出: # --- 用户信息 --- # 姓名: 王五 # 年龄: 28 # 部门: 研发部 # ----------------- # 不提供强制参数会报错 .\Get-UserInfo-Advanced.ps1 -UserName "王五" # 会提示: # cmdlet Get-UserInfo-Advanced 在命令管道位置 1 # 提供了以下参数: # Age: 必须提供该参数。 # UserName: 请输入用户名 # 提供的年龄超出验证范围会报错 .\Get-UserInfo-Advanced.ps1 -UserName "王五" -Age 150 # 会提示: # 所提供的参数 "Age" 的值 "150" 无效,参数 "Age" 的有效值为 "1" 到 "120",请指定一个有效的参数值,然后再次尝试该命令。 # 不提供可选参数,会使用默认值 .\Get-UserInfo-Advanced.ps1 -UserName "王五" -Age 25 # 输出: # --- 用户信息 --- # 姓名: 王五 # 年龄: 25 # 部门: 未指定 # -----------------
接收开关参数
开关参数是一种特殊的布尔参数,它没有值,它的作用是标志某个功能是否启用。
脚本示例 Toggle-Feature.ps1:
param(
[switch]$Verbose # 定义一个开关参数
)
if ($Verbose.IsPresent) {
Write-Host "详细模式已开启,正在执行复杂操作..."
# 这里可以放一些详细的日志输出
} else {
Write-Host "正在执行操作..."
}
Write-Host "操作完成。"
如何运行:
# 不提供 -Verbose 开关 .\Toggle-Feature.ps1 # 输出: # 正在执行操作... # 操作完成。 # 提供 -Verbose 开关 .\Toggle-Feature.ps1 -Verbose # 输出: # 详细模式已开启,正在执行复杂操作... # 正在执行操作... # 操作完成。
开关参数非常方便,因为它不需要你传递 $true 或 $false。
接收参数数组
当你需要接收一个或多个同类型的值时,可以将参数的类型声明为 array。
脚本示例 Install-Apps.ps1:
param(
[string[]]$AppNames # 注意 [],表示这是一个字符串数组
)
Write-Host "准备安装以下应用:"
foreach ($app in $AppNames) {
Write-Host "- $app"
}
如何运行:
# 传入多个值,用逗号分隔 .\Install-Apps.ps1 -AppNames "VSCode", "Git", "Docker" # 输出: # 准备安装以下应用: # - VSCode # - Git # - Docker
总结与最佳实践
| 特性 | 简单变量 | param 关键字 (推荐) |
|---|---|---|
| 定义方式 | 直接在脚本中使用 $Var |
在脚本开头用 param() 块定义 |
| 参数顺序 | 严格按顺序 | 可通过参数名忽略顺序 |
| 强制参数 | 无法实现 | 使用 [Mandatory=$true] 实现 |
| 默认值 | 无法实现 | 在声明时赋值(如 [string]$Var="Default") |
| 类型验证 | 弱,运行时才报错 | 强,在调用时即验证 |
| 帮助信息 | 无法提供 | 使用 [HelpMessage="..."] 提供 |
| 开关参数 | 无法实现 | 使用 [switch] 类型实现 |
| 数组参数 | 无法直接实现 | 使用 [string[]] 类型实现 |
| 代码可读性 | 差,参数散落在代码中 | 优秀,所有参数定义集中在一处 |
最佳实践建议:
- 始终使用
param关键字:这是编写专业、可维护 PowerShell 脚本的基础。 - 为所有参数指定类型:如
[string],[int],[bool]等,这能自动进行类型转换和验证。 - 为关键参数添加
[Mandatory]属性:强制用户思考并提供必要信息。 - 为可选参数提供默认值:让脚本在多数情况下能“开箱即用”。
- 使用开关参数:对于开启/关闭功能的场景,这是最清晰的设计。
- 使用参数名调用:在编写复杂的脚本或构建自动化工具时,始终使用
-ParameterName Value的形式调用,这会让你的脚本调用命令更易于理解和维护。
