文章目录

PowerShell 函数定义:function 与 param

发布于 2026-04-04 11:06:41 · 浏览 21 次 · 评论 0 条

PowerShell 函数定义:function 与 param

在 PowerShell 脚本开发中,函数是模块化代码的核心工具。通过函数,你可以将重复逻辑封装为可复用的代码块。本文将详细介绍 PowerShell 中定义函数的两大核心关键字:functionparam 的用法与区别。


一、function 关键字:函数的声明基础

function 是定义函数的基础关键字,它用于声明一个独立的代码块,给定函数名后即可被调用执行。

最简单的函数形式

一个最基本的 PowerShell 函数只需要 function 关键字加上函数名和一对大括号:

function Get-SystemInfo {
    $os = Get-CimInstance -ClassName Win32_OperatingSystem
    $computer = $env:COMPUTERNAME
    $uptime = (Get-Date) - $os.LastBootUpTime
    
    Write-Host "计算机名称: $computer"
    Write-Host "操作系统: $($os.Caption)"
    Write-Host "已运行时间: $($uptime.Days) 天 $($uptime.Hours) 小时"
}

调用这个函数时,直接输入函数名即可:

Get-SystemInfo

函数命名规范

PowerShell 函数名遵循动名词组合的命名约定,推荐使用「动词-名词」的形式,例如:

  • Get-Process
  • Start-Service
  • Stop-Computer
  • New-Item
  • Remove-File

这种命名方式让函数用途一目了然:Get- 表示获取信息,Start- 表示启动操作。

函数的作用域

默认情况下,在脚本中定义的函数仅在该脚本内部可用。如果希望在当前 PowerShell 会话中全局可用,需要使用 :Global 作用域修饰符:

function :Global:Invoke-Maintenance {
    Write-Host "执行全局维护任务..."
}

二、param 关键字:参数定义的核心

param 是 PowerShell 中定义函数参数的标准方式。它位于函数体开头大括号之前,用于声明函数接受的输入参数。

基本参数定义

使用 param() 语法块定义参数,多个参数用逗号分隔:

function Send-Email {
    param (
        [string]$To,
        [string]$Subject,
        [string]$Body
    )
    
    Write-Host "正在发送邮件到: $To"
    Write-Host "主题: $Subject"
    Write-Host "内容: $Body"
}

调用时,按顺序传入参数:

Send-Email "admin@example.com" "系统警报" "服务器 CPU 使用率过高"

或者使用命名参数,顺序无关:

Send-Email -Subject "系统警报" -Body "服务器 CPU 使用率过高" -To "admin@example.com"

参数类型限制

通过在参数名前方括号中指定类型,可以限制参数的数据类型。如果传入类型不符,PowerShell 会自动尝试转换,转换失败则报错。

参数类型 用途 示例
[string] 文本字符串 $name` | | `[int]` | 整数 | `$count
[bool] 真/假值 $enabled` | | `[array]` | 数组 | `$items
[hashtable] 键值对 $settings` | | `[datetime]` | 日期时间 | `$startDate
function Calculate-Total {
    param (
        [int]$Quantity,
        [decimal]$Price,
        [string]$ProductName
    )
    
    $total = $Quantity * $Price
    Write-Host "商品: $ProductName"
    Write-Host "数量: $Quantity"
    Write-Host "单价: $Price"
    Write-Host "总价: $total"
}

可选参数与默认值

给参数赋值即可设置默认值,使参数变为可选。调用时不传入该参数时,使用默认值:

function New-User {
    param (
        [string]$Username,
        [string]$Role = "User",
        [bool]$Enabled = $true
    )

    Write-Host "创建用户: $Username"
    Write-Host "角色: $Role"
    Write-Host "启用状态: $Enabled"
}
```

**调用**时不传可选参数:

```powershell
New-User -Username "zhangsan"
```

### 参数属性增强

`param` 块支持多种属性修饰符,用于控制参数的行为:

```powershell
function Invoke-Operation {
    param (
        # 必填参数
        [Parameter(Mandatory = $true)]
        [string]$RequiredParam,
        
        # 位置参数(可按位置传入)
        [Parameter(Position = 0)]
        [string]$FirstParam,

        # 参数别名
        [Alias("cn")]
        [string]$ComputerName,
        
        # 帮助消息
        [string]$Description,

        # 允许空值
        [AllowNull()]
        [string]$OptionalParam
    )
    
    Write-Host "必填参数: $RequiredParam"
    Write-Host "位置参数: $FirstParam"
    Write-Host "计算机名: $ComputerName"
}

三、两种参数定义方式的对比

在 PowerShell 中,function 关键字之后既可以使用 function 函数名 { 代码 } 语法,也可以在函数名后直接使用 param() 块。两种方式在功能上等效,但适用场景不同。

方式一:param() 块放函数内部

这是最常用也是推荐的方式,param() 放在函数体开头的位置:

function Install-Application {
    param (
        [string]$AppName,
        [string]$Version = "latest"
    )

    Write-Host "正在安装 $AppName"
    Write-Host "版本: $Version"
}

方式二:$args` 自动变量 对于简单的脚本函数,也可以不使用 `param`,而是通过 `$args 数组访问传入的参数:

function Show-Message {
    Write-Host "第一个参数: $($args[0])"
    Write-Host "第二个参数: $($args[1])"
    Write-Host "参数总数: $($args.Count)"
}

调用

Show-Message "Hello" "World"

