Compare commits

...

70 Commits

Author SHA1 Message Date
wh1te909
b5603a5233 Release 0.6.0 2021-04-15 05:39:24 +00:00
wh1te909
73890f553c bump versions 2021-04-15 05:34:47 +00:00
sadnub
f6243b8968 update community script to include guid and update/delete existing community scripts 2021-04-14 22:43:12 -04:00
sadnub
3770dc74d4 fix scripts dropdown 2021-04-14 21:48:39 -04:00
wh1te909
45f4e947c5 more code signing stuff 2021-04-15 01:24:58 +00:00
Dan
9928d7c6e1 Merge pull request #394 from tremor021/develop
Fixed script naming scheme
2021-04-14 18:20:31 -07:00
tremor021
ae7c0e9195 update 2021-04-14 15:53:54 +02:00
tremor021
e90b640602 Merge branch 'develop' of https://github.com/wh1te909/tacticalrmm into develop 2021-04-14 15:48:37 +02:00
tremor021
ba7529d3f5 update 2021-04-14 15:30:57 +02:00
tremor021
34667f252e Fixed naming and added task scheduling script 2021-04-14 15:23:22 +02:00
wh1te909
d18bddcb7b add code signing auth token 2021-04-14 07:49:28 +00:00
wh1te909
96dff49d33 add better exception messages to tests 2021-04-14 07:39:17 +00:00
Dan
b389728338 Merge pull request #392 from tremor021/develop
Scripts update
2021-04-14 00:35:20 -07:00
tremor021
cdc7da86f3 Fixes 2021-04-14 09:26:42 +02:00
tremor021
4745cc0378 Fixes 2021-04-14 09:25:26 +02:00
wh1te909
434f132479 add a test to make sure community script has jsonfile entry 2021-04-14 07:05:08 +00:00
tremor021
fb0f31ffc7 Added script to json 2021-04-14 08:55:17 +02:00
Dan
bb1d73c0ae Merge pull request #393 from silversword411/develop
Script library additions
2021-04-13 23:32:33 -07:00
silversword411
0e823d1191 Fixing bitlocker get recovery keys script 2021-04-14 00:40:26 -04:00
silversword411
48f4199ff3 script library - bitlocker get recovery keys 2021-04-14 00:39:20 -04:00
silversword411
eaf379587b script library - disable hibernation 2021-04-14 00:04:43 -04:00
silversword411
672446b7d1 script library check if user using temp profile 2021-04-13 23:52:04 -04:00
silversword411
dfe52c1b07 script library - task scheduler monitor 2021-04-13 23:48:15 -04:00
silversword411
d63df03ad8 script library - new user notify 2021-04-13 23:42:34 -04:00
silversword411
aba4f9f2ce script library - Azure Mars Backup check 2021-04-13 23:37:05 -04:00
silversword411
ac5c1e7803 Script library - Adding enable and disable USB devices 2021-04-13 23:26:48 -04:00
tremor021
d521dbf50e Added more scripts 2021-04-13 23:39:44 +02:00
tremor021
f210ed3e6a Added Get_Computer_Users script 2021-04-13 23:25:10 +02:00
tremor021
df3cac4ea6 Merge branch 'develop' of https://github.com/wh1te909/tacticalrmm into develop 2021-04-13 22:14:14 +02:00
tremor021
f778c5175b Added some explanations into scripts 2021-04-13 22:10:37 +02:00
Dan
6c66ff28dd Merge pull request #385 from silversword411/develop
script library updates and docs tweak
2021-04-11 22:39:12 -07:00
silversword411
d5b6ec702b Merge branch 'develop' of https://github.com/silversword411/tacticalrmm into develop 2021-04-11 11:36:20 -04:00
silversword411
c62a5fcef2 script library empty recycle bin2 2021-04-11 11:35:53 -04:00
silversword411
59c47e9200 script library - empty recycle bin 2021-04-11 11:35:53 -04:00
silversword411
4ba44d8932 script library - Monitor info script 2021-04-11 11:35:53 -04:00
silversword411
27dae05e1b Script add - RAM status 2021-04-11 11:35:53 -04:00
silversword411
a251ae9b90 2 scripts added 2021-04-11 11:35:53 -04:00
silversword411
7e960b2bde Fixing Table of Contents levels 2021-04-11 11:35:53 -04:00
silversword411
5df4825158 Consistency check on script "name" field for alphabetic sorts 2021-04-11 11:35:53 -04:00
silversword411
8984d06d93 script library empty recycle bin2 2021-04-11 11:26:59 -04:00
silversword411
eed7aac047 script library - empty recycle bin 2021-04-11 11:26:22 -04:00
silversword411
54b068de4a script library - Monitor info script 2021-04-11 11:21:03 -04:00
silversword411
f0f33b00b6 Script add - RAM status 2021-04-11 09:13:47 -04:00
silversword411
1043405088 2 scripts added 2021-04-11 08:47:36 -04:00
silversword411
0131b10805 Fixing Table of Contents levels 2021-04-11 08:02:51 -04:00
silversword411
a19b441f62 Consistency check on script "name" field for alphabetic sorts 2021-04-11 07:58:03 -04:00
wh1te909
28edc31d43 Release 0.5.3 2021-04-11 08:08:58 +00:00
wh1te909
0f9872a818 bump versions 2021-04-11 08:08:48 +00:00
wh1te909
76ce4296f3 fix graphics 2021-04-11 07:25:37 +00:00
wh1te909
3dd2671380 add graphics 2021-04-11 06:50:16 +00:00
wh1te909
298ca31332 remove unused func 2021-04-11 05:43:17 +00:00
wh1te909
8f911aa6b9 more tests 2021-04-11 05:35:24 +00:00
wh1te909
82a5c7d9b1 add test 2021-04-11 05:17:49 +00:00
wh1te909
7f013dcdba refactor nats-api / optimize queries 2021-04-11 05:04:33 +00:00
wh1te909
68e2e16076 add feat #377 2021-04-11 03:23:40 +00:00
wh1te909
ea23c763c9 add feat #376 2021-04-11 02:01:40 +00:00
wh1te909
5dcecb3206 fix alert text for policy diskspace check where disk doesn't exist 2021-04-10 22:09:24 +00:00
Dan
5bd48e2d0e Merge pull request #380 from silversword411/develop
Community Script Additions
2021-04-10 13:36:26 -07:00
silversword411
afd0a02589 3 scripts added from dinger1986 2021-04-10 13:44:02 -04:00
silversword411
2379192d53 Merge branch 'develop' of https://github.com/silversword411/tacticalrmm into develop 2021-04-10 13:27:35 -04:00
silversword411
a6489290c8 2 scripts added 2021-04-10 13:26:39 -04:00
silversword411
5f74c43415 2 scripts added 2021-04-10 13:22:54 -04:00
wh1te909
aa8b84a302 Release 0.5.2 2021-04-09 18:30:30 +00:00
wh1te909
b987d041b0 bump version 2021-04-09 18:29:08 +00:00
wh1te909
b62e37307e revert meshcentral back to 0.7.93 2021-04-09 18:28:43 +00:00
Dan
61a59aa6ac Merge pull request #375 from silversword411/develop
scripts 4 adds and a rename
2021-04-09 00:09:17 -07:00
silversword411
f79ec27f1d Adding 5 new scripts 2021-04-09 01:05:58 -04:00
silversword411
b993fe380f Merge branch 'develop' of https://github.com/silversword411/tacticalrmm into develop 2021-04-09 00:40:24 -04:00
silversword411
d974b5f55f Script screenconnect rename 2021-04-09 00:38:22 -04:00
silversword411
1be6f8f87a Script screenconnect rename 2021-04-07 11:56:02 +00:00
69 changed files with 1520 additions and 215 deletions

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.2 on 2021-04-11 01:43
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0013_user_client_tree_sort'),
]
operations = [
migrations.AddField(
model_name='user',
name='client_tree_splitter',
field=models.PositiveIntegerField(default=11),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.2 on 2021-04-11 03:03
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0014_user_client_tree_splitter'),
]
operations = [
migrations.AddField(
model_name='user',
name='loading_bar_color',
field=models.CharField(default='red', max_length=255),
),
]

View File

@@ -36,6 +36,8 @@ class User(AbstractUser, BaseAuditModel):
client_tree_sort = models.CharField(
max_length=50, choices=CLIENT_TREE_SORT_CHOICES, default="alphafail"
)
client_tree_splitter = models.PositiveIntegerField(default=11)
loading_bar_color = models.CharField(max_length=255, default="red")
agent = models.OneToOneField(
"agents.Agent",

View File

@@ -13,6 +13,8 @@ class UserUISerializer(ModelSerializer):
"agent_dblclick_action",
"default_agent_tbl_tab",
"client_tree_sort",
"client_tree_splitter",
"loading_bar_color",
]

View File

@@ -278,6 +278,8 @@ class TestUserAction(TacticalTestCase):
"agent_dblclick_action": "editagent",
"default_agent_tbl_tab": "mixed",
"client_tree_sort": "alpha",
"client_tree_splitter": 14,
"loading_bar_color": "green",
}
r = self.client.patch(url, data, format="json")
self.assertEqual(r.status_code, 200)

View File

