前言
可扩展性是PowerShell的一个主要优势。随着微软对PowerShell的持续投入,它为ExchangeServer、SharePoint Server、System Center系列、SQL Server等产品开发了越来越多的命令。通常,当你安装这些产品的管理工具时,还会安装一个或多个Windows PowerShell扩展的图形化管理控制台。
工作机制
尤如图形化的微软管理控制台(MMC)一样,它们涉及的可扩展的工作原理并无不同,部分原因是MMC和PowerShell由微软同一个管理框架下的团队研发。
当你打开一个新的空白MMC控制台,在很大程度上,它的功能有限。因为MMC的内置功能很少,所以它基本上做不了什么事情。如果想让它强大一些,你需要在文件菜单中使用添加/删除管理单元。在MMC中,一个管理单元就是一个工具,这类似于活动目录用户和计算机、DNS管理、DHCP管理等。
这些管理单元从何而来?一旦你安装了类似Exchange Server、Forefront或者System Center产品的相关管理工具,就会在MMC的添加、删除管理单元的对话框里面列出这些产品的管理单元。大多数产品也会安装自己的预配置MMC控制台文件,安装过程仅是加载了基本的MMC和预加载一个或两个管理单元。
产品的“管理Shell”
以活动目录为例,在Windows Server 2008 R2域控制器的开始菜单、管理工具下,你会发现一个关于活动目录组件的Windows PowerShell。如果在这一项单击右键,然后从上下文菜单中选择属性,第一眼就可以看到类似如下的目标域。
该命令运行标准的PowerShell.exe应用程序,并指定命令行参数运行特定命令:Import-Module ActiveDirectory
。执行的效果是可以预加载活动目录。
以上,同样适用于几乎所有特定于产品的“管理Shell”:Exchange、SharePoint等。
SQL Server 2008和SQL Server 2008 R2却是例外。它们“产品相关”的Shell叫作Sqlps。它是一个经过特殊编译专门运行SQL Server扩展的PowerShell。通常称之为mini-Shell。微软第一次在SQLServer中尝试这种方法。但这种方法已经不流行了,并且微软不会再使用这种方法了:SQL Server2012使用的是PowerShell。
扩展
PowerShell存在两种类型的扩展:模块和管理单元。首先讲述管理单元。
添加插件
一个适合管理单元PowerShell的名字是PSSnapin,用于区别这些来自管理单元的图形MMS。一个PSSnapin通常包含一个或多个DLL文件,同时包含配置XML文件和帮助文档。
PSSnapins必须先安装和注册,然后PowerShell才能识别它的存在。
注意:PSSnapin的概念逐步被微软移除了,将来可能会越来越少出现。在内部,微软的重点是提供扩展模块。
可以通过在PowerShell中运行Get-PSSnapin -registered
命令获取到一个可用的管理单元列表。
在域控制机器上安装了SQL Server 2008,返回结果如下:
上面的信息说明机器上安装了两个可用的管理单元,但是并没有加载。你可以通过运行Get-PSSnapin
命令查看已加载的列表。该列表包含所有的核心,包含PowerShell中的本机功能的自动加载管理单元。
加载管理单元
通过运行Add-PSSnapin
并指定管理单元名称的方式,加载某一个管理单元。
当一个管理单元加载成功了,你可能想知道Shell到底增加了什么功能。PSSnapin可以增加Cmdlets命令、提供PSDrive,或者两者都增加。使用Get-Command命令找出已增加的Cmdlets命令。
在这里必须指出,输出的结果中只包含了SqlServerCmdletSnapin100这个管理单元,并且只有两行记录。是的,这就是SQL Server在管理单元中增加的所有内容,而且只有一个可以执行Transact-SQL(T-SQL)的命令。因为你可以通过T-SQL命令在SQL Server上实现几乎所有的操作,Invoke-Sqlcmd这个Cmdlet命令同样可以完成所有的操作。
运行Get-PSProvider,可以查看一个管理单元是否成功加载新的PSDrive:
看起来没有任何新增内容,这是由于我们所加载的Snap-in名称为SqlServerCmdletSnapin100
。我们的可用管理单元同样包含了SqlServerProviderSnapin100
,这意味着微软出于某些原因,把它的Cmdlets命令和PSDrive分开打包。让我们尝试添加第二个:
可以发现SQL Server驱动器已经被添加到我们的Shell当中,由SQLServer的PSDrive提供驱动。新增的该驱动意味着可以运行命令:cd SQLserver
切换到SQL Server驱动器,接着可以开始探索数据库。
添加模块
PowerShell v3(以及v2)提供的第二种扩展方式称为模块。模块被设计得更加独立,因此更加容易分发,但是它的工作原理类似于PSSnapins。
模块不需要复杂的注册,PowerShell会自动在一个特定的目录下查找模块。PSModulePath
这个环境变量定义了PowerShell期望存放模块的路径。
PS D:\(Tmp> Get-Content Env:PSModulePath
d:\Users\guoruilong\Documents\WindowsPowerShell\Modules;C:\Program Files\WindowsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules
上面输出的路径中包含了两个默认的位置:其中一个是存放系统模块的操作系统目录,另外一个是存放个人模块的文档目录。只要知道一个模块的完整路径,就可以从任何其他的位置添加模块。
PSModulePath环境变量
在PowerShell v3中,模块路径很重要。如果有位于其他位置的模块,应该把模块所在的路径加入到PSModulePath
这个环境变量中。通过它,PowerShell可以自动加载位于你计算机上的所有模块。
PowerShell的Update-Help
命令,同样适用PSModulePath
发现已存在的任何模块,然后针对每个模块搜索需要更新的帮助文档。
Tips:
可以使用Get-Module
命令检索一个远程服务器的可用模块列表,还可以使用Import-Module
加载一个远程模块到当前PowerShell会话。
即使在模块还没有显式加载到内存的情况下,PowerShell依然可以自动发现模块,从而使得Shell完成命令名称自动补全、显示帮助和运行命令。
如果一个模块不在被PSModulePath引用的任何一个目录下,你应该使用Import-Module命令并指定模块的完整路径,如C:\MyPrograms\Something\MyModule。
模块还可以添加PSDrive提供程序。你必须使用与PSSnapins中相同的技巧确定有哪些新的提供程序:运行Get-PSProvider
命令。
命令冲突和移除扩展
注意到什么特别的命令名称了吗?大多数的PowerShell扩展(Exchange Server是一个明显的例外)都在它们命令名的名词部分增加了一个短的前缀,如Get-ADUser
和Invoke-SqlCmd
。这些前缀看起来有些多余,但是它们可以防止命令名称的冲突。
如果你已经对冲突不厌其烦,你可以随时选择删除冲突的扩展名。你需要运行Remove-PSSnapin
或Remove-Module
,并指定管理模块或模块命令的名称,从而卸载某个扩展。
玩转新模块
例如,我们的目标是清除我们计算机上的DNS名称解析缓存。我们还不知道PowerShell是否能做到这一点,所以需要先在帮助系统中寻找一些线索。
我们好奇还有其他哪个命令可用。为了找出该命令,我们手动加载该模块并列出所有命令。
运行Clear-DnsClientCache
命令时,PowerShell会在后台为我们加载DnsClient模块。
查看帮助
运行命令:
PS D:\(Tmp> Clear-DnsClientCache # 执行后,没有任何结果返回
# 通过-Verbose开关参数,来确认命令是否正确执行
PS D:\(Tmp> Clear-DnsClientCache -Verbose
详细信息: The specified name resolution records cached on this machine will be removed.
Subsequent name resolutions may return up-to-date information.
所有的命令都有-verbose
开关参数,但并不是所有命令都会实现该参数。在该示例中,我们得到一个指示发生了什么事情的信息,这让我们知道这个命令已经成功运行。
配置脚本:在启动Shell时预加载扩展
创建一个控制台文件:这只能记录已经加载的PSSnapins,而无法加载模块。
1)首先加载所有你想要的管理单元,接着运行下面的命令:
运行该命令,可以把你在Shell中加载的管理单元列表,保存到一个很小的XML文件。
2)接下来,你希望在某些地方创建一个新的PowerShell快捷方式,快捷方式的目标应该是:
当使用该快捷方式打开一个新的PowerShell窗口,这将加载控制台,并且该Shell会自动加载控制台文件内的所有管理单元。
如果同时需要加载管理单元和模块或者只加载其中某些模块,这种情况下应该怎么做?答案就是使用配置脚本。
可以按照下面的步骤来学习如何使用它们:
- 在文档目录,创建一个名为
WindowsPowerShell
的新文件夹。 - 在新文件夹内,创建一个名为
profile.ps1
的新文件。 - 在文件中输入
Add-PSSnapin
和Import-Module
命令,以一行一个命令的格式加载管理单元和模块。 - 回到PowerShell中,需要启用脚本的执行功能,这在默认情况下处于禁用状态。
- 在以管理员身份运行的终端中,运行
Set-ExecutionPolicy RemoteSigned
命令。
- 在以管理员身份运行的终端中,运行
- 关闭并重启Shell,这将会自动加载
profile.ps1
文件,并执行里面的命令,为你加载喜欢的管理单元和模块。从Internet获取模块 - Gallery
微软引入了一个名称为PowerShellGet的模块,这使得从在线仓库中搜索、下载、安装、升级模块变得容易了。PowerShellGet很像Linux管理员喜爱的包管理器-RPM、YUM、apt-get等。微软甚至还维护一个在线源,称为PowerShell Gallery(http://powershellgallery.com)。
警告:微软维护并不意味着微软生产、验证与支持。PowerShell Gallery包含社区贡献的代码,在你的环境执行别人的代码需要小心。
PowerShellGet随着PowerShell v5以及更新版本一起发行(非Windows系统不可用),如果你使用的是v5版本(检查$PSVersionTable),你就拥有了该模块。http://PowerShellGallery.com包含指向PowerShellGet模块的链接,从而可以在Windows 7 SP1以及之后版本,Windows 2008 R2以及之后版本上安装。
使用PowerShellGet非常简单:
- 运行
Register-PSRepository
添加一个源的URL。- http://PowerShellGallery.com通常是默认设置,但也可以添加自用的“gallery”,并利用Register-PSRepository指向该地址。
- 使用
Find-Module
在源中查找模块。- 可以在名称、特定标签等列中,使用通配符缩小搜索结果。
- 如:
Find-Module *privilege*
- 找到所需的模块后,使用
Install-Module
下载与安装一个模块。 - 使用
Update-Module
确保模块的副本是最新的,如果不是,下载最新版本并安装。 ```powershell PS D:(Tmp> Get-Help Register-PSRepository -Online PS D:(Tmp> Get-PSRepository
Name InstallationPolicy SourceLocation
PSGallery Untrusted https://www.powershellgallery.com/api/v2
<a name="f5FbT"></a>
### Register a repository
```powershell
PS D:\(Tmp> $parameters = @{
Name = "myNuGetSource"
SourceLocation = "https://www.myget.org/F/powershellgetdemo/api/v2"
PublishLocation = "https://www.myget.org/F/powershellgetdemo/api/v2/Packages"
InstallationPolicy = 'Trusted'
}
PS D:\(Tmp> Register-PSRepository @parameters
PS D:\(Tmp> Get-PSRepository
Name SourceLocation OneGetProvider InstallationPolicy
---- -------------- -------------- ------------------
PSGallery http://go.micro... NuGet Untrusted
myNuGetSource https://myget.c... NuGet Trusted
PowerShellGet包含一系列其他命令,但上面的操作,是开始所需使用的。
例如,尝试安装PowerShellGet(如果使用的不是PowerShell v5),该安装不会包含EnhancedHTML2(在http://PowerShell.org中有一本免费的电子书“CreatingHTML Reports in PowerShell”阐述该模块)或来自PowerShell Gallery由Jeff编写的ISEScriptingGeek模块。