《Windows Powershell 实战指南》第5章笔记

第5章 提供程序

1. 什么是提供程序

1.1 概念

提供程序(PSProvider):本质上是一个适配器。它可以像访问磁盘驱动器一样访问某些数据存储介质。

驱动程序(PSDrive):驱动程序可通过一个特定的提供程序去连接到某些存储数据的介质。

获取本机上的提供程序:

PS C:\Windows\system32> Get-PSProvider

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

通过Get-PSProvider的执行结果,观察提供程序和驱动程序两者的关系。如果用磁盘和分区来类比的话,提供程序就是一块磁盘,驱动程序就是这块磁盘上划分的几个分区。要想访问磁盘上的数据必须先进入某个分区,我们无法绕过分区直接打开或修改磁盘上的数据。

所以Registry、Alias、Environment等提供程序就是存储数据的底层介质,HKLM,、HKCU、Alias、Env等驱动程序就是上层的分区。而我们要想访问这些介质中的数据,必须先打开HKLM,、HKCU、Alias等驱动程序,就像打开C盘、D盘一样,下一步才能选择其中的文件和数据。

1.2 功能描述

从 Get-PSProvider的执行结果可以看出每个提供程序都有各自不同的功能。这一点很重要,因为这决定了我们如何使用这些提供程序。下面是常见的一些功能描述:

  • ShouldProcess——表明该提供程序支持-whatif-confirm参数,保证我们正式执行这部分脚本之前可以对他们进行测试。
  • Filter——表明在Cmdlet中操作提供程序的数据时,支持-Filter参数。
  • Credentials——表明该提供程序允许使用可变更的凭据去连接数据存储。这也是-Credentials参数的作用。
  • Transactions——表明该提供程序支持事务操作,也就是允许你在该提供程序中将过个变更作为一个原子操作进行提交或者全部回滚。

2. 文件系统的结构

2.1 文件系统

Windows文件系统主要由三种对象组成:磁盘驱动器、文件夹和文件。磁盘驱动器是最上层的对象,包含文件夹和文件。文件夹是一种容器对象,它可以包含文件以及其他文件夹。文件不是容器对象,它可以算作最小单位的对象。

2.2 Item的来源和操作命令

Powershell中的术语和文件系统中的略有不同。因为PSDrive 可能并不是指向某个文件系统——比如PSDrive可以映射到注册表,所以powershell并不会使用“文件”和“文件夹”的说法。相反,powershell采用更通俗的说法“项”(Item)。一个文件或者文件夹都叫项,尽管本质他们是不同的。所以powershell中操作对象的命令都包含“Item”字符。使用下列命令搜索包含“Item”的Cmdlet:

PS C:\> Get-Command -Noun *Item*

CommandType Name                          Version Source
----------- ----                          ------- ------
Function    Get-DAEntryPointTableItem     1.0.0.0 DirectAccessClientComponents
Function    Get-TestDriveItem             3.4.0   Pester
Function    New-DAEntryPointTableItem     1.0.0.0 DirectAccessClientComponents
Function    Remove-DAEntryPointTableItem  1.0.0.0 DirectAccessClientComponents
Function    Rename-DAEntryPointTableItem  1.0.0.0 DirectAccessClientComponents
Function    Reset-DAEntryPointTableItem   1.0.0.0 DirectAccessClientComponents
Function    Set-DAEntryPointTableItem     1.0.0.0 DirectAccessClientComponents
Cmdlet      Add-ClusterVMMonitoredItem    2.0.0.0 FailoverClusters
Cmdlet      Clear-Item                    3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Clear-ItemProperty            3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Copy-Item                     3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Copy-ItemProperty             3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Get-ChildItem                 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Get-ClusterVMMonitoredItem    2.0.0.0 FailoverClusters
Cmdlet      Get-ControlPanelItem          3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Get-Item                      3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Get-ItemProperty              3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Get-ItemPropertyValue         3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Invoke-Item                   3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Move-Item                     3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Move-ItemProperty             3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      New-Item                      3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      New-ItemProperty              3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Remove-ClusterVMMonitoredItem 2.0.0.0 FailoverClusters
Cmdlet      Remove-Item                   3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Remove-ItemProperty           3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Rename-Item                   3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Rename-ItemProperty           3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Set-Item                      3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Set-ItemProperty              3.1.0.0 Microsoft.PowerShell.Management
Cmdlet      Show-ControlPanelItem         3.1.0.0 Microsoft.PowerShell.Management