@@ -195,6 +195,27 @@ class Agent(BaseAuditModel):
except:
return ["unknown cpu model"]
@property
def graphics(self):
ret, mrda = [], []
try:
graphics = self.wmi_detail["graphics"]
for i in graphics:
caption = [x["Caption"] for x in i if "Caption" in x][0]
if "microsoft remote display adapter" in caption.lower():
mrda.append("yes")
continue
ret.append([x["Caption"] for x in i if "Caption" in x][0])
# only return this if no other graphics cards
if not ret and mrda:
return "Microsoft Remote Display Adapter"
return ", ".join(ret)
except:
return "Graphics info requires agent v1.4.14"
@property
def local_ips(self):
ret = []
@@ -322,7 +343,7 @@ class Agent(BaseAuditModel):
online = [
agent
for agent in Agent.objects.only(
"pk", "last_seen", "overdue_time", "offline_time"
"pk", "agent_id", "last_seen", "overdue_time", "offline_time"
)
if agent.status == "online"
]
@@ -819,12 +840,6 @@ class RecoveryAction(models.Model):
def __str__(self):
return f"{self.agent.hostname} - {self.mode}"
def send(self):
ret = {"recovery": self.mode}
if self.mode == "command":
ret["cmd"] = self.command
return ret
class Note(models.Model):
agent = models.ForeignKey(

View File

@@ -16,6 +16,7 @@ class AgentSerializer(serializers.ModelSerializer):
local_ips = serializers.ReadOnlyField()
make_model = serializers.ReadOnlyField()
physical_disks = serializers.ReadOnlyField()
graphics = serializers.ReadOnlyField()
checks = serializers.ReadOnlyField()
timezone = serializers.ReadOnlyField()
all_timezones = serializers.SerializerMethodField()

View File

@@ -1,9 +1,8 @@
import asyncio
import datetime as dt
import json
import random
import subprocess
import tempfile
import requests
import urllib.parse
from time import sleep
from typing import Union
@@ -13,21 +12,33 @@ from loguru import logger
from packaging import version as pyver
from agents.models import Agent
from core.models import CoreSettings
from core.models import CoreSettings, CodeSignToken
from logs.models import PendingAction
from scripts.models import Script
from tacticalrmm.celery import app
from tacticalrmm.utils import run_nats_api_cmd
logger.configure(**settings.LOG_CONFIG)
def agent_update(pk: int) -> str:
def _get_exegen_url() -> str:
urls: list[str] = settings.EXE_GEN_URLS
for url in urls:
try:
r = requests.get(url, timeout=10)
except:
continue
if r.status_code == 200:
return url
return random.choice(urls)
def agent_update(pk: int, codesigntoken: str = None) -> str:
agent = Agent.objects.get(pk=pk)
if pyver.parse(agent.version) <= pyver.parse("1.1.11"):
logger.warning(
f"{agent.hostname} v{agent.version} is running an unsupported version. Refusing to auto update."
)
if pyver.parse(agent.version) <= pyver.parse("1.3.0"):
return "not supported"
# skip if we can't determine the arch
@@ -37,18 +48,15 @@ def agent_update(pk: int) -> str:
)
return "noarch"
# removed sqlite in 1.4.0 to get rid of cgo dependency
# 1.3.0 has migration func to move from sqlite to win registry, so force an upgrade to 1.3.0 if old agent
if pyver.parse(agent.version) >= pyver.parse("1.3.0"):
version = settings.LATEST_AGENT_VER
url = agent.winagent_dl
inno = agent.win_inno_exe
version = settings.LATEST_AGENT_VER
inno = agent.win_inno_exe
if codesigntoken is not None and pyver.parse(version) >= pyver.parse("1.5.0"):
base_url = _get_exegen_url() + "/api/v1/winagents/?"
params = {"version": version, "arch": agent.arch, "token": codesigntoken}
url = base_url + urllib.parse.urlencode(params)
else:
version = "1.3.0"
inno = (
"winagent-v1.3.0.exe" if agent.arch == "64" else "winagent-v1.3.0-x86.exe"
)
url = f"https://github.com/wh1te909/rmmagent/releases/download/v1.3.0/{inno}"
url = agent.winagent_dl
if agent.pendingactions.filter(
action_type="agentupdate", status="pending"
@@ -81,10 +89,15 @@ def agent_update(pk: int) -> str:
@app.task
def send_agent_update_task(pks: list[int]) -> None:
try:
codesigntoken = CodeSignToken.objects.first().token
except:
codesigntoken = None
chunks = (pks[i : i + 30] for i in range(0, len(pks), 30))
for chunk in chunks:
for pk in chunk:
agent_update(pk)
agent_update(pk, codesigntoken)
sleep(0.05)
sleep(4)
@@ -95,6 +108,11 @@ def auto_self_agent_update_task() -> None:
if not core.agent_auto_update:
return
try:
codesigntoken = CodeSignToken.objects.first().token
except:
codesigntoken = None
q = Agent.objects.only("pk", "version")
pks: list[int] = [
i.pk
@@ -105,7 +123,7 @@ def auto_self_agent_update_task() -> None:
chunks = (pks[i : i + 30] for i in range(0, len(pks), 30))
for chunk in chunks:
for pk in chunk:
agent_update(pk)
agent_update(pk, codesigntoken)
sleep(0.05)
sleep(4)
@@ -257,30 +275,13 @@ def run_script_email_results_task(
logger.error(e)
def _get_nats_config() -> dict:
return {
"key": settings.SECRET_KEY,
"natsurl": f"tls://{settings.ALLOWED_HOSTS[0]}:4222",
}
@app.task
def monitor_agents_task() -> None:
agents = Agent.objects.only(
"pk", "agent_id", "last_seen", "overdue_time", "offline_time"
)
ret = [i.agent_id for i in agents if i.status != "online"]
config = _get_nats_config()
config["agents"] = ret
with tempfile.NamedTemporaryFile() as fp:
with open(fp.name, "w") as f:
json.dump(config, f)
cmd = ["/usr/local/bin/nats-api", "-c", fp.name, "-m", "monitor"]
try:
subprocess.run(cmd, capture_output=True, timeout=30)
except Exception as e:
logger.error(e)
ids = [i.agent_id for i in agents if i.status != "online"]
run_nats_api_cmd("monitor", ids)
@app.task
@@ -288,15 +289,5 @@ def get_wmi_task() -> None:
agents = Agent.objects.only(
"pk", "agent_id", "last_seen", "overdue_time", "offline_time"
)
ret = [i.agent_id for i in agents if i.status == "online"]
config = _get_nats_config()
config["agents"] = ret
with tempfile.NamedTemporaryFile() as fp:
with open(fp.name, "w") as f:
json.dump(config, f)
cmd = ["/usr/local/bin/nats-api", "-c", fp.name, "-m", "wmi"]
try:
subprocess.run(cmd, capture_output=True, timeout=30)
except Exception as e:
logger.error(e)
ids = [i.agent_id for i in agents if i.status == "online"]
run_nats_api_cmd("wmi", ids)

View File

@@ -914,8 +914,9 @@ class TestAgentTasks(TacticalTestCase):
self.authenticate()
self.setup_coresettings()
@patch("agents.tasks._get_exegen_url")
@patch("agents.models.Agent.nats_cmd")
def test_agent_update(self, nats_cmd):
def test_agent_update(self, nats_cmd, get_exe):
from agents.tasks import agent_update
agent_noarch = baker.make_recipe(
@@ -926,63 +927,96 @@ class TestAgentTasks(TacticalTestCase):
r = agent_update(agent_noarch.pk)
self.assertEqual(r, "noarch")
agent_1111 = baker.make_recipe(
"agents.agent",
operating_system="Windows 10 Pro, 64 bit (build 19041.450)",
version="1.1.11",
)
r = agent_update(agent_1111.pk)
self.assertEqual(r, "not supported")
agent64_1112 = baker.make_recipe(
"agents.agent",
operating_system="Windows 10 Pro, 64 bit (build 19041.450)",
version="1.1.12",
)
r = agent_update(agent64_1112.pk)
self.assertEqual(r, "created")
action = PendingAction.objects.get(agent__pk=agent64_1112.pk)
self.assertEqual(action.action_type, "agentupdate")
self.assertEqual(action.status, "pending")
self.assertEqual(
action.details["url"],
"https://github.com/wh1te909/rmmagent/releases/download/v1.3.0/winagent-v1.3.0.exe",
)
self.assertEqual(action.details["inno"], "winagent-v1.3.0.exe")
self.assertEqual(action.details["version"], "1.3.0")
nats_cmd.assert_called_with(
{
"func": "agentupdate",
"payload": {
"url": "https://github.com/wh1te909/rmmagent/releases/download/v1.3.0/winagent-v1.3.0.exe",
"version": "1.3.0",
"inno": "winagent-v1.3.0.exe",
},
},
wait=False,
)
agent_64_130 = baker.make_recipe(
agent_130 = baker.make_recipe(
"agents.agent",
operating_system="Windows 10 Pro, 64 bit (build 19041.450)",
version="1.3.0",
)
nats_cmd.return_value = "ok"
r = agent_update(agent_64_130.pk)
r = agent_update(agent_130.pk)
self.assertEqual(r, "not supported")
# test __without__ code signing
agent64_nosign = baker.make_recipe(
"agents.agent",
operating_system="Windows 10 Pro, 64 bit (build 19041.450)",
version="1.4.14",
)
r = agent_update(agent64_nosign.pk, None)
self.assertEqual(r, "created")
action = PendingAction.objects.get(agent__pk=agent64_nosign.pk)
self.assertEqual(action.action_type, "agentupdate")
self.assertEqual(action.status, "pending")
self.assertEqual(
action.details["url"],
f"https://github.com/wh1te909/rmmagent/releases/download/v{settings.LATEST_AGENT_VER}/winagent-v{settings.LATEST_AGENT_VER}.exe",
)
self.assertEqual(
action.details["inno"], f"winagent-v{settings.LATEST_AGENT_VER}.exe"
)
self.assertEqual(action.details["version"], settings.LATEST_AGENT_VER)
nats_cmd.assert_called_with(
{
"func": "agentupdate",
"payload": {
"url": settings.DL_64,
"url": f"https://github.com/wh1te909/rmmagent/releases/download/v{settings.LATEST_AGENT_VER}/winagent-v{settings.LATEST_AGENT_VER}.exe",
"version": settings.LATEST_AGENT_VER,
"inno": f"winagent-v{settings.LATEST_AGENT_VER}.exe",
},
},
wait=False,
)
action = PendingAction.objects.get(agent__pk=agent_64_130.pk)
# test __with__ code signing (64 bit)
codesign = baker.make("core.CodeSignToken", token="testtoken123")
agent64_sign = baker.make_recipe(
"agents.agent",
operating_system="Windows 10 Pro, 64 bit (build 19041.450)",
version="1.4.14",
)
nats_cmd.return_value = "ok"
get_exe.return_value = "https://exe.tacticalrmm.io"
r = agent_update(agent64_sign.pk, codesign.token) # type: ignore
self.assertEqual(r, "created")
nats_cmd.assert_called_with(
{
"func": "agentupdate",
"payload": {
"url": f"https://exe.tacticalrmm.io/api/v1/winagents/?version={settings.LATEST_AGENT_VER}&arch=64&token=testtoken123", # type: ignore
"version": settings.LATEST_AGENT_VER,
"inno": f"winagent-v{settings.LATEST_AGENT_VER}.exe",
},
},
wait=False,
)
action = PendingAction.objects.get(agent__pk=agent64_sign.pk)
self.assertEqual(action.action_type, "agentupdate")
self.assertEqual(action.status, "pending")
# test __with__ code signing (32 bit)
agent32_sign = baker.make_recipe(
"agents.agent",
operating_system="Windows 10 Pro, 32 bit (build 19041.450)",
version="1.4.14",
)
nats_cmd.return_value = "ok"
get_exe.return_value = "https://exe.tacticalrmm.io"
r = agent_update(agent32_sign.pk, codesign.token) # type: ignore
self.assertEqual(r, "created")
nats_cmd.assert_called_with(
{
"func": "agentupdate",
"payload": {
"url": f"https://exe.tacticalrmm.io/api/v1/winagents/?version={settings.LATEST_AGENT_VER}&arch=32&token=testtoken123", # type: ignore
"version": settings.LATEST_AGENT_VER,
"inno": f"winagent-v{settings.LATEST_AGENT_VER}-x86.exe",
},
},
wait=False,
)
action = PendingAction.objects.get(agent__pk=agent32_sign.pk)
self.assertEqual(action.action_type, "agentupdate")
self.assertEqual(action.status, "pending")

View File

@@ -40,7 +40,7 @@ logger.configure(**settings.LOG_CONFIG)
@api_view()
def get_agent_versions(request):
agents = Agent.objects.only("pk")
agents = Agent.objects.prefetch_related("site").only("pk", "hostname")
return Response(
{
"versions": [settings.LATEST_AGENT_VER],

View File

@@ -633,12 +633,15 @@ class Check(BaseAuditModel):
if self.error_threshold:
text += f" Error Threshold: {self.error_threshold}%"
percent_used = [
d["percent"] for d in self.agent.disks if d["device"] == self.disk
][0]
percent_free = 100 - percent_used
try:
percent_used = [
d["percent"] for d in self.agent.disks if d["device"] == self.disk
][0]
percent_free = 100 - percent_used
body = subject + f" - Free: {percent_free}%, {text}"
body = subject + f" - Free: {percent_free}%, {text}"
except:
body = subject + f" - Disk {self.disk} does not exist"
elif self.check_type == "script":
@@ -710,11 +713,15 @@ class Check(BaseAuditModel):
if self.error_threshold:
text += f" Error Threshold: {self.error_threshold}%"
percent_used = [
d["percent"] for d in self.agent.disks if d["device"] == self.disk
][0]
percent_free = 100 - percent_used
body = subject + f" - Free: {percent_free}%, {text}"
try:
percent_used = [
d["percent"] for d in self.agent.disks if d["device"] == self.disk
][0]
percent_free = 100 - percent_used
body = subject + f" - Free: {percent_free}%, {text}"
except:
body = subject + f" - Disk {self.disk} does not exist"
elif self.check_type == "script":
body = subject + f" - Return code: {self.retcode}"
elif self.check_type == "ping":

View File

@@ -1,6 +1,7 @@
from django.contrib import admin
from .models import CoreSettings, CustomField
from .models import CoreSettings, CustomField, CodeSignToken
admin.site.register(CoreSettings)
admin.site.register(CustomField)
admin.site.register(CodeSignToken)

View File

@@ -0,0 +1,20 @@
# Generated by Django 3.2 on 2021-04-13 05:41
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0018_auto_20210329_1709'),
]
operations = [
migrations.CreateModel(
name='CodeSignToken',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('token', models.CharField(blank=True, max_length=255, null=True)),
],
),
]

View File

@@ -266,3 +266,16 @@ class CustomField(models.Model):
return self.default_value_bool
else:
return self.default_value_string
class CodeSignToken(models.Model):
token = models.CharField(max_length=255, null=True, blank=True)
def save(self, *args, **kwargs):
if not self.pk and CodeSignToken.objects.exists():
raise ValidationError("There can only be one CodeSignToken instance")
super(CodeSignToken, self).save(*args, **kwargs)
def __str__(self):
return "Code signing token"

View File

@@ -1,7 +1,7 @@
import pytz
from rest_framework import serializers
from .models import CoreSettings, CustomField
from .models import CoreSettings, CustomField, CodeSignToken
class CoreSettingsSerializer(serializers.ModelSerializer):
@@ -27,3 +27,9 @@ class CustomFieldSerializer(serializers.ModelSerializer):
class Meta:
model = CustomField
fields = "__all__"
class CodeSignTokenSerializer(serializers.ModelSerializer):
class Meta:
model = CodeSignToken
fields = "__all__"

View File

@@ -1,3 +1,4 @@
import requests
from unittest.mock import patch
from channels.db import database_sync_to_async
@@ -12,6 +13,28 @@ from .serializers import CustomFieldSerializer
from .tasks import core_maintenance_tasks
class TestCodeSign(TacticalTestCase):
def setUp(self):
self.setup_coresettings()
self.authenticate()
self.url = "/core/codesign/"
def test_get_codesign(self):
r = self.client.get(self.url)
self.assertEqual(r.status_code, 200)
self.check_not_authenticated("get", self.url)
@patch("requests.post")
def test_edit_codesign_timeout(self, mock_post):
mock_post.side_effect = requests.exceptions.ConnectionError()
data = {"token": "token123"}
r = self.client.patch(self.url, data, format="json")
self.assertEqual(r.status_code, 400)
self.check_not_authenticated("patch", self.url)
class TestConsumers(TacticalTestCase):
def setUp(self):
self.setup_coresettings()

View File

@@ -12,4 +12,5 @@ urlpatterns = [
path("servermaintenance/", views.server_maintenance),
path("customfields/", views.GetAddCustomFields.as_view()),
path("customfields/<int:pk>/", views.GetUpdateDeleteCustomFields.as_view()),
path("codesign/", views.CodeSign.as_view()),
]

View File

@@ -11,8 +11,12 @@ from rest_framework.views import APIView
from tacticalrmm.utils import notify_error
from .models import CoreSettings, CustomField
from .serializers import CoreSettingsSerializer, CustomFieldSerializer
from .models import CoreSettings, CustomField, CodeSignToken
from .serializers import (
CoreSettingsSerializer,
CustomFieldSerializer,
CodeSignTokenSerializer,
)
class UploadMeshAgent(APIView):
@@ -65,6 +69,8 @@ def dashboard_info(request):
"dbl_click_action": request.user.agent_dblclick_action,
"default_agent_tbl_tab": request.user.default_agent_tbl_tab,
"client_tree_sort": request.user.client_tree_sort,
"client_tree_splitter": request.user.client_tree_splitter,
"loading_bar_color": request.user.loading_bar_color,
}
)
@@ -177,3 +183,48 @@ class GetUpdateDeleteCustomFields(APIView):
get_object_or_404(CustomField, pk=pk).delete()
return Response("ok")
class CodeSign(APIView):
def get(self, request):
token = CodeSignToken.objects.first()
return Response(CodeSignTokenSerializer(token).data)
def patch(self, request):
import requests
errors = []
for url in settings.EXE_GEN_URLS:
try:
r = requests.post(
f"{url}/api/v1/checktoken",
json={"token": request.data["token"]},
headers={"Content-type": "application/json"},
timeout=15,
)
except Exception as e:
errors.append(str(e))
else:
errors = []
break
if errors:
return notify_error(", ".join(errors))
if r.status_code == 400 or r.status_code == 401: # type: ignore
return notify_error(r.json()["ret"]) # type: ignore
elif r.status_code == 200: # type: ignore
t = CodeSignToken.objects.first()
if t is None:
CodeSignToken.objects.create(token=request.data["token"])
else:
serializer = CodeSignTokenSerializer(instance=t, data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response("Token was saved")
try:
ret = r.json()["ret"] # type: ignore
except:
ret = "Something went wrong"
return notify_error(ret)

View File

@@ -3,7 +3,7 @@
"guid": "6820cb5e-5a7f-4d9b-8c22-d54677e3cc04",
"filename": "Win_Clear_Firefox_Cache.ps1",
"submittedBy": "https://github.com/Omnicef",
"name": "Clear Firefox Cache",
"name": "Firefox - Clean Cache",
"description": "This script will clean up Mozilla Firefox for all users.",
"shell": "powershell",
"category": "TRMM (Win):Browsers"
@@ -12,7 +12,7 @@
"guid": "3ff6a386-11d1-4f9d-8cca-1b0563bb6443",
"filename": "Win_Clear_Google_Chrome_Cache.ps1",
"submittedBy": "https://github.com/Omnicef",
"name": "Clear Google Chrome Cache",
"name": "Chrome - Clear Cache for All Users",
"description": "This script will clean up Google Chrome for all users.",
"shell": "powershell",
"category": "TRMM (Win):Browsers"
@@ -21,7 +21,7 @@
"guid": "be1de837-f677-4ac5-aa0c-37a0fc9991fc",
"filename": "Win_Install_Adobe_Reader.ps1",
"submittedBy": "https://github.com/Omnicef",
"name": "Install Adobe Reader DC",
"name": "Adobe Reader DC - Install",
"description": "Installs Adobe Reader DC.",
"shell": "powershell",
"category": "TRMM (Win):3rd Party Software>Chocolatey"
@@ -30,7 +30,7 @@
"guid": "2ee134d5-76aa-4160-b334-a1efbc62079f",
"filename": "Win_Install_Duplicati.ps1",
"submittedBy": "https://github.com/Omnicef",
"name": "Install Duplicati",
"name": "Duplicati - Install",
"description": "This script installs Duplicati 2.0.5.1 as a service.",
"shell": "powershell",
"category": "TRMM (Win):3rd Party Software"
@@ -39,7 +39,7 @@
"guid": "81cc5bcb-01bf-4b0c-89b9-0ac0f3fe0c04",
"filename": "Win_Reset_Windows_Update.ps1",
"submittedBy": "https://github.com/Omnicef",
"name": "Reset Windows Update",
"name": "Windows Update - Reset",
"description": "This script will reset all of the Windows Updates components to DEFAULT SETTINGS.",
"shell": "powershell",
"category": "TRMM (Win):Updates"
@@ -48,7 +48,7 @@
"guid": "8db87ff0-a9b4-4d9d-bc55-377bbcb85b6d",
"filename": "Win_Start_Cleanup.ps1",
"submittedBy": "https://github.com/Omnicef",
"name": "Cleanup C: drive",
"name": "Disk - Cleanup C: drive",
"description": "Cleans the C: drive's Window Temperary files, Windows SoftwareDistribution folder, the local users Temperary folder, IIS logs (if applicable) and empties the recycling bin. All deleted files will go into a log transcript in $env:TEMP. By default this script leaves files that are newer than 7 days old however this variable can be edited.",
"shell": "powershell",
"category": "TRMM (Win):Other"
@@ -57,7 +57,7 @@
"guid": "2f28e8c1-ae0f-4b46-a826-f513974526a3",
"filename": "Win_Defender_FullScan_Background.ps1",
"submittedBy": "https://github.com/Omnicef",
"name": "Windows Defender Full Scan",
"name": "Defender - Full Scan",
"description": "Runs a Windows Defender Full background scan.",
"shell": "powershell",
"category": "TRMM (Win):Security>Antivirus"
@@ -66,7 +66,7 @@
"guid": "adf81ddb-3b77-415c-a89b-2ccc826b5aa7",
"filename": "Win_Defender_QuickScan_Background.ps1",
"submittedBy": "https://github.com/Omnicef",
"name": "Windows Defender Quick Scan",
"name": "Defender - Quick Scan",
"description": "Runs a Quick Scan using Windows Defender in the Background.",
"shell": "powershell",
"category": "TRMM (Win):Security>Antivirus"
@@ -75,7 +75,7 @@
"guid": "3c46290b-85db-4cd2-93a2-943c8c93b3b1",
"filename": "Speedtest.py",
"submittedBy": "https://github.com/wh1te909",
"name": "Speed Test",
"name": "Network - Speed Test",
"description": "Runs a Speed Test using Python",
"shell": "python",
"category": "TRMM (Win):Network"
@@ -84,7 +84,7 @@
"guid": "9d34f482-1f0c-4b2f-b65f-a9cf3c13ef5f",
"filename": "Win_Rename_Installed_App.ps1",
"submittedBy": "https://github.com/bradhawkins85",
"name": "Rename Tactical RMM Agent",
"name": "TacticalRMM Agent Rename",
"description": "Updates the DisplayName registry entry for the Tactical RMM windows agent to your desired name. This script takes 1 required argument: the name you wish to set.",
"shell": "powershell",
"category": "TRMM (Win):TacticalRMM Related"
@@ -93,7 +93,7 @@
"guid": "525ae965-1dcf-4c17-92b3-5da3cf6819f5",
"filename": "Win_Bitlocker_Encrypted_Drive_c.ps1",
"submittedBy": "https://github.com/ThatsNASt",
"name": "Check C Drive for Bitlocker Status",
"name": "Bitlocker - Check C Drive for Status",
"description": "Runs a check on drive C for Bitlocker status.",
"shell": "powershell",
"category": "TRMM (Win):Storage"
@@ -111,25 +111,52 @@
"guid": "9e5769c1-3873-4941-bf70-e851e0afbd6d",
"filename": "Win_Bitlocker_Retrieve_Status_Report.ps1",
"submittedBy": "https://github.com/ThatsNASt",
"name": "Retreive Bitlocker Status Report",
"name": "Bitlocker - Retrieve Status Report",
"description": "Retreives a Bitlocker status report.",
"shell": "powershell",
"category": "TRMM (Win):Storage"
},
{
"guid": "72b93487-0266-43f0-97cc-03d4c7ee0b44",
"filename": "Win_Bitlocker_Get_Recovery_Keys.ps1",
"submittedBy": "https://github.com/silversword411",
"name": "Bitlocker - Get Recovery Keys",
"description": "Retreives a Bitlocker Recovery Keys",
"shell": "powershell",
"category": "TRMM (Win):Storage"
},
{
"guid": "cfa14c28-4dfc-4d4e-95ee-a380652e058d",
"filename": "Win_Bios_Check.ps1",
"submittedBy": "https://github.com/ThatsNASt",
"name": "Check BIOS Information",
"name": "BIOS - Check Information",
"description": "Retreives and reports on BIOS make, version, and date.",
"shell": "powershell",
"category": "TRMM (Win):Hardware"
},
{
"guid": "e1c27982-b955-4766-85b6-d92527a177cf",
"filename": "Win_Hardware_Monitor_Get_Info.ps1",
"submittedBy": "https://github.com/MaxAnderson95/",
"name": "Monitor - Get Info",
"description": "Retreives and reports on Monitor info: Manufacturer, Model, Serial",
"shell": "powershell",
"category": "TRMM (Win):Hardware"
},
{
"guid": "ae231ac4-b01f-4a39-a9d2-3d817af75260",
"filename": "Win_Hardware_RAM_Status.ps1",
"submittedBy": "https://github.com/silversword411",
"name": "RAM - Check Information",
"description": "Retreives and reports on RAM info: DIMM's, total memory, slots total and used",
"shell": "powershell",
"category": "TRMM (Win):Hardware"
},
{
"guid": "95a2ee6f-b89b-4551-856e-3081b041caa7",
"filename": "Win_Reset_High_Performance_Power_Profile_to_Defaults.ps1",
"submittedBy": "https://github.com/azulskyknight",
"name": "Reset High Perf Power Profile",
"name": "Power Profile - Reset High Perf Power Profile to defaults",
"description": "Resets monitor, disk, standby, and hibernate timers in the default High Performance power profile to their default values. It also re-indexes the AC and DC power profiles into their default order.",
"shell": "powershell",
"category": "TRMM (Win):Power"
@@ -138,7 +165,7 @@
"guid": "2cbd30b0-84dd-4388-a36d-2e2e980f1a3e",
"filename": "Win_Set_High_Performance_Power_Profile.ps1",
"submittedBy": "https://github.com/azulskyknight",
"name": "Set High Perf Power Profile",
"name": "Power Profile - Set High Performance",
"description": "Sets the High Performance Power profile to the active power profile. Use this to keep machines from falling asleep.",
"shell": "powershell",
"category": "TRMM (Win):Power"
@@ -156,7 +183,7 @@
"guid": "375323e5-cac6-4f35-a304-bb7cef35902d",
"filename": "Win_Disk_Status.ps1",
"submittedBy": "https://github.com/dinger1986",
"name": "Check Disk Hardware Health (using Event Viewer errors)",
"name": "Disk Hardware Health Check (using Event Viewer errors)",
"description": "Checks local disks for errors reported in event viewer within the last 24 hours",
"shell": "powershell",
"category": "TRMM (Win):Hardware"
@@ -165,7 +192,7 @@
"guid": "7c14beb4-d1c3-41aa-8e70-92a267d6e080",
"filename": "Win_Duplicati_Status.ps1",
"submittedBy": "https://github.com/dinger1986",
"name": "Check Duplicati",
"name": "Duplicati - Check",
"description": "Checks Duplicati Backup is running properly over the last 24 hours",
"shell": "powershell",
"category": "TRMM (Win):3rd Party Software"
@@ -174,7 +201,7 @@
"guid": "da51111c-aff6-4d87-9d76-0608e1f67fe5",
"filename": "Win_Defender_Enable.ps1",
"submittedBy": "https://github.com/dinger1986",
"name": "Enable Windows Defender",
"name": "Defender - Enable",
"description": "Enables Windows Defender and sets preferences",
"shell": "powershell",
"category": "TRMM (Win):Security>Antivirus"
@@ -183,8 +210,8 @@
"guid": "a223d03a-e22e-40e0-94f2-92dd8c481d14",
"filename": "Win_Open_SSH_Server_Install.ps1",
"submittedBy": "https://github.com/dinger1986",
"name": "Install SSH",
"description": "Installs and enabled OpenSSH Server",
"name": "SSH - Install Feature and Enable",
"description": "Installs and enabled OpenSSH Server Feature in Win10",
"shell": "powershell",
"category": "TRMM (Win):Windows Features"
},
@@ -192,7 +219,7 @@
"guid": "2435297a-6263-4e90-8688-1847400d0e22",
"filename": "Win_RDP_enable.bat",
"submittedBy": "https://github.com/dinger1986",
"name": "Enable RDP",
"name": "RDP - Enable",
"description": "Enables RDP",
"shell": "cmd",
"category": "TRMM (Win):Windows Features"
@@ -210,16 +237,25 @@
"guid": "a821975c-60df-4d58-8990-6cf8a55b4ee0",
"filename": "Win_Sync_Time.bat",
"submittedBy": "https://github.com/dinger1986",
"name": "Sync DC Time",
"name": "ADDC - Sync DC Time",
"description": "Syncs time with domain controller",
"shell": "cmd",
"category": "TRMM (Win):Active Directory"
},
{
"guid": "b6b9912f-4274-4162-99cc-9fd47fbcb292",
"filename": "Win_ADDC_Sync_Start.bat",
"submittedBy": "https://github.com/silversword411",
"name": "ADDC - Sync AD",
"description": "Trigger AD Sync on domain controller",
"shell": "cmd",
"category": "TRMM (Win):Active Directory"
},
{
"guid": "b720e320-7755-4c89-9992-e1a6c43699ed",
"filename": "Win_Defender_Clear_Logs.ps1",
"submittedBy": "https://github.com/dinger1986",
"name": "Clear Defender Logs",
"name": "Defender - Clear Logs",
"description": "Clears Windows Defender Logs",
"shell": "powershell",
"category": "TRMM (Win):Security>Antivirus"
@@ -228,7 +264,7 @@
"guid": "d980fda3-a068-47eb-8495-1aab07a24e64",
"filename": "Win_Defender_Status.ps1",
"submittedBy": "https://github.com/dinger1986",
"name": "Defender Status",
"name": "Defender - Status",
"description": "This will check for Malware, Antispyware, that Windows Defender is Healthy, last scan etc within the last 24 hours",
"shell": "powershell",
"category": "TRMM (Win):Security>Antivirus"
@@ -237,11 +273,20 @@
"guid": "9956e936-6fdb-4488-a9d8-8b274658037f",
"filename": "Win_Disable_Fast_Startup.bat",
"submittedBy": "https://github.com/dinger1986",
"name": "Disable Fast Startup",
"name": "Power - Fast Startup Disable",
"description": "Disables Faststartup on Windows 10",
"shell": "cmd",
"category": "TRMM (Win):Power"
},
{
"guid": "f628a02b-16c3-4ab5-b788-dec5bc2af1d9",
"filename": "Win_Power_Disable_Hibernation.bat",
"submittedBy": "https://github.com/silversword411",
"name": "Power - Hibernate Disable",
"description": "Disables Hibernation",
"shell": "cmd",
"category": "TRMM (Win):Power"
},
{
"guid": "2472bbaf-1941-4722-8a58-d1dd0f528801",
"filename": "Win_Update_Tactical_Exclusion.ps1",
@@ -255,7 +300,7 @@
"guid": "b253dc76-41a0-48ca-9cea-bee4277402c4",
"filename": "Win_Display_Message_To_User.ps1",
"submittedBy": "https://github.com/bradhawkins85",
"name": "Display Message To User",
"name": "Message Popup To User",
"description": "Displays a popup message to the currently logged on user",
"shell": "powershell",
"category": "TRMM (Win):Other"
@@ -264,7 +309,7 @@
"guid": "19224d21-bd39-44bc-b9cf-8f1ba3ca9c11",
"filename": "Win_Antivirus_Verify.ps1",
"submittedBy": "https://github.com/beejayzed",
"name": "Verify Antivirus Status",
"name": "Antivirus - Verify Status",
"description": "Verify and display status for all installed Antiviruses",
"shell": "powershell",
"category": "TRMM (Win):Security>Antivirus"
@@ -273,7 +318,7 @@
"guid": "f88c5c52-c6fe-44db-b727-b7912a4279ed",
"filename": "Win_Create_All_User_Logon_Script.ps1",
"submittedBy": "https://github.com/nr-plaxon",
"name": "Create User Logon Script",
"name": "Template Example - Create User Logon Script",
"description": "Creates a powershell script that runs at logon of any user on the machine in the security context of the user.",
"shell": "powershell",
"category": "TRMM (Win):Other"
@@ -291,7 +336,7 @@
"guid": "fff8024d-d72e-4457-84fa-6c780f69a16f",
"filename": "Win_AD_Check_And_Enable_AD_Recycle_Bin.ps1",
"submittedBy": "https://github.com/silversword411",
"name": "AD - Check and Enable AD Recycle Bin",
"name": "ADDC - Check and Enable AD Recycle Bin",
"description": "Only run on Domain Controllers, checks for Active Directory Recycle Bin and enables if not already enabled",
"shell": "powershell",
"category": "TRMM (Win):Active Directory"
@@ -300,11 +345,38 @@
"guid": "71090fc4-faa6-460b-adb0-95d7863544e1",
"filename": "Win_Check_Events_for_Bluescreens.ps1",
"submittedBy": "https://github.com/dinger1986",
"name": "Event Viewer - Check for Bluescreens",
"description": "This will check for Bluescreen events on your system",
"name": "Event Viewer - Bluescreen Notification",
"description": "Event Viewer Monitor - Notify Bluescreen events on your system",
"shell": "powershell",
"category": "TRMM (Win):Monitoring"
},
{
"guid": "8373846f-facc-49b9-9891-3a780a394c89",
"filename": "Win_Local_User_Created_Monitor.ps1",
"submittedBy": "https://github.com/dinger1986",
"name": "Event Viewer - New User Notification",
"description": "Event Viewer Monitor - Notify when new Local user is created",
"shell": "powershell",
"category": "TRMM (Win):Monitoring"
},
{
"guid": "65e5cef1-8338-4180-a0bc-cd54e62de690",
"filename": "Win_Task_Scheduler_New_Items_Monitor.ps1",
"submittedBy": "https://github.com/dinger1986",
"name": "Event Viewer - Task Scheduler New Item Notification",
"description": "Event Viewer Monitor - Notify when new Task Scheduler item is created",
"shell": "powershell",
"category": "TRMM (Win):Monitoring"
},
{
"guid": "08ca81f2-f044-4dfc-ad47-090b19b19d76",
"filename": "Win_User_Logged_in_with_Temp_Profile.ps1",
"submittedBy": "https://github.com/dinger1986",
"name": "User Logged in with temp profile check",
"description": "Check if users are logged in with a temp profile",
"shell": "powershell",
"category": "TRMM (Win):Other"
},
{
"guid": "5d905886-9eb1-4129-8b81-a013f842eb24",
"filename": "Win_Rename_Computer.ps1",
@@ -319,8 +391,8 @@
"guid": "f396dae2-c768-45c5-bd6c-176e56ed3614",
"filename": "Win_Finish_updates_and_restart.ps1",
"submittedBy": "https://github.com/tremor021",
"name": "Finish updates and restart",
"description": "Finish installing updates and restart PC",
"name": "Updates - Finish and restart",
"description": "Finish installing Windows updates and restart PC",
"shell": "powershell",
"category": "TRMM (Win):Other"
},
@@ -328,14 +400,14 @@
"guid": "63f89be0-a9c9-4c61-9b55-bce0b28b90b2",
"filename": "Win_Finish_updates_and_shutdown.ps1",
"submittedBy": "https://github.com/tremor021",
"name": "Finish updates and shutdown",
"description": "Finish installing updates and shutdown PC",
"name": "Updates - Finish and Shutdown",
"description": "Finish installing Windows updates and shutdown PC",
"shell": "powershell",
"category": "TRMM (Win):Other"
},
{
"guid": "e09895d5-ca13-44a2-a38c-6e77c740f0e8",
"filename": "ScreenConnectAIO.ps1",
"filename": "Win_ScreenConnectAIO.ps1",
"submittedBy": "https://github.com/bradhawkins85",
"name": "ScreenConnect AIO",
"description": "Install, Uninstall, Start and Stop ScreenConnect Access Agent",
@@ -347,5 +419,164 @@
"default_timeout": "90",
"shell": "powershell",
"category": "TRMM (Win):3rd Party Software"
},
{
"guid": "3abbb62a-3757-492c-8979-b4fc6174845d",
"filename": "Win_Disable_AutoRun.bat",
"submittedBy": "https://github.com/silversword411",
"name": "Autorun - Disable",
"description": "Disable Autorun System Wide",
"shell": "cmd",
"category": "TRMM (Win):Other",
"default_timeout": "30"
},
{
"guid": "4a11877a-7555-494c-ac74-29d6df3c1989",
"filename": "Win_Disable_Cortana.bat",
"submittedBy": "https://github.com/silversword411",
"name": "Cortana - Disable",
"description": "Disable Cortana System Wide",
"shell": "cmd",
"category": "TRMM (Win):Other",
"default_timeout": "30"
},
{
"guid": "28ef1387-dd4f-4bab-b042-26250914e370",
"filename": "Win_WOL_Enable_Status.ps1",
"submittedBy": "https://github.com/silversword411",
"name": "Network WoL - Enable function",
"description": "Wake on Lan enable on Dell, HP, Lenovo",
"shell": "powershell",
"category": "TRMM (Win):Network",
"default_timeout": "90"
},
{
"guid": "685d5432-0b84-46d5-98e8-3ec2054150fe",
"filename": "Win_WOL_Test_State.ps1",
"submittedBy": "https://github.com/silversword411",
"name": "Network WoL - Test State",
"description": "Wake on Lan test status",
"shell": "powershell",
"category": "TRMM (Win):Network",
"default_timeout": "90"
},
{
"guid": "6ce5682a-49db-4c0b-9417-609cf905ac43",
"filename": "Win_Win10_Change_Key_and_Activate.ps1",
"submittedBy": "https://github.com/silversword411",
"name": "Product Key in Win10 Change and Activate",
"description": "Insert new product key and Activate. Requires 1 parameter the product key you want to use",
"shell": "powershell",
"category": "TRMM (Win):Other",
"default_timeout": "90"
},
{
"guid": "83f6c6ea-6120-4fd3-bec8-d3abc505dcdf",
"filename": "Win_TRMM_Start_Menu_Delete_Shortcut.ps1",
"submittedBy": "https://github.com/silversword411",
"name": "TRMM Delete Start Menu Shortcut for App",
"description": "Tactical RMM delete its application shortcut that's installed in the start menu",
"shell": "powershell",
"category": "TRMM (Win):TacticalRMM Related",
"default_timeout": "10"
},
{
"guid": "60130fca-7636-446e-acd7-cc5d29d609c2",
"filename": "Win_Firewall_Check_Status.ps1",
"submittedBy": "https://github.com/dinger1986",
"name": "Windows Firewall - Check Status",
"description": "Windows Firewall - Check state, report status",
"shell": "powershell",
"category": "TRMM (Win):Network"
},
{
"guid": "93379675-c01c-433f-87df-a11597c959f0",
"filename": "Win_UAC_Check_Status.ps1",
"submittedBy": "https://github.com/dinger1986",
"name": "Windows UAC - Check Status",
"description": "Windows UAC - Report status",
"shell": "powershell",
"category": "TRMM (Win):Security"
},
{
"guid": "7ea6a11a-05c0-4151-b5c1-cb8af029299f",
"filename": "Win_AzureAD_Check_Connection_Status.ps1",
"submittedBy": "https://github.com/dinger1986",
"name": "Azure AD - Check Status",
"description": "Azure AD - Check if joined or not",
"shell": "powershell",
"category": "TRMM (Win):Azure>AD"
},
{
"guid": "7d81859a-1ba3-42b0-8664-29844f0dd765",
"filename": "Win_Azure_Mars_Cloud_Backup_Status.ps1",
"submittedBy": "https://github.com/dinger1986",
"name": "Azure - Mars Cloud backup Status",
"description": "Azure - Mars Cloud backup Check Status",
"shell": "powershell",
"category": "TRMM (Win):Azure>Backup"
},
{
"guid": "e18c64d0-b783-4b52-b44b-9bb7592b439b",
"filename": "Win_FileSystem_Enable_Long_Paths.bat",
"submittedBy": "https://github.com/silversword411",
"name": "File System - Enable Long Paths",
"description": "Enables NTFS Long paths greater than 260 characters",
"shell": "cmd",
"category": "TRMM (Win):Storage"
},
{
"guid": "c6252ca8-5172-42ea-9114-e447f80868f5",
"filename": "Win_USB_Disable_Access.bat",
"submittedBy": "https://github.com/silversword411",
"name": "USB - Disable Access",
"description": "USB - Disable Plugged in USB devices",
"shell": "cmd",
"category": "TRMM (Win):Storage"
},
{
"guid": "3785952f-69fb-4bda-b2fe-5e3e8642738a",
"filename": "Win_USB_Enable_Access.bat",
"submittedBy": "https://github.com/silversword411",
"name": "USB - Enable Access",
"description": "USB - Enable Plugged in USB devices",
"shell": "cmd",
"category": "TRMM (Win):Storage"
},
{
"guid": "c6014da2-b188-4e1b-b96a-e3440ade3a6a",
"filename": "Win_RecycleBin_Empty.ps1",
"submittedBy": "https://github.com/silversword411",
"name": "File System - Empty Recycle Bin",
"description": "Empty the recycle bin",
"shell": "powershell",
"category": "TRMM (Win):Storage"
},
{
"guid": "57997ec7-b293-4fd5-9f90-a25426d0eb90",
"filename": "Win_Get_Computer_Users.ps1",
"submittedBy": "https://github.com/tremor021",
"name": "Get Computer Users",
"description": "Get list of computer users and show which one is enabled",
"shell": "powershell",
"category": "TRMM (Win):Other"
},
{
"guid": "77da9c87-5a7a-4ba1-bdde-3eeb3b01d62d",
"filename": "Win_Set_Network_To_Private.ps1",
"submittedBy": "https://github.com/tremor021",
"name": "Set Network To Private",
"description": "Sets current network type to Private",
"shell": "powershell",
"category": "TRMM (Win):Network"
},
{
"guid": "768f42d5-7b45-45ed-8233-254ae537aaa2",
"filename": "Win_TaskScheduler_Add_Task.ps1",
"submittedBy": "https://github.com/tremor021",
"name": "Add task to TaskScheduler",
"description": "Add a task to Task Scheduler, needs editing",
"shell": "powershell",
"category": "TRMM (Win):Other"
}
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.1.7 on 2021-04-15 02:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('scripts', '0007_script_args'),
]
operations = [
migrations.AddField(
model_name='script',
name='guid',
field=models.CharField(blank=True, max_length=64, null=True),
),
]

