Showing posts with label Dell. Show all posts
Showing posts with label Dell. Show all posts

Wednesday, March 6, 2013

Get-DellWarranty Powershell script for getting warranty details

*Update Jan 3, 2014.  The problem with scripts that scrap websites is that websites change.  Dell's site has changed, so the information below doesn't function anymore.  They are now requiring logon and make the warranty details more difficult to find (at least for the full list).*

I had the task recently of running an inventory on a large group of servers looking for old systems that require replacement.   One of the criteria was the hardware warranty expiration.  These are primary Dell systems, so I looked around for scripts to check that, but wasn't having much luck getting them working.  Since the scripts hit the Dell web site looking for details, I would suspect various changes there will cause issues.  So after looking at the code a bit, running some fiddler traces to see the full interaction of the site, I found I would need cookie support.  Since I haven't seen that work well in the past, I had used PERL LWP for this as you can find in a previous post on Oracle Access Manager diagnostic page scrapping automation.  I did some searching and came upon this very useful post which shows how to get cookies working in the Posh v3 invoke-webrequest commandlet.  So, armed with that, I put together this code to pull the details.  Note that there can be more than one warranty listed for a serial number.  This script takes a service tag number, or array of service tag numbers and outputs something like this:


ServiceTag         : ######
Country            : United States
WarrantyExpiration : 3/23/2011
WarrantyType       : Gold or ProSupport with Mission Critical
WarrantyStarted    : 3/23/2007

ServiceTag         : ######
Country            : United States
WarrantyExpiration : 3/23/2011
WarrantyType       : 4 Hour On-Site Service
WarrantyStarted    : 3/22/2008


You can pass any additional parameter to the script that is accepted by invoke-webrequest. So if you need a proxy or authentication, you can do so.


#Requires -version 3.0

#Get-DellWarrantyDetails 
param(
 [parameter(mandatory=$true,position=0)][String[]]$svctags,
 [parameter(mandatory=$false, ValueFromRemainingArguments=$true,position=1)]
      [String[]]$remaining
)

begin {
 #process any extra arguments like proxy settings, credentials, etc (used for invoke-webrequest)
    $extras = @{}
    for ($i = 0; $i -lt $Remaining.Count; $i++) {
     if ($Remaining[$i] -match "^-(.*)") {
      $val = $Matches[1]
      if ($Remaining[$i+1] -match "^-" -or ($remaining.Count -eq $i+1)) {
       $extras.Add($val,$true)
      } else {
       $extras.Add($val,$Remaining[$i+1])
       $i++
      }
     }
    }
 
 $script:posturl = "http://www.dell.com/support/troubleshooting/us/en/555/TroubleShooting/Display_Warranty_Tab?name=TroubleShooting_WarrantyTab"
 $script:geturlPrefix = "http://www.dell.com/support/troubleshooting/us/en/04/Servicetag/"
 $script:geturlSuffix = "?s=BIZ#ui-tabs-5"
 $script:session = New-Object Microsoft.PowerShell.Commands.WebRequestSession  
}

process {
 foreach ($svctag in $svctags) {
  Invoke-WebRequest @extras -Uri ($script:geturlPrefix + $svctag + $script:geturlSuffix) `
   -WebSession $script:session -ErrorAction SilentlyContinue |Out-Null
  $postresult = Invoke-WebRequest @extras -Uri $script:posturl -WebSession $script:session -ErrorAction SilentlyContinue
  if ($postresult -eq $null) {
   #webrequest failed
  } else {
   $countrytag = ($postresult.allelements|where {$_.tagname -match "DIV" -and $_.class -eq "Width100Percent" -and $_.innerHTML -match "CounrtyShipDateRight" -and $_.innerText[0] -eq "C"}).innerhtml.split("`n")[1]
   $countrytag = $countrytag.substring($countrytag.indexof(">")+1)
   $countrytag = $countrytag.substring(0,$countrytag.indexof("<")-1)
   #countrytag is now just a country name in text format with HTML removed
   
   
   
   $warrTbl = ($postresult.allelements|where {$_.tagname -eq "form" -and $_.id -eq "grid"}).innerhtml
   $warrTbl = $warrTbl.replace(" class=uif_t_altRow","").substring($warrTbl.indexof("TBODY")-1)
   $warrXML = [xml]("<root><TABLE>" + $warrTbl + "</root>")
   foreach ($xEntry in $warrXML.root.TABLE.tbody.tr) {
    $result = New-Object PSobject
    Add-Member -InputObject $result NoteProperty ServiceTag $svctag
    Add-Member -InputObject $result NoteProperty Country $countrytag
    Add-Member -InputObject $result NoteProperty WarrantyExpiration $xEntry.td[3]
    Add-Member -InputObject $result NoteProperty WarrantyType $xEntry.td[0]
    Add-Member -InputObject $result NoteProperty WarrantyStarted $xEntry.td[2]
    $result
   }
  } 
 }
}