对上面的命令名称构成的一些解释:

  • 比如Clear,Copy,Get,Move,New,Remove,Rename 和 Set 等动词可以应用于这些项(包括文件夹和文件)以及它们的属性(比如最后修改时间、只读等)。
  • 名词部分只包括一个“Item”,可以应用于文件或文件夹的操作。
  • 名词部分是“ItemProperty”,代表一个项对应的属性,比如只读、创建时间、大小等。
  • 名词部分是“ChildItem”代表一个项(文件或文件夹)包含在另一个项中(文件夹)。

2.3 使用命令

上面的Cmdlet都是通用的,因为它们需要处理各种不同的数据源。但是需要注意的是,某些Cmdlet在特定场合下不一定能正常工作。就是说所有的提供程序都支持这些 Cmdlet 的使用,但是不支持部分参数的使用。从提供程序的功能描述部分(1.2节)中可以找到原因。

例如:文件系统不支持事务,所以在文件系统驱动器下使用命令时都不支持-UseTransaction参数;注册表不支持 Filter 功能,所以在注册表驱动器中使用命令时,也不能使用-Filter参数。

另外某些 PSProvider 并不具有对应的项属性。比如 Environment 提供程序主要的作用是访问Windows 中的环境变量,但它并没有任何项属性:

PS C:\> Get-ItemProperty -Path Env:\PSModulePath
Get-ItemProperty : 无法使用接口。此提供程序不支持 IPropertyCmdletProvider 接口。
所在位置 行:1 字符: 1
+ Get-ItemProperty -Path Env:\PSModulePath
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotImplemented: (:) [Get-ItemProperty], PSNotSupportedException
    + FullyQualifiedErrorId : NotSupported,Microsoft.PowerShell.Commands.GetItemPropertyCommand

3. 使用文件系统

在使用提供程序时,首先需要熟悉的命令为 Set-Location。它的功能是将Shell中当前路径变更为不同的路径。使用 Set-Location命令进入不同的驱动程序,必须在驱动程序末尾加上:\(这里使用斜杠效果也是一样的:/),例如:

PS C:\> Set-Location d:\
PS D:\> Set-Location env:\
PS Env:\> Set-Location Function:\
PS Function:\> Set-Location HKCU:\
PS HKCU:\>

创建一个新的项的命令是 New-Item,由于该命令在所有提供程序中都能使用,所以使用时必须指定新项的类型,例如文件夹、文件或者注册表。例如:

PS C:\> New-Item -Name 123 -ItemType Directory


    目录: C:\


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----         2019/4/2     22:28                123

4. 使用通配符以及绝对路径

大部分的 Cmdlet 都包含-Path参数,默认情况下该参数支持通配符。例如我们查看 Get-ChildItem 的帮助文档中关于-Path参数的部分:

PS C:\> help Get-ChildItem -Parameter path

-Path <String[]>
    Specifies a path to one or more locations. Wildcards are permitted. The default location is the current directory (.).

    是否必需?                    False
    位置?                        0
    默认值                        Current directory
    是否接受管道输入?            True (ByPropertyName, ByValue)
    是否接受通配符?              True

*通配符代码0个或多个字符,?通配符仅代表单个字符。由于它们是通配符,所以在文件夹或文件的名称中不允许使用这两个字符。但是在其他类型的数据存储中,Item 的名称中是可以包含*?的。例如注册表中的项名称就可以使用*?,这就导致一个问题。当一个路径参数中使用了*?powershell该如何识别,是作为通配符还是名称中的一个字符。针对该问题,powershell给出的解决办法是增加一个参数-LiteralPath

PS C:\> help Get-ChildItem -Parameter liter*

-LiteralPath <String[]>
    Specifies, as a string arrya, a path to one or more locations. Unlike the Path parameter, 
    the value of the LiteralPath parameter is used exactly as it is typed. No characters are 
    interpreted as wildcards. If the path includes escape characters, enclose it in single 
    quotation marks. Single quotation marks tell Windows PowerShell not to interpret any 
    characters as escape sequences.

    是否必需?                    True
    位置?                        named
    默认值                None
    是否接受管道输入?            True (ByPropertyName)
    是否接受通配符?              False

如果要查询的名称中带有*?,就要使用-LiteralPath参数,而不能使用-Path。注意-LiteralPath不能隐式赋予,使用时必须写上参数名称。

相关推荐