View File

@@ -23,6 +23,7 @@ logger.configure(**settings.LOG_CONFIG)
class Script(BaseAuditModel):
guid = name = models.CharField(max_length=64, null=True, blank=True)
name = models.CharField(max_length=255)
description = models.TextField(null=True, blank=True)
filename = models.CharField(max_length=255) # deprecated
@@ -78,9 +79,7 @@ class Script(BaseAuditModel):
for script in info:
if os.path.exists(os.path.join(scripts_dir, script["filename"])):
s = cls.objects.filter(script_type="builtin").filter(
name=script["name"]
)
s = cls.objects.filter(script_type="builtin", guid=script["guid"])
category = (
script["category"] if "category" in script.keys() else "Community"
@@ -120,6 +119,46 @@ class Script(BaseAuditModel):
"args",
]
)
# check if script was added without a guid
elif cls.objects.filter(
script_type="builtin", name=script["name"]
).exists():
s = cls.objects.get(script_type="builtin", name=script["name"])
if not s.guid:
print(f"Updating GUID for: {script['name']}")
s.guid = script["guid"]
s.name = script["name"]
s.description = script["description"]
s.category = category
s.shell = script["shell"]
s.default_timeout = default_timeout
s.args = args
with open(
os.path.join(scripts_dir, script["filename"]), "rb"
) as f:
script_bytes = (
f.read().decode("utf-8").encode("ascii", "ignore")
)
s.code_base64 = base64.b64encode(script_bytes).decode(
"ascii"
)
s.save(
update_fields=[
"guid",
"name",
"description",
"category",
"default_timeout",
"code_base64",
"shell",
"args",
]
)
else:
print(f"Adding new community script: {script['name']}")
@@ -131,6 +170,7 @@ class Script(BaseAuditModel):
cls(
code_base64=code_base64,
guid=script["guid"],
name=script["name"],
description=script["description"],
filename=script["filename"],
@@ -141,6 +181,9 @@ class Script(BaseAuditModel):
args=args,
).save()
# delete community scripts that had their name changed
cls.objects.filter(script_type="builtin", guid=None).delete()
@staticmethod
def serialize(script):
# serializes the script and returns json

