PowerShell 技能连载 - 测试 OU

假设您已安装了免费的 Microsoft RSAT 工具,以下是一个简单的方法来检测一个 OU 是否存在:

1
2
3
$OUPath = 'OU=TestOU,DC=train,DC=powershell,DC=local'
$exists = $(try { Get-ADOrganizationalUnit -Identity $OUPath -ErrorAction Ignore } catch{}) -ne $null
"$OUPath : $exists"

$exits 的值将是 $true$false,表示是否找到该 OU。请注意使用 try/catch 处理错误的方法:Get-ADOrganizationalUnit 将在指定的 OU 不存在时抛出终止错误,所以需要 try/catch 来捕获这些错误。

PowerShell 技能连载 - 验证变量有效性

变量和函数参数可以通过验证属性自动地验证有效性。以下是一个简单的例子,确保 $test1 只能存储 1-10 之间的值:

1
[ValidateRange(1,10)]$test1 = 10

当您将一个小于 1 或大于 10 的值赋给这个变量,PowerShell 将会抛出一个异常。不过通过这种方式您无法控制异常的问本。

通过使用脚本验证器,您可以选择自己希望的错误信息:

1
2
3
4
5
6
7
8
[ValidateScript({
If ($_ -gt 10)
{ throw 'You have submitted a value greater than 10. That will not work, dummy!' }
Elseif ($_ -lt 1)
{ throw 'You have submitted a value lower than 1. That will not work, dummy!' }

$true
})]$test2 = 10

以下是输出结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
PS C:\> $test2 =  4

PS C:\> $test2 = 11
You have submitted a value greater than 10. That will not work, dummy!
At line:5 char:3
+ { throw 'You have submitted a value greater than 10. That will not work, dummy ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (You have submitted a...not work, dummy!:String
) [], RuntimeException
+ FullyQualifiedErrorId : You have submitted a value greater than 10. That will not work, dummy!



PS C:\> $test2 = -2
You have submitted a value lower than 1. That will not work, dummy!
At line:7 char:3
+ { throw 'You have submitted a value lower than 1. That will not work, dummy ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (You have submitted a...not work, dummy!:String
) [], RuntimeException
+ FullyQualifiedErrorId : You have submitted a value lower than 1. That will not work, dummy!

PowerShell 技能连载 - 克隆 DHCP 服务器设置

从 Windows Server 2012 开市,您可以快速地导出和重新导入 DHCP 设置。克隆或迁移 DHCP 服务器是通过快照的形式。以下的例子从 \ORIGDHCP 导出设置并导入本地的 DHCP 服务器中:

1
2
Export-DHCPServer -File "$env:temp\dhcpsettings.xml" -Computername ORIGDHCP
Import-DHCPServer -File "$env:temp\dhcpsettings.xml"

PowerShell 技能连载 - 搜索 AD 用户

免费的 Microsoft RSAT 工具给我们带来了 “ActiveDirectory” PowerShell module:许多 cmdlet 可以帮助您管理 Active Directory 用户和计算机。

一个 cmdlet 特别有用。与其使用 Get-ADUser 和复杂得过滤器来查找 AD 用户,我们可以使用更方便的 Search-ADAccount。它注重于某些公共场景的查找用户功能。例如这行代码可以找出所有 120 天未活跃的用户账户:

1
Search-ADAccount -AccountInactive -TimeSpan 120 -UsersOnly

PowerShell 技能连载 - 生成随机密码

以下是一个非常简单的创建复杂随机密码的方法:

1
2
3
4
Add-Type -AssemblyName System.Web
$PasswordLength = 12
$SpecialCharCount = 3
[System.Web.Security.Membership]::GeneratePassword($PasswordLength, $SpecialCharCount)

The API call lets you choose the length of the password, and the number of non-alphanumeric characters it contains.

PowerShell 技能连载 - 冒充 ToString() 方法

在前一个技能当中我们解释了 ToString() 描述一个对象的方法是含糊的,而且对象的作者可以决定 ToString() 返回什么。这在 PowerShell 代码中尤为明显。请看要覆盖任意一个对象的 ToString() 方法是多么容易:

1
2
3
4
5
6
7
8
PS> $a = 1
PS> $a | Add-Member -MemberType ScriptMethod -Name toString -Value { 'go away' } -Force
PS> $a
go away
PS> $a.GetType().FullName
System.Int32
PS> $a -eq 1
True

PowerShell 技能连载 - 请注意 ToString() 方法

任何 .NET 对象都有一个 ToString() 方法,返回的是一段文字描述。这也是当您将一个对象输出为一个字符串时所得到的内容。然而,ToString() 所返回的值可能会改变,所以您永远不要使用它来做一些重要的事情。

Here is an example – these lines both produce a FileInfo object which represents the exact same file. Only the way how the object was created is different. All object properties are identical. Yet, ToString() differs:
以下是一个例子——这两行代码都会创建一个 FileInfo 对象,来代表同一个文件。只是创建对象的方法有所不同。所有的对象属性都相同。然而,ToString() 的结果不同:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
PS> $file1 = Get-ChildItem $env:windir -Filter regedit.exe
PS> $file2 = Get-Item $env:windir\regedit.exe

$file1.FullName; $file2.FullName
C:\WINDOWS\regedit.exe
C:\WINDOWS\regedit.exe

PS> $file1.GetType().FullName; $file2.GetType().FullName
System.IO.FileInfo
System.IO.FileInfo

PS> $file1.ToString(); $file2.ToString()
regedit.exe
C:\WINDOWS\regedit.exe

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
(...)