Wednesday, May 20, 2009

Getting informationon installed CPUs, Cores and Sockets

A friend and former colleague asked me about a way to obtain rather detailed information on the type and number of CPUs installed in a server, as well as the number of cores present.
This is the function I came up with.

Please note that this function is incapable of coping nicely with limitations implemented using /NUMPROC in boot.ini
The function should work on Windows 2000 Server and above.


function GetCPUinfo {
    param ([array]$servernames = ".")
    foreach ($servername in $servernames) {
        [array]$wmiinfo = Get-WmiObject Win32_Processor -computer $servername
        $cpu = ($wmiinfo[0].name) -replace ' +', ' '
        $description = $wmiinfo[0].description
        $cores = ( $wmiinfo | Select SocketDesignation | Measure-Object ).count
        $sockets = ( $wmiinfo | Select SocketDesignation -unique | Measure-Object ).count
        Switch ($wmiinfo[0].architecture) {
            0 { $arch = "x86" }
            1 { $arch = "MIPS" }
            2 { $arch = "Alpha" }
            3 { $arch = "PowerPC" }
            6 { $arch = "Itanium" }
            9 { $arch = "x64" }
        }
        $manfg = $wmiinfo[0].manufacturer
        $obj = New-Object Object
        $obj | Add-Member Noteproperty Servername -value $servername
        $obj | Add-Member Noteproperty CPU -value $cpu
        $obj | Add-Member Noteproperty Description -value $description
        $obj | Add-Member Noteproperty Sockets -value $sockets
        $obj | Add-Member Noteproperty Cores -value $cores
        $obj | Add-Member Noteproperty Architecture -value $arch
        $obj | Add-Member Noteproperty Manufacturer -value $manfg
        $obj
    }
}

The function is invoked with a list of servers as the single parameter. If no parameter is specified, the local server "." is used.

$result = GetCPUinfo server1, server2, server3

The output can then be piped info a Format-Table or similar.

$result | format-table -auto

The result could look something like this:

Servername CPU                                   Description                         Sockets Cores Architecture Manufacturer
---------- ---                                   -----------                         ------- ----- ------------ ------------
server1    Intel(R) Xeon(TM) CPU 2.80GHz         EM64T Family 15 Model 4 Stepping 8        4    16 x64          GenuineIntel
server2    Intel(R) Core(TM)2 CPU 6400 @ 2.13GHz EM64T Family 6 Model 15 Stepping 6        1     2 x64          GenuineIntel
server3    AMD Opteron(tm) Processor 285         AMD64 Family 15 Model 33 Stepping 2       2     2 x64          AuthenticAMD
server4    Intel(R) Xeon(R) CPU E7340 @ 2.40GHz  EM64T Family 6 Model 15 Stepping 8        2     2 x64          GenuineIntel
server5    Intel(R) Xeon(R) CPU E7340 @ 2.40GHz  EM64T Family 6 Model 15 Stepping 11       4    16 x64          GenuineIntel
server6    Intel(R) Xeon(TM) CPU 2.80GHz         x86 Family 15 Model 4 Stepping 8          1     1 x86          GenuineIntel
server7    Pentium III Tualatin                  x86 Family 6 Model 11 Stepping 1          2     2 x86          GenuineIntel


PS
Please let me know if you find any limitations or has suggestions for improvement.

Friday, May 08, 2009

Testing WinRAR 3.90 beta

I recently had to evaluate the preformance of the Rarsofts new beta of WinRAR.
WinRAR is a powerful GUI and CLI archiever that handles many archieve formats.
In order to test the preformance I installed WinRAR 3.80 as well as WinRAR 3.90beta1 (in both 32 and 64-bit versions).

Here is a light version of the PowerShell script I came up with (please adjust file paths and $source according to your own need):

Function Test-Rar {
    param ($winrar = "c:\Program Files (x86)\WinRAR\Rar.exe",
        $source = "d:\psref351.pdf",
        $target = "c:\test.rar",
        $testruns = 1)
    $version = & $winrar
    Write-Host "Test using: $winrar" -fore "green"
    Write-Host $version[1] -fore "green"
    for ($i = 1; $i -le $testruns; $i++){
        if (Test-Path $target) { del $target }
        $time = Measure-Command {& $winrar a $target $source}
        $sourcesize = (Get-ChildItem $source).length
        $targetsize = (Get-ChildItem $target).length
        $obj = New-Object Object
        $obj | Add-Member Noteproperty Testrun -value $i
        $obj | Add-Member Noteproperty TimeInSeconds -value ([math]::round(($time.totalseconds), 2))
        $obj | Add-Member Noteproperty SourceByteSize -value $sourcesize
        $obj | Add-Member Noteproperty TargetByteSize -value $targetsize
        $obj | Add-Member Noteproperty CompressionPercent -value ([math]::round( (1-($targetsize / $sourcesize)) * 100,2))
        $obj
    }
}

The above function can be use in the following way:

Test-Rar -source "d:\psref351.pdf" -target "d:\test.rar"


However, I needed to run tests with several versions of WinRAR and compress rather large files. So I needed a small function to repeat the same test multipel times with different versions of WinRAR.

Function MultiTest {
    Param ($rarversions = "c:\Program Files (x86)\WinRAR\Rar.exe")
    foreach ($rarversion in $rarversions) {
        $result = Test-RAR -testruns 5 -winrar $rarversion
        $result
        $stat = $result | Measure-Object -Property TimeInSeconds -min -max -average
        $stat | Add-Member Noteproperty Executable -value $rarversion
        $stat
    }
}

Here is how to use the function:

$rarversions = "c:\Program Files (x86)\WinRAR\Rar.exe", "D:\wrar39b1\rar.exe", "D:\winrar-x64-39b1\rar.exe"
$result = MultiTest $rarversions
$result | Select Executable, Count, Average, Maximum, Minimum | ft -au


While this is not a preview of the new WinRAR version, my results indicate a decrease in the time required to create a .rar file in the 20-30% range. Most impressive indeed!