第 5 章 - 格式设置、别名、提供程序、比较

先决条件

本章中所示的一些示例需要 SqlServer PowerShell 模块。 有关 SqlServer PowerShell 模块和安装说明的详细信息,请参阅 SQL Server PowerShell 概述。 后续章节中也使用了它。 在 Windows 实验室环境计算机上下载并安装它。

右格式

第 4 章介绍了尽可能向左进行筛选。 手动设置命令输出格式的规则与该规则类似,但需要尽可能向右进行。

最常见的格式命令是 Format-TableFormat-ListFormat-Wide 也可 Format-Custom 使用,但不太常见。

如第 3 章中所述,除非使用自定义格式,否则返回列表的四个以上的属性的命令默认为列表。

Get-Service -Name w32time |
    Select-Object -Property Status, DisplayName, Can*
Status              : Running
DisplayName         : Windows Time
CanPauseAndContinue : False
CanShutdown         : True
CanStop             : True

Format-Table使用 cmdlet 手动替代格式,并在表中显示输出,而不是列表。

Get-Service -Name w32time |
    Select-Object -Property Status, DisplayName, Can* |
    Format-Table
Status  DisplayName  CanPauseAndContinue CanShutdown CanStop
------  -----------  ------------------- ----------- -------
Running Windows Time               False        True    True

表中的默认输出 Get-Service 为三个属性。

Get-Service -Name w32time
Status   Name               DisplayName
------   ----               -----------
Running  w32time            Windows Time

Format-List使用 cmdlet 替代默认格式并在列表中返回结果。

Get-Service -Name w32time | Format-List

请注意,只需管道 Get-Service 即可 Format-List 返回其他属性。 由于该特定命令的格式设置在后台的方式,因此每个命令都不会发生此情况。

Name                : w32time
DisplayName         : Windows Time
Status              : Running
DependentServices   : {}
ServicesDependedOn  : {}
CanPauseAndContinue : False
CanShutdown         : True
CanStop             : True
ServiceType         : Win32OwnProcess, Win32ShareProcess

使用格式 cmdlet 时要注意的头号是,它们生成的格式对象与 PowerShell 中的普通对象不同。

Get-Service -Name w32time | Format-List | Get-Member
   TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatStartData

