Powershell:Excel,运行后保存并closures

运行后如何保存下面的脚本?

脚本来自: Powershell磁盘使用情况报告

$erroractionpreference = "SilentlyContinue" $a = New-Object -comobject Excel.Application $a.visible = $True $b = $a.Workbooks.Add() $c = $b.Worksheets.Item(1) $c.Cells.Item(1,1) = "Server Name" $c.Cells.Item(1,2) = "Drive" $c.Cells.Item(1,3) = "Total Size (GB)" $c.Cells.Item(1,4) = "Free Space (GB)" $c.Cells.Item(1,5) = "Free Space (%)" $d = $c.UsedRange $d.Interior.ColorIndex = 19 $d.Font.ColorIndex = 11 $d.Font.Bold = $True $intRow = 2 $colComputers = get-content "c:\servers.txt" foreach ($strComputer in $colComputers) { $colDisks = get-wmiobject Win32_LogicalDisk -computername $strComputer -Filter "DriveType = 3" foreach ($objdisk in $colDisks) { $c.Cells.Item($intRow, 1) = $strComputer.ToUpper() $c.Cells.Item($intRow, 2) = $objDisk.DeviceID $c.Cells.Item($intRow, 3) = "{0:N0}" -f ($objDisk.Size/1GB) $c.Cells.Item($intRow, 4) = "{0:N0}" -f ($objDisk.FreeSpace/1GB) $c.Cells.Item($intRow, 5) = "{0:P0}" -f ([double]$objDisk.FreeSpace/[double]$objDisk.Size) $intRow = $intRow + 1 } } 

根据https://social.technet.microsoft.com/Forums/windowsserver/en-US/919459dc-3bce-4242-bf6b-fdf37de9ae18/powershell-will-not-save-excel-file ,这将工作,但我我无法:

 Add-Type -AssemblyName Microsoft.Office.Interop.Excel $xlFixedFormat = [Microsoft.Office.Interop.Excel.XlFileFormat]::xlWorkbookDefault $Excel = New-Object -comobject Excel.Application $Excel.Visible = $true ################ $Excel.workbooks.OpenText($file,437,1,1,1,$True,$True,$False,$False,$True,$False) $Excel.ActiveWorkbook.SaveAs($env:tmp + "\myfile.xls", $xlFixedFormat) $Excel.Workbooks.Close() $Excel.Quit() 

得到它的工作! – 特别感谢@Matt

完整的脚本正在工作:

 $erroractionpreference = "SilentlyContinue" $a = New-Object -comobject Excel.Application $a.visible = $True Add-Type -AssemblyName Microsoft.Office.Interop.Excel $xlFixedFormat = [Microsoft.Office.Interop.Excel.XlFileFormat]::xlWorkbookDefault $a.Visible = $true $b = $a.Workbooks.Add() $c = $b.Worksheets.Item(1) $c.Cells.Item(1,1) = "Server Name" $c.Cells.Item(1,2) = "Drive" $c.Cells.Item(1,3) = "Total Size (GB)" $c.Cells.Item(1,4) = "Free Space (GB)" $c.Cells.Item(1,5) = "Free Space (%)" $d = $c.UsedRange $d.Interior.ColorIndex = 19 $d.Font.ColorIndex = 11 $d.Font.Bold = $True $intRow = 2 $colComputers = get-content "c:\servers.txt" foreach ($strComputer in $colComputers) { $colDisks = get-wmiobject Win32_LogicalDisk -computername $strComputer -Filter "DriveType = 3" foreach ($objdisk in $colDisks) { $c.Cells.Item($intRow, 1) = $strComputer.ToUpper() $c.Cells.Item($intRow, 2) = $objDisk.DeviceID $c.Cells.Item($intRow, 3) = "{0:N0}" -f ($objDisk.Size/1GB) $c.Cells.Item($intRow, 4) = "{0:N0}" -f ($objDisk.FreeSpace/1GB) $c.Cells.Item($intRow, 5) = "{0:P0}" -f ([double]$objDisk.FreeSpace/[double]$objDisk.Size) $intRow = $intRow + 1 } } $a.workbooks.OpenText($file,437,1,1,1,$True,$True,$False,$False,$True,$False) $a.ActiveWorkbook.SaveAs("C:\Users\Username\Desktop\myfile.xls", $xlFixedFormat) $a.Workbooks.Close() $a.Quit() 

要正确并完全closuresExcel,还需要释放COM引用。 在我自己的testing中发现,除去Excel的variables还确保不存在将保持Excel.exe打开的其余引用(就像在ISE中debugging一样)。

没有执行上述,如果你看任务pipe理器,你可能会看到Excel仍在运行…在某些情况下,许多副本。

这与如何将COM对象包装在“运行时可调用包装器”中有关。

这是应该使用的骨架代码:

 $excel = New-Object -ComObject Excel.Application $excel.Visible = $true $workbook = $excel.Workbooks.Add() # or $workbook = $excel.Workbooks.Open($xlsxPath) # do work with Excel... $workbook.SaveAs($xlsxPath) $excel.Quit() [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) # no $ needed on variable name in Remove-Variable call Remove-Variable excel 

这对我工作:

 $workbook.Close($false) $excel.Quit() [System.GC]::Collect() [System.GC]::WaitForPendingFinalizers() [System.Runtime.Interopservices.Marshal]::ReleaseComObject($workSheet) [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) Remove-Variable -Name excel 

正如在这里的 MSDN文档中所提到的那样,ReleaseComObject调用只会将该COM对象的引用计数器递减1.如果脚本具有多个同一COM对象的引用,则不会释放该对象。

文档build议使用FinalReleaseComObject方法来完全释放COM对象,并closures所有的Excel进程。

只有当您完成COM引用时才确定调用此方法,否则可能会导致难以debugging的错误。