Files
2018-11-19 22:41:26 +08:00

310 lines
10 KiB
PowerShell

<#
Copyright 2018 VMware, Inc. All rights reserved.
#>
# Class to manage Host resources
Class HostResource {
[VMware.VimAutomation.Types.VMHost] $vmhost
[string] $vcname
[string] $clustername
[string] $dcname
[string] $hostname
[string] $apitype
[string] $powerstatus
[string] $productname
[string] $version
[string] $fullname
[string] $connectionstatus
[string] $checkRelease
[int] $port
[Array] $ComponentResource = @()
[Array] $JsonProperties = @('__type__', 'dcname', 'vcname','clustername','hostname', 'apitype',
'powerstatus', 'productname', 'version', 'fullname', 'connectionstatus','checkRelease')
HostResource(
[VMware.VimAutomation.Types.VMHost] $vmhost) {
$this.vmhost = $vmhost
$view =$vmhost|Get-View
$vCenter_IP = $view.Summary.ManagementServerIp
if($vCenter_IP){
$this.vcname =$vCenter_IP
$this.dcname = (Get-Datacenter -VMHost $vmhost).Name
$this.clustername = (Get-Cluster -VMHost $vmhost).Name
}else{
$this.vcname =$this.vmhost.Name
}
$this.hostname = $this.vmhost.Name
$summary = $this.vmhost.ExtensionData.Summary
$this.powerstatus = $summary.runtime.powerState
$this.connectionstatus = $summary.runtime.connectionState
$this.apitype = $summary.Config.Product.apiType
$this.fullname = $summary.Config.Product.FullName
$this.version = $summary.Config.Product.version
$this.productname = $summary.Config.Product.licenseProductName
$this.port = 443
}
[Array] query_components() {
if ($this.ComponentResource.Count -eq 0) {
# Get server info
for($count_retry=0;$count_retry -lt 3;$count_retry ++){
try{
$svrResoure = [ServerResource]::new()
$svrResoure.set_data($this.vmhost)
$this.ComponentResource += $svrResoure
break
}catch{
error('query components server for '+$this.vmhost.Name +' error, retry it ' +($count_retry+1) +' times')
}
}
# Get PCI devices
for($count_retry=0;$count_retry -lt 3;$count_retry ++){
try{
$this.query_pcidevices()
break
}catch{
error('query components pcidevice for '+$this.vmhost.Name +' error, retry it ' +($count_retry+1) +' times')
if($count_retry -eq 2){
error('query components pcidevice for '+$this.vmhost.Name +' faild')
}
}
}
}
return $this.ComponentResource
}
[void] query_pcidevices() {
$EsxCliV2 = Get-EsxCli -V2 -VMHost $this.vmhost
$AllPciDevice = $EsxCliV2.hardware.pci.list.invoke()
foreach ($Pci in $AllPciDevice) {
# Ignore USB controllers, iLO/iDRAC devices
if ($Pci.DeviceName -like "*USB*" -or $Pci.DeviceName -like "*iLO*" -or $Pci.DeviceName -like "*iDRAC*") {
continue
}
# Get the NICs and storage adapters.
# We found NIC and storage adapters usually have module ID other than 0 or 1
$pciDevice = [IoDeviceResource]::new()
if ($Pci.ModuleID -ne 0 -and $Pci.ModuleID -ne -1) {
if (!$this.is_pcidevice_exist($Pci)) {
$pciDevice.set_data($Pci, $EsxCliV2)
$this.ComponentResource += $pciDevice
}
}
}
}
[boolean] is_pcidevice_exist($device) {
foreach ($pci in $this.ComponentResource) {
if ($pci.psobject.TypeNames[0] -eq "IoDeviceResource") {
$vid = [String]::Format("{0:x4}", [int]$device.VendorID)
$did = [String]::Format("{0:x4}", [int]$device.DeviceID)
$svid = [String]::Format("{0:x4}", [int]$device.SubVendorID)
$ssid = [String]::Format("{0:x4}", [int]$device.SubDeviceID)
if ($pci.vid -eq $vid -and $pci.did -eq $did -and
$pci.svid -eq $svid -and $pci.ssid -eq $ssid) {
return $true
}
}
}
return $false
}
[object] to_jsonobj() {
$Json = $this | Select-Object -Property $this.JsonProperties
$ComponentChildren = @()
$this.ComponentResource | ForEach-Object {$ComponentChildren += $_.to_jsonobj()}
$Json | Add-Member -Name "ComponentResource" -Value $ComponentChildren -MemberType NoteProperty
return $Json
}
[string] get_host_status() {
if ($this.powerstatus -and $this.powerstatus -ne 'unknown') {
return $this.powerstatus
}
if ($this.connectionstatus) {
return ("Server " + $this.connectionstatus)
}
else {
return "Server status is unknown"
}
}
[string] get_prompt_name() {
if ($this.apitype) {
$start = $this.apitype
}
else {
$start = "Host"
}
return $start + " " + $this.hostname
}
}
# Class to manage server resources
Class ServerResource {
[string] $type
[string] $model
[string] $vendor
[string] $biosversion
[string] $cpumodel
[string] $cpufeatureid
[string] $uuid
[string] $status
[array] $matchResult
[array] $warnings
[string] $vcgLink
[array] $updateRelease
[VMware.VimAutomation.Types.VMHost] $vmhost
[Array] $JsonProperties = @('__type__','type', 'model', 'vendor', 'biosversion',
'cpumodel', 'cpufeatureid', 'uuid','status','matchResult','warnings','vcgLink','updateRelease')
[void] set_data(
[VMware.VimAutomation.Types.VMHost] $vmhost) {
$this.vmhost = $vmhost
$this.type = "Server"
$this.model = $this.vmhost.Model
$this.vendor = $this.vmhost.Manufacturer
$this.biosversion = $this.vmhost.ExtensionData.Hardware.BiosInfo.BiosVersion
$this.cpumodel = $this.vmhost.ProcessorType
$cpuFeature = $this.vmhost.ExtensionData.Hardware.CpuFeature
if ($cpuFeature -and $cpuFeature.Count -gt 2) {
$this.cpufeatureid = $this.vmhost.ExtensionData.Hardware.CpuFeature[1].Eax
}
$this.uuid = $this.vmhost.ExtensionData.Hardware.systeminfo.uuid
}
[object] to_jsonobj() {
return $this | Select-Object -Property $this.JsonProperties
}
}
# Class to manage each IO device
Class IoDeviceResource {
[string] $type
[string] $model
[string] $deviceid
[string] $device
[string] $comptype
[string] $vid
[string] $did
[string] $svid
[string] $ssid
[string] $pciid
[string] $vendor
[string] $driver
[string] $driverversion
[string] $firmware
[string] $status
[array] $matchResult
[array] $warnings
[string] $vcgLink
[array] $updateRelease
[Array] $JsonProperties = @('__type__','type', 'model', 'deviceid', 'device',
'comptype', 'vid', 'did', 'svid', 'ssid', 'pciid',
'vendor', 'driver', 'driverversion', 'firmware','status','matchResult','warnings','vcgLink','updateRelease')
[void] set_data(
[object] $pci,
[object] $EsxCli) {
$this.type = "IO Device"
$this.model = $Pci.DeviceName
$this.deviceid = $pci.Address
$this.device = $pci.VMKernelName
$this.vid = [String]::Format("{0:x4}", [int]$Pci.VendorID)
$this.did = [String]::Format("{0:x4}", [int]$Pci.DeviceID)
$this.svid = [String]::Format("{0:x4}", [int]$Pci.SubVendorID)
$this.ssid = [String]::Format("{0:x4}", [int]$Pci.SubDeviceID)
$this.pciid = $this.vid + ":" + $this.did + ":" + $this.svid + ":" + $this.ssid
$this.vendor = $pci.VendorName
$this.driver = $Pci.ModuleName
$this.driverversion = "N/A"
$this.firmware = "N/A"
# Set component type and driverversion, firmware
if ($this.device -match 'nic') {
$arg = @{}
$arg['nicname'] = $this.device
$nic = $EsxCli.network.nic.get.invoke($arg)
$this.comptype = "Physical NIC"
$this.driverversion = $nic.driverinfo.Version
$this.firmware = $nic.driverinfo.FirmwareVersion
}
elseif ($this.device -match 'hba') {
$arg = @{}
$arg['module'] = $this.driver
$module = $EsxCli.system.module.get.invoke($arg)
$this.comptype = "Storage Adapter"
$this.driverversion = $module.Version
}
}
[object] to_jsonobj() {
return $this | Select-Object -Property $this.JsonProperties
}
[string] get_id_detail() {
return $this.driver + " (PCIId:" + $this.pciid + ")"
}
}
# Class to manage IO device group
Class IoDeviceResourceGroup {
[Array] $iodevices = @()
[Array] $nics = @()
[Array] $adapters = @()
[void] append_nic([IODeviceResource] $nic) {
$this.iodevices += $nic
$this.nics += $nic
}
[void] append_storage_adapter([IODeviceResource] $adapter) {
$this.iodevices += $adapter
$this.adapters += $adapter
}
[boolean] has_nics() {
return $this.nics.Count > 0
}
[boolean] has_storage_adapters() {
return $this.adapters.Count > 0
}
}
#
# Collect hardware inventory data from all the hosts
#
Function Get-VCGHWInfo {
Param(
[Parameter(Mandatory=$true)] $vmHosts
)
# Collect the hardware data
$Data = @()
foreach($vmHost in $vmHosts) {
$vm = [HostResource]::new($vmHost)
try {
info ("Collecting hardware data from " + $vm.hostname)
$null = $vm.query_components()
if($vm.powerstatus -eq 'poweredOn' -and $vm.connectionstatus -eq 'connected'){
$Data += $vm
info ("Collecting hardware data from " + $vm.hostname +' success')
}
}
catch {
error ("Failed to collect hardware data from " + $vm.hostname)
}
}
return $Data
}