meshcentral
Version:
Web based remote computer management and file server
702 lines (694 loc) • 105 kB
JavaScript
#!/usr/bin/env node
// Make sure we have the dependency modules
try { require('minimist'); } catch (ex) { console.log('Missing module "minimist", type "npm install minimist" to install it.'); return; }
try { require('ws'); } catch (ex) { console.log('Missing module "ws", type "npm install ws" to install it.'); return; }
var settings = {};
const crypto = require('crypto');
const args = require('minimist')(process.argv.slice(2));
const possibleCommands = ['listusers', 'listusersessions', 'listdevicegroups', 'listdevices', 'listusersofdevicegroup', 'serverinfo', 'userinfo', 'adduser', 'removeuser', 'adddevicegroup', 'removedevicegroup', 'editdevicegroup', 'broadcast', 'showevents', 'addusertodevicegroup', 'removeuserfromdevicegroup', 'addusertodevice', 'removeuserfromdevice', 'sendinviteemail', 'generateinvitelink', 'config', 'movetodevicegroup', 'deviceinfo', 'addusergroup', 'listusergroups', 'removeusergroup', 'runcommand', 'shell', 'upload', 'download', 'deviceopenurl', 'devicemessage', 'devicetoast'];
if (args.proxy != null) { try { require('https-proxy-agent'); } catch (ex) { console.log('Missing module "https-proxy-agent", type "npm install https-proxy-agent" to install it.'); return; } }
if (args['_'].length == 0) {
console.log("MeshCtrl performs command line actions on a MeshCentral server.");
console.log("Information at: https://meshcommander.com/meshcentral");
console.log("No action specified, use MeshCtrl like this:\r\n\r\n meshctrl [action] [arguments]\r\n");
console.log("Supported actions:");
console.log(" Help [action] - Get help on an action.");
console.log(" ServerInfo - Show server information.");
console.log(" UserInfo - Show user information.");
console.log(" ListUsers - List user accounts.");
console.log(" ListUserSessions - List online users.");
console.log(" ListUserGroups - List user groups.");
console.log(" ListDevices - List devices.");
console.log(" ListDeviceGroups - List device groups.");
console.log(" ListUsersOfDeviceGroup - List the users in a device group.");
console.log(" DeviceInfo - Show information about a device.");
console.log(" Config - Perform operation on config.json file.");
console.log(" AddUser - Create a new user account.");
console.log(" RemoveUser - Delete a user account.");
console.log(" AddUserGroup - Create a new user group.");
console.log(" RemoveUserGroup - Delete a user group.");
console.log(" AddDeviceGroup - Create a new device group.");
console.log(" RemoveDeviceGroup - Delete a device group.");
console.log(" EditDeviceGroup - Change a device group values.");
console.log(" MoveToDeviceGroup - Move a device to a different device group.");
console.log(" AddUserToDeviceGroup - Add a user to a device group.");
console.log(" RemoveUserFromDeviceGroup - Remove a user from a device group.");
console.log(" AddUserToDevice - Add a user to a device.");
console.log(" RemoveUserFromDevice - Remove a user from a device.");
console.log(" SendInviteEmail - Send an agent install invitation email.");
console.log(" GenerateInviteLink - Create an invitation link.");
console.log(" Broadcast - Display a message to all online users.");
console.log(" ShowEvents - Display real-time server events in JSON format.");
console.log(" RunCommand - Run a shell command on a remote device.");
console.log(" Shell - Access command shell of a remote device.");
console.log(" Upload - Upload a file to a remote device.");
console.log(" Download - Download a file from a remote device.");
console.log(" DeviceOpenUrl - Open a URL on a remote device.");
console.log(" DeviceMessage - Open a message box on a remote device.");
console.log(" DeviceToast - Display a toast notification on a remote device.");
console.log("\r\nSupported login arguments:");
console.log(" --url [wss://server] - Server url, wss://localhost:443 is default.");
console.log(" --loginuser [username] - Login username, admin is default.");
console.log(" --loginpass [password] - Login password.");
console.log(" --token [number] - 2nd factor authentication token.");
console.log(" --loginkey [hex] - Server login key in hex.");
console.log(" --loginkeyfile [file] - File containing server login key in hex.");
console.log(" --logindomain [domainid] - Domain id, default is empty, only used with loginkey.");
console.log(" --proxy [http://proxy:1] - Specify an HTTP proxy.");
return;
} else {
settings.cmd = args['_'][0].toLowerCase();
if ((possibleCommands.indexOf(settings.cmd) == -1) && (settings.cmd != 'help')) { console.log("Invalid command. Possible commands are: " + possibleCommands.join(', ') + '.'); return; }
//console.log(settings.cmd);
var ok = false;
switch (settings.cmd) {
case 'config': { performConfigOperations(args); return; }
case 'serverinfo': { ok = true; break; }
case 'userinfo': { ok = true; break; }
case 'listusers': { ok = true; break; }
case 'listusersessions': { ok = true; break; }
case 'listusergroups': { ok = true; break; }
case 'listdevicegroups': { ok = true; break; }
case 'listdevices': { ok = true; break; }
case 'listusersofdevicegroup': {
if (args.id == null) { console.log(winRemoveSingleQuotes("Missing group id, use --id '[groupid]'")); }
else { ok = true; }
break;
}
case 'deviceinfo': {
if (args.id == null) { console.log(winRemoveSingleQuotes("Missing device id, use --id '[deviceid]'")); }
else { ok = true; }
break;
}
case 'addusertodevicegroup': {
if ((args.id == null) && (args.group == null)) { console.log(winRemoveSingleQuotes("Device group identifier missing, use --id '[groupid]' or --group [groupname]")); }
else if (args.userid == null) { console.log("Add user to group missing useid, use --userid [userid]"); }
else { ok = true; }
break;
}
case 'removeuserfromdevicegroup': {
if ((args.id == null) && (args.group == null)) { console.log(winRemoveSingleQuotes("Device group identifier missing, use --id '[groupid]' or --group [groupname]")); }
else if (args.userid == null) { console.log("Remove user from group missing useid, use --userid [userid]"); }
else { ok = true; }
break;
}
case 'addusertodevice': {
if (args.userid == null) { console.log("Add user to device missing userid, use --userid [userid]"); }
else if (args.id == null) { console.log(winRemoveSingleQuotes("Add user to device missing device id, use --id '[deviceid]'")); }
else { ok = true; }
break;
}
case 'removeuserfromdevice': {
if (args.userid == null) { console.log("Remove user from device missing userid, use --userid [userid]"); }
else if (args.id == null) { console.log(winRemoveSingleQuotes("Remove user from device missing device id, use --id '[deviceid]'")); }
else { ok = true; }
break;
}
case 'adddevicegroup': {
if (args.name == null) { console.log("Message group name, use --name [name]"); }
else { ok = true; }
break;
}
case 'editdevicegroup':
case 'removedevicegroup': {
if ((args.id == null) && (args.group == null)) { console.log(winRemoveSingleQuotes("Device group identifier missing, use --id '[groupid]' or --group [groupname]")); }
else { ok = true; }
break;
}
case 'movetodevicegroup': {
if ((args.id == null) && (args.group == null)) { console.log(winRemoveSingleQuotes("Device group identifier missing, use --id '[groupid]' or --group [groupname]")); }
else if (args.devid == null) { console.log(winRemoveSingleQuotes("Device identifier missing, use --devid '[deviceid]'")); }
else { ok = true; }
break;
}
case 'broadcast': {
if (args.msg == null) { console.log("Message missing, use --msg [message]"); }
else { ok = true; }
break;
}
case 'showevents': {
ok = true;
break;
}
case 'adduser': {
if (args.user == null) { console.log("New account name missing, use --user [name]"); }
else if ((args.pass == null) && (args.randompass == null)) { console.log("New account password missing, use --pass [password] or --randompass"); }
else { ok = true; }
break;
}
case 'removeuser': {
if (args.userid == null) { console.log("Remove account userid missing, use --userid [id]"); }
else { ok = true; }
break;
}
case 'addusergroup': {
if (args.name == null) { console.log("New user group name missing, use --name [name]"); }
else { ok = true; }
break;
}
case 'removeusergroup': {
if (args.groupid == null) { console.log(winRemoveSingleQuotes("Remove user group id missing, use --groupid '[id]'")); }
else { ok = true; }
break;
}
case 'sendinviteemail': {
if ((args.id == null) && (args.group == null)) { console.log("Device group identifier missing, use --id '[groupid]' or --group [groupname]"); }
else if (args.email == null) { console.log("Device email is missing, use --email [email]"); }
else { ok = true; }
break;
}
case 'generateinvitelink': {
if ((args.id == null) && (args.group == null)) { console.log("Device group identifier missing, use --id '[groupid]' or --group [groupname]"); }
else if (args.hours == null) { console.log("Invitation validity period missing, use --hours [hours]"); }
else { ok = true; }
break;
}
case 'runcommand': {
if (args.id == null) { console.log(winRemoveSingleQuotes("Missing device id, use --id '[deviceid]'")); }
else if (args.run == null) { console.log("Missing run, use --run \"command\""); }
else { ok = true; }
break;
}
case 'shell': {
if (args.id == null) { console.log(winRemoveSingleQuotes("Missing device id, use --id '[deviceid]'")); }
else { ok = true; }
break;
}
case 'upload': {
if (args.id == null) { console.log(winRemoveSingleQuotes("Missing device id, use --id '[deviceid]'")); }
else if (args.file == null) { console.log("Local file missing, use --file [file] specify the file to upload"); }
else if (args.target == null) { console.log("Remote target path missing, use --target [path] to specify the remote location"); }
else if (require('fs').existsSync(args.file) == false) { console.log("Local file does not exists, check --file"); }
else { ok = true; }
break;
}
case 'download': {
if (args.id == null) { console.log(winRemoveSingleQuotes("Missing device id, use --id '[deviceid]'")); }
else if (args.file == null) { console.log("Remote file missing, use --file [file] specify the remote file to download"); }
else if (args.target == null) { console.log("Target path missing, use --target [path] to specify the local download location"); }
else { ok = true; }
break;
}
case 'deviceopenurl': {
if (args.id == null) { console.log(winRemoveSingleQuotes("Missing device id, use --id '[deviceid]'")); }
else if (args.openurl == null) { console.log("Remote URL, use --openurl [url] specify the link to open."); }
else { ok = true; }
break;
}
case 'devicemessage': {
if (args.id == null) { console.log(winRemoveSingleQuotes("Missing device id, use --id '[deviceid]'")); }
else if (args.msg == null) { console.log("Remote message, use --msg \"[message]\" specify a remote message."); }
else { ok = true; }
break;
}
case 'devicetoast': {
if (args.id == null) { console.log(winRemoveSingleQuotes("Missing device id, use --id '[deviceid]'")); }
else if (args.msg == null) { console.log("Remote message, use --msg \"[message]\" specify a remote message."); }
else { ok = true; }
break;
}
case 'help': {
if (args['_'].length < 2) {
console.log("Get help on an action. Type:\r\n\r\n help [action]\r\n\r\nPossible actions are: " + possibleCommands.join(', ') + '.');
} else {
switch (args['_'][1].toLowerCase()) {
case 'config': {
displayConfigHelp();
break;
}
case 'sendinviteemail': {
console.log("Send invitation email with instructions on how to install the mesh agent for a specific device group. Example usage:\r\n");
console.log(winRemoveSingleQuotes(" MeshCtrl SendInviteEmail --id 'groupid' --message \"msg\" --email user@sample.com"));
console.log(winRemoveSingleQuotes(" MeshCtrl SendInviteEmail --group \"My Computers\" --name \"Jack\" --email user@sample.com"));
console.log("\r\nRequired arguments:\r\n");
if (process.platform == 'win32') {
console.log(" --id [groupid] - Device group identifier (or --group).");
} else {
console.log(" --id '[groupid]' - Device group identifier (or --group).");
}
console.log(" --group [groupname] - Device group name (or --id).");
console.log(" --email [email] - Email address.");
console.log("\r\nOptional arguments:\r\n");
console.log(" --name (name) - Name of recipient to be included in the email.");
console.log(" --message (msg) - Message to be included in the email.");
break;
}
case 'generateinvitelink': {
console.log("Generate a agent invitation URL for a given group. Example usage:\r\n");
console.log(winRemoveSingleQuotes(" MeshCtrl GenerateInviteLink --id 'groupid' --hours 24"));
console.log(" MeshCtrl GenerateInviteLink --group \"My Computers\" --hours 0");
console.log("\r\nRequired arguments:\r\n");
if (process.platform == 'win32') {
console.log(" --id [groupid] - Device group identifier (or --group).");
} else {
console.log(" --id '[groupid]' - Device group identifier (or --group).");
}
console.log(" --group [groupname] - Device group name (or --id).");
console.log(" --hours [hours] - Validity period in hours or 0 for infinit.");
break;
}
case 'serverinfo': {
console.log("Get information on the MeshCentral server, Example usages:\r\n");
console.log(" MeshCtrl ServerInfo --loginuser myaccountname --loginpass mypassword");
console.log(" MeshCtrl ServerInfo --loginuser myaccountname --loginkeyfile key.txt");
console.log("\r\nOptional arguments:\r\n");
console.log(" --json - Show result as JSON.");
break;
}
case 'userinfo': {
console.log("Get account information for the login account, Example usages:\r\n");
console.log(" MeshCtrl UserInfo --loginuser myaccountname --loginpass mypassword");
console.log(" MeshCtrl UserInfo --loginuser myaccountname --loginkeyfile key.txt");
console.log("\r\nOptional arguments:\r\n");
console.log(" --json - Show result as JSON.");
break;
}
case 'listusers': {
console.log("List the account on the MeshCentral server, Example usages:\r\n");
console.log(" MeshCtrl ListUsers");
console.log(" MeshCtrl ListUsers --json");
console.log(" MeshCtrl ListUsers --nameexists \"bob\"");
console.log(" MeshCtrl ListUsers --filter 2fa");
console.log("\r\nOptional arguments:\r\n");
console.log(" --idexists [id] - Return 1 if id exists, 0 if not.");
console.log(" --nameexists [name] - Return id if name exists.");
console.log(" --filter [filter1,...] - Filter user names: 2FA, NO2FA.");
console.log(" --json - Show result as JSON.");
break;
}
case 'listusersessions': {
console.log("List active user sessions on the MeshCentral server, Example usages:\r\n");
console.log(" MeshCtrl ListUserSessions");
console.log(" MeshCtrl ListUserSessions --json");
break;
}
case 'listusergroups': {
console.log("List user groups on the MeshCentral server, Example usages:\r\n");
console.log(" MeshCtrl ListUserGroups");
console.log(" MeshCtrl ListUserGroups --json");
break;
}
case 'listdevicegroups': {
console.log("List the device groups for this account, Example usages:\r\n");
console.log(" MeshCtrl ListDeviceGroups ");
console.log(" MeshCtrl ListDeviceGroups --json");
console.log("\r\nOptional arguments:\r\n");
console.log(" --idexists [id] - Return 1 if id exists, 0 if not.");
console.log(" --nameexists [name] - Return id if name exists.");
console.log(" --emailexists [email] - Return id if email exists.");
console.log(" --hex - Display meshid in hex format.");
console.log(" --json - Show result as JSON.");
break;
}
case 'listdevices': {
console.log("List devices, Example usages:\r\n");
console.log(" MeshCtrl ListDevices");
console.log(winRemoveSingleQuotes(" MeshCtrl ListDevices -id '[groupid]' --json"));
console.log("\r\nOptional arguments:\r\n");
if (process.platform == 'win32') {
console.log(" --id [groupid] - Filter by group identifier (or --group).");
} else {
console.log(" --id '[groupid]' - Filter by group identifier (or --group).");
}
console.log(" --group [groupname] - Filter by group name (or --id).");
console.log(" --count - Only return the device count.");
console.log(" --json - Show result as JSON.");
break;
}
case 'listusersofdevicegroup': {
console.log("List users that have permissions for a given device group, Example usage:\r\n");
console.log(" MeshCtrl ListUserOfDeviceGroup ");
console.log("\r\nRequired arguments:\r\n");
if (process.platform == 'win32') {
console.log(" --id [groupid] - Device group identifier.");
} else {
console.log(" --id '[groupid]' - Device group identifier.");
}
console.log("\r\nOptional arguments:\r\n");
console.log(" --json - Show result as JSON.");
break;
}
case 'adduser': {
console.log("Add a new user account, Example usages:\r\n");
console.log(" MeshCtrl AddUser --user newaccountname --pass newpassword");
console.log("\r\nRequired arguments:\r\n");
console.log(" --user [name] - New account name.");
console.log(" --pass [password] - New account password.");
console.log(" --randompass - Create account with a random password.");
console.log("\r\nOptional arguments:\r\n");
console.log(" --email [email] - New account email address.");
console.log(" --emailverified - New account email is verified.");
console.log(" --resetpass - Request password reset on next login.");
console.log(" --siteadmin - Create the account as full site administrator.");
console.log(" --manageusers - Allow this account to manage server users.");
console.log(" --fileaccess - Allow this account to store server files.");
console.log(" --serverupdate - Allow this account to update the server.");
console.log(" --locked - This account will be locked.");
console.log(" --nonewgroups - Account will not be allowed to create device groups.");
console.log(" --notools - Account not see MeshCMD download links.");
console.log(" --domain [domain] - Account domain, only for cross-domain admins.");
break;
}
case 'removeuser': {
console.log("Delete a user account, Example usages:\r\n");
console.log(" MeshCtrl RemoveUser --userid accountid");
console.log("\r\nRequired arguments:\r\n");
console.log(" --userid [id] - Account identifier.");
break;
}
case 'adddevicegroup': {
console.log("Add a device group, Example usages:\r\n");
console.log(" MeshCtrl AddDeviceGroup --name newgroupname");
console.log(" MeshCtrl AddDeviceGroup --name newgroupname --desc description --amtonly");
console.log("\r\nRequired arguments:\r\n");
console.log(" --name [name] - Name of the new group.");
console.log("\r\nOptional arguments:\r\n");
console.log(" --desc [description] - New group description.");
console.log(" --amtonly - New group is agent-less, Intel AMT only.");
break;
}
case 'removedevicegroup': {
console.log("Remove a device group, Example usages:\r\n");
console.log(winRemoveSingleQuotes(" MeshCtrl RemoveDeviceGroup --id 'groupid'"));
console.log("\r\nRequired arguments:\r\n");
if (process.platform == 'win32') {
console.log(" --id [groupid] - Device group identifier (or --group).");
} else {
console.log(" --id '[groupid]' - Device group identifier (or --group).");
}
console.log(" --group [groupname] - Device group name (or --id).");
break;
}
case 'editdevicegroup': {
console.log("Edit a device group, Example usages:\r\n");
console.log(winRemoveSingleQuotes(" MeshCtrl EditDeviceGroup --id 'groupid' --name \"New Name\""));
console.log(winRemoveSingleQuotes(" MeshCtrl EditDeviceGroup --id 'groupid' --desc \"Description\" --consent 63"));
console.log(winRemoveSingleQuotes(" MeshCtrl EditDeviceGroup --id 'groupid' --invitecodes \"code1,code2\" --backgroundonly"));
console.log("\r\nRequired arguments:\r\n");
if (process.platform == 'win32') {
console.log(" --id [groupid] - Device group identifier (or --group).");
} else {
console.log(" --id '[groupid]' - Device group identifier (or --group).");
}
console.log(" --group [groupname] - Device group name (or --id).");
console.log("\r\nOptional arguments:\r\n");
console.log(" --name [name] - Set new device group name.");
console.log(" --desc [description] - Set new device group description, blank to clear.");
console.log(" --flags [number] - Set device group flags, sum of the values below, 0 for none.");
console.log(" 1 = Auto remove device on disconnect.");
console.log(" 2 = Sync hostname.");
console.log(" --consent [number] - Set device group consent options, sum of the values below, 0 for none.");
console.log(" 1 = Desktop notify user.");
console.log(" 2 = Terminal notify user.");
console.log(" 4 = Files notify user.");
console.log(" 8 = Desktop prompt for user consent.");
console.log(" 16 = Terminal prompt for user consent.");
console.log(" 32 = Files prompt for user consent.");
console.log(" 64 = Desktop show connection toolbar.");
console.log(" --invitecodes [aa,bb] - Comma seperated list of invite codes, blank to clear.");
console.log(" --backgroundonly - When used with invitecodes, set agent to only install in background.");
console.log(" --interactiveonly - When used with invitecodes, set agent to only run on demand.");
break;
}
case 'movetodevicegroup': {
console.log("Move a device to a new device group, Example usages:\r\n");
console.log(winRemoveSingleQuotes(" MeshCtrl MoveToDeviceGroup --devid 'deviceid' --id 'groupid'"));
console.log("\r\nRequired arguments:\r\n");
if (process.platform == 'win32') {
console.log(" --id [groupid] - Device group identifier (or --group).");
} else {
console.log(" --id '[groupid]' - Device group identifier (or --group).");
}
console.log(" --group [groupname] - Device group name (or --id).");
if (process.platform == 'win32') {
console.log(" --devid [deviceid] - Device identifier.");
} else {
console.log(" --devid '[deviceid]' - Device identifier.");
}
break;
}
case 'addusertodevicegroup': {
console.log("Add a user to a device group, Example usages:\r\n");
console.log(winRemoveSingleQuotes(" MeshCtrl AddUserToDeviceGroup --id 'groupid' --userid userid --fullrights"));
console.log(" MeshCtrl AddUserToDeviceGroup --group groupname --userid userid --editgroup --manageusers");
console.log("\r\nRequired arguments:\r\n");
if (process.platform == 'win32') {
console.log(" --id [groupid] - Device group identifier (or --group).");
} else {
console.log(" --id '[groupid]' - Device group identifier (or --group).");
}
console.log(" --group [groupname] - Device group name (or --id).");
console.log(" --userid [userid] - The user identifier.");
console.log("\r\nOptional arguments:\r\n");
console.log(" --fullrights - Allow full rights over this device group.");
console.log(" --editgroup - Allow the user to edit group information.");
console.log(" --manageusers - Allow the user to add/remove users.");
console.log(" --managedevices - Allow the user to edit device information.");
console.log(" --remotecontrol - Allow device remote control operations.");
console.log(" --agentconsole - Allow agent console operations.");
console.log(" --serverfiles - Allow access to group server files.");
console.log(" --wakedevices - Allow device wake operation.");
console.log(" --notes - Allow editing of device notes.");
console.log(" --desktopviewonly - Restrict user to view-only remote desktop.");
console.log(" --limiteddesktop - Limit remote desktop keys.");
console.log(" --noterminal - Hide the terminal tab from this user.");
console.log(" --nofiles - Hide the files tab from this user.");
console.log(" --noamt - Hide the Intel AMT tab from this user.");
console.log(" --limitedevents - User can only see his own events.");
console.log(" --chatnotify - Allow chat and notification options.");
console.log(" --uninstall - Allow remote uninstall of the agent.");
if (args.limiteddesktop) { meshrights |= 4096; }
if (args.limitedevents) { meshrights |= 8192; }
if (args.chatnotify) { meshrights |= 16384; }
if (args.uninstall) { meshrights |= 32768; }
break;
}
case 'removeuserfromdevicegroup': {
console.log("Remove a user from a device group, Example usages:\r\n");
console.log(winRemoveSingleQuotes(" MeshCtrl RemoveuserFromDeviceGroup --id 'groupid' --userid userid"));
console.log("\r\nRequired arguments:\r\n");
if (process.platform == 'win32') {
console.log(" --id [groupid] - Device group identifier (or --group).");
} else {
console.log(" --id '[groupid]' - Device group identifier (or --group).");
}
console.log(" --group [groupname] - Device group name (or --id).");
console.log(" --userid [userid] - The user identifier.");
break;
}
case 'addusertodevice': {
console.log("Add a user to a device, Example usages:\r\n");
console.log(winRemoveSingleQuotes(" MeshCtrl AddUserToDevice --id 'deviceid' --userid userid --fullrights"));
console.log(winRemoveSingleQuotes(" MeshCtrl AddUserToDevice --id 'deviceid' --userid userid --remotecontrol"));
console.log("\r\nRequired arguments:\r\n");
if (process.platform == 'win32') {
console.log(" --id [deviceid] - The device identifier.");
} else {
console.log(" --id '[deviceid]' - The device identifier.");
}
console.log(" --userid [userid] - The user identifier.");
console.log("\r\nOptional arguments:\r\n");
console.log(" --fullrights - Allow full rights over this device.");
console.log(" --remotecontrol - Allow device remote control operations.");
console.log(" --agentconsole - Allow agent console operations.");
console.log(" --serverfiles - Allow access to group server files.");
console.log(" --wakedevices - Allow device wake operation.");
console.log(" --notes - Allow editing of device notes.");
console.log(" --desktopviewonly - Restrict user to view-only remote desktop.");
console.log(" --limiteddesktop - Limit remote desktop keys.");
console.log(" --noterminal - Hide the terminal tab from this user.");
console.log(" --nofiles - Hide the files tab from this user.");
console.log(" --noamt - Hide the Intel AMT tab from this user.");
console.log(" --limitedevents - User can only see his own events.");
console.log(" --chatnotify - Allow chat and notification options.");
console.log(" --uninstall - Allow remote uninstall of the agent.");
break;
}
case 'removeuserfromdevice': {
console.log("Remove a user from a device, Example usages:\r\n");
console.log(winRemoveSingleQuotes(" MeshCtrl RemoveuserFromDeviceGroup --id 'deviceid' --userid userid"));
console.log("\r\nRequired arguments:\r\n");
if (process.platform == 'win32') {
console.log(" --id [deviceid] - The device identifier.");
} else {
console.log(" --id '[deviceid]' - The device identifier.");
}
console.log(" --userid [userid] - The user identifier.");
break;
}
case 'broadcast': {
console.log("Display a message to all logged in users, Example usages:\r\n");
console.log(" MeshCtrl Broadcast --msg \"This is a test\"");
console.log("\r\nRequired arguments:\r\n");
console.log(" --msg [message] - Message to display.");
break;
}
case 'deviceinfo': {
console.log("Display information about a device, Example usages:\r\n");
console.log(winRemoveSingleQuotes(" MeshCtrl DeviceInfo --id 'deviceid'"));
console.log(winRemoveSingleQuotes(" MeshCtrl DeviceInfo --id 'deviceid' --json"));
console.log("\r\nRequired arguments:\r\n");
if (process.platform == 'win32') {
console.log(" --id [deviceid] - The device identifier.");
} else {
console.log(" --id '[deviceid]' - The device identifier.");
}
console.log("\r\nOptional arguments:\r\n");
console.log(" --raw - Output raw data in JSON format.");
console.log(" --json - Give results in JSON format.");
break;
}
case 'runcommand': {
console.log("Run a shell command on a remote device, Example usages:\r\n");
console.log(winRemoveSingleQuotes(" MeshCtrl RunCommand --id 'deviceid' --run \"command\""));
console.log(winRemoveSingleQuotes(" MeshCtrl RunCommand --id 'deviceid' --run \"command\" --powershell"));
console.log("\r\nRequired arguments:\r\n");
if (process.platform == 'win32') {
console.log(" --id [deviceid] - The device identifier.");
} else {
console.log(" --id '[deviceid]' - The device identifier.");
}
console.log(" --run \"[command]\" - Shell command to execute on the remote device.");
console.log("\r\nOptional arguments:\r\n");
console.log(" --powershell - Run in Windows PowerShell.");
break;
}
case 'shell': {
console.log("Access a command shell on a remote device, Example usages:\r\n");
console.log(winRemoveSingleQuotes(" MeshCtrl Shell --id 'deviceid'"));
console.log(winRemoveSingleQuotes(" MeshCtrl Shell --id 'deviceid' --powershell"));
console.log("\r\nRequired arguments:\r\n");
if (process.platform == 'win32') {
console.log(" --id [deviceid] - The device identifier.");
} else {
console.log(" --id '[deviceid]' - The device identifier.");
}
console.log("\r\nOptional arguments:\r\n");
console.log(" --powershell - Run a Windows PowerShell.");
break;
}
case 'upload': {
console.log("Upload a local file to a remote device, Example usages:\r\n");
console.log(winRemoveSingleQuotes(" MeshCtrl Upload --id 'deviceid' --file sample.txt --target c:\\"));
console.log(winRemoveSingleQuotes(" MeshCtrl Upload --id 'deviceid' --file sample.txt --target /tmp"));
console.log("\r\nRequired arguments:\r\n");
if (process.platform == 'win32') {
console.log(" --id [deviceid] - The device identifier.");
} else {
console.log(" --id '[deviceid]' - The device identifier.");
}
console.log(" --file [localfile] - The local file to upload.");
console.log(" --target [remotepath] - The remote path to upload the file to.");
break;
}
case 'download': {
console.log("Download a file from a remote device, Example usages:\r\n");
console.log(winRemoveSingleQuotes(" MeshCtrl Download --id 'deviceid' --file C:\\sample.txt --target c:\\temp"));
console.log(winRemoveSingleQuotes(" MeshCtrl Download --id 'deviceid' --file /tmp/sample.txt --target /tmp"));
console.log("\r\nRequired arguments:\r\n");
if (process.platform == 'win32') {
console.log(" --id [deviceid] - The device identifier.");
} else {
console.log(" --id '[deviceid]' - The device identifier.");
}
console.log(" --file [remotefile] - The remote file to download.");
console.log("\r\nOptional arguments:\r\n");
console.log(" --target [localpath] - The local path to download the file to.");
break;
}
case 'deviceopenurl': {
console.log("Open a web page on a remote device, Example usages:\r\n");
console.log(winRemoveSingleQuotes(" MeshCtrl DeviceOpenUrl --id 'deviceid' --openurl http://meshcentral.com"));
console.log("\r\nRequired arguments:\r\n");
if (process.platform == 'win32') {
console.log(" --id [deviceid] - The device identifier.");
} else {
console.log(" --id '[deviceid]' - The device identifier.");
}
console.log(" --openurl [url] - Link to the web page.");
break;
}
case 'devicemessage': {
console.log("Display a message on the remote device, Example usages:\r\n");
console.log(winRemoveSingleQuotes(" MeshCtrl DeviceMessage --id 'deviceid' --msg \"message\""));
console.log(winRemoveSingleQuotes(" MeshCtrl DeviceMessage --id 'deviceid' --msg \"message\" --title \"title\""));
console.log("\r\nRequired arguments:\r\n");
if (process.platform == 'win32') {
console.log(" --id [deviceid] - The device identifier.");
} else {
console.log(" --id '[deviceid]' - The device identifier.");
}
console.log(" --msg [message] - The message to display.");
console.log("\r\nOptional arguments:\r\n");
console.log(" --title [title] - Messagebox title, default is \"MeshCentral\".");
break;
}
case 'devicetoast': {
console.log("Display a toast message on the remote device, Example usages:\r\n");
console.log(winRemoveSingleQuotes(" MeshCtrl DeviceToast --id 'deviceid' --msg \"message\""));
console.log(winRemoveSingleQuotes(" MeshCtrl DeviceToast --id 'deviceid' --msg \"message\" --title \"title\""));
console.log("\r\nRequired arguments:\r\n");
if (process.platform == 'win32') {
console.log(" --id [deviceid] - The device identifier.");
} else {
console.log(" --id '[deviceid]' - The device identifier.");
}
console.log(" --msg [message] - The message to display.");
console.log("\r\nOptional arguments:\r\n");
console.log(" --title [title] - Toast title, default is \"MeshCentral\".");
break;
}
default: {
console.log("Get help on an action. Type:\r\n\r\n help [action]\r\n\r\nPossible actions are: " + possibleCommands.join(', ') + '.');
}
}
}
break;
}
}
if (ok) { serverConnect(); }
}
function displayConfigHelp() {
console.log("Perform operations on the config.json file. Example usage:\r\n");
console.log(" MeshCtrl config --show");
console.log("\r\nOptional arguments:\r\n");
console.log(" --show - Display the config.json file.");
console.log(" --listdomains - Display non-default domains.");
console.log(" --adddomain [domain] - Add a domain.");
console.log(" --removedomain [domain] - Remove a domain.");
console.log(" --settodomain [domain] - Set values to the domain.");
console.log(" --removefromdomain [domain] - Remove values from the domain.");
console.log("\r\nWith adddomain, removedomain, settodomain and removefromdomain you can add the key and value pair. For example:\r\n");
console.log(" --adddomain \"MyDomain\" --title \"My Server Name\" --newAccounts false");
console.log(" --settodomain \"MyDomain\" --title \"My Server Name\"");
console.log(" --removefromdomain \"MyDomain\" --title");
}
function performConfigOperations(args) {
var domainValues = ['title', 'title2', 'titlepicture', 'trustedcert', 'welcomepicture', 'welcometext', 'userquota', 'meshquota', 'newaccounts', 'usernameisemail', 'newaccountemaildomains', 'newaccountspass', 'newaccountsrights', 'geolocation', 'lockagentdownload', 'userconsentflags', 'Usersessionidletimeout', 'auth', 'ldapoptions', 'ldapusername', 'ldapuserbinarykey', 'ldapuseremail', 'footer', 'certurl', 'loginKey', 'userallowedip', 'agentallowedip', 'agentnoproxy', 'agentconfig', 'orphanagentuser', 'httpheaders', 'yubikey', 'passwordrequirements', 'limits', 'amtacmactivation', 'redirects', 'sessionrecording', 'hide', 'loginkey'];
var domainObjectValues = [ 'ldapoptions', 'httpheaders', 'yubikey', 'passwordrequirements', 'limits', 'amtacmactivation', 'redirects', 'sessionrecording' ];
var domainArrayValues = [ 'newaccountemaildomains', 'newaccountsrights', 'loginkey', 'agentconfig' ];
var configChange = false;
var fs = require('fs');
var path = require('path');
var configFile = 'config.json';
var didSomething = 0;
if (fs.existsSync(configFile) == false) { configFile = path.join('meshcentral-data', 'config.json'); }
if (fs.existsSync(configFile) == false) { configFile = path.join(__dirname, 'config.json'); }
if (fs.existsSync(configFile) == false) { configFile = path.join(__dirname, 'meshcentral-data', 'config.json'); }
if (fs.existsSync(configFile) == false) { configFile = path.join(__dirname, '..', 'meshcentral-data', 'config.json'); }
if (fs.existsSync(configFile) == false) { configFile = path.join(__dirname, '..', '..', 'meshcentral-data', 'config.json'); }
if (fs.existsSync(configFile) == false) { console.log("Unable to find config.json."); return; }
var config = null;
try { config = fs.readFileSync(configFile).toString('utf8'); } catch (ex) { console.log("Error: Unable to read config.json"); return; }
try { config = require(configFile); } catch (e) { console.log('ERROR: Unable to parse ' + configFilePath + '.'); return null; }
if (args.adddomain != null) {
didSomething++;
if (config.domains == null) { config.domains = {}; }
if (config.domains[args.adddomain] != null) { console.log("Error: Domain \"" + args.adddomain + "\" already exists"); }
else {
configChange = true;
config.domains[args.adddomain] = {};
for (var i in args) {
if (domainValues.indexOf(i.toLowerCase()) >= 0) {
if (args[i] == 'true') { args[i] = true; } else if (args[i] == 'false') { args[i] = false; } else if (parseInt(args[i]) == args[i]) { args[i] = parseInt(args[i]); }
config.domains[args.adddomain][i] = arg