Name                                    MemberType Definition
----                                    ---------- ----------
Equals                                  Method     bool Equals(System.Obj...
GetHashCode                             Method     int GetHashCode()
GetType                                 Method     type GetType()
ToString                                Method     string ToString()
autosizeInfo                            Property   Microsoft.PowerShell.C...
ClassId2e4f51ef21dd47e99d3c952918aff9cd Property   string ClassId2e4f51ef...
groupingEntry                           Property   Microsoft.PowerShell.C...
pageFooterEntry                         Property   Microsoft.PowerShell.C...
pageHeaderEntry                         Property   Microsoft.PowerShell.C...
shapeInfo                               Property   Microsoft.PowerShell.C...


   TypeName: Microsoft.PowerShell.Commands.Internal.Format.GroupStartData

Name                                    MemberType Definition
----                                    ---------- ----------
Equals                                  Method     bool Equals(System.Obj...
GetHashCode                             Method     int GetHashCode()
GetType                                 Method     type GetType()
ToString                                Method     string ToString()
ClassId2e4f51ef21dd47e99d3c952918aff9cd Property   string ClassId2e4f51ef...
groupingEntry                           Property   Microsoft.PowerShell.C...
shapeInfo                               Property   Microsoft.PowerShell.C...


   TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData

Name                                    MemberType Definition
----                                    ---------- ----------
Equals                                  Method     bool Equals(System.Obj...
GetHashCode                             Method     int GetHashCode()
GetType                                 Method     type GetType()
ToString                                Method     string ToString()
ClassId2e4f51ef21dd47e99d3c952918aff9cd Property   string ClassId2e4f51ef...
formatEntryInfo                         Property   Microsoft.PowerShell.C...
outOfBand                               Property   bool outOfBand {get;set;}
writeStream                             Property   Microsoft.PowerShell.C...


   TypeName: Microsoft.PowerShell.Commands.Internal.Format.GroupEndData

Name                                    MemberType Definition
----                                    ---------- ----------
Equals                                  Method     bool Equals(System.Obj...
GetHashCode                             Method     int GetHashCode()
GetType                                 Method     type GetType()
ToString                                Method     string ToString()
ClassId2e4f51ef21dd47e99d3c952918aff9cd Property   string ClassId2e4f51ef...
groupingEntry                           Property   Microsoft.PowerShell.C...


   TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatEndData

Name                                    MemberType Definition
----                                    ---------- ----------
Equals                                  Method     bool Equals(System.Obj...
GetHashCode                             Method     int GetHashCode()
GetType                                 Method     type GetType()
ToString                                Method     string ToString()
ClassId2e4f51ef21dd47e99d3c952918aff9cd Property   string ClassId2e4f51ef...
groupingEntry                           Property   Microsoft.PowerShell.C...

这意味着格式命令不能通过管道传递给大多数其他命令。 它们可以通过管道传递给某些 Out-* 命令,但就是这样。 这就是为什么你想要在行的末尾执行任何格式设置(格式右)。

别名

PowerShell 中的别名是命令的较短名称。 PowerShell 包括一组内置别名,还可以定义自己的别名。

Get-Alias cmdlet 用于查找别名。 如果已知道命令的别名,则 Name 参数用于确定别名与之关联的命令。

Get-Alias -Name gcm
CommandType     Name                                               Version
-----------     ----                                               -------
Alias           gcm -> Get-Command

可以为 Name 参数的值指定多个别名。

Get-Alias -Name gcm, gm
CommandType     Name                                               Version
-----------     ----                                               -------
Alias           gcm -> Get-Command
Alias           gm -> Get-Member

通常会看到省略 Name 参数,因为它是位置参数。

Get-Alias gm
CommandType     Name                                               Version
-----------     ----                                               -------
Alias           gm -> Get-Member

如果要查找命令的别名,则需要使用 Definition 参数。

Get-Alias -Definition Get-Command, Get-Member
CommandType     Name                                               Version
-----------     ----                                               -------
Alias           gcm -> Get-Command
Alias           gm -> Get-Member

不能以位置方式使用 Definition 参数,因此必须指定它。

别名可以保存几个击键,在控制台中键入命令时,它们很好。 不应在脚本或任何正在保存或与他人共享的代码中使用它们。 如本书前面所述,使用完整的 cmdlet 和参数名称是自我记录的,更易于理解。

创建自己的别名时请小心,因为它们仅存在于计算机上的当前 PowerShell 会话中。

提供者

PowerShell 中的提供程序是允许文件系统式访问数据存储的接口。 PowerShell 中有多个内置提供程序。

Get-PSProvider

如以下结果所示,注册表、别名、环境变量、文件系统、函数、变量、证书和 WSMan 都有内置提供程序。

Name                 Capabilities                 Drives
----                 ------------                 ------
Registry             ShouldProcess, Transactions  {HKLM, HKCU}
Alias                ShouldProcess                {Alias}
Environment          ShouldProcess                {Env}
FileSystem           Filter, ShouldProcess, Cr... {C, D}
Function             ShouldProcess                {Function}
Variable             ShouldProcess                {Variable}

可以使用 cmdlet 确定 Get-PSDrive 这些提供程序用于公开其数据存储的实际驱动器。 该 Get-PSDrive cmdlet 不仅显示提供程序公开的驱动器,还显示 Windows 逻辑驱动器,包括映射到网络共享的驱动器。

Get-PSDrive
Name           Used (GB)     Free (GB) Provider      Root
----           ---------     --------- --------      ----
Alias                                  Alias
C                  18.56        107.62 FileSystem    C:\
Cert                                   Certificate   \
D                                      FileSystem    D:\
Env                                    Environment
Function                               Function
HKCU                                   Registry      HKEY_CURRENT_USER
HKLM                                   Registry      HKEY_LOCAL_MACHINE
Variable                               Variable
WSMan                                  WSMan

第三方模块(如 ActiveDirectory PowerShell 模块和 SqlServer PowerShell 模块)都添加了自己的 PowerShell 提供程序和 PSDrive。

导入 ActiveDirectorySqlServer PowerShell 模块。

Import-Module -Name ActiveDirectory, SQLServer

检查是否添加了任何其他 PowerShell 提供程序。

Get-PSProvider

请注意,在以下结果集中,现在存在两个新的 PowerShell 提供程序,一个用于 Active Directory,另一个用于 SQL Server。

Name                 Capabilities                       Drives
----                 ------------                       ------
Registry             ShouldProcess, Transactions        {HKLM, HKCU}
Alias                ShouldProcess                      {Alias}
Environment          ShouldProcess                      {Env}
FileSystem           Filter, ShouldProcess, Credentials {C, A, D}
Function             ShouldProcess                      {Function}
Variable             ShouldProcess                      {Variable}
ActiveDirectory      Include, Exclude, Filter, Shoul... {AD}
SqlServer            Credentials                        {SQLSERVER}

还添加了每个模块的 PSDrive。

Get-PSDrive
Name           Used (GB)     Free (GB) Provider      Root
----           ---------     --------- --------      ----
A                                      FileSystem    A:\
AD                                     ActiveDire... //RootDSE/
Alias                                  Alias
C                  19.38        107.13 FileSystem    C:\
Cert                                   Certificate   \
D                                      FileSystem    D:\
Env                                    Environment
Function                               Function
HKCU                                   Registry      HKEY_CURRENT_USER
HKLM                                   Registry      HKEY_LOCAL_MACHINE
SQLSERVER                              SqlServer     SQLSERVER:\
Variable                               Variable
WSMan                                  WSMan

可以像传统文件系统一样访问 PSDrive。

Get-ChildItem -Path Cert:\LocalMachine\CA
   PSParentPath: Microsoft.PowerShell.Security\Certificate::LocalMachine\CA

Thumbprint                                Subject
----------                                -------
FEE449EE0E3965A5246F000E87FDE2A065FD89D4  CN=Root Agency
D559A586669B08F46A30A133F8A9ED3D038E2EA8  OU=www.verisign.com/CPS Incorp....
109F1CAED645BB78B3EA2B94C0697C740733031C  CN=Microsoft Windows Hardware C...

比较运算符

PowerShell 包含用于比较值或查找与某些模式匹配的值的各种比较运算符。 下表包含 PowerShell 中的比较运算符列表。

表中列出的所有运算符都区分大小写。 若要使它们区分大小写,请将一个 c 放在运算符的前面。 例如, -ceq 等于 (-eq) 比较运算符的区分大小写的版本。

操作员 定义
-eq 等于
-ne 不等于
-gt 大于
-ge 大于或等于
-lt 小于
-le 小于或等于
-like 使用 * 通配符进行匹配
-notlike 与使用 * 通配符不匹配
-match 匹配指定的正则表达式
-notmatch 与指定的正则表达式不匹配
-contains 确定集合是否包含指定值
-notcontains 确定集合是否不包含特定值
-in 确定指定的值是否在集合中
-notin 确定指定的值是否不在集合中
-replace 替换指定的值

正确的大小写“PowerShell”等于使用等号比较运算符的小写“powershell”。

'PowerShell' -eq 'powershell'
True

它不等于使用相等比较运算符的区分大小写的版本。

'PowerShell' -ceq 'powershell'
False

不相等的比较运算符将反转条件。

'PowerShell' -ne 'powershell'
False

大于、大于或等于、小于和小于或等于所有处理字符串或数值。

5 -gt 5
False

使用大于或等于而不是与上一个示例一起使用返回 布尔 值 true,因为 5 等于 5。

5 -ge 5
True

根据前两个示例的结果,你可能会猜出小于和小于或等于工作的方式。

5 -lt 10
True

即使对于经验丰富的 PowerShell 用户,这些 -like-match 作员也可能会感到困惑。 -like 与通配符 * 一起使用并 ? 执行“like”匹配。

'PowerShell' -like '*shell'
True

运算符 -match 使用正则表达式来执行匹配。

'PowerShell' -match '^.*shell$'
True

使用 range 运算符将数字 1 到 10 存储在变量中。

$Numbers = 1..10

确定变量 $Numbers 是否包含 15。

$Numbers -contains 15
False

确定它是否包含数字 10。

$Numbers -contains 10
True

运算符 -notcontains 反转逻辑,以查看变量是否 $Numbers 不包含值。

$Numbers -notcontains 15

上一个示例返回布尔值 true,因为变量不包含 15。$Numbers

True

但是,它确实包含数字 10,因此测试时为 false。

$Numbers -notcontains 10
False

-in比较运算符首先在 PowerShell 版本 3.0 中引入。 它用于确定值是否 在数组中 。 变量 $Numbers 是一个数组,因为它包含多个值。

15 -in $Numbers
False

换句话说,执行与包含比较运算符相同的测试, -in 但相反的方向除外。

10 -in $Numbers
True

数组中 $Numbers 没有 15 个值,因此以下示例中返回 false。

15 -in $Numbers
False

与运算符一样 -containsnot 反转运算符的 -in 逻辑。

10 -notin $Numbers

上面的示例返回 false, $Numbers 因为数组包含 10,并且条件测试以确定它是否不包含 10。

False

确定 15 个不在数组中 $Numbers

15 -notin $Numbers

15 是数组“不在”中 $Numbers ,因此它返回 布尔 值 true。

True

作员 -replace 确实希望你会想到的。 它用于替换某些内容。 指定一个值会将该值替换为无值。 在以下示例中,将“Shell”替换为无内容。

'PowerShell' -replace 'Shell'
Power

如果要将值替换为其他值,请在要替换的模式后指定新值。 SQL 星期六在巴吞鲁日是一个我每年试图发言的事件。 在下面的示例中,“Saturday”一词替换为缩写“Sat”。

'SQL Saturday - Baton Rouge' -replace 'saturday','Sat'
SQL Sat - Baton Rouge

还有一些方法(如 Replace() 可用于替换类似于 replace 运算符工作原理的东西。 但是, -replace 运算符默认不区分大小写, Replace() 方法区分大小写。

'SQL Saturday - Baton Rouge'.Replace('saturday','Sat')

请注意,“星期六”一词未替换。 这是因为它在与原始大小写不同的情况下指定。

SQL Saturday - Baton Rouge

如果单词“Saturday”与原始值相同,则 Replace() 方法将按预期执行替换。

'SQL Saturday - Baton Rouge'.Replace('Saturday','Sat')
SQL Sat - Baton Rouge

使用方法转换数据时要小心,因为可能会遇到不可预见的问题,如未能通过 土耳其测试。 有关示例,请参阅我的博客文章: 使用 Pester 通过其他区域性测试 PowerShell 代码。 建议尽可能使用运算符而不是方法来避免这些类型的问题。

虽然可以使用比较运算符,如前面的示例所示,我通常将它们与 cmdlet 一起使用 Where-Object 来执行筛选。

概要

在本章中,你学习了几个主题,包括格式设置右、别名、提供程序和比较运算符。

回顾

  1. 为什么必须尽可能适当地执行格式设置?
  2. 如何确定别名的实际 cmdlet % 是什么?
  3. 为什么你不应该在保存的脚本中使用别名或与他人共享的代码?
  4. 对与注册表提供程序关联的驱动器执行目录列表。
  5. 使用替换运算符而不是 replace 方法的主要优点之一?

参考文献

后续步骤

在下一章中,你将了解流控制、脚本、循环和条件逻辑。