Skip to content

Quick Start

Roger Zander edited this page Dec 20, 2017 · 21 revisions

This Quick-Start Guide will give you an example on how to upload data into jaindb and do some basic reporting. In the following examples, Inventory data is used as data source. But jaindb is not limited to inventory data, you can upload whatever you want... but no everything makes sense... Jaindb is using a blockchain to guarantee the integrity of the data which is great for Inventory/Asset data where you want to keep an auditable history for a long time.

Installation

For the current Scenario, we will use the published Docker-Image as it includes Redis.

Pre-Requisites for Windows

  • Windows 10 (>1703) or Server 2016 with the "Container" feature installed
  • Docker
  • Internet connection to download the docker image
  • Directory on the Host to store the Redis-Database and configuration Files ("D:\jaindb" in my examples)

Setup

Get the latest Version of the jaindb image:

docker pull zanderr/jaindb

The Docker-Variable "localURL" must point to the public URL of the published container (internal Port TCP:5000). In my example, I will publish the internal Port TCP:5000 to the public Port TCP:5000, so the URl is my IP of the host on port 5000.
If you want to query the Redis-DB directly, you should publish Port 6379 as well.

Finally, let's redirect the internal path /app/wwwroot to an external directory d:\jaindb. This will redirect all important data to a directory on the host so we can rebuild the container without loosing data...!

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

Jaindb is now up and running (hopefully). If you directly want to upload some inventory data, jump over to the section:
Collect Inventory Data

Configure

In the current example, we will use jaindb as an Inventory database. If your container is runnig, you should find an "inventory.ps1" File in your published directory (d:\jaindb in the example). This file is a PowerShell example which collects most important data of a computer and uploads the data to jaindb.

The next view chapters give you some basics on how to upload custom data.

Object ID

To identify the Computer, a unique identifier is required. Inventory.ps1 generates that id based on a hash value of the UUID, Domain and Computer name. If any of these three values changes, a new ID is generated.

function GetMyID {
    $uuid = getinv -Name "Computer" -WMIClass "win32_ComputerSystemProduct" -Properties @("#UUID")
    $comp = getinv -Name "Computer" -WMIClass "win32_ComputerSystem" -Properties @("Domain", "#Name") -AppendProperties $uuid 
    return GetHash($comp | ConvertTo-Json -Compress)
}

Key-Names

Every Object in jaindb can have one or many Key-Names which are used to find an Object by using common names or values. Key-Names are Root-Properties on the Object starting with a '#' (hash sign).

The inventory.ps1 example generates Key-Names for the following values:

  • #id
  • #UUID
  • #Name
  • #SerialNumber
  • #MAC (all IP-Enabled MAC addresses)
function SetID {
    Param(
        [ref]
        $AppendObject )

    if ($AppendObject.Value -ne $null) {
        $AppendObject.Value | Add-Member -MemberType NoteProperty -Name "#id" -Value (GetMyID) -ea SilentlyContinue
        $AppendObject.Value | Add-Member -MemberType NoteProperty -Name "#UUID" -Value (getinv -Name "Computer" -WMIClass "win32_ComputerSystemProduct" -Properties @("#UUID"))."#UUID" -ea SilentlyContinue
        $AppendObject.Value | Add-Member -MemberType NoteProperty -Name "#Name" -Value (getinv -Name "Computer" -WMIClass "win32_ComputerSystem" -Properties @("Name"))."Name" -ea SilentlyContinue
        $AppendObject.Value | Add-Member -MemberType NoteProperty -Name "#SerialNumber" -Value (getinv -Name "Computer" -WMIClass "win32_SystemEnclosure" -Properties @("SerialNumber"))."SerialNumber" -ea SilentlyContinue
        $AppendObject.Value | Add-Member -MemberType NoteProperty -Name "#MAC" -Value (get-wmiobject -class "Win32_NetworkAdapterConfiguration" | Where {($_.IpEnabled -Match "True")}).MACAddress.Replace(':', '-')
        return $null
    }   
}

Dynamic data

jaindb will keep the history of all uploaded objects. To benefit from data deduplication, it's recommended to tag dynamic attributes with a '#' prefix. Dynamic data are all attributes which are unique on a device. Example:

BuildNumber        : 16299
BootDevice         : \Device\HarddiskVolume3
Caption            : Microsoft Windows 10 Enterprise
CodeSet            : 1252
CountryCode        : 41
@CurrentTimeZone   : 60
EncryptionLevel    : 256
Locale             : 0807
Manufacturer       : Microsoft Corporation
MUILanguages       : {en-US}
OperatingSystemSKU : 4
OSArchitecture     : 64-bit
OSLanguage         : 1033
SystemDrive        : C:
Version            : 10.0.16299
#InstallDate       : 22.10.2017 13:24:00
@LastBootUpTime    : 13.12.2017 19:54:16

As you can see, 'InstallDate' is tagged as dynamic data as every computer may have a different installdate. Additionally, we can tag attributes with the sign '@' from being excluded from the data archive and blockchain. This is helpful for attributes that are not relevant for history or change frequently.

Note: Choose the required data attributes with care and tag dynamic data and short time date as it has a huge impact of the database size.

Normalize values

Storing "free Disk space" in bytes is not very useful as with every check that value will change. Inventory.ps1 will 'Normalize' or 'Round' integer values that are not very important. Example:

  • free Disk Space
  • Disk size
  • total Memory size as in these cases it's fine if we know the Disk size in gigabytes.

Note: Normalizing data will help to deduplicate data where the exact value is not important.

Get Inventory Data

Every inventory class like OS, BIOS, CPU etc. must be a child Object of the Root-Object: The following part of Inventory.ps1 does generate the Root-Object: $object = New-Object PSObject.

To simplify attribute tagging, inventory.ps1 contains the function "getinv" to collect and tag attributes.
Example:
getinv -Name "BIOS" -WMIClass "win32_BIOS" -Properties @("Name", "Manufacturer", "Version", "#SerialNumber") -AppendObject ([ref]$object) In this case, the class "BIOS" will be added (by using -AppendObject) to the Root-Object.

Convert to JSON and upload

Jaindb can only handle JSON Objects. One of the last steps in invetory.ps1 will convert the $object into a JSON string:
$con = $object | ConvertTo-Json -Compress

The JSON will is now ready to get upload by using the jaindb Rest-API:
Invoke-RestMethod -Uri "%LocalURL%/upload/$($id)" -Method Post -Body $con -ContentType "application/json; charset=utf-8"

"%LocalURL%" will be automatically replaced with the Docker-Variable if you are using the 'getps' method of the REST-API

Collect Inventory Data

To feed jaindb, it's very easy to upload some inventory data from windows(10) clients. Just open a PowerShell command as Admin (required to collect System-Information) and run the following command (change the URL to reflect the IP or DNS-name of your Environment!):

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

The command will get and run the inventory.ps1 PowerShell-Script from your published directory (d:\jaindb in the example).

As a result, you will receive your Device ID and the Hash of your uploaded data:

Device ID: 9qZpJhJqeRB2nZKCjX5i5MV5L
9qZdT7xPUyW7HrpFgq7YKPj4d

jaindb validates your data and appends a new block on the blockchain of your device.

Query

Jaindb provies a REST-API to query the uploaded data. Please check the REST-API reference for all available options.

Note: The following examples are using PowerShell, but you can also use Power-BI or any other tool that can handle JSON results as a reporting tool.

Let's get back the date we have uploaded:
Invoke-RestMethod -Uri "http://192.168.2.146:5000/full?name=$($env:Computername)"

This will return the inventory from cache, so it includes the attributes tagged with '@'
To get the data from the blockchain, we have to specify the index (starting with 1, as 0 is the genesis block):
Invoke-RestMethod -Uri "http://192.168.2.146:5000/full?name=$($env:Computername)&index=1"

To get a list of history data with all the indexes and timestamps for your computer:
Invoke-RestMethod -Uri "http://192.168.2.146:5000/history?name=$($env:Computername)"

If you want to know all current Computer-Names and Operating-Systems in your jaindb:
Invoke-RestMethod -Uri 'http://192.168.2.146:5000/query?OS.Caption,OS.Version&$select=%23Name,_date'

To include historical data to e.g. chart the progress of your Win10 rollout:
Invoke-RestMethod -Uri 'http://192.168.2.146:5000/queryall?OS.Caption,OS.Version&$select=%23Name,_date'

Sometimes it's also important to know what has changed. The current example gets the difference from current data to index 2:
Invoke-RestMethod -Uri "http://192.168.2.146:5000/diff?name=$($env:Computername)&index=2,mode=0"

Clone this wiki locally