两种方式的区别

| 特性 | param() 方式 | $args 方式 | |-----|-------------|-----------| | 参数命名 | 支持 | 不支持 | | 类型限制 | 支持 | 不支持 | | Mandatory 属性 | 支持 | 不支持 | | 别名 | 支持 | 不于持 | | 参数验证 | 支持 | 不支持 | | 代码可读性 | 高 | 低 | 对于生产环境,**强烈建议使用 `param()` 方式**,因为它提供了完整的参数控制能力。 --- ## 四、高级参数用法 ### 参数验证属性 PowerShell 提供了丰富的参数验证属性,确保传入参数符合预期: ```powershell function Process-Data { param ( # 值必须在指定范围内 [ValidateRange(1, 100)] [int]$Count,

    # 值必须在枚举列表中
    [ValidateSet("Low", "Medium", "High")]
    [string]$Priority,
        
        # 字符串长度范围
        [ValidateLength(3, 20)]
        [string]$Name,

    # 正则表达式验证
    [ValidatePattern("^\d{4}-\d{2}-\d{2}$")]
        [string]$Date,

    # 参数数量验证
    [ValidateCount(1, 5)]
    [array]$Items
    )
    
    Write-Host "Count: $Count"
Write-Host "Priority: $Priority"
    Write-Host "Name: $Name"
Write-Host "Date: $Date"
    Write-Host "Items: $($Items -join ', ')"
}
```

### 管道输入支持

让函数能够接收管道数据,需要使用 `ValueFromPipeline` 属性:

```powershell
function Format-Text {
    param (
        [Parameter(ValueFromPipeline = $true)]
    [string]$InputText,
        
        [string]$Prefix = "[INFO]",
    [string]$Suffix = ""
    )
    
    process {
        "$Prefix $InputText $Suffix"
}

}


**调用**:

```powershell
"第一行" | Format-Text -Suffix "(已处理)"
"第二行" | Format-Text -Prefix "[WARN]"

切换参数

使用 [switch] 类型定义布尔型切换参数,无需传入值:

function Backup-Files {
    param (
        [string]$Source,
        [string]$Destination,
        [switch]$Compress,
        [switch]$Force,
        [switch]$Verbose
    )
    
    Write-Host "源目录: $Source"
    Write-Host "目标目录: $Destination"
    Write-Host "压缩: $Compress"
    Write-Host "强制覆盖: $Force"
    Write-Host "详细模式: $Verbose"
}

调用

Backup-Files -Source "C:\Data" -Destination "D:\Backup" -Compress -Force

五、完整函数示例

以下是一个综合运用 functionparam 的完整示例,展示了一个生产级别的日志函数:

function Write-LogMessage {
    param (
        [Parameter(Mandatory = $true)]
        [string]$Message,

        [Parameter(Mandatory = $false)]
        [ValidateSet("Info", "Warning", "Error", "Debug")]
        [string]$Level = "Info",

        [Parameter(Mandatory = $false)]
        [string]$Source = "Script",

        [Parameter(Mandatory = $false)]
        [switch]$WriteToFile,

        [Parameter(Mandatory = $false)]
        [string]$LogFile = "C:\Logs\app.log"
    )

    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $logEntry = "[$timestamp] [$Level] [$Source] $Message"

    # 输出到控制台
    switch ($Level) {
        "Error"   { Write-Host $logEntry -ForegroundColor Red }
        "Warning" { Write-Host $logEntry -ForegroundColor Yellow }
        "Debug"   { Write-Host $logEntry -ForegroundColor Gray }
        default   { Write-Host $logEntry }
    }
    
    # 可选:写入文件
    if ($WriteToFile) {
        $logEntry | Out-File -FilePath $LogFile -Append -Encoding UTF8
    }

    return $logEntry
}
```

---

## 六、常见错误与调试

### 参数未传递导致的错误

当参数定义为必填但调用时未传递,会触发参数绑定失败错误:

```powershell
function Test-Function {
    param (
        [Parameter(Mandatory = $true)]
        [string]$Required
    )
    Write-Host $Required
}

错误信息:Missing an argument for parameter 'Required'. Specify a parameter and try again.

参数类型不匹配

传入类型与声明类型不符时,PowerShell 尝试自动转换,失败则报错:

function Add-Numbers {
    param ([int]$A, [int]$B)
    $A + $B
}

调用 Add-Numbers -A "abc" -B 5 会报错,因为字符串无法转换为整数。

调试参数

在函数开头添加断点调试参数值:

function Debug-Function {
    param ($Name, $Value)

    Write-Host "函数被调用"
    Write-Host "参数 Name: $Name"
    Write-Host "参数 Value: $Value"
}

七、最佳实践总结

定义 PowerShell 函数时,遵循以下原则可以写出高质量、可维护的代码:

使用 function 关键字时,函数名采用「动词-名词」的 PascalCase 命名规范,使代码自文档化。将 param() 块放在函数体开头,保持结构清晰。参数尽量声明具体类型,便于类型检查和 IDE 智能提示。

使用 param 关键字时,必填参数使用 Mandatory = $true 属性并提供清晰的帮助消息。可选参数设置合理的默认值。使用 ValidateSetValidateRange 等属性进行输入验证。复杂函数支持管道输入以增强灵活性。

评论 (0)

暂无评论,快来抢沙发吧!

扫一扫,手机查看

扫描上方二维码,在手机上查看本文