How to collect custom inventory from Azure AD Joined devices
Published Apr 22 2021 09:01 AM 37.1K Views
Microsoft

Kubilay Dagdelen on my team worked with several other folks to pull together a method for doing some custom inventory collection with Intune.  There are some performance delays that can be encountered if over-used, but it can be handy at times.

 

ConfigMgr admins love extending hardware inventory and collecting data from Windows devices.
Did you know Intune can do the same?!
The answer is Intune PowerShell scripts! Also known as SideCar… IME… Intune Management Extensions…

Well, IME is just another channel that runs parallel to MDM that sort of acts like the ConfigMgr client. We deliver different features over this channel: PowerShell scripts, Win32 apps, Proactive Remediation scripts, Win32 app log collection…


Can you give us an example?
Maybe you are interested to know more about Win32_BIOS.
Run the following PowerShell one-liner on a device

 

 

 

Get-WmiObject -Class Win32_BIOS |
select CurrentLanguage,
Description,
EmbeddedControllerMajorVersion,
EmbeddedControllerMinorVersion,
Manufacturer,
ReleaseDate,
SerialNumber | ConvertTo-Json -Compress

 

 


Script outputs the following:

MikeGriz_0-1619043818972.png

 

Beautified:

 

 

{
"CurrentLanguage": "en-US",
"Description": "N2EET43W (1.25 )",
"EmbeddedControllerMajorVersion": 1,
"EmbeddedControllerMinorVersion": 13,
"Manufacturer": "LENOVO",
"ReleaseDate": "20191028000000.000000+000",
"SerialNumber": "12345678"
}

 

 


Let’s create an Intune PowerShell script and deploy it to some users/devices to demonstrate Win32_BIOS data as an example.

MikeGriz_2-1619043913367.png


Tip: <scriptId> is stored in the URL

MikeGriz_3-1619043946125.png


You can access the data via the following Graph endpoint in graph explorer
https://graph.microsoft.com/beta/deviceManagement/deviceManagementScripts/<scriptID>/deviceRunStates...

 

It turns out that we store the above-mentioned script output in a property on the service side. If you are familiar with Graph Explorer, then you can take a look at the results


In the property “resultMessage”:

MikeGriz_4-1619043988087.png


How do I see the data from all devices?
Prerequisites:
Install-Module -Name Microsoft.Graph.Intune


You need one more script to retrieve your results from Graph…

 

 

Update-MSGraphEnvironment -SchemaVersion 'beta'
Connect-MSGraph

$result = Invoke-MSGraphRequest -HttpMethod GET -Url 'deviceManagement/deviceManagementScripts/b113448a-528a-4beb-b7d5-381a117d5184/deviceRunStates?$expand=managedDevice' | Get-MSGraphAllPages
$success = $result| Where-Object -Property errorCode -EQ 0
$resultMessage = $success.resultMessage 
$objResultMessage = $resultMessage | ConvertFrom-Json
$objResultMessage | Out-GridView 

 

 

 

MikeGriz_0-1619044884955.png


You can store the data in Log Analytics, SQL etc and visualize the way you want.
Enjoy!

10 Comments
Copper Contributor

Hi @MikeGriz , 

 

Thank you for wonderful article. I have followed the same but it is giving me below error. Can you suggest ?

 

umeshkumarchauhan_0-1619162555168.png

 

Microsoft

@umeshkumarchauhan Just a guess have you replaced the scriptID with the one in your environment? 

Invoke-MSGraphRequest -HttpMethod GET -Url 'deviceManagement/deviceManagementScripts/<yourScriptID>/deviceRunStates?$expand=managedDevice' | Get-MSGraphAllPages

 

Copper Contributor

YEs @MikeGriz , I have replaced the Script ID then only i have run this. Kindly suggest. Your article is very helpful. 

 

umeshkumarchauhan_0-1619267749057.pngumeshkumarchauhan_1-1619267772311.png

 

Copper Contributor

Great post, I have used the following script to collect W10 activation information from over 6000 devices. 

 

$COMPUTER=Get-CimInstance Win32_Computersystem
$BIOS=Get-CimInstance Win32_BIOS
$SLP=Get-CimInstance SoftwareLicensingProduct -Filter "Name like 'Windows%'" | where { $_.PartialProductKey }
$SLS=Get-CimInstance SoftwareLicensingService

$theThingIActuallyWant = New-Object psobject -Property @{
SystemName = $COMPUTER.Name
Manufacturer = $COMPUTER.manufacturer
Model=$COMPUTER.Model
SystemSKUNumber=$COMPUTER.SystemSKUNumber
Serialnumber=$BIOS.SerialNumber
ProductKeyChannel=$SLP.ProductKeyChannel
LicenseFamily=$SLP.LicenseFamily
PartialProductKey=$SLP.PartialProductKey
LicenseStatus=$SLP.LicenseStatus
OA3xOriginalProductKey=$SLS.OA3xOriginalProductKey
}

$theThingIActuallyWant | ConvertTo-Json -Compress

 

When I query the Graph Explorer I get the correct output, but I cannot convert back to json using the command convertfrom-json. 

 

I receive the following error message: 

At line:1 char:38
+ $objResultMessage = $resultMessage | ConvertFrom-Json
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [ConvertFrom-Json], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand

Microsoft

@tjmklaver I wonder if some device reported non JSON output. Did you take a look at $resultMessage alone without convertFrom-Json?

Microsoft

@umeshkumarchauhan Do you see any results in the MEM portal for "Device Status"?

kubidag_0-1622762306737.png

 

Copper Contributor

@kubidag Yes, I did look at $resultMessage without convertfrom-json, but there are a lot of resultmessages (over 4000). I

instead used convertfrom-csv. With some help of find/replace in Excel I was able to read the report in the end. In this process I noticed that some resultmessages were in a different format, then expected. I believe this was causing the error message to do the output to json. Converting to CSV i was able to quickly get the necessary report.
2021-06-04_08-57-21.jpg

Copper Contributor

$resultMessage is returning a blank value in my case.

 

grvranjan_0-1631705967969.png

 

Copper Contributor

Hello,

 

I get this result, here is the sample:

djolenole_0-1674508755656.png

 

 

and after that I get resultMessage but not able to work with this list of strings(it is not valid json output):

 

{"ComputerName":"name1","RAM(GB)":16,"CPU":"Intel(R) Core(TM) i7-9850H CPU @ 2.60GHz","Model":"Latitude 5501","SerialNumber":"serial1"}
{"ComputerName":"name2","RAM(GB)":16,"CPU":"Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz","Model":"HP EliteBook 850 G7","SerialNumber":"serial2"}
{"ComputerName":"name3","RAM(GB)":16,"CPU":"Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz","Model":"Latitude 5591","SerialNumber":"serial3"}
{"ComputerName":"name4","RAM(GB)":16,"CPU":"Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz","Model":"Latitude 5591","SerialNumber":"serial4"}
{"ComputerName":"name5","RAM(GB)":32,"CPU":"Intel(R) Core(TM) i7-10850H CPU @ 2.70GHz","Model":"Latitude 5511","SerialNumber":"serial5"}

 

 

Copper Contributor

Thanks, this seems to be much more effective than using the Graph API's native requests for hardware info.

Co-Authors
Version history
Last update:
‎Jun 03 2021 08:14 AM
Updated by: