Hey, Scripting Guy! We are having problems with several of our servers at work. Several of them were upgraded from Windows NT 4, and as a result, we are constantly running into disk space issues on the C: drive. I would rather manage the problem than take the servers down and rebuild them because we already have budget to replace them next quarter. Therefore, in the meantime, I have to baby-sit 30 servers.
This whole thing came to a head last week when one server blue-screened because of no disk space on the C: drive when the page file was unable to grow. Now the pointy-headed boss wants a daily disk space report for the 30 servers. I wrote a quick Windows PowerShell script that will report the disk space for the 30 servers, and gave him the script (hoping in vain that he would run it). But he wants an actual Microsoft Word document report. I found your How Can I Create a Microsoft Word Document from WMI Information? article, but it does not really do what I need to accomplish. I would appreciate it if you would help me out.
— CA
Hello CA,
Microsoft Scripting Guy Ed Wilson here. I am listening to UFO on my Zune HD, and sipping a nice cup of Earl Grey tea with a cinnamon stick and a splash of milk in it. I am also munching on one of my carefully guarded ANZAC biscuits. Probably because of the cold weather, I have been reviewing some of the pictures I took during my last dive trip to Key Largo, Florida, with my scuba club. The following picture makes me want to grab my gear and dive in.
CA, writing WMI information to a Microsoft Word document by using a Windows PowerShell script is easier than stepping off a dive boat and swimming with sharks.
The first thing we do in the WriteDiskSpaceToWord.ps1 script is assign a few strings to some variables. The Win32_Volume WMI class is used to obtain the free disk space from the C: drive. The Win32_Volume WMI class was first introduced in Windows Server 2003, and if you have to query Windows XP or earlier computers, you will need to use the Win32_LogicalDisk WMI class. The $path variable holds the location that will store the complete disk space report. You will need to edit the script to point to a location that is available to your computer, and you can name the report file anything that makes sense to you. The $computers variable stores an array of computer names and will need to be modified for your specific network. If you have more than ten computers, you will probably want to store your computer names in a text file and use the Get-Content cmdlet to read the file. You could still store the results in the $comptuers variable, as seen here:
$computers = Get-Content –path c:fsocomputerlist.txt
The complete variable initialization section of the WriteDiskSpaceToWord.ps1 script is seen here:
$class = “Win32_Volume”
$path = “C:fsoVolume.docx”
$computers = “Win7-pc”,”MrEd1″,”HyperV”
To save the Microsoft Word document, use an instance of the wdSaveFormat enumeration. The wdSaveFormat enumeration is documented on MSDN and is used to determine the type of document that will be saved.
I used the wdSaveFormat enumeration to allow me to convert a folder full of Microsoft Word documents into PDF files in a recent Hey, Scripting Guy! post.
After the WdSaveFormat enumeration is created, it is saved in the $SaveFormat reference variable. This is seen here.
[ref]$SaveFormat = “microsoft.office.interop.word.WdSaveFormat” -as [type]
For more information about using the [ref] type, refer to this Hey, Scripting Guy! post. To create the new Microsoft Word document, you will need to first create the Word.Application object. To do this, use the New-Object cmdlet and specify the –ComObject parameter while using the word.application program ID. Store the resulting application object in the $word variable, as seen here. If you want to see the Word document while the WMI query is writing to it, you can set the visible property of the application object to $true. After you have the script working on your network, you will probably want to change this value to $false.
$word = New-Object -ComObject word.application
$word.visible = $true
It is time create a new Microsoft Word document. To do this, use the add method from the documents collection. Store the resulting document object in the $doc variable. You also need to create a selection object by using the selection property from the application object. Store the resultant selection object in the $selection variable. This section of the script is seen here:
$doc = $word.documents.add()
$selection = $word.selection
To walk through the array of computer names that is stored in the $computers variable, use the Foreach statement:
Foreach($computer in $Computers)
{
Use the TypeText method from the selection object to write the heading for each computer report. Each computer name is stored in the $computer variable. The `r`n special character sequence generates a carriage return and a line feed in the Microsoft Word document. The `t will tab over the line of text by one tab. This section of the script is seen here:
$selection.typeText(“Disk Space Report for $Computer `r`n `tDisk C gigabytes: “)
Use the Get-WmiObject cmdlet to query the Win32_Volume WMI class. The .NET format specifier command causes the resulting free disk space to be returned to two decimal places. The GB is an administrative constant that converts numbers to gigabytes. The resulting WMI object is piped to the Out-String cmdlet so that the results can be displayed as text. This command is seen here:
“{0:n2}” -f ((Get-WmiObject -Class Win32_Volume -ComputerName $computer `
-Filter “DriveLetter = ‘c:'”).FreeSpace/1GB) |
Out-String |
To use a command in the middle of a pipeline, use the ForEach-Object cmdlet. This requirement exists even if there is only one item on the pipeline. The typeText method is used to write the current information on the pipeline. The typeParagraph method from the selection object writes a blank paragraph. This is seen here:
ForEach-Object { $selection.typeText($_)}
$selection.TypeParagraph()
}
The saveas method from the document object needs the path to the file and a wdSaveFormat enumeration value. In this example, the wdFormatDocument enumeration value is used, which will save to the default word format. For Microsoft Word 2007, this is a DOCX format file. When you are done, make sure you call the quit method from the application object to release the word application object from memory:
$doc.saveas($path, $saveFormat::wdFormatDocument)
$word.quit()
When the WriteDiskSpaceToWord.ps1 script runs, the Microsoft Word document shown in the following image is created.
CA, that is all there is to using Microsoft Word to store information you gathered from WMI. This concludes our Microsoft Word Week articles. Join us tomorrow for Quick-Hits Friday.
If you want to know exactly what we will be covering tomorrow, follow us on Twitter or Facebook. If you have any questions, send e-mail to us at scripter@microsoft.com or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson and Craig Liebendorfer, Scripting Guys
0 comments