文章目录
- 介绍
- 函数
-
- 介绍
- 为函数添加参数
- 接受管道输入
- 你把这叫作脚本
-
- 使得命令可重复执行
- 参数化命令
- 创建一个带有参数的脚本
- 为脚本添加文档
- 作用域初探
- 优化可传参脚本
-
- 介绍
- 将参数定义为强制化参数及添加参数别名
- 验证输入参数及添加详细输出以获取易用性体验
- 总结
介绍
函数
介绍
函数使用
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"
而对于一些脚本使用者来说,他们希望看到脚本输出执行的进度,我们更倾向于使用
总结
以上是对