View File

@@ -245,12 +245,39 @@ class TestScriptViews(TacticalTestCase):
Script.load_community_scripts()
community_scripts = Script.objects.filter(script_type="builtin").count()
self.assertEqual(len(info), community_scripts)
community_scripts_count = Script.objects.filter(script_type="builtin").count()
if len(info) != community_scripts_count:
raise Exception(
f"There are {len(info)} scripts in json file but only {community_scripts_count} in database"
)
# test updating already added community scripts
Script.load_community_scripts()
self.assertEqual(len(info), community_scripts)
community_scripts_count2 = Script.objects.filter(script_type="builtin").count()
self.assertEqual(len(info), community_scripts_count2)
def test_community_script_has_jsonfile_entry(self):
with open(
os.path.join(settings.BASE_DIR, "scripts/community_scripts.json")
) as f:
info = json.load(f)
filenames = [i["filename"] for i in info]
# normal
if not settings.DOCKER_BUILD:
scripts_dir = os.path.join(Path(settings.BASE_DIR).parents[1], "scripts")
# docker
else:
scripts_dir = settings.SCRIPTS_DIR
with os.scandir(scripts_dir) as it:
for f in it:
if not f.name.startswith(".") and f.is_file():
if f.name not in filenames:
raise Exception(
f"{f.name} is missing an entry in community_scripts.json"
)
def test_script_filenames_do_not_contain_spaces(self):
with open(
@@ -259,4 +286,5 @@ class TestScriptViews(TacticalTestCase):
info = json.load(f)
for script in info:
fn: str = script["filename"]
self.assertTrue(" " not in fn)
if " " in fn:
raise Exception(f"{fn} must not contain spaces in filename")

View File

@@ -15,16 +15,16 @@ EXE_DIR = os.path.join(BASE_DIR, "tacticalrmm/private/exe")
AUTH_USER_MODEL = "accounts.User"
# latest release
TRMM_VERSION = "0.5.1"
TRMM_VERSION = "0.6.0"
# bump this version everytime vue code is changed
# to alert user they need to manually refresh their browser
APP_VER = "0.0.127"
APP_VER = "0.0.129"
# https://github.com/wh1te909/rmmagent
LATEST_AGENT_VER = "1.4.13"
LATEST_AGENT_VER = "1.5.0"
MESH_VER = "0.8.5"
MESH_VER = "0.7.93"
# for the update script, bump when need to recreate venv or npm install
PIP_VER = "15"
@@ -34,8 +34,8 @@ DL_64 = f"https://github.com/wh1te909/rmmagent/releases/download/v{LATEST_AGENT_
DL_32 = f"https://github.com/wh1te909/rmmagent/releases/download/v{LATEST_AGENT_VER}/winagent-v{LATEST_AGENT_VER}-x86.exe"
EXE_GEN_URLS = [
"https://exe2.tacticalrmm.io/api/v1/exe",
"https://exe.tacticalrmm.io/api/v1/exe",
"https://exe2.tacticalrmm.io",
"https://exe.tacticalrmm.io",
]
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"

View File

@@ -12,6 +12,7 @@ from .utils import (
generate_winagent_exe,
get_bit_days,
reload_nats,
run_nats_api_cmd,
)
@@ -74,6 +75,12 @@ class TestUtils(TestCase):
mock_subprocess.assert_called_once()
@patch("subprocess.run")
def test_run_nats_api_cmd(self, mock_subprocess):
ids = ["a", "b", "c"]
_ = run_nats_api_cmd("monitor", ids)
mock_subprocess.assert_called_once()
def test_bitdays_to_string(self):
a = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
all_days = [

View File

@@ -4,6 +4,7 @@ import string
import subprocess
import tempfile
import time
import urllib.parse
from typing import Union
import pytz
@@ -19,6 +20,7 @@ from rest_framework import status
from rest_framework.response import Response
from agents.models import Agent
from core.models import CodeSignToken
logger.configure(**settings.LOG_CONFIG)
@@ -50,12 +52,27 @@ def generate_winagent_exe(
file_name: str,
) -> Union[Response, FileResponse]:
from agents.tasks import _get_exegen_url
inno = (
f"winagent-v{settings.LATEST_AGENT_VER}.exe"
if arch == "64"
else f"winagent-v{settings.LATEST_AGENT_VER}-x86.exe"
)
try:
codetoken = CodeSignToken.objects.first().token
base_url = _get_exegen_url() + "/api/v1/winagents/?"
params = {
"version": settings.LATEST_AGENT_VER,
"arch": arch,
"token": codetoken,
}
dl_url = base_url + urllib.parse.urlencode(params)
except:
codetoken = ""
dl_url = settings.DL_64 if arch == "64" else settings.DL_32
data = {
"client": client,
"site": site,
@@ -66,8 +83,9 @@ def generate_winagent_exe(
"goarch": "amd64" if arch == "64" else "386",
"token": token,
"inno": inno,
"url": settings.DL_64 if arch == "64" else settings.DL_32,
"url": dl_url,
"api": api,
"codesigntoken": codetoken,
}
headers = {"Content-type": "application/json"}
@@ -76,7 +94,7 @@ def generate_winagent_exe(
for url in settings.EXE_GEN_URLS:
try:
r = requests.post(
url,
f"{url}/api/v1/exe",
json=data,
headers=headers,
stream=True,
@@ -228,3 +246,20 @@ class KnoxAuthMiddlewareInstance:
KnoxAuthMiddlewareStack = lambda inner: KnoxAuthMiddlewareInstance(
AuthMiddlewareStack(inner)
)
def run_nats_api_cmd(mode: str, ids: list[str], timeout: int = 30) -> None:
config = {
"key": settings.SECRET_KEY,
"natsurl": f"tls://{settings.ALLOWED_HOSTS[0]}:4222",
"agents": ids,
}
with tempfile.NamedTemporaryFile() as fp:
with open(fp.name, "w") as f:
json.dump(config, f)
cmd = ["/usr/local/bin/nats-api", "-c", fp.name, "-m", mode]
try:
subprocess.run(cmd, capture_output=True, timeout=timeout)
except Exception as e:
logger.error(e)

View File

@@ -14,8 +14,29 @@ class TestWinUpdateViews(TacticalTestCase):
self.authenticate()
self.setup_coresettings()
def test_get_winupdates(self):
@patch("agents.models.Agent.nats_cmd")
def test_run_update_scan(self, nats_cmd):
agent = baker.make_recipe("agents.agent")
url = f"/winupdate/{agent.pk}/runupdatescan/"
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
nats_cmd.assert_called_with({"func": "getwinupdates"}, wait=False)
self.check_not_authenticated("get", url)
@patch("agents.models.Agent.nats_cmd")
def test_install_updates(self, nats_cmd):
agent = baker.make_recipe("agents.agent")
baker.make("winupdate.WinUpdate", agent=agent, _quantity=4)
baker.make("winupdate.WinUpdatePolicy", agent=agent)
url = f"/winupdate/{agent.pk}/installnow/"
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
nats_cmd.assert_called_once()
self.check_not_authenticated("get", url)
def test_get_winupdates(self):
agent = baker.make_recipe("agents.agent")
baker.make("winupdate.WinUpdate", agent=agent, _quantity=4)
@@ -27,8 +48,8 @@ class TestWinUpdateViews(TacticalTestCase):
resp = self.client.get(url, format="json")
serializer = UpdateSerializer(agent)
self.assertEqual(resp.status_code, 200)
self.assertEqual(len(resp.data["winupdates"]), 4)
self.assertEqual(resp.data, serializer.data)
self.assertEqual(len(resp.data["winupdates"]), 4) # type: ignore
self.assertEqual(resp.data, serializer.data) # type: ignore
self.check_not_authenticated("get", url)
@@ -99,7 +120,7 @@ class TestWinUpdateViews(TacticalTestCase):
resp = self.client.patch(url, invalid_data, format="json")
self.assertEqual(resp.status_code, 404)
data = {"pk": winupdate.pk, "policy": "inherit"}
data = {"pk": winupdate.pk, "policy": "inherit"} # type: ignore
resp = self.client.patch(url, data, format="json")
self.assertEqual(resp.status_code, 200)

View File

@@ -1,12 +1,11 @@
import asyncio
from django.shortcuts import get_object_or_404
from packaging import version as pyver
from rest_framework.decorators import api_view
from rest_framework.response import Response
from agents.models import Agent
from tacticalrmm.utils import get_default_timezone, notify_error
from tacticalrmm.utils import get_default_timezone
from .models import WinUpdate
from .serializers import UpdateSerializer
@@ -24,9 +23,6 @@ def get_win_updates(request, pk):
def run_update_scan(request, pk):
agent = get_object_or_404(Agent, pk=pk)
agent.delete_superseded_updates()
if pyver.parse(agent.version) < pyver.parse("1.3.0"):
return notify_error("Requires agent version 1.3.0 or greater")
asyncio.run(agent.nats_cmd({"func": "getwinupdates"}, wait=False))
return Response("ok")
@@ -35,9 +31,6 @@ def run_update_scan(request, pk):
def install_updates(request, pk):
agent = get_object_or_404(Agent, pk=pk)
agent.delete_superseded_updates()
if pyver.parse(agent.version) < pyver.parse("1.3.0"):
return notify_error("Requires agent version 1.3.0 or greater")
agent.approve_updates()
nats_data = {
"func": "installwinupdates",

View File

@@ -19,7 +19,7 @@ Login to your Github
Choose local folder
### 3a. Install extra vscode Extensions
#### 3a. Install extra vscode Extensions
GitLens

View File

@@ -0,0 +1,2 @@
net start ADSync
exit

View File

@@ -0,0 +1,15 @@
$ErrorActionPreference = 'silentlycontinue'
$aadchk = dsregcmd /status | Where-Object { $_ -match 'AzureAdJoined : ' } | ForEach-Object { $_.Trim() }
if ($aadchk -Eq 'AzureAdJoined : Yes') {
Write-Output "Machine is Azure Ad Joined"
exit 0
}
else {
Write-Output "Machine is not Azure Ad Joined"
exit 1
}
Exit $LASTEXITCODE

View File

@@ -0,0 +1,23 @@
$ErrorActionPreference= 'silentlycontinue'
$TimeSpan = (Get-Date) - (New-TimeSpan -Day 1)
##Check for Errors in Backup
if (Get-WinEvent -FilterHashtable @{LogName='CloudBackup/Operational';ID='11','18';StartTime=$TimeSpan})
{
Write-Host "Cloud Backup Mars Ended with Errors"
Get-WinEvent -FilterHashtable @{LogName='CloudBackup/Operational';ID='1','14','11','18','16';StartTime=$TimeSpan}
exit 1
}
else
{
Write-Host "Cloud Backup Mars Backup Is Working Correctly"
Get-WinEvent -FilterHashtable @{LogName='CloudBackup/Operational';ID='1','14','16'}
exit 0
}
Exit $LASTEXITCODE

View File

@@ -0,0 +1 @@
manage-bde -protectors C: -get

View File

@@ -0,0 +1 @@
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" /v NoDriveTypeAutoRun /t REG_DWORD /d 255 /f

View File

@@ -0,0 +1 @@
reg add "hklm\SOFTWARE\Policies\Microsoft\Windows\Windows Search" /d "AllowCortana"=dword:00000000

View File

@@ -1,20 +1,18 @@
# Checks local disks for errors reported in event viewer within the last 24 hours
$ErrorActionPreference= 'silentlycontinue'
$ErrorActionPreference = 'silentlycontinue'
$TimeSpan = (Get-Date) - (New-TimeSpan -Day 1)
if (Get-WinEvent -FilterHashtable @{LogName='system';ID='11','9','15','52','129','7','98';Level=2,3;ProviderName='*disk*','*storsvc*','*ntfs*';StartTime=$TimeSpan})
if (Get-WinEvent -FilterHashtable @{LogName = 'system'; ID = '11', '9', '15', '52', '129', '7', '98'; Level = 2, 3; ProviderName = '*disk*', '*storsvc*', '*ntfs*'; StartTime = $TimeSpan } -MaxEvents 10 | Where-Object -Property Message -Match Volume*)
{
Write-Output "Disk errors detected please investigate"
Get-WinEvent -FilterHashtable @{LogName='system';ID='11','9','15','52','129','7','98';Level=2,3;ProviderName='*disk*','*storsvc*','*ntfs*';StartTime=$TimeSpan}
exit 1
Write-Output "Disk errors detected please investigate"
Get-WinEvent -FilterHashtable @{LogName = 'system'; ID = '11', '9', '15', '52', '129', '7', '98'; Level = 2, 3; ProviderName = '*disk*', '*storsvc*', '*ntfs*'; StartTime = $TimeSpan }
exit 1
}
else
{
Write-Output "Disks are Healthy"
exit 0
else {
Write-Output "Disks are Healthy"
exit 0
}

View File

@@ -0,0 +1 @@
REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem" /V LongPathsEnabled /T REG_DWORD /D 1 /F

View File

@@ -1 +1,5 @@
Restart-Computer -ComputerName $env:COMPUTERNAME -Force
# This script will force the computer to finish installing updates
# and restart. Normal restart doesn't install updates before issuing
# a reboot command. This one does.
Restart-Computer -ComputerName $env:COMPUTERNAME -Force

View File

@@ -1 +1,5 @@
# This script will force the computer to finish installing updates
# and shutdown. Normal shutdown doesn't install updates before issuing
# a shutdown command. This one does.
Stop-Computer -ComputerName $env:COMPUTERNAME -Force

View File

@@ -0,0 +1,17 @@
$ErrorActionPreference = 'silentlycontinue'
$fwenabled = (get-netfirewallprofile -policystore activestore).Enabled
if ($fwenabled.Contains('True')) {
Write-Output "Firewall is Enabled"
netsh advfirewall show currentprofile
exit 0
}
else {
Write-Host "Firewall is Disabled"
exit 1
}
Exit $LASTEXITCODE

View File

@@ -0,0 +1,5 @@
# This script return the list of all users and checks
# if they are enabled or disabled
get-localuser | Select name,Enabled > $env:TEMP\users.txt
Get-Content $env:TEMP\users.txt | foreach {Write-Output $_}

View File

@@ -0,0 +1,154 @@
<#
.SYNOPSIS
This powershell function gets information about the monitors attached to any computer. It uses EDID information provided by WMI. If this value is not specified it pulls the monitors of the computer that the script is being run on.
.DESCRIPTION
The function begins by looping through each computer specified. For each computer it gets a litst of monitors.
It then gets all of the necessary data from each monitor object and converts and cleans the data and places it in a custom PSObject. It then adds
the data to an array. At the end the array is displayed.
.PARAMETER ComputerName
Use this to specify the computer(s) which you'd like to retrieve information about monitors from.
.EXAMPLE
PS C:/> Get-Monitor.ps1 -ComputerName SSL1-F1102-1G2Z
Manufacturer Model SerialNumber AttachedComputer
------------ ----- ------------ ----------------
HP HP E241i CN12345678 SSL1-F1102-1G2Z
HP HP E241i CN91234567 SSL1-F1102-1G2Z
HP HP E241i CN89123456 SSL1-F1102-1G2Z
.EXAMPLE
PS C:/> $Computers = @("SSL7-F108F-9D4Z","SSL1-F1102-1G2Z","SSA7-F1071-0T7F")
PS C:/> Get-Monitor.ps1 -ComputerName $Computers
Manufacturer Model SerialNumber AttachedComputer
------------ ----- ------------ ----------------
HP HP LA2405x CN12345678 SSL7-F108F-9D4Z
HP HP E241i CN91234567 SSL1-F1102-1G2Z
HP HP E241i CN89123456 SSL1-F1102-1G2Z
HP HP E241i CN78912345 SSL1-F1102-1G2Z
HP HP ZR22w CN67891234 SSA7-F1071-0T7F
#>
[CmdletBinding()]
PARAM (
[Parameter(ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)]
[String[]]$ComputerName = $env:ComputerName
)
#List of Manufacture Codes that could be pulled from WMI and their respective full names. Used for translating later down.
$ManufacturerHash = @{
"AAC" = "AcerView";
"ACR" = "Acer";
"AOC" = "AOC";
"AIC" = "AG Neovo";
"APP" = "Apple Computer";
"AST" = "AST Research";
"AUO" = "Asus";
"BNQ" = "BenQ";
"CMO" = "Acer";
"CPL" = "Compal";
"CPQ" = "Compaq";
"CPT" = "Chunghwa Pciture Tubes, Ltd.";
"CTX" = "CTX";
"DEC" = "DEC";
"DEL" = "Dell";
"DPC" = "Delta";
"DWE" = "Daewoo";
"EIZ" = "EIZO";
"ELS" = "ELSA";
"ENC" = "EIZO";
"EPI" = "Envision";
"FCM" = "Funai";
"FUJ" = "Fujitsu";
"FUS" = "Fujitsu-Siemens";
"GSM" = "LG Electronics";
"GWY" = "Gateway 2000";
"HEI" = "Hyundai";
"HIT" = "Hyundai";
"HSL" = "Hansol";
"HTC" = "Hitachi/Nissei";
"HWP" = "HP";
"IBM" = "IBM";
"ICL" = "Fujitsu ICL";
"IVM" = "Iiyama";
"KDS" = "Korea Data Systems";
"LEN" = "Lenovo";
"LGD" = "Asus";
"LPL" = "Fujitsu";
"MAX" = "Belinea";
"MEI" = "Panasonic";
"MEL" = "Mitsubishi Electronics";
"MS_" = "Panasonic";
"NAN" = "Nanao";
"NEC" = "NEC";
"NOK" = "Nokia Data";
"NVD" = "Fujitsu";
"OPT" = "Optoma";
"PHL" = "Philips";
"REL" = "Relisys";
"SAN" = "Samsung";
"SAM" = "Samsung";
"SBI" = "Smarttech";
"SGI" = "SGI";
"SNY" = "Sony";
"SRC" = "Shamrock";
"SUN" = "Sun Microsystems";
"SEC" = "Hewlett-Packard";
"TAT" = "Tatung";
"TOS" = "Toshiba";
"TSB" = "Toshiba";
"VSC" = "ViewSonic";
"ZCM" = "Zenith";
"UNK" = "Unknown";
"_YV" = "Fujitsu";
}
#Takes each computer specified and runs the following code:
ForEach ($Computer in $ComputerName) {
#Grabs the Monitor objects from WMI
$Monitors = Get-WmiObject -Namespace "root\WMI" -Class "WMIMonitorID" -ComputerName $Computer -ErrorAction SilentlyContinue
#Creates an empty array to hold the data
$Monitor_Array = @()
#Takes each monitor object found and runs the following code:
ForEach ($Monitor in $Monitors) {
#Grabs respective data and converts it from ASCII encoding and removes any trailing ASCII null values
If ([System.Text.Encoding]::ASCII.GetString($Monitor.UserFriendlyName) -ne $null) {
$Mon_Model = ([System.Text.Encoding]::ASCII.GetString($Monitor.UserFriendlyName)).Replace("$([char]0x0000)", "")
}
else {
$Mon_Model = $null
}
$Mon_Serial_Number = ([System.Text.Encoding]::ASCII.GetString($Monitor.SerialNumberID)).Replace("$([char]0x0000)", "")
$Mon_Attached_Computer = ($Monitor.PSComputerName).Replace("$([char]0x0000)", "")
$Mon_Manufacturer = ([System.Text.Encoding]::ASCII.GetString($Monitor.ManufacturerName)).Replace("$([char]0x0000)", "")
#Filters out "non monitors". Place any of your own filters here. These two are all-in-one computers with built in displays. I don't need the info from these.
If ($Mon_Model -like "*800 AIO*" -or $Mon_Model -like "*8300 AiO*") { Break }
#Sets a friendly name based on the hash table above. If no entry found sets it to the original 3 character code
$Mon_Manufacturer_Friendly = $ManufacturerHash.$Mon_Manufacturer
If ($Mon_Manufacturer_Friendly -eq $null) {
$Mon_Manufacturer_Friendly = $Mon_Manufacturer
}
#Creates a custom monitor object and fills it with 4 NoteProperty members and the respective data
$Monitor_Obj = [PSCustomObject]@{
Manufacturer = $Mon_Manufacturer_Friendly
Model = $Mon_Model
SerialNumber = $Mon_Serial_Number
AttachedComputer = $Mon_Attached_Computer
}
#Appends the object to the array
$Monitor_Array += $Monitor_Obj
} #End ForEach Monitor
#Outputs the Array
$Monitor_Array
} #End ForEach Computer

View File

@@ -0,0 +1,26 @@
#Identifies Computer RAM capacity and status
[Cmdletbinding()]
Param(
[string]$Computername = "localhost"
)
cls
$PysicalMemory = Get-WmiObject -class "win32_physicalmemory" -namespace "root\CIMV2" -ComputerName $Computername
Write-Host "RAM Modules:" -ForegroundColor Green
$PysicalMemory | Format-Table Tag, BankLabel, @{n = "Capacity(GB)"; e = { $_.Capacity / 1GB } }, Manufacturer, PartNumber, Speed -AutoSize
Write-Host "Total Memory:" -ForegroundColor Green
Write-Host "$((($PysicalMemory).Capacity | Measure-Object -Sum).Sum/1GB)GB"
$TotalSlots = ((Get-WmiObject -Class "win32_PhysicalMemoryArray" -namespace "root\CIMV2" -ComputerName $Computername).MemoryDevices | Measure-Object -Sum).Sum
Write-Host "`nTotal Memory Slots:" -ForegroundColor Green
Write-Host $TotalSlots
$UsedSlots = (($PysicalMemory) | Measure-Object).Count
Write-Host "`nUsed Memory Slots:" -ForegroundColor Green
Write-Host $UsedSlots
If ($UsedSlots -eq $TotalSlots) {
Write-Host "All memory slots are filled up, none is empty!" -ForegroundColor Yellow
}

View File

@@ -0,0 +1,17 @@
$ErrorActionPreference= 'silentlycontinue'
$TimeSpan = (Get-Date) - (New-TimeSpan -Day 1)
if (Get-WinEvent -FilterHashtable @{LogName='security';ID='4720','4720','4728','4732','4756','4767';StartTime=$TimeSpan})
{
Write-Output "A change has been made to local users"
Get-WinEvent -FilterHashtable @{LogName='security';ID='4720','4720','4728','4732','4756','4767';StartTime=$TimeSpan}
exit 1
}
else
{
Write-Output "No changes all looks fine"
exit 0
}
Exit $LASTEXITCODE

View File

@@ -0,0 +1 @@
%SYSTEMROOT%\System32\powercfg.exe -H OFF

View File

@@ -0,0 +1 @@
Clear-RecycleBin -Force

View File

@@ -0,0 +1,3 @@
#This script sets current network profile to Private
$net = get-netconnectionprofile;Set-NetConnectionProfile -Name $net.Name -NetworkCategory Private

View File

@@ -0,0 +1 @@
Remove-Item -Path "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Tactical RMM Agent.lnk" -Force

View File

@@ -0,0 +1,6 @@
# Add a task to Task Scheduler
$Trigger = New-ScheduledTaskTrigger -At 10:00am Daily # Specify the trigger settings
$User = "NT AUTHORITY\SYSTEM" # Specify the account to run the script
$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "YOUR COMMAND HERE" # Specify what program to run and with its parameters
Register-ScheduledTask -TaskName "SomeTaskName" -Trigger $Trigger -User $User -Action $Action -RunLevel Highest Force # Specify the name of the task

View File

@@ -0,0 +1,18 @@
$ErrorActionPreference= 'silentlycontinue'
$TimeSpan = (Get-Date) - (New-TimeSpan -Day 1)
if (Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-TaskScheduler/Operational';ID='106';StartTime=$TimeSpan} | Where-Object -Property Message -notlike *$env:COMPUTERNAME*)
{
Write-Output "New Task Has Been Added"
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-TaskScheduler/Operational';ID='106';StartTime=$TimeSpan}
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-TaskScheduler/Operational';ID='141';StartTime=$TimeSpan}
exit 1
}
else
{
Write-Output "No changes with Task Scheduler"
exit 0
}
Exit $LASTEXITCODE

View File

@@ -0,0 +1,22 @@
$ErrorActionPreference = 'silentlycontinue'
$PSDenabled = (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System).PromptOnSecureDesktop
$CPAenabled = (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System).ConsentPromptBehaviorAdmin
if ($PSDenabled -Eq 1 -And $CPAenabled -Eq 5) {
Write-Output "UAC is Enabled"
exit 0
}
elseif ($PSDenabled -Eq 1 -And $CPAenabled -Eq 2) {
Write-Output "UAC is Enabled"
exit 0
}
else {
Write-Output "UAC is Disabled"
exit 1
}
Exit $LASTEXITCODE

View File

@@ -0,0 +1 @@
reg add HKLM\SYSTEM\CurrentControlSet\Services\UsbStor /v "Start" /t REG_DWORD /d "4" /f

View File

@@ -0,0 +1 @@
reg add HKLM\SYSTEM\CurrentControlSet\Services\UsbStor /v "Start" /t REG_DWORD /d "3" /f

View File

@@ -0,0 +1,17 @@
$ErrorActionPreference= 'silentlycontinue'
$TimeSpan = (Get-Date) - (New-TimeSpan -Day 1)
if (Get-WinEvent -FilterHashtable @{LogName='Application';ID='1511';StartTime=$TimeSpan})
{
Write-Output "An account has been logged in with a Temporary profile"
Get-WinEvent -FilterHashtable @{LogName='Application';ID='1511';StartTime=$TimeSpan}
exit 1
}
else
{
Write-Output "All looks fine"
exit 0
}
Exit $LASTEXITCODE

View File

@@ -0,0 +1,90 @@
[CmdletBinding()]
param ()
begin {
$PPNuGet = Get-PackageProvider -ListAvailable | Where-Object { $_.Name -eq 'Nuget' }
if (!$PPNuget) {
Write-Output 'Installing Nuget provider'
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
}
$PSGallery = Get-PSRepository -Name PsGallery
if (!$PSGallery) {
Write-Output 'Setting PSGallery as trusted Repository'
Set-PSRepository -InstallationPolicy Trusted -Name PSGallery
}
$PsGetVersion = (Get-Module PowerShellGet).version
if ($PsGetVersion -lt [version]'2.0') {
Write-Output 'Installing latest version of PowerShellGet provider'
Install-Module PowerShellGet -MinimumVersion 2.2 -Force
Write-Output 'Reloading Modules'
Remove-Module PowerShellGet -Force
Remove-Module PackageManagement -Force
Import-Module PowerShellGet -MinimumVersion 2.2 -Force
Write-Output 'Updating PowerShellGet'
Install-Module -Name PowerShellGet -MinimumVersion 2.2.3 -Force
Write-Output 'PowerShellGet update requires all active PS Sessions to be restarted before it can continue.'
Exit 1
}
}
process {
Write-Output 'Checking device Manufacturer'
$Manufacturer = (Get-WmiObject -Class:Win32_ComputerSystem).Manufacturer
if ($Manufacturer -like '*Dell*') {
Write-Output 'Manufacturer is Dell. Installing Module and trying to enable Wake on LAN.'
Write-Output 'Installing Dell Bios Provider'
Install-Module -Name DellBIOSProvider -Force
Import-Module DellBIOSProvider
try {
Set-Item -Path 'DellSmBios:\PowerManagement\WakeOnLan' -Value 'LANOnly' -ErrorAction Stop
}
catch {
Write-Output 'An error occured. Was unable to set WakeOnLan.'
Exit 2
}
}
if ($Manufacturer -like '*HP*' -or $Manufacturer -like '*Hewlett*') {
Write-Output 'Manufacturer is HP. Installing module and trying to enable WakeOnLan. All HP Drivers are required for this operation to succeed.'
Write-Output 'Installing HP Provider'
Install-Module -Name HPCMSL -Force -AcceptLicense
Import-Module HPCMSL
try {
$WolTypes = get-hpbiossettingslist | Where-Object { $_.Name -like '*Wake On Lan*' }
ForEach ($WolType in $WolTypes) {
Write-Output "Setting WOL Type: $($WOLType.Name)"
Set-HPBIOSSettingValue -name $($WolType.name) -Value 'Boot to Hard Drive' -ErrorAction Stop
}
}
catch {
Write-Output 'An error occured. Was unable to set WakeOnLan.'
Exit 2
}
}
if ($Manufacturer -like '*Lenovo*') {
Write-Output 'Manufacturer is Lenovo. Trying to set via WMI. All Lenovo Drivers are required for this operation to succeed.'
try {
Write-Output 'Setting BIOS.'
(Get-WmiObject -ErrorAction Stop -class 'Lenovo_SetBiosSetting' -namespace 'root\wmi').SetBiosSetting('WakeOnLAN,Primary') | Out-Null
Write-Output 'Saving BIOS.'
(Get-WmiObject -ErrorAction Stop -class 'Lenovo_SaveBiosSettings' -namespace 'root\wmi').SaveBiosSettings() | Out-Null
}
catch {
Write-Output 'An error occured. Was unable to set WakeOnLan.'
Exit 2
}
}
}
end {
Write-Output 'Setting NIC to enable WOL'
$NicsWithWake = Get-CimInstance -ClassName 'MSPower_DeviceWakeEnable' -Namespace 'root/wmi'
foreach ($Nic in $NicsWithWake) {
Write-Output 'Enabling for NIC'
Set-CimInstance $NIC -Property @{Enable = $true }
}
Exit 0
}

View File

@@ -0,0 +1,105 @@
[CmdletBinding()]
param ()
begin {
$PPNuGet = Get-PackageProvider -ListAvailable | Where-Object { $_.Name -eq 'Nuget' }
if (!$PPNuget) {
Write-Output 'Installing Nuget provider'
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
}
$PSGallery = Get-PSRepository -Name PsGallery
if (!$PSGallery) {
Write-Output 'Installing PSGallery'
Set-PSRepository -InstallationPolicy Trusted -Name PSGallery
}
$PsGetVersion = (Get-Module PowerShellGet).version
if ($PsGetVersion -lt [version]'2.0') {
Write-Output 'Installing latest version of PowerShellGet provider'
Install-Module PowerShellGet -MinimumVersion 2.2 -Force
Write-Output 'Reloading Modules'
Remove-Module PowerShellGet -Force
Remove-Module PackageManagement -Force
Import-Module PowerShellGet -MinimumVersion 2.2 -Force
Write-Output 'Updating PowerShellGet'
Install-Module -Name PowerShellGet -MinimumVersion 2.2.3 -Force
Write-Output 'PowerShellGet update requires all active PS Sessions to be restarted before it can continue.'
Exit 1
}
}
process {
Write-Output 'Checking Manufacturer'
$Manufacturer = (Get-WmiObject -Class:Win32_ComputerSystem).Manufacturer
if ($Manufacturer -like '*Dell*') {
Write-Output 'Manufacturer is Dell. Installing Module and trying to get WOL state'
Write-Output 'Installing Dell Bios Provider if needed'
$Mod = Get-Module DellBIOSProvider
if (!$mod) {
Install-Module -Name DellBIOSProvider -Force
}
Import-Module DellBIOSProvider
try {
$WOLMonitor = Get-Item -Path 'DellSmBios:\PowerManagement\WakeOnLan' -ErrorAction SilentlyContinue
if ($WOLMonitor.currentvalue -eq 'LanOnly') { $WOLState = 'Healthy' }
}
catch {
Write-Output 'An error occured. Could not get WOL setting.'
Exit 3
}
}
if ($Manufacturer -like '*HP*' -or $Manufacturer -like '*Hewlett*') {
Write-Output 'Manufacturer is HP. Installing module and trying to get WOL State.'
Write-Output 'Installing HP Provider if needed.'
$Mod = Get-Module HPCMSL
if (!$mod) {
Install-Module -Name HPCMSL -Force -AcceptLicense
}
Import-Module HPCMSL
try {
$WolTypes = get-hpbiossettingslist | Where-Object { $_.Name -like '*Wake On Lan*' }
$WOLState = ForEach ($WolType in $WolTypes) {
Write-Output "Setting WOL Type: $($WOLType.Name)"
get-HPBIOSSettingValue -name $($WolType.name) -ErrorAction Stop
}
}
catch {
Write-Output 'An error occured. Could not find WOL state'
Exit 3
}
}
if ($Manufacturer -like '*Lenovo*') {
Write-Output 'Manufacturer is Lenovo. Trying to get via WMI'
try {
Write-Output 'Getting BIOS.'
$currentSetting = (Get-WmiObject -ErrorAction Stop -class 'Lenovo_BiosSetting' -namespace 'root\wmi') | Where-Object { $_.CurrentSetting -ne '' }
$WOLStatus = $currentSetting.currentsetting | ConvertFrom-Csv -Delimiter ',' -Header 'Setting', 'Status' | Where-Object { $_.setting -eq 'Wake on lan' }
$WOLStatus = $WOLStatus.status -split ';'
if ($WOLStatus[0] -eq 'Primary') { $WOLState = 'Healthy' }
}
catch {
Write-Output 'An error occured. Could not find WOL state'
Exit 3
}
}
}
end {
$NicsWithWake = Get-CimInstance -ClassName 'MSPower_DeviceWakeEnable' -Namespace 'root/wmi' | Where-Object { $_.Enable -eq $False }
if (!$NicsWithWake) {
$NICWOL = 'Healthy - All NICs enabled for WOL within the OS.'
Exit 0
}
else {
$NICWOL = 'Unhealthy - NIC does not have WOL enabled inside of the OS.'
Exit 4
}
if (!$WOLState) {
$NICWOL = 'Unhealthy - Could not find WOL state'
Exit 3
}
return $NICWOL
}

View File

@@ -0,0 +1,48 @@
<#
.SYNOPSIS
License Windows 10
.DESCRIPTION
Insert License key into Windows 10 and activate
.NOTES
For Windows installations in different languages, you will need to edit the following:
Select-String -Pattern "^License Status:"
and
$LicenseStatus -match "Licensed"
to match your specific language translation.
.FUNCTIONALITY
PowerShell v3+
#>
if ($Args.Count -eq 0) {
Write-Output "New Product Key is Required"
exit 1
}
$param1 = $args[0]
$OSKey = "$param1"
$SLMgr = "C:\Windows\System32\slmgr.vbs"
Write-Output "Inserting license key: $OSKey"
$InsertKey = & cscript $SLMgr /ipk $OSKey
$RetryCount = 3
while ($RetryCount -gt 0) {
Write-Output "Activating license key..."
& cscript $SLMgr /ato
Write-Output "Verifying activation status"
$SLMgrResult = & cscript $SLMgr /dli
$LicenseStatus = ([string]($SLMgrResult | Select-String -Pattern "^License Status:")).Remove(0, 16)
if ($LicenseStatus -match "Licensed") {
Write-Host "Activation Successful" -ForegroundColor Green
$retryCount = 0
}
else {
Write-Error "Activation failed."
$RetryCount -= 1
}
}

View File

@@ -89,7 +89,6 @@ module.exports = function () {
],
config: {
loadingBar: {
color: "red",
size: "4px"
},
notify: {

View File

@@ -23,6 +23,7 @@
<q-tab name="base_board" label="Motherboard" />
<q-tab name="comp_sys_prod" label="Computer System Product" />
<q-tab name="network_config" label="Network Config" />
<q-tab name="graphics" label="Graphics" />
<q-tab name="desktop_monitor" label="Monitors" />
<q-tab name="network_adapter" label="Network Adapters" />
</q-tabs>
@@ -63,6 +64,9 @@
<q-tab-panel name="desktop_monitor">
<WmiDetail :info="desktop_monitor" />
</q-tab-panel>
<q-tab-panel name="graphics">
<WmiDetail :info="graphics" />
</q-tab-panel>
<q-tab-panel name="network_adapter">
<WmiDetail :info="network_adapter" />
</q-tab-panel>
@@ -125,6 +129,9 @@ export default {
network_adapter() {
return this.assets.network_adapter;
},
graphics() {
return this.assets.graphics;
},
},
};
</script>

View File

@@ -89,6 +89,10 @@
<q-item clickable v-close-popup @click="showEditCoreSettingsModal = true">
<q-item-section>Global Settings</q-item-section>
</q-item>
<!-- code sign -->
<q-item clickable v-close-popup @click="showCodeSign = true">
<q-item-section>Code Signing</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
@@ -179,6 +183,10 @@
<q-dialog v-model="showServerMaintenance">
<ServerMaintenance @close="showMaintenance = false" />
</q-dialog>
<!-- Code Sign -->
<q-dialog v-model="showCodeSign">
<CodeSign @close="showCodeSign = false" />
</q-dialog>
</q-bar>
</div>
</template>
@@ -201,6 +209,7 @@ import AuditManager from "@/components/AuditManager";
import BulkAction from "@/components/modals/agents/BulkAction";
import Deployment from "@/components/Deployment";
import ServerMaintenance from "@/components/modals/core/ServerMaintenance";
import CodeSign from "@/components/modals/coresettings/CodeSign";
export default {
name: "FileBar",
@@ -217,6 +226,7 @@ export default {
BulkAction,
Deployment,
ServerMaintenance,
CodeSign,
},
data() {
return {
@@ -233,6 +243,7 @@ export default {
showDeployment: false,
showDebugLog: false,
showScriptManager: false,
showCodeSign: false,
};
},
methods: {

View File

@@ -39,6 +39,13 @@
</q-item-section>
<q-item-section>{{ disk }}</q-item-section>
</q-item>
<!-- graphics -->
<q-item>
<q-item-section avatar>
<q-icon name="fas fa-tv" />
</q-item-section>
<q-item-section>{{ summary.graphics }}</q-item-section>
</q-item>
<q-item>
<q-item-section avatar>
<q-icon name="fas fa-globe-americas" />

View File

@@ -0,0 +1,67 @@
<template>
<q-card style="min-width: 85vh">
<q-card-section class="row items-center">
<div class="text-h6">Code Signing</div>
<q-space />
<q-btn icon="close" flat round dense v-close-popup />
</q-card-section>
<q-form @submit.prevent="editToken">
<q-card-section class="row">
<div class="col-2">Token:</div>
<div class="col-1"></div>
<q-input
outlined
dense
v-model="settings.token"
class="col-9 q-pa-none"
:rules="[val => !!val || 'Token is required']"
/>
</q-card-section>
<q-card-section class="row items-center">
<q-btn label="Save" color="primary" type="submit" />
</q-card-section>
</q-form>
</q-card>
</template>
<script>
import mixins from "@/mixins/mixins";
export default {
name: "CodeSign",
mixins: [mixins],
data() {
return {
settings: {
token: "",
},
};
},
methods: {
getToken() {
this.$axios
.get("/core/codesign/")
.then(r => {
this.settings = r.data;
})
.catch(e => this.notifyError(e.response.data));
},
editToken() {
this.$q.loading.show();
this.$axios
.patch("/core/codesign/", this.settings)
.then(r => {
this.$q.loading.hide();
this.notifySuccess(r.data);
this.$emit("close");
})
.catch(e => {
this.$q.loading.hide();
this.notifyError(e.response.data, 4000);
});
},
},
created() {
this.getToken();
},
};
</script>

View File

@@ -46,6 +46,18 @@
class="col-4"
/>
</q-card-section>
<q-card-section class="row">
<div class="col-4">Loading Bar Color:</div>
<div class="col-4"></div>
<q-select
outlined
dense
options-dense
v-model="loading_bar_color"
:options="loadingBarColors"
class="col-4"
/>
</q-card-section>
<q-card-section class="row">
<div class="col-2">Client Sort:</div>
<div class="col-2"></div>
@@ -73,6 +85,7 @@
</template>
<script>
import { loadingBarColors } from "@/mixins/data";
import mixins from "@/mixins/mixins";
export default {
@@ -80,11 +93,13 @@ export default {
mixins: [mixins],
data() {
return {
loadingBarColors,
agentDblClickAction: "",
defaultAgentTblTab: "",
clientTreeSort: "",
tab: "ui",
splitterModel: 20,
loading_bar_color: "",
clientTreeSortOptions: [
{
label: "Sort alphabetically, moving failing clients to the top",
@@ -131,6 +146,7 @@ export default {
this.agentDblClickAction = r.data.dbl_click_action;
this.defaultAgentTblTab = r.data.default_agent_tbl_tab;
this.clientTreeSort = r.data.client_tree_sort;
this.loading_bar_color = r.data.loading_bar_color;
});
},
editUserPrefs() {
@@ -138,6 +154,7 @@ export default {
agent_dblclick_action: this.agentDblClickAction,
default_agent_tbl_tab: this.defaultAgentTblTab,
client_tree_sort: this.clientTreeSort,
loading_bar_color: this.loading_bar_color,
};
this.$axios.patch("/accounts/users/ui/", data).then(r => {
this.notifySuccess("Preferences were saved!");

View File

@@ -20,21 +20,6 @@
label="Select script"
map-options
emit-value
/>
</q-card-section>
<q-card-section>
<q-select
dense
label="Script Arguments (press Enter after typing each argument)"
filled
v-model="localTask.script_args"
use-input
use-chips
multiple
hide-dropdown-icon
input-debounce="0"
new-value-mode="add"
@input="setScriptDefaults"
>
<template v-slot:option="scope">
<q-item v-if="!scope.opt.category" v-bind="scope.itemProps" v-on="scope.itemEvents" class="q-pl-lg">
@@ -48,6 +33,21 @@
</template>
</q-select>
</q-card-section>
<q-card-section>
<q-select
dense
label="Script Arguments (press Enter after typing each argument)"
filled
v-model="localTask.script_args"
use-input
use-chips
multiple
hide-dropdown-icon
input-debounce="0"
new-value-mode="add"
@input="setScriptDefaults"
/>
</q-card-section>
<q-card-section>
<q-input
:rules="[val => !!val || '*Required']"
@@ -55,6 +55,7 @@
dense
v-model="localTask.name"
label="Descriptive name of task"
class="q-pb-none"
/>
</q-card-section>
<q-card-section>
@@ -77,6 +78,7 @@
v-model.number="localTask.timeout"
type="number"
label="Maximum permitted execution time (seconds)"
class="q-pb-none"
/>
</q-card-section>
<q-card-actions align="right">

View File

@@ -59,4 +59,6 @@ const monthDays = [
"31"
]
export { scheduledTimes, monthDays };
const loadingBarColors = ["red", "pink", "purple", "deep-purple", "indigo", "blue", "light-blue", "cyan", "teal", "green", "light-green", "lime", "yellow", "amber", "orange", "deep-orange", "brown", "grey", "blue-grey"]
export { scheduledTimes, monthDays, loadingBarColors };

View File

@@ -33,8 +33,12 @@ export default function () {
agentDblClickAction: "",
defaultAgentTblTab: "server",
clientTreeSort: "alphafail",
clientTreeSplitter: 11,
},
getters: {
clientTreeSplitterModel(state) {
return state.clientTreeSplitter;
},
loggedIn(state) {
return state.token !== null;
},
@@ -132,6 +136,9 @@ export default function () {
agentHeight <= 15.0 ? state.tableHeight = "15vh" : state.tableHeight = `${agentHeight}vh`;
tabsHeight <= 15.0 ? state.tabHeight = "15vh" : state.tabHeight = `${tabsHeight}vh`;
},
SET_CLIENT_SPLITTER(state, val) {
state.clientTreeSplitter = val;
},
SET_NOTES(state, notes) {
state.notes = notes;
},
@@ -149,6 +156,11 @@ export default function () {
}
},
actions: {
setClientTreeSplitter(context, val) {
axios.patch("/accounts/users/ui/", { client_tree_splitter: Math.trunc(val) }).then(r => {
context.commit("SET_CLIENT_SPLITTER", val)
})
},
setShowCommunityScripts(context, data) {
axios.patch("/accounts/users/ui/", { show_community_scripts: data }).then(r => {
context.commit("setShowCommunityScripts", data)

View File

@@ -90,7 +90,7 @@
<q-page-container>
<FileBar />
<q-splitter v-model="outsideModel">
<q-splitter v-model="clientTreeSplitter">
<template v-slot:before>
<div v-if="!treeReady" class="q-pa-sm q-gutter-sm text-center" style="height: 30vh">
<q-spinner size="40px" color="primary" />
@@ -397,7 +397,6 @@ export default {
serverOfflineCount: 0,
workstationCount: 0,
workstationOfflineCount: 0,
outsideModel: 11,
selectedTree: "",
innerModel: 50,
clientActive: "",
@@ -712,8 +711,10 @@ export default {
getDashInfo(edited = true) {
this.$store.dispatch("getDashInfo").then(r => {
if (edited) {
this.$q.loadingBar.setDefaults({ color: r.data.loading_bar_color });
this.$store.commit("SET_DEFAULT_AGENT_TBL_TAB", r.data.default_agent_tbl_tab);
this.$store.commit("SET_CLIENT_TREE_SORT", r.data.client_tree_sort);
this.$store.commit("SET_CLIENT_SPLITTER", r.data.client_tree_splitter);
}
this.darkMode = r.data.dark_mode;
this.$q.dark.set(this.darkMode);
@@ -802,13 +803,21 @@ export default {
treeReady: state => state.treeReady,
clients: state => state.clients,
}),
...mapGetters(["selectedAgentPk", "needRefresh"]),
...mapGetters(["selectedAgentPk", "needRefresh", "clientTreeSplitterModel"]),
wsUrl() {
return getBaseUrl().split("://")[1];
},
token() {
return this.$store.state.token;
},
clientTreeSplitter: {
get: function () {
return this.clientTreeSplitterModel;
},
set: function (newVal) {
this.$store.dispatch("setClientTreeSplitter", newVal);
},
},
tab: {
get: function () {
return this.$store.state.defaultAgentTblTab;

View File

@@ -72,10 +72,11 @@ export default {
this.title = `${r.data.hostname} - ${r.data.client} - ${r.data.site} | Remote Background`;
});
},
getDark() {
getUI() {
this.$store.dispatch("getDashInfo").then(r => {
this.darkMode = r.data.dark_mode;
this.$q.dark.set(this.darkMode);
this.$q.loadingBar.setDefaults({ color: r.data.loading_bar_color });
});
},
},
@@ -90,7 +91,7 @@ export default {
},
},
created() {
this.getDark();
this.getUI();
this.genURLS();
},
};

View File

@@ -54,6 +54,12 @@ export default {
};
},
methods: {
getUI() {
this.$store.dispatch("getDashInfo").then(r => {
this.$q.dark.set(r.data.dark_mode);
this.$q.loadingBar.setDefaults({ color: r.data.loading_bar_color });
});
},
genURL() {
this.$q.loading.show();
this.visible = false;
@@ -117,6 +123,7 @@ export default {
},
},
created() {
this.getUI();
this.genURL();
},
};