| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037 |
- /*
- Copyright 2019-2021 Intel Corporation
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- function trimIdentifiers(val)
- {
- for(var v in val)
- {
- if (!val[v] || val[v] == 'None' || val[v] == '' || val[v].trim() == '') { delete val[v]; }
- }
- }
- function trimResults(val)
- {
- var i, x;
- for (i = 0; i < val.length; ++i)
- {
- for (x in val[i])
- {
- if (x.startsWith('_'))
- {
- delete val[i][x];
- }
- else
- {
- if (val[i][x] == null || val[i][x] == 0)
- {
- delete val[i][x];
- }
- }
- }
- }
- }
- function brief(headers, obj)
- {
- var i, x;
- for (x = 0; x < obj.length; ++x)
- {
- for (i in obj[x])
- {
- if (!headers.includes(i))
- {
- delete obj[x][i];
- }
- }
- }
- return (obj);
- }
- function dataHandler(c)
- {
- this.str += c.toString();
- }
- function linux_identifiers()
- {
- var identifiers = {};
- var ret = {};
- var values = {};
- if (!require('fs').existsSync('/sys/class/dmi/id')) {
- if (require('fs').existsSync('/sys/firmware/devicetree/base/model')) {
- if (require('fs').readFileSync('/sys/firmware/devicetree/base/model').toString().trim().startsWith('Raspberry')) {
- identifiers['board_vendor'] = 'Raspberry Pi';
- identifiers['board_name'] = require('fs').readFileSync('/sys/firmware/devicetree/base/model').toString().trim();
- identifiers['board_serial'] = require('fs').readFileSync('/sys/firmware/devicetree/base/serial-number').toString().trim();
- const memorySlots = [];
- var child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', dataHandler);
- child.stdin.write('vcgencmd get_mem arm && vcgencmd get_mem gpu\nexit\n');
- child.waitExit();
- try {
- const lines = child.stdout.str.trim().split('\n');
- if (lines.length == 2) {
- memorySlots.push({ Locator: "ARM Memory", Size: lines[0].split('=')[1].trim() })
- memorySlots.push({ Locator: "GPU Memory", Size: lines[1].split('=')[1].trim() })
- ret.memory = { Memory_Device: memorySlots };
- }
- } catch (xx) { }
- } else {
- throw('Unknown board');
- }
- } else {
- throw ('this platform does not have DMI statistics');
- }
- } else {
- var entries = require('fs').readdirSync('/sys/class/dmi/id');
- for (var i in entries) {
- if (require('fs').statSync('/sys/class/dmi/id/' + entries[i]).isFile()) {
- try {
- ret[entries[i]] = require('fs').readFileSync('/sys/class/dmi/id/' + entries[i]).toString().trim();
- } catch(z) { }
- if (ret[entries[i]] == 'None') { delete ret[entries[i]]; }
- }
- }
- entries = null;
- identifiers['bios_date'] = ret['bios_date'];
- identifiers['bios_vendor'] = ret['bios_vendor'];
- identifiers['bios_version'] = ret['bios_version'];
- identifiers['bios_serial'] = ret['product_serial'];
- identifiers['board_name'] = ret['board_name'];
- identifiers['board_serial'] = ret['board_serial'];
- identifiers['board_vendor'] = ret['board_vendor'];
- identifiers['board_version'] = ret['board_version'];
- identifiers['product_uuid'] = ret['product_uuid'];
- identifiers['product_name'] = ret['product_name'];
- }
- try {
- identifiers['bios_mode'] = (require('fs').statSync('/sys/firmware/efi').isDirectory() ? 'UEFI': 'Legacy');
- } catch (ex) { identifiers['bios_mode'] = 'Legacy'; }
- var child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', dataHandler);
- child.stdin.write('cat /proc/cpuinfo | grep -i "model name" | ' + "tr '\\n' ':' | awk -F: '{ print $2 }'\nexit\n");
- child.waitExit();
- identifiers['cpu_name'] = child.stdout.str.trim();
- if (identifiers['cpu_name'] == "") { // CPU BLANK, check lscpu instead
- child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', dataHandler);
- child.stdin.write('lscpu | grep -i "model name" | ' + "tr '\\n' ':' | awk -F: '{ print $2 }'\nexit\n");
- child.waitExit();
- identifiers['cpu_name'] = child.stdout.str.trim();
- }
- child = null;
- // Fetch GPU info
- child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', dataHandler);
- child.stdin.write("lspci | grep ' VGA ' | tr '\\n' '`' | awk '{ a=split($0,lines" + ',"`"); printf "["; for(i=1;i<a;++i) { split(lines[i],gpu,"r: "); printf "%s\\"%s\\"", (i==1?"":","),gpu[2]; } printf "]"; }\'\nexit\n');
- child.waitExit();
- try { identifiers['gpu_name'] = JSON.parse(child.stdout.str.trim()); } catch (xx) { }
- child = null;
- // Fetch Storage Info
- child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', dataHandler);
- child.stdin.write("lshw -class disk -disable network | tr '\\n' '`' | awk '" + '{ len=split($0,lines,"*"); printf "["; for(i=2;i<=len;++i) { model=""; caption=""; size=""; clen=split(lines[i],item,"`"); for(j=2;j<clen;++j) { split(item[j],tokens,":"); split(tokens[1],key," "); if(key[1]=="description") { caption=substr(tokens[2],2); } if(key[1]=="product") { model=substr(tokens[2],2); } if(key[1]=="size") { size=substr(tokens[2],2); } } if(model=="") { model=caption; } if(caption!="" || model!="") { printf "%s{\\"Caption\\":\\"%s\\",\\"Model\\":\\"%s\\",\\"Size\\":\\"%s\\"}",(i==2?"":","),caption,model,size; } } printf "]"; }\'\nexit\n');
- child.waitExit();
- try { identifiers['storage_devices'] = JSON.parse(child.stdout.str.trim()); } catch (xx) { }
- child = null;
- // Fetch storage volumes using df
- child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', dataHandler);
- child.stdin.write('df -T -x tmpfs -x devtmpfs -x efivarfs | awk \'NR==1 || $1 ~ ".+"{print $3, $4, $5, $7, $2}\' | awk \'NR>1 {printf "{\\"size\\":\\"%s\\",\\"used\\":\\"%s\\",\\"available\\":\\"%s\\",\\"mount_point\\":\\"%s\\",\\"type\\":\\"%s\\"},", $1, $2, $3, $4, $5}\' | sed \'$ s/,$//\' | awk \'BEGIN {printf "["} {printf "%s", $0} END {printf "]"}\'\nexit\n');
- child.waitExit();
- try { ret.volumes = JSON.parse(child.stdout.str.trim()); } catch (xx) { }
- child = null;
- values.identifiers = identifiers;
- values.linux = ret;
- trimIdentifiers(values.identifiers);
- var dmidecode = require('lib-finder').findBinary('dmidecode');
- if (dmidecode != null)
- {
- child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', dataHandler);
- child.stderr.str = ''; child.stderr.on('data', dataHandler);
- child.stdin.write(dmidecode + " -t memory | tr '\\n' '`' | ");
- child.stdin.write(" awk '{ ");
- child.stdin.write(' printf("[");');
- child.stdin.write(' comma="";');
- child.stdin.write(' c=split($0, lines, "``");');
- child.stdin.write(' for(i=1;i<=c;++i)');
- child.stdin.write(' {');
- child.stdin.write(' d=split(lines[i], val, "`");');
- child.stdin.write(' split(val[1], tokens, ",");');
- child.stdin.write(' split(tokens[2], dmitype, " ");');
- child.stdin.write(' dmi = dmitype[3]+0; ');
- child.stdin.write(' if(dmi == 5 || dmi == 6 || dmi == 16 || dmi == 17)');
- child.stdin.write(' {');
- child.stdin.write(' ccx="";');
- child.stdin.write(' printf("%s{\\"%s\\": {", comma, val[2]);');
- child.stdin.write(' for(j=3;j<d;++j)');
- child.stdin.write(' {');
- child.stdin.write(' sub(/^[ \\t]*/,"",val[j]);');
- child.stdin.write(' if(split(val[j],tmp,":")>1)');
- child.stdin.write(' {');
- child.stdin.write(' sub(/^[ \\t]*/,"",tmp[2]);');
- child.stdin.write(' gsub(/ /,"",tmp[1]);');
- child.stdin.write(' printf("%s\\"%s\\": \\"%s\\"", ccx, tmp[1], tmp[2]);');
- child.stdin.write(' ccx=",";');
- child.stdin.write(' }');
- child.stdin.write(' }');
- child.stdin.write(' printf("}}");');
- child.stdin.write(' comma=",";');
- child.stdin.write(' }');
- child.stdin.write(' }');
- child.stdin.write(' printf("]");');
- child.stdin.write("}'\nexit\n");
- child.waitExit();
- try
- {
- var j = JSON.parse(child.stdout.str);
- var i, key, key2;
- for (i = 0; i < j.length; ++i)
- {
- for (key in j[i])
- {
- delete j[i][key]['ArrayHandle'];
- delete j[i][key]['ErrorInformationHandle'];
- for (key2 in j[i][key])
- {
- if (j[i][key][key2] == 'Unknown' || j[i][key][key2] == 'Not Specified' || j[i][key][key2] == '')
- {
- delete j[i][key][key2];
- }
- }
- }
- }
- if(j.length > 0){
- var mem = {};
- for (i = 0; i < j.length; ++i)
- {
- for (key in j[i])
- {
- if (mem[key] == null) { mem[key] = []; }
- mem[key].push(j[i][key]);
- }
- }
- values.linux.memory = mem;
- }
- }
- catch (e)
- { }
- child = null;
- }
- var usbdevices = require('lib-finder').findBinary('usb-devices');
- if (usbdevices != null)
- {
- var child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', dataHandler);
- child.stderr.str = ''; child.stderr.on('data', dataHandler);
- child.stdin.write(usbdevices + " | tr '\\n' '`' | ");
- child.stdin.write(" awk '");
- child.stdin.write('{');
- child.stdin.write(' comma="";');
- child.stdin.write(' printf("[");');
- child.stdin.write(' len=split($0, group, "``");');
- child.stdin.write(' for(i=1;i<=len;++i)');
- child.stdin.write(' {');
- child.stdin.write(' comma2="";');
- child.stdin.write(' xlen=split(group[i], line, "`");');
- child.stdin.write(' scount=0;');
- child.stdin.write(' for(x=1;x<xlen;++x)');
- child.stdin.write(' {');
- child.stdin.write(' if(line[x] ~ "^S:")');
- child.stdin.write(' {');
- child.stdin.write(' ++scount;');
- child.stdin.write(' }');
- child.stdin.write(' }');
- child.stdin.write(' if(scount>0)');
- child.stdin.write(' {');
- child.stdin.write(' printf("%s{", comma); comma=",";');
- child.stdin.write(' for(x=1;x<xlen;++x)');
- child.stdin.write(' {');
- child.stdin.write(' if(line[x] ~ "^T:")');
- child.stdin.write(' {');
- child.stdin.write(' comma3="";');
- child.stdin.write(' printf("%s\\"hardware\\": {", comma2); comma2=",";');
- child.stdin.write(' sub(/^T:[ \\t]*/, "", line[x]);');
- child.stdin.write(' gsub(/= */, "=", line[x]);');
- child.stdin.write(' blen=split(line[x], tokens, " ");');
- child.stdin.write(' for(y=1;y<blen;++y)');
- child.stdin.write(' {');
- child.stdin.write(' match(tokens[y],/=/);');
- child.stdin.write(' h=substr(tokens[y],1,RSTART-1);');
- child.stdin.write(' v=substr(tokens[y],RSTART+1);');
- child.stdin.write(' sub(/#/, "", h);');
- child.stdin.write(' printf("%s\\"%s\\": \\"%s\\"", comma3, h, v); comma3=",";');
- child.stdin.write(' }');
- child.stdin.write(' printf("}");');
- child.stdin.write(' }');
- child.stdin.write(' if(line[x] ~ "^S:")');
- child.stdin.write(' {');
- child.stdin.write(' sub(/^S:[ \\t]*/, "", line[x]);');
- child.stdin.write(' match(line[x], /=/);');
- child.stdin.write(' h=substr(line[x],1,RSTART-1);');
- child.stdin.write(' v=substr(line[x],RSTART+1);');
- child.stdin.write(' printf("%s\\"%s\\": \\"%s\\"", comma2, h,v); comma2=",";');
- child.stdin.write(' }');
- child.stdin.write(' }');
- child.stdin.write(' printf("}");');
- child.stdin.write(' }');
- child.stdin.write(' }');
- child.stdin.write(' printf("]");');
- child.stdin.write("}'\nexit\n");
- child.waitExit();
- try
- {
- values.linux.usb = JSON.parse(child.stdout.str);
- }
- catch(x)
- { }
- child = null;
- }
- var pcidevices = require('lib-finder').findBinary('lspci');
- if (pcidevices != null)
- {
- var child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', dataHandler);
- child.stderr.str = ''; child.stderr.on('data', dataHandler);
- child.stdin.write(pcidevices + " -m | tr '\\n' '`' | ");
- child.stdin.write(" awk '");
- child.stdin.write('{');
- child.stdin.write(' printf("[");');
- child.stdin.write(' comma="";');
- child.stdin.write(' alen=split($0, lines, "`");');
- child.stdin.write(' for(a=1;a<alen;++a)');
- child.stdin.write(' {');
- child.stdin.write(' match(lines[a], / /);');
- child.stdin.write(' blen=split(lines[a], meta, "\\"");');
- child.stdin.write(' bus=substr(lines[a], 1, RSTART);');
- child.stdin.write(' gsub(/ /, "", bus);');
- child.stdin.write(' printf("%s{\\"bus\\": \\"%s\\"", comma, bus); comma=",";');
- child.stdin.write(' printf(", \\"device\\": \\"%s\\"", meta[2]);');
- child.stdin.write(' printf(", \\"manufacturer\\": \\"%s\\"", meta[4]);');
- child.stdin.write(' printf(", \\"description\\": \\"%s\\"", meta[6]);');
- child.stdin.write(' if(meta[8] != "")');
- child.stdin.write(' {');
- child.stdin.write(' printf(", \\"subsystem\\": {");');
- child.stdin.write(' printf("\\"manufacturer\\": \\"%s\\"", meta[8]);');
- child.stdin.write(' printf(", \\"description\\": \\"%s\\"", meta[10]);');
- child.stdin.write(' printf("}");');
- child.stdin.write(' }');
- child.stdin.write(' printf("}");');
- child.stdin.write(' }');
- child.stdin.write(' printf("]");');
- child.stdin.write("}'\nexit\n");
- child.waitExit();
- try
- {
- values.linux.pci = JSON.parse(child.stdout.str);
- }
- catch (x)
- { }
- child = null;
- }
- // Linux Last Boot Up Time
- try {
- child = require('child_process').execFile('/usr/bin/uptime', ['', '-s']); // must include blank value at begining for some reason?
- child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
- child.stderr.on('data', function () { });
- child.waitExit();
- var regex = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;
- if (regex.test(child.stdout.str.trim())) {
- values.linux.LastBootUpTime = child.stdout.str.trim();
- } else {
- child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
- child.stdin.write('date -d "@$(( $(date +%s) - $(awk \'{print int($1)}\' /proc/uptime) ))" "+%Y-%m-%d %H:%M:%S"\nexit\n');
- child.waitExit();
- if (regex.test(child.stdout.str.trim())) {
- values.linux.LastBootUpTime = child.stdout.str.trim();
- }
- }
- child = null;
- } catch (ex) { }
- // Linux TPM
- try {
- if (require('fs').statSync('/sys/class/tpm/tpm0').isDirectory()){
- values.tpm = {
- SpecVersion: require('fs').readFileSync('/sys/class/tpm/tpm0/tpm_version_major').toString().trim()
- }
- }
- } catch (ex) { }
- // Linux Batteries
- try {
- var batteries = require('fs').readdirSync('/sys/class/power_supply/');
- if (batteries.length != 0) {
- values.battery = [];
- for (var i in batteries) {
- const filesToRead = [
- 'capacity', 'cycle_count', 'energy_full', 'energy_full_design',
- 'energy_now', 'manufacturer', 'model_name', 'power_now',
- 'serial_number', 'status', 'technology', 'voltage_now'
- ];
- const thedata = {};
- for (var x in filesToRead) {
- try {
- const content = require('fs').readFileSync('/sys/class/power_supply/' + batteries[i] + '/' + filesToRead[x]).toString().trim();
- thedata[filesToRead[x]] = /^\d+$/.test(content) ? parseInt(content, 10) : content;
- } catch (err) { }
- }
- if (Object.keys(thedata).length === 0) continue; // No data read, skip
- const status = (thedata.status || '').toLowerCase();
- const isCharging = status === 'charging';
- const isDischarging = status === 'discharging';
- const toMilli = function (val) { return Math.round((val || 0) / 1000) }; // Convert from µ units to m units (divide by 1000)
- const batteryJson = {
- "InstanceName": batteries[i],
- "CycleCount": thedata.cycle_count || 0,
- "FullChargedCapacity": toMilli(thedata.energy_full),
- "Chemistry": (thedata.technology || ''),
- "DesignedCapacity": toMilli(thedata.energy_full_design),
- "DeviceName": thedata.model_name || "Battery",
- "ManufactureName": thedata.manufacturer || "Unknown",
- "SerialNumber": thedata.serial_number || "unknown",
- "ChargeRate": isCharging ? toMilli(thedata.power_now) : 0,
- "Charging": isCharging,
- "DischargeRate": isDischarging ? toMilli(thedata.power_now) : 0,
- "Discharging": isDischarging,
- "RemainingCapacity": toMilli(thedata.energy_now),
- "Voltage": toMilli(thedata.voltage_now),
- "Health": (thedata.energy_full && thedata.energy_full_design ? Math.floor((thedata.energy_full / thedata.energy_full_design) * 100) : 0),
- "BatteryCharge": (thedata.energy_now && thedata.energy_full ? Math.floor((thedata.energy_now / thedata.energy_full) * 100) : 0)
- };
- values.battery.push(batteryJson);
- }
- if (values.battery.length == 0) { delete values.battery; }
- }
- } catch (ex) { }
- return (values);
- }
- function windows_wmic_results(str)
- {
- var lines = str.trim().split('\r\n');
- var keys = lines[0].split(',');
- var i, key, keyval;
- var tokens;
- var result = [];
- console.log('Lines: ' + lines.length, 'Keys: ' + keys.length);
- for (i = 1; i < lines.length; ++i)
- {
- var obj = {};
- console.log('i: ' + i);
- tokens = lines[i].split(',');
- for (key = 0; key < keys.length; ++key)
- {
- var tmp = Buffer.from(tokens[key], 'binary').toString();
- console.log(tokens[key], tmp);
- tokens[key] = tmp == null ? '' : tmp;
- if (tokens[key].trim())
- {
- obj[keys[key].trim()] = tokens[key].trim();
- }
- }
- delete obj.Node;
- result.push(obj);
- }
- return (result);
- }
- function windows_identifiers()
- {
- var ret = { windows: {} };
- var items, item, i;
- ret['identifiers'] = {};
- var values = require('win-wmi').query('ROOT\\CIMV2', "SELECT * FROM Win32_Bios", ['ReleaseDate', 'Manufacturer', 'SMBIOSBIOSVersion', 'SerialNumber']);
- if(values[0]){
- ret['identifiers']['bios_date'] = values[0]['ReleaseDate'];
- ret['identifiers']['bios_vendor'] = values[0]['Manufacturer'];
- ret['identifiers']['bios_version'] = values[0]['SMBIOSBIOSVersion'];
- ret['identifiers']['bios_serial'] = values[0]['SerialNumber'];
- }
- ret['identifiers']['bios_mode'] = 'Legacy';
- values = require('win-wmi').query('ROOT\\CIMV2', "SELECT * FROM Win32_BaseBoard", ['Product', 'SerialNumber', 'Manufacturer', 'Version']);
- if(values[0]){
- ret['identifiers']['board_name'] = values[0]['Product'];
- ret['identifiers']['board_serial'] = values[0]['SerialNumber'];
- ret['identifiers']['board_vendor'] = values[0]['Manufacturer'];
- ret['identifiers']['board_version'] = values[0]['Version'];
- }
- values = require('win-wmi').query('ROOT\\CIMV2', "SELECT * FROM Win32_ComputerSystemProduct", ['UUID', 'Name']);
- if(values[0]){
- ret['identifiers']['product_uuid'] = values[0]['UUID'];
- ret['identifiers']['product_name'] = values[0]['Name'];
- }
- values = require('win-wmi').query('ROOT\\CIMV2', "SELECT * FROM Win32_SystemEnclosure", ['SerialNumber', 'SMBIOSAssetTag', 'Manufacturer']);
- if(values[0]){
- ret['identifiers']['chassis_serial'] = values[0]['SerialNumber'];
- ret['identifiers']['chassis_assettag'] = values[0]['SMBIOSAssetTag'];
- ret['identifiers']['chassis_manufacturer'] = values[0]['Manufacturer'];
- }
- trimIdentifiers(ret.identifiers);
- values = require('win-wmi').query('ROOT\\CIMV2', "SELECT * FROM Win32_PhysicalMemory");
- if(values[0]){
- trimResults(values);
- ret.windows.memory = values;
- }
- values = require('win-wmi').query('ROOT\\CIMV2', "SELECT * FROM Win32_OperatingSystem");
- if(values[0]){
- trimResults(values);
- ret.windows.osinfo = values[0];
- }
- values = require('win-wmi-fixed').query('ROOT\\CIMV2', "SELECT * FROM Win32_DiskPartition");
- if(values[0]){
- trimResults(values);
- ret.windows.partitions = values;
- for (var i in values) {
- if (values[i].Type=='GPT: System') {
- ret['identifiers']['bios_mode'] = 'UEFI';
- }
- }
- }
- values = require('win-wmi').query('ROOT\\CIMV2', "SELECT * FROM Win32_Processor", ['Caption', 'DeviceID', 'Manufacturer', 'MaxClockSpeed', 'Name', 'SocketDesignation']);
- if(values[0]){
- ret.windows.cpu = values;
- }
-
- values = require('win-wmi').query('ROOT\\CIMV2', "SELECT * FROM Win32_VideoController", ['Name', 'CurrentHorizontalResolution', 'CurrentVerticalResolution']);
- if(values[0]){
- ret.windows.gpu = values;
- }
- values = require('win-wmi').query('ROOT\\CIMV2', "SELECT * FROM Win32_DiskDrive", ['Caption', 'DeviceID', 'Model', 'Partitions', 'Size', 'Status']);
- if(values[0]){
- ret.windows.drives = values;
- }
-
- // Insert GPU names
- ret.identifiers.gpu_name = [];
- for (var gpuinfo in ret.windows.gpu)
- {
- if (ret.windows.gpu[gpuinfo].Name) { ret.identifiers.gpu_name.push(ret.windows.gpu[gpuinfo].Name); }
- }
- // Insert Storage Devices
- ret.identifiers.storage_devices = [];
- for (var dv in ret.windows.drives)
- {
- ret.identifiers.storage_devices.push({ Caption: ret.windows.drives[dv].Caption, Model: ret.windows.drives[dv].Model, Size: ret.windows.drives[dv].Size });
- }
- try { ret.identifiers.cpu_name = ret.windows.cpu[0].Name; } catch (x) { }
- // Windows TPM
- IntToStr = function (v) { return String.fromCharCode((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF); };
- try {
- values = require('win-wmi').query('ROOT\\CIMV2\\Security\\MicrosoftTpm', "SELECT * FROM Win32_Tpm", ['IsActivated_InitialValue','IsEnabled_InitialValue','IsOwned_InitialValue','ManufacturerId','ManufacturerVersion','SpecVersion']);
- if(values[0]) {
- ret.tpm = {
- SpecVersion: values[0].SpecVersion.split(",")[0],
- ManufacturerId: IntToStr(values[0].ManufacturerId).replace(/[^\x00-\x7F]/g, ""),
- ManufacturerVersion: values[0].ManufacturerVersion,
- IsActivated: values[0].IsActivated_InitialValue,
- IsEnabled: values[0].IsEnabled_InitialValue,
- IsOwned: values[0].IsOwned_InitialValue,
- }
- }
- } catch (ex) { }
- // Windows Batteries
- IntToStrLE = function (v) { return String.fromCharCode(v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF, (v >> 24) & 0xFF); };
- try {
- function mergeJSONArrays() {
- var resultMap = {};
- var result = [];
- // Loop through all arguments (arrays)
- for (var i = 0; i < arguments.length; i++) {
- var currentArray = arguments[i];
- // Skip if not an array
- if (!currentArray || currentArray.constructor !== Array) {
- continue;
- }
- // Process each object in the array
- for (var j = 0; j < currentArray.length; j++) {
- var obj = currentArray[j];
- // Skip if not an object or missing InstanceName
- if (!obj || typeof obj !== 'object' || !obj.InstanceName) {
- continue;
- }
- var name = obj.InstanceName;
- // Create new entry if it doesn't exist
- if (!resultMap[name]) {
- resultMap[name] = { InstanceName: name };
- result.push(resultMap[name]);
- }
- // Copy all properties except InstanceName
- for (var key in obj) {
- if (obj.hasOwnProperty(key) && key !== 'InstanceName') {
- resultMap[name][key] = obj[key];
- }
- }
- }
- }
- return result;
- }
- values = require('win-wmi').query('ROOT\\WMI', "SELECT * FROM BatteryCycleCount",['InstanceName','CycleCount']);
- var values2 = require('win-wmi').query('ROOT\\WMI', "SELECT * FROM BatteryFullChargedCapacity",['InstanceName','FullChargedCapacity']);
- var values3 = require('win-wmi').query('ROOT\\WMI', "SELECT * FROM BatteryRuntime",['InstanceName','EstimatedRuntime']);
- var values4 = require('win-wmi').query('ROOT\\WMI', "SELECT * FROM BatteryStaticData",['InstanceName','Chemistry','DesignedCapacity','DeviceName','ManufactureDate','ManufactureName','SerialNumber']);
- for (i = 0; i < values4.length; ++i) {
- if (values4[i].Chemistry) { values4[i].Chemistry = IntToStrLE(parseInt(values4[i].Chemistry)); }
- if (values4[i].ManufactureDate) { if (values4[i].ManufactureDate.indexOf('*****') != -1) delete values4[i].ManufactureDate; }
- }
- var values5 = require('win-wmi').query('ROOT\\WMI', "SELECT * FROM BatteryStatus",['InstanceName','ChargeRate','Charging','DischargeRate','Discharging','RemainingCapacity','Voltage']);
- var values6 = [];
- if (values2.length > 0 && values4.length > 0) {
- for (i = 0; i < values2.length; ++i) {
- for (var j = 0; j < values4.length; ++j) {
- if (values2[i].InstanceName == values4[j].InstanceName) {
- if ((values4[j].DesignedCapacity && values4[j].DesignedCapacity > 0) && (values2[i].FullChargedCapacity && values2[i].FullChargedCapacity > 0)) {
- values6[i] = {
- Health: Math.floor((values2[i].FullChargedCapacity / values4[j].DesignedCapacity) * 100),
- InstanceName: values2[i].InstanceName
- };
- if (values6[i].Health > 100) { values6[i].Health = 100; }
- } else {
- values6[i] = { Health: 0, InstanceName: values2[i].InstanceName };
- }
- break;
- }
- }
- }
- }
- var values7 = [];
- if (values2.length > 0 && values5.length > 0) {
- for (i = 0; i < values2.length; ++i) {
- for (var j = 0; j < values5.length; ++j) {
- if (values2[i].InstanceName == values5[j].InstanceName) {
- if ((values2[i].FullChargedCapacity && values2[i].FullChargedCapacity > 0) && (values5[j].RemainingCapacity && values5[j].RemainingCapacity > 0)) {
- values7[i] = {
- BatteryCharge: Math.floor((values5[j].RemainingCapacity / values2[i].FullChargedCapacity) * 100),
- InstanceName: values2[i].InstanceName
- };
- } else {
- values7[i] = { BatteryCharge: 0, InstanceName: values2[i].InstanceName };
- }
- break;
- }
- }
- }
- }
- ret.battery = mergeJSONArrays(values, values2, values3, values4, values5, values6, values7);
- } catch (ex) { }
- return (ret);
- }
- function macos_identifiers()
- {
- var ret = { identifiers: {}, darwin: {} };
- var child;
- child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
- child.stdin.write('ioreg -d2 -c IOPlatformExpertDevice | grep board-id | awk -F= \'{ split($2, res, "\\""); print res[2]; }\'\nexit\n');
- child.waitExit();
- ret.identifiers.board_name = child.stdout.str.trim();
- child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
- child.stdin.write('ioreg -d2 -c IOPlatformExpertDevice | grep IOPlatformSerialNumber | awk -F= \'{ split($2, res, "\\""); print res[2]; }\'\nexit\n');
- child.waitExit();
- ret.identifiers.board_serial = child.stdout.str.trim();
- child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
- child.stdin.write('ioreg -d2 -c IOPlatformExpertDevice | grep manufacturer | awk -F= \'{ split($2, res, "\\""); print res[2]; }\'\nexit\n');
- child.waitExit();
- ret.identifiers.board_vendor = child.stdout.str.trim();
- child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
- child.stdin.write('ioreg -d2 -c IOPlatformExpertDevice | grep version | awk -F= \'{ split($2, res, "\\""); print res[2]; }\'\nexit\n');
- child.waitExit();
- ret.identifiers.board_version = child.stdout.str.trim();
- child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
- child.stdin.write('ioreg -d2 -c IOPlatformExpertDevice | grep IOPlatformUUID | awk -F= \'{ split($2, res, "\\""); print res[2]; }\'\nexit\n');
- child.waitExit();
- ret.identifiers.product_uuid = child.stdout.str.trim();
- child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
- child.stdin.write('sysctl -n machdep.cpu.brand_string\nexit\n');
- child.waitExit();
- ret.identifiers.cpu_name = child.stdout.str.trim();
- child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
- child.stdin.write('system_profiler SPMemoryDataType\nexit\n');
- child.waitExit();
- var lines = child.stdout.str.trim().split('\n');
- if(lines.length > 0) {
- const memorySlots = [];
- if(lines[2].trim().includes('Memory Slots:')) { // OLD MACS WITH SLOTS
- var memorySlots1 = child.stdout.str.split(/\n{2,}/).slice(3);
- memorySlots1.forEach(function(slot,index) {
- var lines = slot.split('\n');
- if(lines.length == 1){ // start here
- if(lines[0].trim()!=''){
- var slotObj = { DeviceLocator: lines[0].trim().replace(/:$/, '') }; // Initialize name as an empty string
- var nextline = memorySlots1[index+1].split('\n');
- nextline.forEach(function(line) {
- if (line.trim() !== '') {
- var parts = line.split(':');
- var key = parts[0].trim();
- var value = parts[1].trim();
- value = (key == 'Part Number' || key == 'Manufacturer') ? hexToAscii(parts[1].trim()) : parts[1].trim();
- slotObj[key.replace(' ','')] = value; // Store attribute in the slot object
- }
- });
- memorySlots.push(slotObj);
- }
- }
- });
- } else { // NEW MACS WITHOUT SLOTS
- memorySlots.push({ DeviceLocator: "Onboard Memory", Size: lines[2].split(":")[1].trim(), PartNumber: lines[3].split(":")[1].trim(), Manufacturer: lines[4].split(":")[1].trim() })
- }
- ret.darwin.memory = memorySlots;
- }
- child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
- child.stdin.write('diskutil info -all\nexit\n');
- child.waitExit();
- var sections = child.stdout.str.split('**********\n');
- if(sections.length > 0){
- var devices = [];
- for (var i = 0; i < sections.length; i++) {
- var lines = sections[i].split('\n');
- var deviceInfo = {};
- var wholeYes = false;
- var physicalYes = false;
- var oldmac = false;
- for (var j = 0; j < lines.length; j++) {
- var keyValue = lines[j].split(':');
- var key = keyValue[0].trim();
- var value = keyValue[1] ? keyValue[1].trim() : '';
- if (key === 'Virtual') oldmac = true;
- if (key === 'Whole' && value === 'Yes') wholeYes = true;
- if (key === 'Virtual' && value === 'No') physicalYes = true;
- if(value && key === 'Device / Media Name'){
- deviceInfo['Caption'] = value;
- }
- if(value && key === 'Disk Size'){
- deviceInfo['Size'] = value.split(' ')[0] + ' ' + value.split(' ')[1];
- }
- }
- if (wholeYes) {
- if (oldmac) {
- if (physicalYes) devices.push(deviceInfo);
- } else {
- devices.push(deviceInfo);
- }
- }
- }
- ret.identifiers.storage_devices = devices;
- }
- // Fetch storage volumes using df
- child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', dataHandler);
- child.stdin.write('df -aHY | awk \'NR>1 {printf "{\\"size\\":\\"%s\\",\\"used\\":\\"%s\\",\\"available\\":\\"%s\\",\\"mount_point\\":\\"%s\\",\\"type\\":\\"%s\\"},", $3, $4, $5, $10, $2}\' | sed \'$ s/,$//\' | awk \'BEGIN {printf "["} {printf "%s", $0} END {printf "]"}\'\nexit\n');
- child.waitExit();
- try {
- ret.darwin.volumes = JSON.parse(child.stdout.str.trim());
- for (var index = 0; index < ret.darwin.volumes.length; index++) {
- if (ret.darwin.volumes[index].type == 'auto_home'){
- ret.darwin.volumes.splice(index,1);
- }
- }
- if (ret.darwin.volumes.length == 0) { // not sonima OS so dont show type for now
- child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', dataHandler);
- child.stdin.write('df -aH | awk \'NR>1 {printf "{\\"size\\":\\"%s\\",\\"used\\":\\"%s\\",\\"available\\":\\"%s\\",\\"mount_point\\":\\"%s\\"},", $2, $3, $4, $9}\' | sed \'$ s/,$//\' | awk \'BEGIN {printf "["} {printf "%s", $0} END {printf "]"}\'\nexit\n');
- child.waitExit();
- try {
- ret.darwin.volumes = JSON.parse(child.stdout.str.trim());
- for (var index = 0; index < ret.darwin.volumes.length; index++) {
- if (ret.darwin.volumes[index].size == 'auto_home'){
- ret.darwin.volumes.splice(index,1);
- }
- }
- } catch (xx) { }
- }
- } catch (xx) { }
- child = null;
- // MacOS Last Boot Up Time
- try {
- child = require('child_process').execFile('/usr/sbin/sysctl', ['', 'kern.boottime']); // must include blank value at begining for some reason?
- child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
- child.stderr.on('data', function () { });
- child.waitExit();
- const timestampMatch = /\{ sec = (\d+), usec = \d+ \}/.exec(child.stdout.str.trim());
- if (!ret.darwin) {
- ret.darwin = { LastBootUpTime: parseInt(timestampMatch[1]) };
- } else {
- ret.darwin.LastBootUpTime = parseInt(timestampMatch[1]);
- }
- child = null;
- } catch (ex) { }
- trimIdentifiers(ret.identifiers);
- child = null;
- return (ret);
- }
- function hexToAscii(hexString) {
- if(!hexString.startsWith('0x')) return hexString.trim();
- hexString = hexString.startsWith('0x') ? hexString.slice(2) : hexString;
- var str = '';
- for (var i = 0; i < hexString.length; i += 2) {
- var hexPair = hexString.substr(i, 2);
- str += String.fromCharCode(parseInt(hexPair, 16));
- }
- str = str.replace(/[\u007F-\uFFFF]/g, ''); // Remove characters from 0x0080 to 0xFFFF
- return str.trim();
- }
- function win_chassisType()
- {
- // use new win-wmi-fixed module to get arrays correctly for time being
- try {
- var tokens = require('win-wmi-fixed').query('ROOT\\CIMV2', 'SELECT ChassisTypes FROM Win32_SystemEnclosure', ['ChassisTypes']);
- if (tokens[0]) {
- return (parseInt(tokens[0]['ChassisTypes'][0]));
- }
- } catch (e) {
- return (2); // unknown
- }
- }
- function win_systemType()
- {
- try {
- var tokens = require('win-wmi').query('ROOT\\CIMV2', 'SELECT PCSystemType FROM Win32_ComputerSystem', ['PCSystemType']);
- if (tokens[0]) {
- return (parseInt(tokens[0]['PCSystemType']));
- } else {
- return (parseInt(1)); // default is desktop
- }
- } catch (ex) {
- return (parseInt(1)); // default is desktop
- }
- }
- function win_formFactor(chassistype)
- {
- var ret = 'DESKTOP';
- switch (chassistype)
- {
- case 11: // Handheld
- case 30: // Tablet
- case 31: // Convertible
- case 32: // Detachable
- ret = 'TABLET';
- break;
- case 9: // Laptop
- case 10: // Notebook
- case 14: // Sub Notebook
- ret = 'LAPTOP';
- break;
- default:
- ret = win_systemType() == 2 ? 'MOBILE' : 'DESKTOP';
- break;
- }
- return (ret);
- }
- switch(process.platform)
- {
- case 'linux':
- module.exports = { _ObjectID: 'identifiers', get: linux_identifiers };
- break;
- case 'win32':
- module.exports = { _ObjectID: 'identifiers', get: windows_identifiers, chassisType: win_chassisType, formFactor: win_formFactor, systemType: win_systemType };
- break;
- case 'darwin':
- module.exports = { _ObjectID: 'identifiers', get: macos_identifiers };
- break;
- default:
- module.exports = { get: function () { throw ('Unsupported Platform'); } };
- break;
- }
- module.exports.isDocker = function isDocker()
- {
- if (process.platform != 'linux') { return (false); }
- var child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
- child.stdin.write("cat /proc/self/cgroup | tr '\n' '`' | awk -F'`' '{ split($1, res, " + '"/"); if(res[2]=="docker"){print "1";} }\'\nexit\n');
- child.waitExit();
- return (child.stdout.str != '');
- };
- module.exports.isBatteryPowered = function isBatteryOperated()
- {
- var ret = false;
- switch(process.platform)
- {
- default:
- break;
- case 'linux':
- var devices = require('fs').readdirSync('/sys/class/power_supply');
- for (var i in devices)
- {
- if (require('fs').readFileSync('/sys/class/power_supply/' + devices[i] + '/type').toString().trim() == 'Battery')
- {
- ret = true;
- break;
- }
- }
- break;
- case 'win32':
- var GM = require('_GenericMarshal');
- var stats = GM.CreateVariable(12);
- var kernel32 = GM.CreateNativeProxy('Kernel32.dll');
- kernel32.CreateMethod('GetSystemPowerStatus');
- if (kernel32.GetSystemPowerStatus(stats).Val != 0)
- {
- if(stats.toBuffer()[1] != 128 && stats.toBuffer()[1] != 255)
- {
- ret = true;
- }
- else
- {
- // No Battery detected, so lets check if there is supposed to be one
- var formFactor = win_formFactor(win_chassisType());
- return (formFactor == 'LAPTOP' || formFactor == 'TABLET' || formFactor == 'MOBILE');
- }
- }
- break;
- case 'darwin':
- var child = require('child_process').execFile('/bin/sh', ['sh']);
- child.stdout.str = ''; child.stdout.on('data', function(c){ this.str += c.toString(); });
- child.stderr.str = ''; child.stderr.on('data', function(c){ this.str += c.toString(); });
- child.stdin.write("pmset -g batt | tr '\\n' '`' | awk -F'`' '{ if(NF>2) { print \"true\"; }}'\nexit\n");
- child.waitExit();
- if(child.stdout.str.trim() != '') { ret = true; }
- break;
- }
- return (ret);
- };
- module.exports.isVM = function isVM()
- {
- var ret = false;
- var id = this.get();
- if (id.linux && id.linux.sys_vendor)
- {
- switch (id.linux.sys_vendor)
- {
- case 'VMware, Inc.':
- case 'QEMU':
- case 'Xen':
- ret = true;
- break;
- default:
- break;
- }
- }
- if (id.identifiers.bios_vendor)
- {
- switch(id.identifiers.bios_vendor)
- {
- case 'VMware, Inc.':
- case 'Xen':
- case 'SeaBIOS':
- case 'EFI Development Kit II / OVMF':
- case 'Proxmox distribution of EDK II':
- ret = true;
- break;
- default:
- break;
- }
- }
- if (id.identifiers.board_vendor && id.identifiers.board_vendor == 'VMware, Inc.') { ret = true; }
- if (id.identifiers.board_name)
- {
- switch (id.identifiers.board_name)
- {
- case 'VirtualBox':
- case 'Virtual Machine':
- ret = true;
- break;
- default:
- break;
- }
- }
- if (process.platform == 'win32' && !ret)
- {
- for(var i in id.identifiers.gpu_name)
- {
- if(id.identifiers.gpu_name[i].startsWith('VMware '))
- {
- ret = true;
- break;
- }
- }
- }
- if (!ret) { ret = this.isDocker(); }
- return (ret);
- };
- // bios_date = BIOS->ReleaseDate
- // bios_vendor = BIOS->Manufacturer
- // bios_version = BIOS->SMBIOSBIOSVersion
- // board_name = BASEBOARD->Product = ioreg/board-id
- // board_serial = BASEBOARD->SerialNumber = ioreg/serial-number | ioreg/IOPlatformSerialNumber
- // board_vendor = BASEBOARD->Manufacturer = ioreg/manufacturer
- // board_version = BASEBOARD->Version
|