适用于 PowerShell 所有版本
以下是一个获取字符串(而不是字符串数组!)行数的技巧:
$text = @'
This is some
sample text
Let's find out
the number of lines.
'@
$text.Length - $text.Replace("`n",'').Length + 1
技术上来说,这个例子用的是 here-string 来创建多行字符串,不过这只是一个例子。它对所有类型的字符串都有效,无论它的来源是什么。
适用于 PowerShell 所有版本
以下是一个获取字符串(而不是字符串数组!)行数的技巧:
$text = @'
This is some
sample text
Let's find out
the number of lines.
'@
$text.Length - $text.Replace("`n",'').Length + 1
技术上来说,这个例子用的是 here-string 来创建多行字符串,不过这只是一个例子。它对所有类型的字符串都有效,无论它的来源是什么。
适用于 PowerShell 所有版本
在路径名中,有些字符,例如冒号和双引号,都是非法的。如果您的脚本中的路径名称来自于外部信息,那么您可能希望最终的路径名是合法的。
以下是一个将路径中所有非法字符替换成下划线的函数:
function Get-LegalPathName($Path)
{
$illegalChars = [System.IO.Path]::GetInvalidFileNameChars()
foreach($illegalChar in $illegalChars)
{ $Path = $Path.Replace($illegalChar, '_') }
$Path
}
这是结果看起来的样子:
PS> Get-LegalPathName 'some:"illegal"\path<chars>.txt'
some__illegal__path_chars_.txt
适用于 PowerShell 所有版本
由于 PowerShell 会将所有命令的执行结果返回,所以在 PowerShell 脚本中忽略掉所有不希望返回的结果是十分重要的。
有很多方法能实现这个目的,以下是最常见的两种。请注意每行都会尝试在您的 C: 创建一个新的文件夹。New-Item 命令将会返回一个新的文件夹对象,但是如果您只是希望创建一个新的文件夹,那么您很可能希望忽略掉返回的结果:
1 | $null = New-Item -Path c:\newfolderA -ItemType Directory |
哪么那种方式更好呢?当然是第一种方式了。将不需要的结果通过管道传送给 Out-Null 的开销是很大的,能达到将近 40 倍的差别。只调用一次的差别并不明显,但如果在一个循环中的话,差异就很明显了。
So better get into the habit of using $null rather than Out-Null!
所以最好养成习惯使用 $null 而不是 Out-Null!
PowerShell 技能连载 - 同时支持可选参数和必选参数
适用于 PowerShell 所有版本
一个函数的参数是否能既为可选的,又为必选的呢?这是可以的,基于不同的上下文即可。
一个参数可以在当其它参数存在的时候为必选的,否则为可选的。
function Connect-Somewhere
{
[CmdletBinding(DefaultParameterSetName='A')]
param
(
[Parameter(ParameterSetName='A',Mandatory=$false)]
[Parameter(ParameterSetName='B',Mandatory=$true)]
$ComputerName,
[Parameter(ParameterSetName='B',Mandatory=$false)]
$Credential
)
$chosen = $PSCmdlet.ParameterSetName
"You have chosen $chosen parameter set."
}
# -Computername is optional
Connect-Somewhere
# here, -Computername is mandatory
Connect-Somewhere -Credential test
适用于 PowerShell 不同版本
以下是管理脚本中最重要的 4 个数学函数:
[Math]::Floor(4.9)
[Math]::Ceiling(3.2)
[Math]::Max(3,8)
[Math]::Min(3,8)
适用于 PowerShell 所有版本
以下是一系列有用的(并且易用的)用于处理文件路径的系统函数:
[System.IO.Path]::GetFileNameWithoutExtension('file.ps1')
[System.IO.Path]::GetExtension('file.ps1')
[System.IO.Path]::ChangeExtension('file.ps1', '.copy.ps1')
[System.IO.Path]::GetFileNameWithoutExtension('c:\test\file.ps1')
[System.IO.Path]::GetExtension('c:\test\file.ps1')
[System.IO.Path]::ChangeExtension('c:\test\file.ps1', '.bak')
所有这些方法都能接受文件名称或完整路径参数、能返回路径的不同部分,或改变其中的部分,例如扩展名。
适用于 PowerShell 所有版本
要查找一系列数据中的最小值和最大值,请使用 Measure-Object 命令:
$list = 1,4,3,1,3,12,990
$result = $list | Measure-Object -Minimum -Maximum
$result.Minimum
$result.Maximum
它对输入的任何数据类型都有效。以下是稍作修改的代码,可以返回 Windows 文件夹中最旧和最新的文件:
$list = Get-ChildItem -Path C:\windows
$result = $list | Measure-Object -Property LastWriteTime -Minimum -Maximum
$result.Minimum
$result.Maximum
如果您的输入数据有多个属性,只需要加上 -Property 参数,并选择您想检测的属性即可。
适用于 PowerShell 所有版本
假设您想检查可疑的服务状态,例如启动类型为“自动”而状态处于停止的,或检查服务的 ExitCode 为非正常值的。
以下是一些示例代码,演示如何查询这些场景并将执行结果合并为一个变量。
Sort-Object 确保您的结果在输出到 grid view 窗口之前是不重复的。
$list = @()
$list += Get-WmiObject -Class Win32_Service -Filter 'State="Stopped" and StartMode="Auto" and ExitCode!=0' |
Select-Object -Property Name, DisplayName, ExitCode, Description, PathName, DesktopInteract
$list += Get-WmiObject -Class Win32_Service -Filter 'ExitCode!=0 and ExitCode!=1077' |
Select-Object -Property Name, DisplayName, ExitCode, Description, PathName, DesktopInteract
$list |
# remove identical (-Unique)
Sort-Object -Unique -Property Name |
Out-GridView
适用于 PowerShell 所有版本
当遇到生日或重要的赛事时,您可能会想到用 PowerShell 来计算事件还有多少小时到来。以下是实现方法:
$result = New-TimeSpan -End '2014-12-25 06:45:00'
$hours = [Int]$result.TotalHours
'Another {0:n0} hours to go...' -f $hours
这个例子计算距离 2014 年圣诞节还剩余的小时数。只需要替换代码中的日期,就可以得到距您期待的事件到来还有多少小时。
PowerShell 技能连载 - 使用 -f 操作符合并字符串和数据
适用于 PowerShell 所有版本
用双引号包围的字符串能够解析变量,所以类似这样的书写方式很常见:
$name = $host.Name
"Your host is called $name."
然而,这种技术有一些限制。如果您想显示对象的属性而不只是变量,将会失败:
PS> "Your host is called $host.Name."
Your host is called System.Management.Automation.Internal.Host.InternalHost.Name.
这是因为 PowerShell 只会解析变量(在例子中是 $host),而不是代码中的剩余部分。
而且您也无法控制数字格式。这段代码可以工作,但是显示的小数位数太多,看起来不美观:
# get available space in bytes for C: drive
$freeSpace = ([WMI]'Win32_LogicalDisk.DeviceID="C:"').FreeSpace
# convert to MB
$freeSpaceMB = $freeSpace / 1MB
# output
"Your C: drive has $freeSpaceMB MB space available."
-f 操作符可以解决这两个问题。它的左侧是一个静态的文本模板,右侧是提供给模板用的值:
# insert any data into the text template
'Your host is called {0}.' -f $host.Name
# calculate free space on C: in MB
$freeSpace = ([WMI]'Win32_LogicalDisk.DeviceID="C:"').FreeSpace
$freeSpaceMB = $freeSpace /1MB
# output with just ONE digit after the comma
'Your C: drive has {0:n1} MB space available.' -f $freeSpaceMB
如您所见,使用 -f 可以给您带来两个好处:占位符(花括号)指示 PowerShell 插入点的位置,并且占位符还可以接受格式化信息。“n1”代表小数点后 1 位。只需要调整数值就能满足您的需要。