So, there comes a time in every sysadmin's life when they need to make inventory of hardware servers and no one knows what the IP address for the OOBM devices is anymore. Their DNS records are rarely setup, and the major problem is of course, that you have 1000+ different servers from a variety of manufacturers, be it Dell, HP, IBM, Fujitsu etc.

The OOBM systems go by different proprietary names depending on the manufacturer, HP: iLO, Dell: iDRAC, Fujitsu: iRMC, IBM: IMM and so on.
Each manufacturer has their propietary tools and there's lots of complicated ways to get the OOBM's device IP address, usually by browsing the server's manufacturer management web tools, using modules requiring specific providers or using their MS-DOS tools (e.g. hpasmcli or racadm).
I tried many options, including RedFish and ipmi, but the clear winner is the method from Michael Albert's blog that reaches out to the BMC (Baseboard Management Controller) from the OS, via good old WMI.
What's really sweet about it, is that the MICROSOFT_IPMI class is manufacturer agnostic, I was able to pull the IP and MAC addresses from all the HW Windows devices I reached, it worked against Windows Server 2003 up to 2012R2 OS servers, as well as HP, Dell, Fujitsu and IBM machines.
Michael's script is pretty neat and has done all the heavy lifting for us, he even mentions in his post that since it's a wmi cmdlet, we can just use "-computername" to run it against remote machines.
I've taken his advice and created a quick & dirty wrap, my version added the following features:
- Input a batch list of remote servers
- Error handling
- Progress bar
- Exports a csv report
Looks like this in action:
Click to "embiggen"
Download the Get-OOBMIP Script from Microsoft TechNet: https://gallery.technet.microsoft.com/Get-Servers-OOBM-IP-iLO-19e71069
<#
Name: Get-OOBMIP.ps1
Date: June 15th, 2018
Created by: Michael Albert, modified by Erick Sevilla
This is a mod of Michael Albert's genius: http://michlstechblog.info/blog/windows-read-the-ip-address-of-a-bmc-board/
Purpose: Get IP, MAC and Subnet addresses from OOBM devices such as HP iLO's, Dell iDRAC's or Fujitsu's iRMC,
IBM's IMM etc.from a list of remote servers
Instructions: 1) From PowerShell as Admin, cd to script's path and run Get-OOBMIP.ps1
2) A .txt file will prompt, enter a list of hosts, IP's or FQDN's or remote machines
3) Find results in console and csv file report
#>
$ErrorActionPreference = "SilentlyContinue" # Don't use this, it's bad practice :) -- Remove to debug
$Timestamp = (Get-Date -f yyyy-MM-dd-hhmmss) # Current DateTime for logs
$SourceFile = "$PSScriptRoot\Serverlist.txt" # Server list source, currently set as script's location
$DestinationFile = "$PSScriptRoot\Results_Get-OOBMIP_$Timestamp.csv" # Report file export name and location, currently set as script's location
Write-Output "Replace this text with list of hosts you want to query, save and close..."| Out-File -FilePath $SourceFile -Encoding ASCII
Start-Process $SourceFile -Wait # Propmts hosts.txt for user to populate with list of hosts
Write-Host @("`r`nRunning Get-OOBMIP script...") -NoNewline -ForegroundColor Cyan -BackgroundColor Black
# OOBM Query function
function GetOOBMData {
[cmdletbinding()]
Param($Server)
$oIPMI=Get-WmiObject -Namespace root\WMI -Class MICROSOFT_IPMI -ComputerName $Server
[byte]$BMCResponderAddress = 0x20
[byte]$GetLANInfoCmd = 0x02
[byte]$GetChannelInfoCmd = 0x42
[byte]$SetSystemInfoCmd = 0x58
[byte]$GetSystemInfoCmd = 0x59
[byte]$DefaultLUN = 0x00
[byte]$IPMBProtocolType = 0x01
[byte]$8023LANMediumType = 0x04
[byte]$MaxChannel = 0x0b
[byte]$EncodingAscii = 0x00
[byte]$MaxSysInfoDataSize = 19
[byte[]]$RequestData=@(0)
$oMethodParameter=$oIPMI.GetMethodParameters("RequestResponse")
$oMethodParameter.Command=$GetChannelInfoCmd
$oMethodParameter.Lun=$DefaultLUN
$oMethodParameter.NetworkFunction=0x06
$oMethodParameter.RequestData=$RequestData
$oMethodParameter.RequestDataSize=$RequestData.length
$oMethodParameter.ResponderAddress=$BMCResponderAddress
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa392344%28v=vs.85%29.aspx
$RequestData=@(0)
[Int16]$iLanChannel=0
[bool]$bFoundLAN=$false
for(;$iLanChannel -le $MaxChannel;$iLanChannel++){
$RequestData=@($iLanChannel)
$oMethodParameter.RequestData=$RequestData
$oMethodParameter.RequestDataSize=$RequestData.length
$oRet=$oIPMI.PSBase.InvokeMethod("RequestResponse",$oMethodParameter,(New-Object System.Management.InvokeMethodOptions))
#$oRet
if($oRet.ResponseData[2] -eq $8023LANMediumType){
$bFoundLAN=$true
break;
}
}
$oMethodParameter.Command=$GetLANInfoCmd
$oMethodParameter.NetworkFunction=0x0c
if($bFoundLAN){
$RequestData=@($iLanChannel,3,0,0)
$oMethodParameter.RequestData=$RequestData
$oMethodParameter.RequestDataSize=$RequestData.length
$oRet=$oIPMI.PSBase.InvokeMethod("RequestResponse",$oMethodParameter,(New-Object System.Management.InvokeMethodOptions))
$OOBIP = (""+$oRet.ResponseData[2]+"."+$oRet.ResponseData[3]+"."+$oRet.ResponseData[4]+"."+$oRet.ResponseData[5] )
$RequestData=@($iLanChannel,6,0,0)
$oMethodParameter.RequestData=$RequestData
$oMethodParameter.RequestDataSize=$RequestData.length
$oRet=$oIPMI.PSBase.InvokeMethod("RequestResponse",$oMethodParameter,(New-Object System.Management.InvokeMethodOptions))
$OOBSubnet = (""+$oRet.ResponseData[2]+"."+$oRet.ResponseData[3]+"."+$oRet.ResponseData[4]+"."+$oRet.ResponseData[5] )
$RequestData=@($iLanChannel,5,0,0)
$oMethodParameter.RequestData=$RequestData
$oMethodParameter.RequestDataSize=$RequestData.length
$oRet=$oIPMI.PSBase.InvokeMethod("RequestResponse",$oMethodParameter,(New-Object System.Management.InvokeMethodOptions))
$OOBMACAddress = (("{0:x2}:{1:x2}:{2:x2}:{3:x2}:{4:x2}:{5:x2}" -f $oRet.ResponseData[2],$oRet.ResponseData[3],$oRet.ResponseData[4],$oRet.ResponseData[5],$oRet.ResponseData[6],$oRet.ResponseData[7]))
$Status='SUCCESS'
$Message = ''
New-Object PSObject -Property @{Hostname=$Server;Status=$Status;OOBIP=$OOBIP;OOBMACAddress=$OOBMACAddress;OOBSubnet=$OOBSubnet;Message=$Message}
}
}
# Function processing: Loop, progress bar and try-catch, all in a tasty wrap
$Wrapper = @(
$Servers = Get-Content $SourceFile
$i = 0;$CountDuckula = @($Servers).Count
foreach ($Server in $Servers) {
$i++;[int]$Percentage = (($i/$CountDuckula)*100)
Write-Progress -Activity "Get-OOBM Tool: Querying $Server" -Status "Completed $i of $CountDuckula - $Percentage%" -PercentComplete $Percentage
try { GetOOBMData -Server $Server -ErrorAction Stop } catch {
$Message=$($PSItem.ToString())
$Status='FAIL'
New-Object PSObject -Property @{
Hostname=$Server;
Status=$Status;
OOBIP=$OOBIP;
OOBMACAddress=$OOBMACAddress;
OOBSubnet=$OOBSubnet;
Message=$Message }
$OOBIP='';$OOBMACAddress='';$OOBSubnet='';$Message=$($PSItem.ToString())}
}
)
# Processing wrapped results for output
$Wrapper | Select-Object Hostname,Status,OOBIP,OOBMACAddress,OOBSubnet,Message |
Export-Csv -Path $DestinationFile -Append -NoTypeInformation -Force # Output to csv file
Write-Host " Done!" -ForegroundColor Green -BackgroundColor Black # One puppy a day keeps the questions away
Write-Host "Path to report: " -ForegroundColor Cyan -BackgroundColor Black -NoNewline # In case you are wondering the file's name and location
Write-Host "$DestinationFile" -BackgroundColor Black # More write-host 'cause we hate puppies
$Wrapper | Format-Table Hostname,Status,OOBIP,OOBMACAddress,OOBSubnet,Message # Output to console because we are Homo videns
start $PSScriptRoot # Opening folder where the report is located for your convenience