Poor man's inventory with JainDB

A year ago, I've blogged about "Poor man's inventory with PowerShell, DocumentDB and Power BI"... Now, I will give you some ideas on collecting Inventory-Data to JainDB, a blockchain based Data warehouse.

What is JainDB

JainDB is an Open-Source REST-API to store JSON Documents in an auditable way by using Blockchain technology ( but it's NOT (yet) using a distributed (Peer-To-Peer) storage). The stored documents will be splitted into smaller fragments to allow data deduplication. These fragments can be stored as Files or in Redis, a fast Key-Value store (CosmosDB is in preparation).

Why JainDB?

Inventory data is the ideal case for JainDB, as it keeps the Inventory-History of every Device automatically. As many of the Devices do share the same Hardware- and Software-Items, JainDB needs to store this Information only once.

The setup of JainDB is very simple, as you can download a Docker-Container (Linux) to host the Web- and the Redis-Service.

JainDB also provides a REST-API to query the uploaded data, which makes it a great source for Power-BI.

Prerequisites

JainDB is running on .NET Core 2.0, so you can run it on Windows or Linux. The easiest way is using the Docker-Image. You will need:

  • a Host for running Docker (Win10/Server2016 or Linux)
  • latest Version of Docker (on Windows, you can use RuckZuck to install Docker)
  • a Folder on the Host to store the Redis-DB (or .json Files) as you should not store the data within the container.

Installation

docker pull zanderr/jaindb  
  • Configure and run the Container:
docker run --name jaindb -d -e "localURL=http://192.168.2.146:5000" -p 5000:5000/tcp -p 6379:6379/tcp -v d:/jaindb:/app/wwwroot zanderr/jaindb  

"localURL" is the public URL of the Web-Service and "d:\jaindb" is the Folder on the Host to store all data. Docker may prompt if you want to share the drive on your host.

  • JainDB (should) now be running... To verify, open the "localURL" in your browser:

Collecting Inventory

JainDB includes a PowerShell example to collect and upload inventory data. Check out the redirected Folder on your Docker-Host (d:\jaindb in my example), you should have a File "inventory.ps1". But you can also access the script through the REST Service by running the following PowerShell command (replace the IP/Port with your "localURL") Invoke-RestMethod -Uri 'http://192.168.2.146:5000/getps'

to collect inventory and upload to JainDB just run:

Invoke-RestMethod -Uri 'http://192.168.2.146:5000/getps' | iex  

as a Result, you will get the Device-ID and a Hash-Value of the current inventory.

Device ID: 9qZpJhJqeRB2nZKCjX5i5MV5L  
9qZdT7xPUyW7HrpFgq7YKPj4d  

If you enter $object, you will get the data that was uploaded to JainDB.

Note: you have to run the command with elevated privileges (as Admin).

If you run the same command again, you should get the same Hash-Value unless something has changed in the Inventory. The Device-ID should always be the same.

Customize Inventory

You can edit the "inventory.ps1" file on the redirected Folder to get the data you need.
There are a few things to keep in mind to keep JainDB efficient:

Device Identifier

In the example, the Device Identifier is calculated based on the UUID, Hostname and Domain. If any of these values changes, you will get a new Device-ID. You can change this by modifying the function "GetMyID".

Key-Values

Key-Values are used to find your device quickly by using one of these Key-Values. The Key-Values in the example are UUID, HostName, SerialNumber and all MAC addresses as defined in the function "SetID"

Key-Values must start with a "#" (Hash) Sign as they are unique on every device.

Dynamic- and Unique-Data

As we want to benefit from Data-Deduplication, we must tag all attributes which are unique on every device with a "#" (Hash) Sign. As an example, to collection BIOS information, the script is using:

getinv -Name "BIOS" -WMIClass "win32_BIOS" -Properties @("Name", "Manufacturer", "Version", "#SerialNumber")  

The "SerialNumber" is unique on every device, that's why the attribute is tagged with a #.

Another example to collect the logical-Disks:

getinv -Name "LogicalDisk" -WMIClass "Win32_LogicalDisk" -Properties @("DeviceID", "DriveType", "FileSystem", "MediaType", "Size", "VolumeName", "@FreeSpace", "#VolumeSerialNumber")  

The "FreeSpace" attribute is tagged with an "@" to mark it as Dynamic-Data as it will change on every inventory cycle. Dynamic-Data attributes will be excluded from history and deduplication. They will be available only on current data as this data is cached in a separate store (for 90 Days) and is not part of the blockchain.

Normalize Data

The "FreeSpace" attribute on Logical Disk does represent the number of free Bytes which does change permanently. To get a more common number, the example script contains the function "normalize" to round these numbers.

Reporting

To get the Data back, you can try the PowerShell examples from Quick-Start... Or you can connect the REST-API with Power-BI

Note: Make sure you have the latest Version of Power-BI!

JainDB as Data-Source

To select JainDB as Data-Source, use the "Web" Source in Power-BI:

Enter the URL for the REST-API. In the current example we will use:
http://192.168.2.146:5000/query?OS.Caption,OS.Version&$select=%23Name,_date
This will list all current (no history data) OS-Captions and -Versions with the Key-Values "#Name" and "_date" (upload timestamp).

Prepare Data

In the Query-Editor you will get al list of "Record's". Convert the List "To Table":

Now you have a Column with Records that can be extended by pressing the extend button:
Select the Columns you need...

...and you will get a Table with all the data:

Create a Chart

Click on "Close and Apply", add a Pie-Chart from the "Visualizations" Toolbar and drag the Column: "Version" to the Field "Legend" and "Values"

et voila, you Chart:

If you have any questions about JainDB or reporting with JainDB, please open an issue on https://github.com/rzander/jaindb/issues