PowerShell 技能连载 - 将时钟周期转换为日期和时间(第一部分)

有时候您可能会遇到一些奇怪的日期和时间格式,它们可能用的是类似这样的 64 位 integer 数值:636264671350358729。

如果您想将这样的“时钟周期”(Windows 中最小的时间片),只需要将数字转换为 DateTime 类型:

1
2
3
PS> [DateTime]636264671350358729

Thursday, March 30, 2017 10:38:55

类似地,要将一个日期转换为时钟周期,请试试这段代码:

1
2
3
4
PS> $date = Get-Date -Date '2017-02-03 19:22:11'

PS> $date.Ticks
636217465310000000

比如说,您可以利用这个时钟周期来将日期和时间序列化成非特定区域的格式。

PowerShell 技能连载 - 直接导入证书(第二部分)

在前一个技能中我们演示了如何在任何版本的 PowerShell 中用 .NET 方法导入数字证书。新版本的 PowerShell 有一个 “PKI” module,其中包括了 Import-Certificate cmdlet,导入证书变得更简单了。

1
2
3
4
#requires -Version 2.0 -Modules PKI
# importing to personal store
$Path = 'C:\Path\To\CertFile.cer'
Import-Certificate -FilePath $Path -CertStoreLocation Cert:\CurrentUser\My

请注意 Import-Certificate 如何通过 -CertStoreLocation 指定目标存储位置。这个命令返回导入的证书。

PowerShell 技能连载 - 直接导入证书(第一部分)

可以在任意版本的 PowerShell 中用 .NET 方法将证书安装到计算机中。这将导入一个证书文件到个人存储中:

1
2
3
4
5
6
# importing to personal store
$Path = 'C:\Path\To\CertFile.cer'
$Store = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList My, CurrentUser
$Store.Open('ReadWrite')
$Store.Add($Path)
$Store.Close()

您可以打开证书管理器证实这一点:

1
PS C:\> certmgr.msc

如果您想将证书导入到一个不同的存储位置,只需要调整创建存储对象的参数即可。

PowerShell 技能连载 - 请注意别名

您能指出这段代码的错误吗?

1
2
3
4
5
6
PS C:\> function r { "This never runs" }

PS C:\> r
function r { "This never runs" }

PS C:\>

如果您执行函数 “r”,它只会返回函数的源代码。

错误的原因是函数名 “r” 和内置的别名冲突:

1
2
3
4
5
6
7
8
PS C:\> Get-Alias r

CommandType Name Version Source
----------- ---- ------- ------
Alias r -> Invoke-History


PS C:\>

所以请始终确保知道内置的别名——它们的优先级永远比函数或其它命令高。更好的做法是,按照最佳实践,始终用 Verb-Noum 的方式来命名您的函数。

PowerShell 技能连载 - 处理长文件路径

以前,当路径长于 256 字符时,Windows 文件系统有时会变得缓慢。在 PowerShell Gallery 有一个 module,增加了一系列 cmdlet,可以快速搜索文件系统,并且支持任意长度的路径。

如果您使用 PowerShell 5 或安装了 PowerShellGet(www.powershellgallery.com),那么您可以从 PowerShell Gallery 中下载和安装 “PSAlphaFS” module:

1
Install-Module -Name PSAlphaFS -Scope CurrentUser

不幸的是,这些 cmdlet 似乎需要完整的管理员特权,而对普通用户会抛出异常。如果您是管理员,您可以以这种方式查找长路径的文件:

1
2
Get-LongChildItem -Path c:\windows -Recurse -File |
Where-Object { $_.FullName.Length -gt 250 }

PowerShell 技能连载 - 检测字符代码 0

有些时候,字符串适用 “\0“ 作为分隔符。不像其它大多数分隔符,这个分隔符并不显示在文本输出中,但仍然可以用于分割文本。

PowerShell 可以处理包含字符代码 0 的字符串。它用反斜杠后跟着数字 0 来表示。请注意文本需要放在双引号之内,才能将反斜杠序列转换为字节 0。

以下是一个演示如何分割 \0 分割的文本的例子:

