Friday, May 8, 2009

Create a server form with PowerShell 2 & Word 2007 (Part 2)

Previous part of this post is HERE !

This is the first step : selecting and getting information about servers !

In this post we wiil create a PowerShell module which will gather all information from our servers. But... What is a module ? It's just a set of functions, a library we will reuse and share !

Modules are only available with PowerShell 2.0.

First, we have to create a file named « Computer_Info.psm1 ». File extension is .PSM1 and not .PS1 !
Then we can write our functions into the file. Theses functions will get information we need on our servers.

The PowerShell script which will generate the Word 2007 report will call functions from this module. The goal is to capitalize !

By default, PowerShell searches modules in folders listed in the environment variable PSMODULEPATH and in the working directory. To display the variable use the command:

PS> $env:PSMODULEPATH

Now we can start to get information from our servers. For this job, we will use more than one method. The first one is WMI !

The following function (the first one in our module) is just an abstract layer for the PowerShell Cmdlet Get-WmiObject. Just to make the code easier to read... :)

  1. function Get-WmiInfo($strClass, $strComputer)
  2. {
  3.     return Get-WmiObject -Class $strClass -Namespace 'root\cimv2' `
  4.                          -ComputerName $strComputer
  5. }

We will add an other "tool function":

  1. function Add-Property($obj, $strProperty, $objValue)
  2. {
  3.     Add-Member -InputObject $obj -Type 'NoteProperty' -Name $strProperty `
  4.                -value $objValue -force
  5. }


Add-Property function is an abstract layer for the PowerShell Cmdlet Add-Member : here, the function adds a simple property to an object.

So, now we can do the main traitment: gather all information we need !
The following function gets hardware information from servers:

  1. function Get-ComputerHardware($strComputer)
  2. {
  3.     $objRes = New-Object Object
  4.     $int = 0
  5.     
  6.     # Processors
  7.     $obj = Get-WmiInfo 'Win32_Processor' $strComputer
  8.     foreach ($objInfo in $obj) {
  9.         Add-Property $objRes 'Is32Bit' ($objInfo.Architecture -eq 0x0)
  10.         Add-Property $objRes 'Is64Bit' ($objInfo.Architecture -eq 0x9)
  11.         $int++
  12.     }
  13.     Add-Property $objRes 'NbCPU' $int
  14.     
  15.     # BIOS
  16.     $obj = Get-WmiInfo 'Win32_Bios' $strComputer
  17.     Add-Property $objRes 'BIOS' $obj.Name
  18.     
  19.     # System
  20.     $obj = Get-WmiInfo 'Win32_ComputerSystem' $strComputer
  21.     $int = [int]($obj.TotalPhysicalMemory / 1024 / 1024 / 1024)
  22.     Add-Property $objRes 'TotalMemory' "$int Go"
  23.     Add-Property $objRes 'Manufacturer' $obj.Manufacturer
  24.     Add-Property $objRes 'Model' $obj.Model
  25.     Add-Property $objRes 'Domain' $obj.Domain
  26.     Add-Property $objRes 'DNSName' ($obj.Name + '.' + $obj.Domain)
  27.     Add-Property $objRes 'NetBIOSName' $obj.Name
  28.     
  29.     # Media
  30.     $obj = Get-WmiInfo 'Win32_CDROMDrive' $strComputer
  31.     foreach ($objInfo in $obj) {
  32.         switch ($objInfo.MediaType)
  33.         {
  34.             'CD-ROM' { Add-Property $objRes 'MediaCD' $true }
  35.             'DVD-ROM' { Add-Property $objRes 'MediaDVD' $true }
  36.             'CD Writer' { Add-Property $objRes 'MediaCDRW' $true }
  37.             'DVD Writer' { Add-Property $objRes 'MediaDVDRW' $true }
  38.             default { }
  39.         }
  40.     }
  41.     
  42.     # Physical or virtual
  43.     $obj = Get-WmiInfo 'Win32_BaseBoard' $strComputer
  44.     $bln = ($obj.Manufacturer.Tolower() -contains 'microsoft'-Or
  45.            ($obj.Manufacturer.Tolower() -contains 'vmware')
  46.     Add-Property $objRes 'IsVirtual' $bln
  47.     Add-Property $objRes 'IsPhysical' (-not $bln)
  48.     
  49.     # Network adapters
  50.     Set-StrictMode -Off
  51.     $obj = Get-WmiInfo 'Win32_NetworkAdapter' $strComputer |
  52.            Where-Object { $_.PhysicalAdapter -eq $true } |
  53.            Select-Object ProductName, MACAddress
  54.     Set-StrictMode -Version 2.0
  55.     Add-Property $objRes 'NetworkCards' $obj
  56.     
  57.     # Disks
  58.     $obj = Get-WmiInfo 'Win32_DiskDrive' $strComputer |
  59.            Select-Object Model, Size
  60.     Add-Property $objRes 'Disks' $obj
  61.     
  62.     # Volumes
  63.     $obj = Get-WmiInfo 'Win32_LogicalDisk' $strComputer |
  64.            Where-Object { $_.DriveType -eq 3 } |
  65.            Select-Object VolumeName, DeviceID, Size, FreeSpace
  66.     Add-Property $objRes 'Volumes' $obj

  67.     return $objRes
  68. }

Get-ComputerHardware function returns a customized object. Each property of the object is an information about server's hardware.

For softwares:

  1. function Get-ComputerSoftware($strComputer)
  2. {
  3.     $objRes = New-Object Object
  4.     
  5.     # Operating system
  6.     $obj = Get-WmiInfo 'Win32_OperatingSystem' $strComputer
  7.     Add-Property $objRes 'OSName' $Obj.Caption
  8.     Add-Property $objRes 'OSVersion' $Obj.Version
  9.     Add-Property $objRes 'OSServicePack' $obj.CSDVersion
  10.     Add-Property $objRes 'OSArchitecture' $obj.OSArchitecture
  11.     
  12.     # Services
  13.     $obj = Get-Service -ComputerName $strComputer |
  14.            Select-Object DisplayName, ServiceName, Status
  15.     Add-Property $objRes 'Services' $Obj
  16.     
  17.     # KB
  18.     $obj = Get-WmiInfo 'Win32_QuickFixEngineering' $strComputer |
  19.            Sort-Object InstalledOn |
  20.            Select-Object Description, HotFixID, InstalledBy, InstalledOn
  21.     Add-Property $objRes 'KB' $Obj
  22.     
  23.     return $objRes
  24. }

Here we use the Get-Service Cmdlet with –ComputerName parameter which has been added in PowerShell V2 !

At this point, our module is not yet usable !

In our module, we wrote some functions used only by function which get software and hardware information. We want that only the two main functions of the module are usable because use the tools function out of context could be a bad idea...

  1. Export-ModuleMember -Function 'Get-ComputerHardware',
  2.                               'Get-ComputerSoftware'

Export-ModuleMember Cmdlet exposes only specified functions. So, only our main functions will be usable with our module !

In this post we have:
1. Created PowerShell 2 module,
2. Get hardware and software information from a remote computer.

In the next post, we will create our Word 2007 document which will use to generate our server form !

No comments:

Post a Comment