Powershell针对Excel的一些简单操作
稍微高级点的语言都会涉及到对COM对象的操作,作为微软自己进化的脚本语言,powershell有这个功能一点不稀奇,首先它使用 .NET Framework 提供的强大类库,很多特性和C#相似;其次,虽然作为脚本但它面向对象。使用powershell来管理WMI和COM更简单。
用微软官方的话概括powershell就是:
Windows PowerShell™ 是一种基于任务的命令行 shell 和脚本语言,专门用于管理系统。 Windows PowerShell™ 构建于 .NET Framework 之上,能够帮助 IT 专业人员和高级用户控制和自动管理 Windows 操作系统以及在 Windows 上运行的应用程序。
内置 Windows PowerShell 命令(称为 cmdlet)可用于通过命令行管理企业中的计算机。使用 Windows PowerShell™ Provider,您可以像访问文件系统那样轻松地访问数据存储,如注册表和证书存储。 此外,Windows PowerShell™ 还具有一个功能丰富的表达式分析程序和一种经过充分开发的脚本语言。
下面介绍powershell对excel的简单操作。
首先,我执行一条命令来获取系统当前正在运行的所有进程:

Get-Process cmdlet显示当前本地进程运行状态,包括处于打开状态的句柄数量、各种内存占用视图以及 CPU 使用率的快照。powershell和Linux shell一个很大的不同点就是大小写不敏感,无论是系统函数还是命令。这点可以减少犯错的概率。
您可能疑惑为什么讲这个?对于系统管理员来说,冗长的数据背后隐藏着大量细节,get-process是获取本地进程运行情况,当然加上-computername参数后可以访问远程计算机,但目前这个对于网络管理员来说犹如海市蜃楼,所以不得不使用windows WMI和 Win32_Process WMI 类来监视远程系统并以实用方式显示信息。如果认为 Get-Process 的输出内容非常丰富,请再仔细看看 Win32_Process 的输出:

很明显,这个输出很详细,但是可读性不强,管理员需要的是易于阅读的内存占用量报告。可以转用Excel实现自动操作。
自动化 Excel 有多难?实际上非常简单,因为 Microsoft 已创建了专门用于处理 Excel 的自动化模型。程序 ID 是 Excel.Application,它是一个 COM 对象。创建 Excel.Application 对象的实例时,Excel 会默认启动并运行,只是您看不见它。但是,可使用 visible 属性让 Excel 显示出来。
以下代码显示了如何创建 Excel.Application 对象、查询 visible 属性的状态,然后将 visible 属性设为 true:
PS > $excel = New-Object -ComObject Excel.Application ==>创建一个excel应用的COM对象
PS > $excel.Visible ==>默认新建的excel视图不显示,即没有打开
False
PS > $excel.Visible = $true ==>看到下面的界面
</div>
然后,您会看到一个非常奇怪的 Excel 视图,它看起来就像 Excel 应用程序的一个外壳(如下图)。没有工作簿、没有电子表格,—个是光秃秃的 Excel。

当然,这个肯定是无法使用的,但是它是建立工作簿的前提,它是存放工作簿的容器。现在我们需要将一个工作簿添加到应用程序中。为此,需要借助工作簿对象的 add 方法。工作簿对象是从主 Excel.Application 对象进行访问的,正如您看到的,我们将工作簿对象存储在一个名为 $workbook 的变量中:
$workbook = $excel.Workbooks.add() ==>现在添加了一个空的工作簿
</div>
现在,需连接特定的电子表格。默认情况下,工作簿添加到 Excel 时,会向其中添加三个电子表格(sheet1,sheet2,sheeet3)。这些电子表格可通过数字进行标识。在以下代码行中,连接第一个电子表格并将返回的电子表格对象存储在名为 $sheet 的变量中:
$sheet = $workbook.worksheets.Item(1) ==>表示我使用的是第一个sheet
</div>
现在我再运行一次$excel.Visible = $true来查看excel变成什么样了(建好了工作簿并且选择了sheet1):

现在,可将数据写入该电子表格。Excel 电子表格中的信息存储在单元格中。由于单元格位于电子表格之中,所以可使用 $sheet 变量中存储的电子表格对象访问特定的单元格。具体方法是使用指代电子表格中行和列的数字。在 Excel 电子表格中,行是数字而列是字母,这一点有些让人迷惑。但使用自动化模型时,行和列均为数字。第一个数字是行,第二个数字是列。只需对特定单元格进行赋值即可写入单元格:
$sheet.cells.item(1,1) = "Test" ==>我在第一个单元格填入“Test”
</div>
这时,您再运行$excel.Visible = $true,查看excel变成啥样了:

嗯,意料之中,Excel 的一个不足是工作簿始终会创建三个电子表格,这有点浪费,因为我现在这个测试只需要第一个sheet。幸运的是,可利用自动化删除多余的电子表格:使用工作表集合连接第三个电子表格并调用 delete 方法。执行相同的操作删除第二个电子表格:
$workbook.workSheets.item(3).delete()
$workbook.WorkSheets.item(2).delete()
</div>
这样只剩下sheet1了,接下来,重命名剩余的电子表格。这一点非常重要,因为如果决定使用 ActiveX 数据对象 (ADO) 来查询 Excel 电子表格,将在连接字符串中使用此电子表格名称。因此,要使代码易读且直观,电子表格应具有逻辑名称。要重命名电子表格,只需向特定电子表格的 name 属性赋一个值即可。以下代码将第一个电子表格重命名为 "Processes":
$workbook.WorkSheets.item(1).Name = "Processes"
</div>
现在,需连接重命名后的电子表格。使用工作表对象的 Item 方法并将电子表格的名称指定给它:
$sheet = $workbook.WorkSheets.Item("Processes")
</div>
这时我们再查看excel的样子:

以上测试过程的代码如下:
$excel = New-Object -ComObject Excel.Application
#$excel.Visible = $true
$workbook = $excel.Workbooks.add()
$sheet = $workbook.worksheets.Item(1)
$sheet.cells.item(1,1) = "Test"
$workbook.workSheets.item(3).delete()
$workbook.WorkSheets.item(2).delete()
$workbook.WorkSheets.item(1).Name = "Processes"
$excel.Visible = $true
</div>
下面我们开始将process中的内容移植到excel中。
电子表格的第一行将包含标头信息。将绘制边框并使属性名称显示为粗体。由于数据将从第二行开始,因此将值 2 赋给计数器变量 $x:

