Clutching at Security Blankets

Lessons learned while working in Information Security.

moc.navat@ymerej

Identifying PCI devices in Powershell


27 August 2015

I had a need recently to identify the device that failed on a Dell server. The server reported the failure in terms of PCI Bus, Device, and Function. Unfortunately, unlike Linux with its lspci(8), Windows doesn’t expose those very easily. The Dell technician suggested installing and running their diagnostic gathering tool on the server, but given protections in place on the server it would have taken some time to do so. It should be noted that finding the code to obtain this information took at least as long as whitelisting the tool and running it would have, but was much more educational. A little searching on the Internet and a little assembly of code resulted in the following:

Function Resolve-PCIBusInfo {
    param (
        [parameter(ValueFromPipeline=$true,Mandatory=$true)]
        [string] $locationInfo
    )
    PROCESS {
		[void]($locationInfo -match "\d+,\d+,\d+")
		$busId,$deviceID,$functionID = $matches[0] -split ","
	
		New-Object psobject -property @{
                "BusID"         = $busId
                "DeviceID"      = $deviceID
                "FunctionID"    = $functionID
        }
    }
}

$PnPEntities = Get-WmiObject Win32_PnPEntity | Where-Object { $_.Path -like "*PCI*" }

foreach ($dev in $PnPEntities) {
    $locationinfo = (Get-ItemProperty -ErrorAction SilentlyContinue -Path "HKLM:\SYSTEM\CurrentControlSet\Enum\$($dev."PNPDeviceID")" -name locationinformation).locationInformation

    if ($locationinfo) { 
    	$businfo = Resolve-PCIBusInfo -locationInfo $locationinfo
		Write-Host $dev."Name" -NoNewline
		Write-Host ": $($businfo."BusID"),$($businfo."DeviceID"),$($businfo."FunctionID")" 
    } else {
        Write-Host "$($dev."Name"): Unknown"
    }
}

This article is tagged: code windows powershell