1
2
3
4
5
6
# create a sample text
$text = "Part 1`0Part 2`0Part 3"
# delimiter does not show in output...
$text
# ...but can be used to split:
$text -split "`0"

PowerShell 技能连载 - 自动定义函数的别名

您也许知道 PowerShell 支持命令的别名。但是您是否知道也可以在函数定义内部为 PowerShell 函数定义别名(PowerShell 4 引入的功能)呢?让我们来看看:

1
2
3
4
5
6
7
8
function Get-AlcoholicBeverage
{
[Alias('Beer','Drink')]
[CmdletBinding()]
param()

"Here is your beer."
}

这个函数的“正式”名称是 Get-AlcoholicBeverage,但是这个函数也可以通过 “Beer“ 和 “Drink“ 别名来引用。在函数定义时,PowerShell 自动增加了这些别名:

1
2
3
4
CommandType     Name
----------- ----
Alias Beer -> Get-AlcoholicBeverage
Alias Drink -> Get-AlcoholicBeverage

PowerShell 技能连载 - 检查操作系统版本

以下是一个简单快速的检查操作系统版本的方法:

1
2
3
4
5
6
PS C:\> [Environment]::OSVersion


Platform ServicePack Version VersionString
-------- ----------- ------- -------------
Win32NT 10.0.14393.0 Microsoft Windows NT 10.0.14393.0

所以要检查一个脚本是否运行在一个预定的操作系统上变得十分简单。例如要检查是否运行在 Windows 10 上,请试试这行代码:

1
2
3
PS C:\> [Environment]::OSVersion.Version.Major -eq 10

True

PowerShell 技能连载 - 检查变量是否为 $NULL

如果您想检查一个变量是否为 $Null(空),请记住始终将 $null 放在比较运算符的左边。大多数情况下,顺序不重要:

1
2
3
4
5
6
7
8
9
PS C:\> $a = $null

PS C:\> $b = 12

PS C:\> $a -eq $null
True

PS C:\> $b -eq $null
False

然而,如果一个变量为一个数组,则将数组放在对比操作符左边的行为类似过滤器。这时候顺序变得很关键:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# this all produces inconsistent and fishy results

$a = $null
$a -eq $null # works: returns $true

$a = 1,2,3
$a -eq $null # fails: returns $null

$a = 1,2,$null,3,4
$a -eq $null # fails: returns $null

$a = 1,2,$null,3,4,$null,5
$a -eq $null # fails: returns array of 2x $null
($a -eq $null).Count

如果您将变量放在左侧,PowerShell 将检测数组内部的 $null 值,并且返回这些值。如果没有 $null 值,则返回 $null

如果您将变量放在右侧,PowerShell 将检查变量是否为 $null

1
2
3
4
5
6
7
8
9
10
11
12
13
# by reversing the operands, all is FINE:

$a = $null
$null -eq $a # works: $true

$a = 1,2,3
$null -eq $a # works: $false

$a = 1,2,$null,3,4
$null -eq $a # works: $false

$a = 1,2,$null,3,4,$null,5
$null -eq $a # works: $false

可以将 $null 放在比较运算符的左侧而不是右侧,来消除这个问题。

PowerShell 技能连载 - 检查证书详细信息

如果您想检查和查看一个证书文件的详细信息而不需要将它导入证书存储空间,以下是一个简单的例子:

1
2
3
4
5
6
7
# replace path with actual path to CER file
$Path = 'C:\Path\To\CertificateFile\test.cer'

Add-Type -AssemblyName System.Security
[Security.Cryptography.X509Certificates.X509Certificate2]$cert = [Security.Cryptography.X509Certificates.X509Certificate2]::CreateFromCertFile($Path)

$cert | Select-Object -Property *

您现在可以存取所有详细信息并获取指纹或检查失效日期:

1
2
3
4
5
6
PS C:\> $cert.Thumbprint
7A5A350D95247BB173CDF0867ADA2DBFFCCABDE6

PS C:\> $cert.NotAfter

Monday June 12 2017 06:00:00