Wednesday, February 1, 2012

Dell components check for updates via powershell (remote machine SUU)

Yesterday I posted on my XPath learning that I was going through while playing around with the Dell SUU catalog.xml file.  After further coding today, I threw together a good functional prototype of a powershell script to run SUU checks on remote machine.  It will find the upgradable components for the target machine, and return details like this:

Component      : FlashBIOS Updates
path           : PE2850_BIOS_WIN_A07.EXE
vendorVersion  : A07
currentversion : A05
releaseDate    : May 23, 2008
Criticality    : Optional
AtCurrent      : False

Component      : Embedded Server Management
path           : BMC_FRMW_WIN_R223079.EXE
vendorVersion  : 1.83
currentversion : 1.52
releaseDate    : June 30, 2009
Criticality    : Optional
AtCurrent      : False

for all firmware, bios, and drivers (probably OMSA too).  The AtCurrent value is a true/false test to show if you are at the current level (current to your version of SUU that you are using).  The script takes a server name and path (to your catalog.xml file in the suu\repository folder), and remotely checks the machine.  This works for windows machines only, since it uses WMI.  I'm sure some method of scripting using omreport data could be used to due similiar work for Linux.  Some ideas for using this information for updating, take the file name returned in each component, copy the file from the repository to the remote machine and run the installs with the silent run switch.



#Requires -version 2
#Author: Nathan Linley
#Script: Computer-DellUpdates
#Date: 2/9/2012

param(
 [parameter(mandatory=$true)][ValidateScript({test-path $_ -pathtype 'leaf'})][string]$catalogpath,
 [parameter(mandatory=$true,ValueFromPipeline=$true)][string]$server
)

function changedatacase([string]$str) {
 #we need to change things like this:  subDeviceID="1f17" to subDeviceID="1F17"
 #without changing case of the portion before the =
 if ($str -match "`=`"") {
  $myparts = $str.split("=")
  $result = $myparts[0] + "=" + $myparts[1].toupper()
  return $result
 } else { return $str}
}

$catalog = [xml](get-Content $catalogpath)
$oscodeid = &{
 $caption = (Get-WmiObject win32_operatingsystem -ComputerName $server).caption
 if ($caption -match "2003") {
  if ($caption -match "x64") { "WX64E" } else { "WNET2"}
 } elseif ($caption -match "2008 R2") { 
  "W8R2" 
 } elseif ($caption -match "2008" ) {
   if ($caption -match "x64") { 
    "WSSP2" 
   } else {
    "LHS86"
   } 
 }
}
write-debug $oscodeid

$systemID = (Get-WmiObject -Namespace "root\cimv2\dell" -query "Select Systemid from Dell_CMInventory" -ComputerName $server).systemid
$model = (Get-WmiObject -Namespace "root\cimv2\dell" -query "select Model from Dell_chassis" -ComputerName $server).Model
$model = $model.replace("PowerEdge","PE").replace("PowerVault","PV").split(" ")   #model[0] = Brand Prefix  #model[1] = Model #

