文章目录
- 介绍
- 函数
-
- 介绍
- 为函数添加参数
- 接受管道输入
- 你把这叫作脚本
-
- 使得命令可重复执行
- 参数化命令
- 创建一个带有参数的脚本
- 为脚本添加文档
- 作用域初探
- 优化可传参脚本
-
- 介绍
- 将参数定义为强制化参数及添加参数别名
- 验证输入参数及添加详细输出以获取易用性体验
- 总结
介绍
函数
介绍
函数使用
function Install-Software { Write-Host 'I installed some software, Yippee!' } Install-Software
可以在脚本中定义函数,也可以直接在控制台中输入。
函数的命名一般遵循动词+名称的方式进行
为函数添加参数
通过
function Install-Software { [CmdletBinding()] param( [Parameter()] [string] $Version ) Write-Host "I installed software version $Version, Yippee!" }
Install-Software -Version 2 # 输出:I installed software version 2, Yippee!
如上,定义了一个
function Install-Software { [CmdletBinding()] param( [Parameter(Mandatory)] # 强制输入 [ValidateSet('1','2')] # 输入值验证,必须在1和2之中才可以,否则报错 [string] $Version = 2 # 参数默认值2,即调用的时候可以不需要输入参数 ) Write-Host "I installed software version $Version, Yippee!" }
接受管道输入
接下来,我们可以考虑让我们的函数接收管道的输入。首先我们来添加一个新的参数
function Install-Software { [CmdletBinding()] param( [Parameter(Mandatory)] # 强制输入 [ValidateSet('1','2')] # 输入值验证,必须在1和2之中才可以,否则报错 [string] $Version = 2 # 参数默认值2,即调用的时候可以不需要输入参数 [Parameter(Mandatory)] [string] $ComputerName ) Write-Host "I installed software version $Version on $ComputerName, Yippee!" } Install-Software -Version 2 ComputerName "SRV1"
function Install-Software { [CmdletBinding()] param( [Parameter(Mandatory)] # 强制输入 [ValidateSet('1','2')] # 输入值验证,必须在1和2之中才可以,否则报错 [string] $Version = 2 # 参数默认值2,即调用的时候可以不需要输入参数 [Parameter(Mandatory,ValueFromPipeline)] [string] $ComputerName ) Write-Host "I installed software version $Version on $ComputerName, Yippee!" } # 调用 $computers =@("SRV1","SRV2","SRV3") $computers | Install-Software -Version 2 # 输出: I installed software version 2 on SRV3, Yippee!
可以看到,函数只在数组中的最后一个字符串上执行了,为了解决这个问题,我们可以添加
function Install-Software { [CmdletBinding()] param( [Parameter(Mandatory)] # 强制输入 [ValidateSet('1','2')] # 输入值验证,必须在1和2之中才可以,否则报错 [string] $Version = 2 # 参数默认值2,即调用的时候可以不需要输入参数 [Parameter(Mandatory,ValueFromPipeline)] [string] $ComputerName ) process { Write-Host "I installed software version $Version on $ComputerName, Yippee!" } } # 调用 $computers =@("SRV1","SRV2","SRV3") $computers | Install-Software -Version 2
添加了
I installed software version 2 on SRV1, Yippee! I installed software version 2 on SRV2, Yippee! I installed software version 2 on SRV3, Yippee!
你把这叫作脚本
使得命令可重复执行
Get-WmiObject -Class Win32_LogicalDisk -ComputerName localhost ` -Filter "DriveType=3" | Sort-Object -Property DeviceID | Select-Object -Property DeviceID, @{ label='FreeSpace(MB)';expression={ $_.FreeSpace / 1MB -as [int] } }, @{ name='Size(GB)';expression={ $_.Size / 1GB -as [int]} }, @{ name='%Free';expression={ $_.FreeSpace / $_.Size * 100 -as [int]} }
请记住,这里使用
name 和label 都是可以的,但是此处更建议使用name ,它们可以分别简写为n 和l (L 的小写)
编辑好后,我们就保存命令——现在就可以把保存后的命令称为脚本。我们将其另存为
参数化命令
当你考虑到一遍遍运行同一个命令是,你或许会意识到命令的某些部分在每次运行时都会产生变化。就以当前示例,计算机名称是会变动的,因为不能你把脚本分享给你的同事使用时,还是执行的本地计算机的查询命令。所有我们考虑使用以下修改。
$computername='localhost' Get-WmiObject -Class Win32_LogicalDisk -ComputerName $computername ` -Filter "DriveType=3" | Sort-Object -Property DeviceID | Select-Object -Property DeviceID, @{ label='FreeSpace(MB)';expression={ $_.FreeSpace / 1MB -as [int] } }, @{ name='Size(GB)';expression={ $_.Size / 1GB -as [int]} }, @{ name='%Free';expression={ $_.FreeSpace / $_.Size * 100 -as [int]} }
创建一个带有参数的脚本
既然我们已经识别出了脚本中每次执行可能变化的部分,那么我们就需要提供一种更让其他人赋予这些元素新值的方式。换句话说,我们需要将被赋予常量的
Param ( $computername='localhost' ) Get-WmiObject -Class Win32_LogicalDisk -ComputerName $computername ` -Filter "DriveType=3" | Sort-Object -Property DeviceID | Select-Object -Property DeviceID, @{ label='FreeSpace(MB)';expression={ $_.FreeSpace / 1MB -as [int] } }, @{ name='Size(GB)';expression={ $_.Size / 1GB -as [int]} }, @{ name='%Free';expression={ $_.FreeSpace / $_.Size * 100 -as [int]} }
我们只需要在变量声明代码附件添加一个
.Get-DiskInventory.ps1 server-r2 .Get-DiskInventory.ps1 -computername server-r2 .Get-DiskInventory.ps1 -comp server-r2
你可以通过逗号作为分隔符指定任意数量的参数。比如,我们希望将过滤条件设置为参数。当前脚本仅获取类型为
Param ( $computername='localhost', $drivetype=3 ) Get-WmiObject -Class Win32_LogicalDisk -ComputerName $computername ` -Filter "DriveType=$drivetype" | Sort-Object -Property DeviceID | Select-Object -Property DeviceID, @{ label='FreeSpace(MB)';expression={ $_.FreeSpace / 1MB -as [int] } }, @{ name='Size(GB)';expression={ $_.Size / 1GB -as [int]} }, @{ name='%Free';expression={ $_.FreeSpace / $_.Size * 100 -as [int]} }
使用该脚本的方式如下。
.Get-DiskInventory.ps1 server-r2 3 .Get-DiskInventory.ps1 -computername server-r2 -drive 3 .Get-DiskInventory.ps1 server-r2 .Get-DiskInventory.ps1 -drive 3
为脚本添加文档
<# .SYNOPSIS Get-DiskInventory retrieves logical disk information from one or more computers. .DESCRIPTION Get-DiskInventory uses WMI to retrieve the Win32_LogicalDisk instances from one or more computers. It displays each disk's drive letter, free space , total size, and percentage of free space. .PARAMETER computername The computer name, or names.Default: localhost. .PARAMETER drivetype The drive type to query. See Win32_LogicalDisk documentation for values. 3 is fixed disk, and is the default. .EXAMPLE Get-DiskInventory -computername SERVER-R2 -drivetype 3 #> Param ( $computername='localhost', $drivetype=3 ) Get-WmiObject -Class Win32_LogicalDisk -ComputerName $computername ` -Filter "DriveType=$drivetype" | Sort-Object -Property DeviceID | Select-Object -Property DeviceID, @{ label='FreeSpace(MB)';expression={ $_.FreeSpace / 1MB -as [int] } }, @{ name='Size(GB)';expression={ $_.Size / 1GB -as [int]} }, @{ name='%Free';expression={ $_.FreeSpace / $_.Size * 100 -as [int]} }
正常情况,
在
作用域初探
我们最后需要讨论的一个主题是作用域(
作用域的生命周期只持续到作用域所需执行的最后一行代码之前。这意味着全局作用域只有在
优化可传参脚本
介绍
我们还是使用之前创建的
<# .SYNOPSIS Get-DiskInventory retrieves logical disk information from one or more computers. .DESCRIPTION Get-DiskInventory uses WMI to retrieve the Win32_LogicalDisk instances from one or more computers. It displays each disk's drive letter, free space , total size, and percentage of free space. .PARAMETER computername The computer name, or names.Default: localhost. .PARAMETER drivetype The drive type to query. See Win32_LogicalDisk documentation for values. 3 is fixed disk, and is the default. .EXAMPLE Get-DiskInventory -computername SERVER-R2 -drivetype 3 #> [CmdletBinding()] Param ( $computername='localhost', $drivetype=3 ) Get-WmiObject -Class Win32_LogicalDisk -ComputerName $computername ` -Filter "DriveType=$drivetype" | Sort-Object -Property DeviceID | Select-Object -Property DeviceID, @{ label='FreeSpace(MB)';expression={ $_.FreeSpace / 1MB -as [int] } }, @{ name='Size(GB)';expression={ $_.Size / 1GB -as [int]} }, @{ name='%Free';expression={ $_.FreeSpace / $_.Size * 100 -as [int]} }
注意:脚本最后用的是
Select-Object 而不是Format-Table ,因为脚本的结果已经格式化不是一个好的主意,而应该将其交给使用者,让其决定以何种格式输出,如csv 、xml 等
将参数定义为强制化参数及添加参数别名
在此示例中,对于
<# .SYNOPSIS Get-DiskInventory retrieves logical disk information from one or more computers. .DESCRIPTION Get-DiskInventory uses WMI to retrieve the Win32_LogicalDisk instances from one or more computers. It displays each disk's drive letter, free space , total size, and percentage of free space. .PARAMETER computername The computer name, or names.Default: localhost. .PARAMETER drivetype The drive type to query. See Win32_LogicalDisk documentation for values. 3 is fixed disk, and is the default. .EXAMPLE Get-DiskInventory -computername SERVER-R2 -drivetype 3 #> [CmdletBinding()] Param ( [Parameter(Mandatory=$True)] [Alias('hostname')] [string]$computername='localhost', [int]$drivetype=3 ) Get-WmiObject -Class Win32_LogicalDisk -ComputerName $computername ` -Filter "DriveType=$drivetype" | Sort-Object -Property DeviceID | Select-Object -Property DeviceID, @{ label='FreeSpace(MB)';expression={ $_.FreeSpace / 1MB -as [int] } }, @{ name='Size(GB)';expression={ $_.Size / 1GB -as [int]} }, @{ name='%Free';expression={ $_.FreeSpace / $_.Size * 100 -as [int]} }
仅仅使用
下面是需要注意的重点。
- 所有的参数都必须被包括在
Param() 代码段的括号内 - 可以对一个参数添加多个修饰符,多个修饰符可以是一行,也可以多行,多行更易于阅读,但是重点是即使是多行,它们也是一个整体。
Mandatory 标签仅仅修饰-ComputerName 参数,对-drivetype 参数并没有影响 - 除了最后一个参数外,所有参数之间以逗号隔开
- 为了更好的阅读性,我们还喜欢在参数之间添加空格
- 我们定义参数时,就好像参数是变量——
$computername 和$drivetype ——但是使用脚本的人会将其当作普通的PowerShell 命令行参数
验证输入参数及添加详细输出以获取易用性体验
让我们来看看
<# .SYNOPSIS Get-DiskInventory retrieves logical disk information from one or more computers. .DESCRIPTION Get-DiskInventory uses WMI to retrieve the Win32_LogicalDisk instances from one or more computers. It displays each disk's drive letter, free space , total size, and percentage of free space. .PARAMETER computername The computer name, or names.Default: localhost. .PARAMETER drivetype The drive type to query. See Win32_LogicalDisk documentation for values. 3 is fixed disk, and is the default. .EXAMPLE Get-DiskInventory -computername SERVER-R2 -drivetype 3 #> [CmdletBinding()] Param ( [Parameter(Mandatory=$True)] [Alias('hostname')] [string]$computername='localhost', [ValidateSet(2,3)] [int]$drivetype=3 ) Write-Verbose "Cennecting to $computername" Write-Verbose "Looking for drive type $drivetype" Get-WmiObject -Class Win32_LogicalDisk -ComputerName $computername ` -Filter "DriveType=$drivetype" | Sort-Object -Property DeviceID | Select-Object -Property DeviceID, @{ label='FreeSpace(MB)';expression={ $_.FreeSpace / 1MB -as [int] } }, @{ name='Size(GB)';expression={ $_.Size / 1GB -as [int]} }, @{ name='%Free';expression={ $_.FreeSpace / $_.Size * 100 -as [int]} } Write-Verbose "Finished running command"
而对于一些脚本使用者来说,他们希望看到脚本输出执行的进度,我们更倾向于使用
总结
以上是对