因为PowerShell并不是完全成熟的用于生成管理报表的工具,但是它能够很好的收集计算机的信息,并以定制的格式输出,用于输出定制的方式称为格式化。
默认格式
现在我们运行一个熟悉的cmdlet: get-process, 然后注意结果的列头部分。可以看到他并不是非常符合常规的属性名。取而代之的是一个固定的宽度、别名等。
其实这些格式都是来自于配置文件,我们可以在安装PowerShell的路径下找到其中一个命名为:“.format.ps1xml”的文件,其中进程对象的格式化目录在DotNetTypes.format.ps1xml中。
首先我们进入PowerShell的安装目录,并且打开DotNetTypes.format.ps1xml文件。NOte:不要随意更改这个文件,这个文件是带有数字签名的,即使一个空格都会影响到powerShell的使用。
cd $pshome
notepad DotNetTypes.format.ps1xml
打开文件以后,从中找出准确的类型并返回给: get-process
接下来完成下面的步骤:
- 复制完整的类型名: System.Diagnostics.Process ,并粘贴
- 切换到记事本,打开查找窗口
- 粘贴类型名,然后单击查找
- 直到找到System.Diagnostics.Process为止,如下图
现在我们可以看到在记事本中以默认形式显示一个进程的管理目录。你会看到每个列的列名,以及宽度等其他的一些属性。
在返回PowerShell,运行get-process时,在shell中会发生下面的事情:
- cmdlet把类型为: System.Diagnostics.Process的对象放入管道。
- 在管道末端是一个名为“Out-Default”的隐藏的cmdlet。 这个cmdlet的作用时把需要运行的命令全部放入管道中。
- out-default 把对象传输到 Out-Host,原因是Powershell控制台默认把输出结果显示到及其所在的显示屏(称为Host)上。其实你也完全可以写一个shell把文件或打印机作为博人输出设备。
- 大部分out-cmdlets不适合用在普通对象中,而主要用于特定格式化指令上。所以当Out-Host看到那些普通对象时,会把他们传递给格式化系统。
- 格式化系统以其内部格式化的规则检查对象的类型,然后用这些规则产生格式化指令,最终传输回:Out-Host.
- 一旦: Out-Host 发现已经生成了格式化指令,就会根据这个指令产生显示到屏幕上的结果。
上面提到的内容也会在你手动指定Out-Cmdlet的时候发生。比如你运行Get-Process | Out-File procs.txt 和 out-files时,PowerShell会看到你发送了一些普通对象,它会把这些对象发给格式化系统,然后创建格式化指令后回传给Out-File。 Out-File基于这些指令创建格式化后的文本文件,所以在需要把对象转换成用户可读的文本输出格式时,格式化系统就会起到作用。
在上面的步骤中,PowerShell会依赖于什么格式化规则?其中第一个规则时系统会检查对象类型是否已经被预定义视图处理过。也就是我们见到的DotNetTypes.format.ps1xml 针对进程的对象。PowerShell中预装了其他的。format.ps1xml文件,在shell启动时自动加载。
格式化系统对特定对象的类型查找相应的预定义视图,在本例中就是查找System.Diagnostics.Process 对象的视图。
如果没有找到对应的视图会发生什么呢?比如运行:
Get-WmiObject win32_operatingsystem | gm
你会发现放进管道中的对象类型为: System.Management.ManagementObject#root\cimv2\Win32_OperatingSystem,这在我们的ps1xml文件中是找不到的。
这也就是格式化系统下一步要做的事情,称之为第二格式化规则:格式化系统寻找是否有针对这个对象类型的“default display property set”. 这些可以在另外一个配置文件“Types.ps1xml” 中找到。
如果格式化系统找到一个default display property set会把这个属性集用于下一步的决策。如果没有找到,那么下一步的决策将考虑所有对象的属性值。
接下来是决策,即格式化第三个规则---用于决定输出的样式。
如果格式化系统将显示4个或以下的属性,将决定以表格形式展现。
如果有5个或者以上的属性,会使用列表的形式。