$devices = Get-WmiObject -Namespace "root\cimv2\dell" -Class dell_cmdeviceapplication -ComputerName $server
foreach ($dev in $devices) {
 $xpathstr = $parts = $version = ""
 if ($dev.Dependent -match "(version=`")([A-Z\d.-]+)`"") { $version = $matches[2] } else { $version = "unknown" }
 $parts = $dev.Antecedent.split(",")
 for ($i = 2; $i -lt 6; $i++) {
  $parts[$i] = &changedatacase $parts[$i]
 }
 $depparts = $dev.dependent.split(",")
 $componentType = $depparts[0].substring($depparts[0].indexof('"'))
 Write-Debug $parts[1]
 if ($dev.Antecedent -match 'componentID=""') {
  $xpathstr = "//SoftwareComponent[@packageType='LWXP']/SupportedDevices/Device/PCIInfo"
  if ($componentType -match "DRVR") {
   $xpathstr += "[@" + $parts[2] + " and @" + $parts[3] + "]/../../.."
   $xpathstr += "/SupportedOperatingSystems/OperatingSystem[@osVendor=`'Microsoft`' and @osCode=`'" + $osCodeID + "`']/../.."
  } else {
   $xpathstr += "[@" + $parts[2] + " and @" + $parts[3] + " and @" + $parts[4] + " and @" + $parts[5] + "]/../../.."
   #$xpathstr += "/SupportedSystems/Brand[@prefix=`'" + $model[0] + "`']/Model[@systemID=`'" + $systemID + "`']/../../.."
   $xpathstr += "/ComponentType[@value='FRMW']/.."
   
  }
  $xpathstr += "/ComponentType[@value=" + $componentType + "]/.."
 } else {
  $xpathstr = "//SoftwareComponent[@packageType='LWXP']/SupportedDevices/Device[@" 
  $xpathstr += $parts[0].substring($parts[0].indexof("componentID"))
  $xpathstr += "]/../../SupportedSystems/Brand[@prefix=`'" + $model[0] + "`']/Model[@systemID=`'"
  $xpathstr += $systemID + "`']/../../.."
 }
 Write-Debug $xpathstr
 
 $result = Select-Xml $catalog -XPath $xpathstr |Select-Object -ExpandProperty Node
 $result |Select-Object @{Name="Component";Expression = {$_.category.display."#cdata-section"}},path,vendorversion,@{Name="currentversion"; Expression = {$version}},releasedate,@{Name="Criticality"; Expression={($_.Criticality.display."#cdata-section").substring(0,$_.Criticality.display."#cdata-section".indexof("-"))}},@{Name="AtCurrent";Expression = {$_.vendorVersion -le $version}}
}

Tuesday, January 31, 2012

Powershell XML XPATH search example (Dell SUU)

Over the last few years, I have taken a few shots at using powershell's XML features to do some automating of the Dell SUU update system.  In the past, I had some vaguely working prototypes that worked on one system and didn't work on another.  After taking another look at it, I discovered the use of Xpath to help match up available updates for a system.  In the SUU CD/DVD sets, you will find a Catalog.xml file in the Repository folder.  This file contains SoftwareComponents and SoftwareBundle branches.  The Bundle nodes are collections of OS + Device Model information to provide a full list of all updates.  The SoftwareComponents get into the individual updates themselves + OS + SupportedDevices.  Using Dell's WMI extensions (installed with OMSA 4.? and higher); namespace: root\CIMV2\Dell and class Dell_CMDevice to get information about the on board devices.  Each entry in this Class has a deviceID, vendorID, subDeviceID and subVendorID which can be used as an XPath search in the catalog file for the latest update for that component.

Here's an example of getting started with this:

$catalog = [xml](get-content c:\temp\suu\repository\catalog.xml)
$devices = Get-wmiobject -namespace "root\cimv2\dell" -class Dell_cmdevice
$mydevice = $devices[0]
$xpathstr = "//SoftwareComponent[@packageType='LWXP']/SupportedDevices/Device/PCIInfo"
$xpathstr += "[@deviceID=`'" + $mydevice.deviceID + "`' and @vendorID=`'" + $mydevice.vendorID +"`' and @subDeviceID=`'" + $mydevice.subDeviceID + "`' and @subVendorID=`'" + $mydevice.subvendorID + "`']/../../.."
select-xml $catalog -xpath $xpathstr |select-object -expandproperty Node

This will give you something like this:

schemaVersion        : 1.0
packageID              : R222914
releaseID                : R222914
hashMD5                : 6944D638979E5CE651234D216AFDC3C7
path                         : RAC_FRMW_WIN_R222914.EXE
dateTime                  : 2009-06-30T14:33:14-05:00
releaseDate              : June 30, 2009
vendorVersion          : 1.75
dellVersion               : A01
packageType           : LWXP
Name                      : Name
ComponentType      : ComponentType
Description              : Description
LUCategory            : LUCategory
Category                 : Category
SupportedDevices   : SupportedDevices
ImportantInfo           : ImportantInfo
Criticality                 : Criticality

As you can see, the device that is being check is a RAC card.  This is the latest update package for it.  You can use other classes in the Dell WMI namespace to pull the current version details of your devices to compare it to what is available in the SUU repository.  This part its a bit hackish though as you need to look at Dell_CMDeviceApplication and pull data out of the middle of strings, or combine Dell_CMDeviceApplication with Dell_CMApplication class results to get an easier version number.  The Dell_CMDeviceApplication class seems to just bridge between two different classes giving data like this:

Antecedent       : //Server/root/cimv2/dell:Dell_CMDevice.componentID="
                   ",name="Dell Remote Access Controller 4/I",vendorID="1028",d
                   eviceID="0012",subDeviceID="0012",subVendorID="1028",bus="",
                   device="",function=""
