PowerShell 技能连载 - 转义通配符

当您使用 -like 操作符时,它支持三种通配符:”*“ 代表所有数字和字母,”?“ 代表任意单个字符,”[a-z]“ 代表字符的列表。另外有一个不太为人所知的,它支持 PowerShell 的转义字符 “```”,可以用它来转义通配符。

所以当您需要检查一个字符串中的 “*“ 字符,这行代码能够工作但实际上是错的:

1
'*abc' -like '*abc'

这是错的,因为它在这种情况下也是返回 true:

1
'xyzabc' -like '*abc'

由于您希望检查 “*“ 字符并且不希望将它解释为一个通配符,所以需要对它进行转义:

1
2
3
4
5
PS> '*abc' -like '`*abc'
True

PS> 'xyzabc' -like '`*abc'
False

而且如果您使用双引号,请不要忘了对转义符转义:

1
2
3
4
5
6
7
8
9
10
11
12
# wrong:
PS> "xyzabc" -like "`*abc"
True

# correct:
PS> "xyzabc" -like "``*abc"
False

PS> "*abc" -like "``*abc"
True

PS>

PowerShell 技能连载 - 验证整形变量

您可以在一个变量前简单地加上 [Int] 来确保它只包含数字位。但您是否知道从 PowerShell 4.0 开始,支持正则表达式的验证器呢?

通过这种方式,您可以定义一个变量只能为 2 位至 6 位的正数,或其它指定的模式:

1
2
3
4
5
6
7
8
9
10
11
12
PS>  [ValidatePattern('^\d{2,6}$')][int]$id = 666

PS> $id = 10000

PS> $id = 1000000
Cannot check variable id. Value 1000000 is invalid for variable id.


PS> $id = 10

PS> $id = 1
Cannot check variable id. Value 1 is invalid for variable id.

PowerShell 技能连载 - 创建随机的 MAC 地址

如果您只是需要一系列随机生成的 MAC 地址,而不关心这些地址是否合法,以下是一行实现代码:

1
2
3
4
5
6
7
PS> (0..5 | ForEach-Object { '{0:x}{1:x}' -f (Get-Random -Minimum 0 -Maximum 15),(Get-Random -Minimum 0 -Maximum 15)})  -join ':'

a5:66:07:6d:d9:18

PS> (0..5 | ForEach-Object { '{0:x}{1:x}' -f (Get-Random -Minimum 0 -Maximum 15),(Get-Random -Minimum 0 -Maximum 15)}) -join ':'

3c:c8:4e:e3:75:6c

将它加到一个循环中,就可以生成任意多个 MAC 地址:

1
2
3
4
5
6
7
8
PS> 0..100 | ForEach-Object { (0..5 | Foreach-Object { '{0:x}{1:x}' -f (Get-Random -Minimum 0 -Maximum 15),(Get-Random -Minimum 0 -Maximum 15)})  -join ':' }

bc:38:3a:91:a9:79
36:55:3a:a0:3d:c4
6d:2c:91:ae:01:35
ec:01:11:42:a7:09
e7:0b:24:d3:14:1d
(...)

PowerShell 技能连载 - 按位移位

PowerShell 包含许多不太常用的二进制操作符,例如按位移位。-shl 操作符按位左移指定的位数:

1
2
3
4
5
6
7
8
PS> 1 -shl 1
2

PS> 2 -shl 1
4

PS> 3 -shl 1
6

PowerShell 技能连载 - 将二进制字符串转为整形

以下是将一段二进制文本字符串转为对应的整形值的方法:

1
2
3
$binary = "110110110"
$int = [Convert]::ToInt32($binary,2)
$int

用另一种方法可以更简单:

1
2
PS> [Convert]::ToString(438,2)
110110110

PowerShell 技能连载 - 使用剪贴板来传输数据和结果

终于,在 PowerShell 5 中原生支持将结果发送到剪贴板中,以及从剪贴板中接收结果:

1
2
3
4
5
6
PS> Get-Command -Noun Clipboard

CommandType Name Version Source
----------- ---- ------- ------
Cmdlet Get-Clipboard 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Set-Clipboard 3.1.0.0 Microsoft.PowerShell.Management

例如,您可以打开一个包含一些数据的 Excel 表格,将一列复制到剪贴板中,然后在 PowerShell 中进一步处理数据,例如过滤它:

1
PS> $list = (Get-ClipBoard) -like '*err*'

PowerShell 技能连载 - 在远程系统中安装 MSI

以下是一些或许对您有用的代码。您需要远程系统的管理员权限。

1
2
3
4
5
$ComputerName = 'NameOfMachineToInstall'
$TargetPathMSI = '\\softwareserver\product\package.msi'

$class = [wmiclass]"\\$ComputerName\ROOT\cimv2:Win32_Product"
$class.Install($TargetPathMSI)

如果权限和网络连接允许,这段代码将在远程系统中安装一个 MSI 包。请在开始之前调整好变量。第一个是需要安装 MSI 的机器名称。第二个是需要安装的 MSI 路径。

PowerShell 技能连载 - .Replace() 和 -replace 的区别

有两种方法可以替换一个字符串中的问本:Replace() 方法,和 -replace 操作符。它们的工作机制是不同的。

Replace() 是大小写敏感的,能够将文本替换为新的文本:

1
2
3
4
5
PS> 'Hello World.'.Replace('o', '0')
Hell0 W0rld

PS> 'Hello World.'.Replace('ell','oo')
Hooo World

-replace 操作符缺省是大小写不敏感的(如果希望大小写敏感,请使用 -creplace)。它接受一个正则表达式输入,很多人忽略了这个功能:

1
2
3
4
5
PS> 'Hello World.' -replace 'ell', 'oo'
Hooo World.

PS> 'Hello World.' -replace '.', '!'
!!!!!!!!!!!!

第二个输出会让不了解正则表达式的人感到惊讶。如果您希望用 -replace 来替换静态文本,请确保对文本进行转义:

1
2
PS> 'Hello World.' -replace [Regex]::Escape('.'), '!'
Hello World!

PowerShell 技能连载 - HTML 高级编码

.NET 静态方法 HtmlEncode 能够较好地将普通字符进行编码,但是对于许多特殊字符会处理失败。要正确地对所有字符编码,我们编写了一个 ConvertTo-EncodedHtml 函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function ConvertTo-EncodedHTML($HtmlText)
{

$chars = [Web.HttpUtility]::HtmlEncode($HtmlText).ToCharArray()
$txt = New-Object System.Text.StringBuilder
$null = . {
foreach($c in $chars)
{
if ([int]$c -gt 127)
{
$txt.Append("&#" + [int]$c + ";")
}
else
{
$txt.Append($c)
}
}
}
return $txt.ToString()
}

这个函数检查所有 ASCII 代码大于 127 的字符并将这些字符转换为编码后的版本:

1
2
PS> Convert-EncodedHTML -HtmlText "A – s ‘Test’"
A – s ‘Test’

PowerShell 技能连载 - HTML 编码

有一个 .NET 的静态方法可以对一段文本进行 HTML 编码,例如如果您希望在 HTML 输出中正常显示一段文本:

1
2
PS>  [System.Web.HttpUtility]::HtmlEncode('Österreich heißt so.')
Österreich heißt so.