Dependent        : //Server/root/cimv2/dell:Dell_CMApplication.componen
                   tType="FRMW",subComponentID="",version="1.35",name="Dell Rem
                   ote Access Controller 4/I Firmware",deviceKey=":Dell Remote
                   Access Controller 4/I:1028:0012:0012:1028:::"

In the future, I will pull this together a bit more and try to provide a working SUU check for all devices on a Dell system along with update options.  Update: Solution sample

Wednesday, February 24, 2010

Dell system monitoring with WMI

For those who may be interested in checking Dell hardware through scripts there are several ways to do it. I will focus on Windows in this post, and skip over wmic and vbscript, to show some powershell examples of this. For background reference and WMI, there is a useful document at Dell for wmic and a reference guide for Common Information Model administration as well. For some background on Dell's WMI namespace, this has existed for quite some time in Dell OpenManage, starting sometime in version 4.x (I have seen in it 4.4 and higher, though I can't verify earlier versions). The namespace is unique branch on CIMV2, called root\CIMV2\Dell. Some examples of information provided inside this namespace: -Per component details and status -Hardware log retrieval -Component types installed and firmware information -Remote access card component information Using the same WMI capabilities that come with the Dell OpenManage software, we can use Powershell's Get-WMIObject commandlet to pull information from a machine. Using this, you can limit the results displayed similar to the examples of wmic, however the results are objects, so they are much easier to work with for further programming. Here is a basic example
PS C:\> gwmi -namespace root\cimv2\dell -class CIM_PhysicalMemory __GENUS : 2 __CLASS : CIM_PhysicalMemory __SUPERCLASS : CIM_Chip __DYNASTY : CIM_ManagedSystemElement __RELPATH : CIM_PhysicalMemory.CreationClassName="CIM_PhysicalMemory ",Tag="0" __PROPERTY_COUNT : 27 __DERIVATION : {CIM_Chip, CIM_PhysicalComponent, CIM_PhysicalElement, C IM_ManagedSystemElement} __SERVER : myserver __NAMESPACE : root\cimv2\dell __PATH : \\myserver\root\cimv2\dell:CIM_PhysicalMemory.Crea tionClassName="CIM_PhysicalMemory",Tag="0" BankLabel : Capacity : 2147483648 Caption : CreationClassName : CIM_PhysicalMemory DataWidth : 64 Description : FormFactor : 9 HotSwappable : InstallDate : InterleavePosition : Manufacturer : MemoryType : 19 Model : Name : DIMM1_A OtherIdentifyingInfo : PartNumber : PositionInRow : PoweredOn : Removable : Replaceable : SerialNumber : SKU : Speed : 2 Status : OK Tag : 0 TotalWidth : 72 Version : __GENUS : 2 __CLASS : CIM_PhysicalMemory __SUPERCLASS : CIM_Chip __DYNASTY : CIM_ManagedSystemElement __RELPATH : CIM_PhysicalMemory.CreationClassName="CIM_PhysicalMemory ",Tag="1" __PROPERTY_COUNT : 27 __DERIVATION : {CIM_Chip, CIM_PhysicalComponent, CIM_PhysicalElement, C IM_ManagedSystemElement} __SERVER : myserver __NAMESPACE : root\cimv2\dell __PATH : \\myserver\root\cimv2\dell:CIM_PhysicalMemory.Crea tionClassName="CIM_PhysicalMemory",Tag="1" BankLabel : Capacity : 2147483648 Caption : CreationClassName : CIM_PhysicalMemory DataWidth : 64 Description : FormFactor : 9 HotSwappable : InstallDate : InterleavePosition : Manufacturer : MemoryType : 19 Model : Name : DIMM1_B OtherIdentifyingInfo : PartNumber : PositionInRow : PoweredOn : Removable : Replaceable : SerialNumber : SKU : Speed : 2 Status : OK Tag : 1 TotalWidth : 72 Version :
As you can see, this provides a lot of attributes, many of which are not read by the system. You can filter out what you want with Select-Object, such as: PS C:\> gwmi -namespace root\cimv2\dell -class CIM_PhysicalMemory|select-object name,status name status ---- ------ DIMM1_A OK DIMM1_B OK This provides a nice summary of a component. You can easily do follow on processing to look for bad components, such as a foreach loop on the result and list where status does not match "OK". If you are looking for a solution in a mixed hardware environment where not all servers may be up to date for OMSA, and updating is not an easy task, a work around is to set your erroraction to silentlycontinue, read the error message of the wmi connection and direct the user to use the web interface for omsa or a command line tool like omreport to collect the information. For more examples of code, you can use scriptomatic to look through the namespace and test what information is available. I also have a few examples posted on Microsoft's technet script center.