Compare commits
	
		
			32 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 5aa15c51ec | ||
|  | a8aedd9cf3 | ||
|  | b851b632bc | ||
|  | 541e07fb65 | ||
|  | 6ad16a897d | ||
|  | 72f1053a93 | ||
|  | fb15a2762c | ||
|  | 9165248b91 | ||
|  | add18b29db | ||
|  | 1971653548 | ||
|  | 392cd64d7b | ||
|  | b5affbb7c8 | ||
|  | 71d1206277 | ||
|  | 26e6a8c409 | ||
|  | eb54fae11a | ||
|  | ee773e5966 | ||
|  | 7218ccdba8 | ||
|  | 332400e48a | ||
|  | ad1a5d3702 | ||
|  | 3006b4184d | ||
|  | 84eb84a080 | ||
|  | 60beea548b | ||
|  | 5f9c149e59 | ||
|  | 53367c6f04 | ||
|  | d7f817ee44 | ||
|  | d33a87da54 | ||
|  | 3aebfb12b7 | ||
|  | 1d6c55ffa6 | ||
|  | 5e7080aac3 | ||
|  | fad739bc01 | ||
|  | c6b7f23884 | ||
|  | a6f7e446de | 
| @@ -211,6 +211,7 @@ def agent_outages_task() -> None: | ||||
|  | ||||
|     agents = Agent.objects.only( | ||||
|         "pk", | ||||
|         "agent_id", | ||||
|         "last_seen", | ||||
|         "offline_time", | ||||
|         "overdue_time", | ||||
|   | ||||
| @@ -321,11 +321,16 @@ class CheckRunner(APIView): | ||||
|  | ||||
|     def patch(self, request): | ||||
|         check = get_object_or_404(Check, pk=request.data["id"]) | ||||
|         if pyver.parse(check.agent.version) < pyver.parse("1.5.7"): | ||||
|             return notify_error("unsupported") | ||||
|  | ||||
|         check.last_run = djangotime.now() | ||||
|         check.save(update_fields=["last_run"]) | ||||
|         status = check.handle_checkv2(request.data) | ||||
|         status = check.handle_check(request.data) | ||||
|         if status == "failing" and check.assignedtask.exists():  # type: ignore | ||||
|             check.handle_assigned_task() | ||||
|  | ||||
|         return Response(status) | ||||
|         return Response("ok") | ||||
|  | ||||
|  | ||||
| class CheckRunnerInterval(APIView): | ||||
| @@ -378,9 +383,18 @@ class TaskRunner(APIView): | ||||
|                     ) | ||||
|  | ||||
|                 # get last line of stdout | ||||
|                 value = new_task.stdout.split("\n")[-1].strip() | ||||
|                 value = ( | ||||
|                     new_task.stdout | ||||
|                     if task.collector_all_output | ||||
|                     else new_task.stdout.split("\n")[-1].strip() | ||||
|                 ) | ||||
|  | ||||
|                 if task.custom_field.type in ["text", "number", "single", "datetime"]: | ||||
|                 if task.custom_field.type in [ | ||||
|                     "text", | ||||
|                     "number", | ||||
|                     "single", | ||||
|                     "datetime", | ||||
|                 ]: | ||||
|                     agent_field.string_value = value | ||||
|                     agent_field.save() | ||||
|                 elif task.custom_field.type == "multiple": | ||||
|   | ||||
| @@ -0,0 +1,18 @@ | ||||
| # Generated by Django 3.2.1 on 2021-05-29 03:26 | ||||
|  | ||||
| from django.db import migrations, models | ||||
|  | ||||
|  | ||||
| class Migration(migrations.Migration): | ||||
|  | ||||
|     dependencies = [ | ||||
|         ('autotasks', '0021_alter_automatedtask_custom_field'), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
|         migrations.AddField( | ||||
|             model_name='automatedtask', | ||||
|             name='collector_all_output', | ||||
|             field=models.BooleanField(default=False), | ||||
|         ), | ||||
|     ] | ||||
| @@ -104,6 +104,7 @@ class AutomatedTask(BaseAuditModel): | ||||
|     task_type = models.CharField( | ||||
|         max_length=100, choices=TASK_TYPE_CHOICES, default="manual" | ||||
|     ) | ||||
|     collector_all_output = models.BooleanField(default=False) | ||||
|     run_time_date = DateTimeField(null=True, blank=True) | ||||
|     remove_if_not_scheduled = models.BooleanField(default=False) | ||||
|     run_asap_after_missed = models.BooleanField(default=False)  # added in agent v1.4.7 | ||||
|   | ||||
| @@ -1,4 +1,3 @@ | ||||
| import asyncio | ||||
| import json | ||||
| import os | ||||
| import string | ||||
| @@ -14,9 +13,7 @@ from django.core.validators import MaxValueValidator, MinValueValidator | ||||
| from django.db import models | ||||
| from logs.models import BaseAuditModel | ||||
| from loguru import logger | ||||
| from packaging import version as pyver | ||||
|  | ||||
| from .utils import bytes2human | ||||
|  | ||||
| logger.configure(**settings.LOG_CONFIG) | ||||
|  | ||||
| @@ -318,7 +315,7 @@ class Check(BaseAuditModel): | ||||
|     def add_check_history(self, value: int, more_info: Any = None) -> None: | ||||
|         CheckHistory.objects.create(check_history=self, y=value, results=more_info) | ||||
|  | ||||
|     def handle_checkv2(self, data): | ||||
|     def handle_check(self, data): | ||||
|         from alerts.models import Alert | ||||
|  | ||||
|         # cpuload or mem checks | ||||
| @@ -349,9 +346,6 @@ class Check(BaseAuditModel): | ||||
|         elif self.check_type == "diskspace": | ||||
|             if data["exists"]: | ||||
|                 percent_used = round(data["percent_used"]) | ||||
|                 total = bytes2human(data["total"]) | ||||
|                 free = bytes2human(data["free"]) | ||||
|  | ||||
|                 if self.error_threshold and (100 - percent_used) < self.error_threshold: | ||||
|                     self.status = "failing" | ||||
|                     self.alert_severity = "error" | ||||
| @@ -365,7 +359,7 @@ class Check(BaseAuditModel): | ||||
|                 else: | ||||
|                     self.status = "passing" | ||||
|  | ||||
|                 self.more_info = f"Total: {total}B, Free: {free}B" | ||||
|                 self.more_info = data["more_info"] | ||||
|  | ||||
|                 # add check history | ||||
|                 self.add_check_history(100 - percent_used) | ||||
| @@ -381,12 +375,7 @@ class Check(BaseAuditModel): | ||||
|             self.stdout = data["stdout"] | ||||
|             self.stderr = data["stderr"] | ||||
|             self.retcode = data["retcode"] | ||||
|             try: | ||||
|                 # python agent | ||||
|                 self.execution_time = "{:.4f}".format(data["stop"] - data["start"]) | ||||
|             except: | ||||
|                 # golang agent | ||||
|                 self.execution_time = "{:.4f}".format(data["runtime"]) | ||||
|             self.execution_time = "{:.4f}".format(data["runtime"]) | ||||
|  | ||||
|             if data["retcode"] in self.info_return_codes: | ||||
|                 self.alert_severity = "info" | ||||
| @@ -422,22 +411,8 @@ class Check(BaseAuditModel): | ||||
|  | ||||
|         # ping checks | ||||
|         elif self.check_type == "ping": | ||||
|             output = data["output"] | ||||
|  | ||||
|             if pyver.parse(self.agent.version) <= pyver.parse("1.5.2"): | ||||
|                 # DEPRECATED | ||||
|                 success = ["Reply", "bytes", "time", "TTL"] | ||||
|                 if data["has_stdout"]: | ||||
|                     if all(x in output for x in success): | ||||
|                         self.status = "passing" | ||||
|                     else: | ||||
|                         self.status = "failing" | ||||
|                 elif data["has_stderr"]: | ||||
|                     self.status = "failing" | ||||
|             else: | ||||
|                 self.status = data["status"] | ||||
|  | ||||
|             self.more_info = output | ||||
|             self.status = data["status"] | ||||
|             self.more_info = data["output"] | ||||
|             self.save(update_fields=["more_info"]) | ||||
|  | ||||
|             self.add_check_history( | ||||
| @@ -446,41 +421,8 @@ class Check(BaseAuditModel): | ||||
|  | ||||
|         # windows service checks | ||||
|         elif self.check_type == "winsvc": | ||||
|             svc_stat = data["status"] | ||||
|             self.more_info = f"Status {svc_stat.upper()}" | ||||
|  | ||||
|             if data["exists"]: | ||||
|                 if svc_stat == "running": | ||||
|                     self.status = "passing" | ||||
|                 elif svc_stat == "start_pending" and self.pass_if_start_pending: | ||||
|                     self.status = "passing" | ||||
|                 else: | ||||
|                     if self.agent and self.restart_if_stopped: | ||||
|                         nats_data = { | ||||
|                             "func": "winsvcaction", | ||||
|                             "payload": {"name": self.svc_name, "action": "start"}, | ||||
|                         } | ||||
|                         r = asyncio.run(self.agent.nats_cmd(nats_data, timeout=32)) | ||||
|                         if r == "timeout" or r == "natsdown": | ||||
|                             self.status = "failing" | ||||
|                         elif not r["success"] and r["errormsg"]: | ||||
|                             self.status = "failing" | ||||
|                         elif r["success"]: | ||||
|                             self.status = "passing" | ||||
|                             self.more_info = f"Status RUNNING" | ||||
|                         else: | ||||
|                             self.status = "failing" | ||||
|                     else: | ||||
|                         self.status = "failing" | ||||
|  | ||||
|             else: | ||||
|                 if self.pass_if_svc_not_exist: | ||||
|                     self.status = "passing" | ||||
|                 else: | ||||
|                     self.status = "failing" | ||||
|  | ||||
|                 self.more_info = f"Service {self.svc_name} does not exist" | ||||
|  | ||||
|             self.status = data["status"] | ||||
|             self.more_info = data["more_info"] | ||||
|             self.save(update_fields=["more_info"]) | ||||
|  | ||||
|             self.add_check_history( | ||||
| @@ -488,49 +430,7 @@ class Check(BaseAuditModel): | ||||
|             ) | ||||
|  | ||||
|         elif self.check_type == "eventlog": | ||||
|             log = [] | ||||
|             is_wildcard = self.event_id_is_wildcard | ||||
|             eventType = self.event_type | ||||
|             eventID = self.event_id | ||||
|             source = self.event_source | ||||
|             message = self.event_message | ||||
|             r = data["log"] | ||||
|  | ||||
|             for i in r: | ||||
|                 if i["eventType"] == eventType: | ||||
|                     if not is_wildcard and not int(i["eventID"]) == eventID: | ||||
|                         continue | ||||
|  | ||||
|                     if not source and not message: | ||||
|                         if is_wildcard: | ||||
|                             log.append(i) | ||||
|                         elif int(i["eventID"]) == eventID: | ||||
|                             log.append(i) | ||||
|                         continue | ||||
|  | ||||
|                     if source and message: | ||||
|                         if is_wildcard: | ||||
|                             if source in i["source"] and message in i["message"]: | ||||
|                                 log.append(i) | ||||
|  | ||||
|                         elif int(i["eventID"]) == eventID: | ||||
|                             if source in i["source"] and message in i["message"]: | ||||
|                                 log.append(i) | ||||
|  | ||||
|                         continue | ||||
|  | ||||
|                     if source and source in i["source"]: | ||||
|                         if is_wildcard: | ||||
|                             log.append(i) | ||||
|                         elif int(i["eventID"]) == eventID: | ||||
|                             log.append(i) | ||||
|  | ||||
|                     if message and message in i["message"]: | ||||
|                         if is_wildcard: | ||||
|                             log.append(i) | ||||
|                         elif int(i["eventID"]) == eventID: | ||||
|                             log.append(i) | ||||
|  | ||||
|             log = data["log"] | ||||
|             if self.fail_when == "contains": | ||||
|                 if log and len(log) >= self.number_of_events_b4_alert: | ||||
|                     self.status = "failing" | ||||
| @@ -567,6 +467,11 @@ class Check(BaseAuditModel): | ||||
|  | ||||
|         return self.status | ||||
|  | ||||
|     def handle_assigned_task(self) -> None: | ||||
|         for task in self.assignedtask.all():  # type: ignore | ||||
|             if task.enabled: | ||||
|                 task.run_win_task() | ||||
|  | ||||
|     @staticmethod | ||||
|     def serialize(check): | ||||
|         # serializes the check and returns json | ||||
|   | ||||
| @@ -158,14 +158,8 @@ class AssignedTaskCheckRunnerField(serializers.ModelSerializer): | ||||
|  | ||||
| class CheckRunnerGetSerializer(serializers.ModelSerializer): | ||||
|     # only send data needed for agent to run a check | ||||
|     assigned_tasks = serializers.SerializerMethodField() | ||||
|     script = ScriptCheckSerializer(read_only=True) | ||||
|  | ||||
|     def get_assigned_tasks(self, obj): | ||||
|         if obj.assignedtask.exists(): | ||||
|             tasks = obj.assignedtask.all() | ||||
|             return AssignedTaskCheckRunnerField(tasks, many=True).data | ||||
|  | ||||
|     class Meta: | ||||
|         model = Check | ||||
|         exclude = [ | ||||
| @@ -193,6 +187,7 @@ class CheckRunnerGetSerializer(serializers.ModelSerializer): | ||||
|             "modified_by", | ||||
|             "modified_time", | ||||
|             "history", | ||||
|             "dashboard_alert", | ||||
|         ] | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -400,7 +400,7 @@ class TestCheckTasks(TacticalTestCase): | ||||
|     def setUp(self): | ||||
|         self.authenticate() | ||||
|         self.setup_coresettings() | ||||
|         self.agent = baker.make_recipe("agents.agent") | ||||
|         self.agent = baker.make_recipe("agents.agent", version="1.5.7") | ||||
|  | ||||
|     def test_prune_check_history(self): | ||||
|         from .tasks import prune_check_history | ||||
| @@ -526,6 +526,7 @@ class TestCheckTasks(TacticalTestCase): | ||||
|             "percent_used": 85, | ||||
|             "total": 500, | ||||
|             "free": 400, | ||||
|             "more_info": "More info", | ||||
|         } | ||||
|  | ||||
|         resp = self.client.patch(url, data, format="json") | ||||
| @@ -543,6 +544,7 @@ class TestCheckTasks(TacticalTestCase): | ||||
|             "percent_used": 95, | ||||
|             "total": 500, | ||||
|             "free": 400, | ||||
|             "more_info": "More info", | ||||
|         } | ||||
|  | ||||
|         resp = self.client.patch(url, data, format="json") | ||||
| @@ -573,6 +575,7 @@ class TestCheckTasks(TacticalTestCase): | ||||
|             "percent_used": 95, | ||||
|             "total": 500, | ||||
|             "free": 400, | ||||
|             "more_info": "More info", | ||||
|         } | ||||
|  | ||||
|         resp = self.client.patch(url, data, format="json") | ||||
| @@ -592,6 +595,7 @@ class TestCheckTasks(TacticalTestCase): | ||||
|             "percent_used": 95, | ||||
|             "total": 500, | ||||
|             "free": 400, | ||||
|             "more_info": "More info", | ||||
|         } | ||||
|  | ||||
|         resp = self.client.patch(url, data, format="json") | ||||
| @@ -608,6 +612,7 @@ class TestCheckTasks(TacticalTestCase): | ||||
|             "percent_used": 50, | ||||
|             "total": 500, | ||||
|             "free": 400, | ||||
|             "more_info": "More info", | ||||
|         } | ||||
|  | ||||
|         resp = self.client.patch(url, data, format="json") | ||||
| @@ -791,12 +796,7 @@ class TestCheckTasks(TacticalTestCase): | ||||
|         ) | ||||
|  | ||||
|         # test failing info | ||||
|         data = { | ||||
|             "id": ping.id, | ||||
|             "output": "Reply from 192.168.1.27: Destination host unreachable", | ||||
|             "has_stdout": True, | ||||
|             "has_stderr": False, | ||||
|         } | ||||
|         data = {"id": ping.id, "status": "failing", "output": "reply from a.com"} | ||||
|  | ||||
|         resp = self.client.patch(url, data, format="json") | ||||
|         self.assertEqual(resp.status_code, 200) | ||||
| @@ -806,13 +806,6 @@ class TestCheckTasks(TacticalTestCase): | ||||
|         self.assertEqual(new_check.alert_severity, "info") | ||||
|  | ||||
|         # test failing warning | ||||
|         data = { | ||||
|             "id": ping.id, | ||||
|             "output": "Reply from 192.168.1.27: Destination host unreachable", | ||||
|             "has_stdout": True, | ||||
|             "has_stderr": False, | ||||
|         } | ||||
|  | ||||
|         ping.alert_severity = "warning" | ||||
|         ping.save() | ||||
|  | ||||
| @@ -824,13 +817,6 @@ class TestCheckTasks(TacticalTestCase): | ||||
|         self.assertEqual(new_check.alert_severity, "warning") | ||||
|  | ||||
|         # test failing error | ||||
|         data = { | ||||
|             "id": ping.id, | ||||
|             "output": "Reply from 192.168.1.27: Destination host unreachable", | ||||
|             "has_stdout": True, | ||||
|             "has_stderr": False, | ||||
|         } | ||||
|  | ||||
|         ping.alert_severity = "error" | ||||
|         ping.save() | ||||
|  | ||||
| @@ -842,13 +828,6 @@ class TestCheckTasks(TacticalTestCase): | ||||
|         self.assertEqual(new_check.alert_severity, "error") | ||||
|  | ||||
|         # test failing error | ||||
|         data = { | ||||
|             "id": ping.id, | ||||
|             "output": "some output", | ||||
|             "has_stdout": False, | ||||
|             "has_stderr": True, | ||||
|         } | ||||
|  | ||||
|         resp = self.client.patch(url, data, format="json") | ||||
|         self.assertEqual(resp.status_code, 200) | ||||
|  | ||||
| @@ -857,12 +836,7 @@ class TestCheckTasks(TacticalTestCase): | ||||
|         self.assertEqual(new_check.alert_severity, "error") | ||||
|  | ||||
|         # test passing | ||||
|         data = { | ||||
|             "id": ping.id, | ||||
|             "output": "Reply from 192.168.1.1: bytes=32 time<1ms TTL=64", | ||||
|             "has_stdout": True, | ||||
|             "has_stderr": False, | ||||
|         } | ||||
|         data = {"id": ping.id, "status": "passing", "output": "reply from a.com"} | ||||
|  | ||||
|         resp = self.client.patch(url, data, format="json") | ||||
|         self.assertEqual(resp.status_code, 200) | ||||
| @@ -881,7 +855,7 @@ class TestCheckTasks(TacticalTestCase): | ||||
|         ) | ||||
|  | ||||
|         # test passing running | ||||
|         data = {"id": winsvc.id, "exists": True, "status": "running"} | ||||
|         data = {"id": winsvc.id, "status": "passing", "more_info": "ok"} | ||||
|  | ||||
|         resp = self.client.patch(url, data, format="json") | ||||
|         self.assertEqual(resp.status_code, 200) | ||||
| @@ -889,20 +863,8 @@ class TestCheckTasks(TacticalTestCase): | ||||
|         new_check = Check.objects.get(pk=winsvc.id) | ||||
|         self.assertEqual(new_check.status, "passing") | ||||
|  | ||||
|         # test passing start pending | ||||
|         winsvc.pass_if_start_pending = True | ||||
|         winsvc.save() | ||||
|  | ||||
|         data = {"id": winsvc.id, "exists": True, "status": "start_pending"} | ||||
|  | ||||
|         resp = self.client.patch(url, data, format="json") | ||||
|         self.assertEqual(resp.status_code, 200) | ||||
|  | ||||
|         new_check = Check.objects.get(pk=winsvc.id) | ||||
|         self.assertEqual(new_check.status, "passing") | ||||
|  | ||||
|         # test failing no start | ||||
|         data = {"id": winsvc.id, "exists": True, "status": "not running"} | ||||
|         # test failing | ||||
|         data = {"id": winsvc.id, "status": "failing", "more_info": "ok"} | ||||
|  | ||||
|         resp = self.client.patch(url, data, format="json") | ||||
|         self.assertEqual(resp.status_code, 200) | ||||
| @@ -911,7 +873,7 @@ class TestCheckTasks(TacticalTestCase): | ||||
|         self.assertEqual(new_check.status, "failing") | ||||
|         self.assertEqual(new_check.alert_severity, "info") | ||||
|  | ||||
|         # test failing and attempt start | ||||
|         """ # test failing and attempt start | ||||
|         winsvc.restart_if_stopped = True | ||||
|         winsvc.alert_severity = "warning" | ||||
|         winsvc.save() | ||||
| @@ -976,9 +938,9 @@ class TestCheckTasks(TacticalTestCase): | ||||
|         self.assertEqual(resp.status_code, 200) | ||||
|  | ||||
|         new_check = Check.objects.get(pk=winsvc.id) | ||||
|         self.assertEqual(new_check.status, "passing") | ||||
|         self.assertEqual(new_check.status, "passing") """ | ||||
|  | ||||
|     def test_handle_eventlog_check(self): | ||||
|     """ def test_handle_eventlog_check(self): | ||||
|         from checks.models import Check | ||||
|  | ||||
|         url = "/api/v3/checkrunner/" | ||||
| @@ -1180,4 +1142,4 @@ class TestCheckTasks(TacticalTestCase): | ||||
|  | ||||
|         new_check = Check.objects.get(pk=eventlog.id) | ||||
|  | ||||
|         self.assertEquals(new_check.status, "passing") | ||||
|         self.assertEquals(new_check.status, "passing") """ | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| from django.core.management.base import BaseCommand | ||||
|  | ||||
| from agents.models import Agent | ||||
| from logs.models import PendingAction | ||||
| from scripts.models import Script | ||||
|  | ||||
| @@ -9,22 +8,6 @@ class Command(BaseCommand): | ||||
|     help = "Collection of tasks to run after updating the rmm, after migrations" | ||||
|  | ||||
|     def handle(self, *args, **kwargs): | ||||
|         # 10-16-2020 changed the type of the agent's 'disks' model field | ||||
|         # from a dict of dicts, to a list of disks in the golang agent | ||||
|         # the following will convert dicts to lists for agent's still on the python agent | ||||
|         agents = Agent.objects.only("pk", "disks") | ||||
|         for agent in agents: | ||||
|             if agent.disks is not None and isinstance(agent.disks, dict): | ||||
|                 new = [] | ||||
|                 for k, v in agent.disks.items(): | ||||
|                     new.append(v) | ||||
|  | ||||
|                 agent.disks = new | ||||
|                 agent.save(update_fields=["disks"]) | ||||
|                 self.stdout.write( | ||||
|                     self.style.SUCCESS(f"Migrated disks on {agent.hostname}") | ||||
|                 ) | ||||
|  | ||||
|         # remove task pending actions. deprecated 4/20/2021 | ||||
|         PendingAction.objects.filter(action_type="taskaction").delete() | ||||
|  | ||||
|   | ||||
| @@ -85,7 +85,7 @@ def dashboard_info(request): | ||||
|             "client_tree_sort": request.user.client_tree_sort, | ||||
|             "client_tree_splitter": request.user.client_tree_splitter, | ||||
|             "loading_bar_color": request.user.loading_bar_color, | ||||
|             "no_code_sign": hasattr(settings, "NOCODESIGN") and settings.NOCODESIGN, | ||||
|             "hosted": hasattr(settings, "HOSTED") and settings.HOSTED, | ||||
|         } | ||||
|     ) | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| asgiref==3.3.4 | ||||
| asyncio-nats-client==0.11.4 | ||||
| celery==5.0.5 | ||||
| celery==5.1.0 | ||||
| certifi==2020.12.5 | ||||
| cffi==1.14.5 | ||||
| channels==3.0.3 | ||||
| @@ -8,12 +8,11 @@ channels_redis==3.2.0 | ||||
| chardet==4.0.0 | ||||
| cryptography==3.4.7 | ||||
| daphne==3.0.2 | ||||
| Django==3.2.2 | ||||
| Django==3.2.3 | ||||
| django-cors-headers==3.7.0 | ||||
| django-rest-knox==4.1.0 | ||||
| djangorestframework==3.12.4 | ||||
| future==0.18.2 | ||||
| kombu==5.0.2 | ||||
| loguru==0.5.3 | ||||
| msgpack==1.0.2 | ||||
| packaging==20.9 | ||||
| @@ -26,10 +25,10 @@ pytz==2021.1 | ||||
| qrcode==6.1 | ||||
| redis==3.5.3 | ||||
| requests==2.25.1 | ||||
| six==1.15.0 | ||||
| six==1.16.0 | ||||
| sqlparse==0.4.1 | ||||
| twilio==6.57.0 | ||||
| urllib3==1.26.4 | ||||
| twilio==6.59.0 | ||||
| urllib3==1.26.5 | ||||
| uWSGI==2.0.19.1 | ||||
| validators==0.18.2 | ||||
| vine==5.0.0 | ||||
|   | ||||
| @@ -6,7 +6,9 @@ | ||||
|     "name": "Firefox - Clean Cache", | ||||
|     "description": "This script will clean up Mozilla Firefox for all users.", | ||||
|     "shell": "powershell", | ||||
|     "category": "TRMM (Win):Browsers" | ||||
|     "category": "TRMM (Win):Browsers", | ||||
|     "default_timeout": "300" | ||||
|  | ||||
|   }, | ||||
|   { | ||||
|     "guid": "3ff6a386-11d1-4f9d-8cca-1b0563bb6443", | ||||
| @@ -15,7 +17,8 @@ | ||||
|     "name": "Chrome - Clear Cache for All Users", | ||||
|     "description": "This script will clean up Google Chrome for all users.", | ||||
|     "shell": "powershell", | ||||
|     "category": "TRMM (Win):Browsers" | ||||
|     "category": "TRMM (Win):Browsers", | ||||
|     "default_timeout": "300" | ||||
|   }, | ||||
|   { | ||||
|     "guid": "be1de837-f677-4ac5-aa0c-37a0fc9991fc", | ||||
| @@ -24,7 +27,8 @@ | ||||
|     "name": "Adobe Reader DC - Install", | ||||
|     "description": "Installs Adobe Reader DC.", | ||||
|     "shell": "powershell", | ||||
|     "category": "TRMM (Win):3rd Party Software>Chocolatey" | ||||
|     "category": "TRMM (Win):3rd Party Software>Chocolatey", | ||||
|     "default_timeout": "300" | ||||
|   }, | ||||
|   { | ||||
|     "guid": "2ee134d5-76aa-4160-b334-a1efbc62079f", | ||||
| @@ -33,7 +37,8 @@ | ||||
|     "name": "Duplicati - Install", | ||||
|     "description": "This script installs Duplicati 2.0.5.1 as a service.", | ||||
|     "shell": "powershell", | ||||
|     "category": "TRMM (Win):3rd Party Software" | ||||
|     "category": "TRMM (Win):3rd Party Software", | ||||
|     "default_timeout": "300"    | ||||
|   }, | ||||
|   { | ||||
|     "guid": "81cc5bcb-01bf-4b0c-89b9-0ac0f3fe0c04", | ||||
| @@ -42,7 +47,8 @@ | ||||
|     "name": "Windows Update - Reset", | ||||
|     "description": "This script will reset all of the Windows Updates components to DEFAULT SETTINGS.", | ||||
|     "shell": "powershell", | ||||
|     "category": "TRMM (Win):Updates" | ||||
|     "category": "TRMM (Win):Updates", | ||||
|     "default_timeout": "300"     | ||||
|   }, | ||||
|   { | ||||
|     "guid": "8db87ff0-a9b4-4d9d-bc55-377bbcb85b6d", | ||||
| @@ -51,7 +57,8 @@ | ||||
|     "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):Maintenance" | ||||
|     "category": "TRMM (Win):Maintenance", | ||||
|     "default_timeout": "25000"     | ||||
|   }, | ||||
|   { | ||||
|     "guid": "2f28e8c1-ae0f-4b46-a826-f513974526a3", | ||||
| @@ -78,7 +85,8 @@ | ||||
|     "name": "Speed Test - Python", | ||||
|     "description": "Runs a Speed Test using Python", | ||||
|     "shell": "python", | ||||
|     "category": "TRMM (Win):Network" | ||||
|     "category": "TRMM (Win):Network", | ||||
|     "default_timeout": "120" | ||||
|   }, | ||||
|   { | ||||
|     "guid": "9d34f482-1f0c-4b2f-b65f-a9cf3c13ef5f", | ||||
| @@ -161,6 +169,18 @@ | ||||
|     "shell": "powershell", | ||||
|     "category": "TRMM (Win):Collectors" | ||||
|   }, | ||||
|   { | ||||
|     "guid": "973c34d7-cab0-4fda-999c-b4933655f946", | ||||
|     "filename": "Win_Screenconnect_GetGUID.ps1", | ||||
|     "submittedBy": "https://github.com/silversword411", | ||||
|     "name": "Screenconnect - Get GUID for client", | ||||
|     "description": "Returns Screenconnect GUID for client - Use with Custom Fields for later use. ", | ||||
|     "args": [ | ||||
|       "-serviceName {{client.ScreenConnectService}}" | ||||
|     ], | ||||
|     "shell": "powershell", | ||||
|     "category": "TRMM (Win):Collectors" | ||||
|   }, | ||||
|   { | ||||
|     "guid": "95a2ee6f-b89b-4551-856e-3081b041caa7", | ||||
|     "filename": "Win_Power_Profile_Reset_High_Performance_to_Defaults.ps1", | ||||
| @@ -186,7 +206,8 @@ | ||||
|     "name": "Windows 10 Upgrade", | ||||
|     "description": "Forces an upgrade to the latest release of Windows 10.", | ||||
|     "shell": "powershell", | ||||
|     "category": "TRMM (Win):Updates" | ||||
|     "category": "TRMM (Win):Updates", | ||||
|     "default_timeout": "25000" | ||||
|   }, | ||||
|   { | ||||
|     "guid": "375323e5-cac6-4f35-a304-bb7cef35902d", | ||||
| @@ -222,7 +243,8 @@ | ||||
|     "name": "SSH - Install Feature and Enable", | ||||
|     "description": "Installs and enabled OpenSSH Server Feature in Win10", | ||||
|     "shell": "powershell", | ||||
|     "category": "TRMM (Win):Windows Features" | ||||
|     "category": "TRMM (Win):Windows Features", | ||||
|     "default_timeout": "300" | ||||
|   }, | ||||
|   { | ||||
|     "guid": "2435297a-6263-4e90-8688-1847400d0e22", | ||||
| @@ -339,7 +361,8 @@ | ||||
|     "name": "Update Installed Apps", | ||||
|     "description": "Update all apps that were installed using Chocolatey.", | ||||
|     "shell": "cmd", | ||||
|     "category": "TRMM (Win):3rd Party Software>Chocolatey" | ||||
|     "category": "TRMM (Win):3rd Party Software>Chocolatey", | ||||
|     "default_timeout": "3600" | ||||
|   }, | ||||
|   { | ||||
|     "guid": "fff8024d-d72e-4457-84fa-6c780f69a16f", | ||||
| @@ -660,4 +683,4 @@ | ||||
|     "category": "TRMM (Win):Misc>Reference", | ||||
|     "default_timeout": "1" | ||||
|   } | ||||
| ] | ||||
| ] | ||||
|   | ||||
| @@ -41,7 +41,7 @@ app.conf.beat_schedule = { | ||||
|     }, | ||||
|     "get-wmi": { | ||||
|         "task": "agents.tasks.get_wmi_task", | ||||
|         "schedule": crontab(minute="*/18"), | ||||
|         "schedule": crontab(minute=18, hour="*/5"), | ||||
|     }, | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -15,22 +15,22 @@ EXE_DIR = os.path.join(BASE_DIR, "tacticalrmm/private/exe") | ||||
| AUTH_USER_MODEL = "accounts.User" | ||||
|  | ||||
| # latest release | ||||
| TRMM_VERSION = "0.6.11" | ||||
| TRMM_VERSION = "0.6.13" | ||||
|  | ||||
| # bump this version everytime vue code is changed | ||||
| # to alert user they need to manually refresh their browser | ||||
| APP_VER = "0.0.136" | ||||
| APP_VER = "0.0.137" | ||||
|  | ||||
| # https://github.com/wh1te909/rmmagent | ||||
| LATEST_AGENT_VER = "1.5.6" | ||||
| LATEST_AGENT_VER = "1.5.7" | ||||
|  | ||||
| MESH_VER = "0.8.35" | ||||
| MESH_VER = "0.8.49" | ||||
|  | ||||
| # for the update script, bump when need to recreate venv or npm install | ||||
| PIP_VER = "16" | ||||
| NPM_VER = "15" | ||||
| PIP_VER = "17" | ||||
| NPM_VER = "16" | ||||
|  | ||||
| SETUPTOOLS_VER = "56.1.0" | ||||
| SETUPTOOLS_VER = "57.0.0" | ||||
| WHEEL_VER = "0.36.2" | ||||
|  | ||||
| DL_64 = f"https://github.com/wh1te909/rmmagent/releases/download/v{LATEST_AGENT_VER}/winagent-v{LATEST_AGENT_VER}.exe" | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| FROM nats:2.2-alpine | ||||
| FROM nats:2.2.6-alpine | ||||
|  | ||||
| ENV TACTICAL_DIR /opt/tactical | ||||
| ENV TACTICAL_READY_FILE ${TACTICAL_DIR}/tmp/tactical.ready | ||||
|   | ||||
							
								
								
									
										31
									
								
								docs/docs/functions/examples.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								docs/docs/functions/examples.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| # Examples | ||||
|  | ||||
| ## Create Run URL Action to Computer support page | ||||
|  | ||||
| This will create a URL link that will take you to the support page for a computer based on the computers Serial Number | ||||
|  | ||||
| 1. Goto `Settings | Global Settings | Custom Fields`  | ||||
|      | ||||
|     Under Agents tab Add Custom Field (CaSe SeNsItIve) | ||||
|  | ||||
|      | ||||
|  | ||||
| 2. Create Task (best to use `Settings | Automation Manager` if you want to apply it to all computers). Add script that has an output of the data you want. | ||||
|  | ||||
|      | ||||
|  | ||||
| 3. Create URL Action (under `Settings | Global Settings | URL ACTIONS`) for Manufacturer websites | ||||
|  | ||||
|      | ||||
|  | ||||
| Dell Support Page | ||||
|  | ||||
| ``` | ||||
| https://www.dell.com/support/home/en-us/product-support/servicetag/{{agent.SerialNumber}}/overview | ||||
| ``` | ||||
|  | ||||
| Lenovo  Support Page | ||||
|  | ||||
| ``` | ||||
| https://www.dell.com/support/home/en-us/product-support/servicetag/{{agent.SerialNumber}}/overview | ||||
| ``` | ||||
							
								
								
									
										
											BIN
										
									
								
								docs/docs/images/example1_customfield.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/docs/images/example1_customfield.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 13 KiB | 
							
								
								
									
										
											BIN
										
									
								
								docs/docs/images/example1_taskcollectorscript.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/docs/images/example1_taskcollectorscript.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 24 KiB | 
							
								
								
									
										
											BIN
										
									
								
								docs/docs/images/example1_urlaction.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/docs/images/example1_urlaction.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 16 KiB | 
| @@ -14,6 +14,10 @@ | ||||
|  | ||||
| ## Install | ||||
|  | ||||
| !!!info | ||||
|     It is recommended that you keep your server updated regularly (monthly). SSL wildcard certs will expire every 3 months and need manual updating as well. <br/><br/> | ||||
|     Until we reach production release, there may be architectural changes that may be made to Tactical RMM and only a regular patching schedule is supported by developers. | ||||
|  | ||||
| #### Run updates and setup the linux user | ||||
| SSH into the server as **root**.<br/><br/> | ||||
| Download and run the prereqs and latest updates<br/> | ||||
|   | ||||
| @@ -23,6 +23,7 @@ nav: | ||||
|       - "User Interface Preferences": functions/user_ui.md | ||||
|       - "Django Admin": functions/django_admin.md | ||||
|       - "Settings Override": functions/settings_override.md | ||||
|       - "Examples": functions/examples.md | ||||
|   - Backup: backup.md | ||||
|   - Restore: restore.md | ||||
|   - Troubleshooting: troubleshooting.md | ||||
|   | ||||
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							| @@ -5,6 +5,6 @@ go 1.16 | ||||
| require ( | ||||
| 	github.com/nats-io/nats-server/v2 v2.1.8-0.20201129161730-ebe63db3e3ed // indirect | ||||
| 	github.com/nats-io/nats.go v1.11.0 | ||||
| 	github.com/ugorji/go/codec v1.2.5 | ||||
| 	github.com/ugorji/go/codec v1.2.6 | ||||
| 	golang.org/x/sys v0.0.0-20210122235752-a8b976e07c7b // indirect | ||||
| ) | ||||
|   | ||||
							
								
								
									
										8
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								go.sum
									
									
									
									
									
								
							| @@ -34,10 +34,10 @@ github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8= | ||||
| github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4= | ||||
| github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= | ||||
| github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= | ||||
| github.com/ugorji/go v1.2.5 h1:NozRHfUeEta89taVkyfsDVSy2f7v89Frft4pjnWuGuc= | ||||
| github.com/ugorji/go v1.2.5/go.mod h1:gat2tIT8KJG8TVI8yv77nEO/KYT6dV7JE1gfUa8Xuls= | ||||
| github.com/ugorji/go/codec v1.2.5 h1:8WobZKAk18Msm2CothY2jnztY56YVY8kF1oQrj21iis= | ||||
| github.com/ugorji/go/codec v1.2.5/go.mod h1:QPxoTbPKSEAlAHPYt02++xp/en9B/wUdwFCz+hj5caA= | ||||
| github.com/ugorji/go v1.2.6 h1:tGiWC9HENWE2tqYycIqFTNorMmFRVhNwCpDOpWqnk8E= | ||||
| github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0= | ||||
| github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ= | ||||
| github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw= | ||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||
| golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||
| golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| SCRIPT_VERSION="48" | ||||
| SCRIPT_VERSION="49" | ||||
| SCRIPT_URL='https://raw.githubusercontent.com/wh1te909/tacticalrmm/master/install.sh' | ||||
|  | ||||
| sudo apt install -y curl wget dirmngr gnupg lsb-release | ||||
| @@ -167,11 +167,11 @@ sudo chmod 775 -R /etc/letsencrypt | ||||
| print_green 'Downloading NATS' | ||||
|  | ||||
| nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX) | ||||
| wget https://github.com/nats-io/nats-server/releases/download/v2.2.3/nats-server-v2.2.3-linux-amd64.tar.gz -P ${nats_tmp} | ||||
| wget https://github.com/nats-io/nats-server/releases/download/v2.2.6/nats-server-v2.2.6-linux-amd64.tar.gz -P ${nats_tmp} | ||||
|  | ||||
| tar -xzf ${nats_tmp}/nats-server-v2.2.3-linux-amd64.tar.gz -C ${nats_tmp} | ||||
| tar -xzf ${nats_tmp}/nats-server-v2.2.6-linux-amd64.tar.gz -C ${nats_tmp} | ||||
|  | ||||
| sudo mv ${nats_tmp}/nats-server-v2.2.3-linux-amd64/nats-server /usr/local/bin/ | ||||
| sudo mv ${nats_tmp}/nats-server-v2.2.6-linux-amd64/nats-server /usr/local/bin/ | ||||
| sudo chmod +x /usr/local/bin/nats-server | ||||
| sudo chown ${USER}:${USER} /usr/local/bin/nats-server | ||||
| rm -rf ${nats_tmp} | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							| @@ -1,6 +1,6 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| SCRIPT_VERSION="26" | ||||
| SCRIPT_VERSION="27" | ||||
| SCRIPT_URL='https://raw.githubusercontent.com/wh1te909/tacticalrmm/master/restore.sh' | ||||
|  | ||||
| sudo apt update | ||||
| @@ -108,11 +108,11 @@ sudo apt update | ||||
| print_green 'Downloading NATS' | ||||
|  | ||||
| nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX) | ||||
| wget https://github.com/nats-io/nats-server/releases/download/v2.2.3/nats-server-v2.2.3-linux-amd64.tar.gz -P ${nats_tmp} | ||||
| wget https://github.com/nats-io/nats-server/releases/download/v2.2.6/nats-server-v2.2.6-linux-amd64.tar.gz -P ${nats_tmp} | ||||
|  | ||||
| tar -xzf ${nats_tmp}/nats-server-v2.2.3-linux-amd64.tar.gz -C ${nats_tmp} | ||||
| tar -xzf ${nats_tmp}/nats-server-v2.2.6-linux-amd64.tar.gz -C ${nats_tmp} | ||||
|  | ||||
| sudo mv ${nats_tmp}/nats-server-v2.2.3-linux-amd64/nats-server /usr/local/bin/ | ||||
| sudo mv ${nats_tmp}/nats-server-v2.2.6-linux-amd64/nats-server /usr/local/bin/ | ||||
| sudo chmod +x /usr/local/bin/nats-server | ||||
| sudo chown ${USER}:${USER} /usr/local/bin/nats-server | ||||
| rm -rf ${nats_tmp} | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| cup -y all | ||||
| cup all -y | ||||
|   | ||||
| @@ -31,6 +31,7 @@ else { | ||||
|     Install-Module -Name RunAsUser -Force | ||||
| } | ||||
|  | ||||
| # Used to pull variables in and use them inside the script block. Contains message to show user | ||||
| Set-Content -Path c:\windows\temp\message.txt -Value $args | ||||
|  | ||||
| Invoke-AsCurrentUser -scriptblock { | ||||
| @@ -55,5 +56,5 @@ Invoke-AsCurrentUser -scriptblock { | ||||
|     Submit-BTNotification -Content $Content | ||||
| } | ||||
|  | ||||
|  | ||||
| # Cleanup temp file for message variables | ||||
| Remove-Item -Path c:\windows\temp\message.txt | ||||
|   | ||||
| @@ -10,28 +10,6 @@ | ||||
|    Submitted by: https://github.com/dinger1986 | ||||
| #> | ||||
|  | ||||
| [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 | ||||
|  | ||||
| $regpath = HKCU:\Software\Microsoft\Office\16.0\Outlook\Preferences | ||||
| $regname = DelegateSentItemsStyle | ||||
| $regvalue = 1 | ||||
| $regproperty = Dword | ||||
|  | ||||
|  | ||||
| If (!(test-path '%ProgramData%\Tactical RMM\temp')) { | ||||
|     New-Item -ItemType Directory -Force -Path '%ProgramData%\Tactical RMM\temp' | ||||
| } | ||||
|  | ||||
| If (!(test-path C:\TEMP\curpsxpolicy.txt)) { | ||||
|     $curexpolicy = Get-ExecutionPolicy | ||||
|  | ||||
|     ( | ||||
|         echo $curexpolicy | ||||
|     )>"%ProgramData%\Tactical RMM\temp\curpsxpolicy.txt" | ||||
| } | ||||
|  | ||||
| Set-ExecutionPolicy -ExecutionPolicy Unrestricted | ||||
|  | ||||
| if (Get-PackageProvider -Name NuGet) { | ||||
|     Write-Output "NuGet Already Added" | ||||
| }  | ||||
| @@ -48,14 +26,30 @@ else { | ||||
|     Install-Module -Name RunAsUser -Force | ||||
| } | ||||
|  | ||||
| If (!(test-path $env:programdata\TacticalRMM\temp\)) { | ||||
|     New-Item -ItemType Directory -Force -Path $env:programdata\TacticalRMM\temp\ | ||||
| } | ||||
|  | ||||
| If (!(test-path $env:programdata\TacticalRMM\temp\curpsxpolicy.txt)) { | ||||
|     $curexpolicy = Get-ExecutionPolicy | ||||
|  | ||||
|     ( | ||||
|         Write-Output $curexpolicy | ||||
|     )>$env:programdata\TacticalRMM\temp\curpsxpolicy.txt | ||||
| } | ||||
| Set-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell -Name ExecutionPolicy -Value Unrestricted | ||||
|  | ||||
| Invoke-AsCurrentUser -scriptblock { | ||||
|     New-ItemProperty -Path "$regpath" -Name "$regname" -Value "$regvalue"  -PropertyType "$regproperty" | ||||
|     # Modify below for other versions of Office | ||||
|     $regpath = 'Software\Microsoft\Office\16.0\Outlook\Preferences' | ||||
|     $regname = "DelegateSentItemsStyle" | ||||
|     $regvalue = "1" | ||||
|     $regproperty = "Dword" | ||||
|     New-ItemProperty -Path HKCU:\$regpath -Name $regname -Value $regvalue  -PropertyType $regproperty | ||||
| } | ||||
|  | ||||
| Write-Output "Successfully changed Sent Items for Delegated folders" | ||||
|  | ||||
| $curpsxpol = Get-Content -Path "%ProgramData%\Tactical RMM\temp\curpsxpolicy.txt"; | ||||
| $curpsxpol = Get-Content -Path $env:programdata\TacticalRMM\temp\curpsxpolicy.txt; | ||||
|      | ||||
| Set-ExecutionPolicy -ExecutionPolicy $curpsxpol | ||||
|  | ||||
| del "%ProgramData%\Tactical RMM\temp\curpsxpolicy.txt" | ||||
| Set-ExecutionPolicy -ExecutionPolicy $curpsxpol | ||||
							
								
								
									
										26
									
								
								scripts/Win_Screenconnect_GetGUID.ps1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								scripts/Win_Screenconnect_GetGUID.ps1
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| <# | ||||
| Requires global variables for serviceName "ScreenConnectService"  | ||||
| serviceName is the name of the ScreenConnect Service once it is installed EG: "ScreenConnect Client (1327465grctq84yrtocq)" | ||||
| Variable value must start and end with " (Prior to TRMM Version 0.6.5), remove / don't use " on TRMM Version 0.6.5 or later. | ||||
| Requires Custom Fields Agent entry Name: ScreenConnectGUID   Type: text | ||||
| URL Action entry (check your screenconnect to see what folder name is your "All Machines" folder): https://YOURNAME.screenconnect.com/Host#Access/All%20Machines//{{agent.ScreenConnectGUID}}/Join | ||||
|     or https://YOURNAME.screenconnect.com/Host#Access/All%20Machines%20by%20Company//{{agent.ScreenConnectGUID}}/Join | ||||
| #> | ||||
|  | ||||
| param ( | ||||
|     [string] $serviceName | ||||
| ) | ||||
|  | ||||
| if (!$serviceName) { | ||||
|     write-output "Variable not specified ScreenConnectService, please create a global custom field under Client called ScreenConnectService, Example Value: `"ScreenConnect Client (1327465grctq84yrtocq)`" `n" | ||||
|     $ErrorCount += 1 | ||||
| } | ||||
|  | ||||
| if (!$ErrorCount -eq 0) { | ||||
|     exit 1 | ||||
| } | ||||
|      | ||||
| $imagePath = Get-Itempropertyvalue "HKLM:\SYSTEM\ControlSet001\Services\$serviceName" -Name "ImagePath" | ||||
| $imagePath2 = ($imagePath -split "&s=")[1] | ||||
| $machineGUID = ($imagePath2 -split "&k=")[0] | ||||
| Write-Output $machineGUID | ||||
| @@ -1,18 +0,0 @@ | ||||
| # Needs to be parameterized: $icofile, $URL, $ShortcutPath | ||||
| # Need to change paths and test/create if don't exist | ||||
|  | ||||
|  | ||||
| wget "https://www.example.com/logos/example.ico" -outfile "c:\agent\example.ico" | ||||
|  | ||||
| $WshShell = New-Object -comObject WScript.Shell | ||||
| $path = "C:\Users\All Users\desktop\example.url" | ||||
| $targetpath = "https://example.com/" | ||||
| $iconlocation = "c:\agent\example.ico" | ||||
| $iconfile = "IconFile=" + $iconlocation | ||||
| $Shortcut = $WshShell.CreateShortcut($path) | ||||
| $Shortcut.TargetPath = $targetpath | ||||
| $Shortcut.Save() | ||||
| Add-Content $path "HotKey=0" | ||||
| Add-Content $path "$iconfile" | ||||
| Add-Content $path "IconIndex=0" | ||||
|  | ||||
| @@ -1,3 +1,5 @@ | ||||
| REM Print Spooler reset script. Will stop spooler, fix permissions on print folders, clear all files in print queues, and restart spooler service. | ||||
|  | ||||
| REM Stop Print Spooler  | ||||
| net stop "Spooler" | ||||
|  | ||||
|   | ||||
| @@ -1,2 +0,0 @@ | ||||
| net stop "Print Spooler" | ||||
| net start "Print Spooler" | ||||
							
								
								
									
										25
									
								
								scripts_wip/Win_Print_Spooler_Restart_Service.ps1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								scripts_wip/Win_Print_Spooler_Restart_Service.ps1
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| <# | ||||
| .Synopsis | ||||
|    Restart Print Spooler Service | ||||
| .DESCRIPTION | ||||
|    Will force-restart the spooler service. With additional command parameter will also delete any pending print jobs | ||||
| .EXAMPLE | ||||
|    Another example of how to use this cmdlet | ||||
| .OUTPUTS | ||||
|    Any print jobs that are deleted | ||||
| .NOTES | ||||
|    v1.0 5/2021 | ||||
|    https://github.com/silversword411 | ||||
| .FUNCTIONALITY | ||||
|    Print Spooler Troubleshooting, restarts spooler service. Can also delete all print jobs that are pending  | ||||
| #> | ||||
|  | ||||
| #Restart Spooler service | ||||
| Restart-Service -Name spooler -Force  | ||||
|  | ||||
| #Deletes All print jobs within the last 15 years | ||||
| $PrintJobs = get-wmiobject -class "Win32_PrintJob" -namespace "root\CIMV2" -computername . | Where-Object { [System.Management.ManagementDateTimeConverter]::ToDateTime($_.TimeSubmitted) -lt (Get-Date).AddDays(-5500) }  | ||||
| foreach ($job in $PrintJobs) {     | ||||
|     #   Write-Host "Canceling job $($job.JobId)"     | ||||
|     $job.Delete()  | ||||
| } | ||||
| @@ -1,8 +0,0 @@ | ||||
| #Update with command parameters | ||||
| #Deletes All print jobs within the last 2 days | ||||
|  | ||||
| $PrintJobs = get-wmiobject -class "Win32_PrintJob" -namespace "root\CIMV2" -computername . | Where-Object { [System.Management.ManagementDateTimeConverter]::ToDateTime($_.TimeSubmitted) -lt (Get-Date).AddDays(-2) }  | ||||
| foreach ($job in $PrintJobs) {     | ||||
|     #   Write-Host "Canceling job $($job.JobId)"     | ||||
|     $job.Delete()  | ||||
| }  | ||||
| @@ -1,7 +1,9 @@ | ||||
| md -Path 'C:\agent' -Force | ||||
| wget "http://www.yourwebsite.com/logos/yourico.ico" -outfile "c:\agent\yourico.ico" | ||||
|  | ||||
|  | ||||
| mkdir -Path 'C:\agent' -Force | ||||
| Invoke-WebRequest "http://www.yourwebsite.com/logos/yourico.ico" -outfile "c:\agent\yourico.ico" | ||||
| $WshShell = New-Object -comObject WScript.Shell | ||||
| $path = "C:\Users\All Users\desktop\Jaxsupport.url" | ||||
| $path = "C:\Users\All Users\desktop\Shortcut.url" | ||||
| $targetpath = "https://yourwebsite.com" | ||||
| $iconlocation = "c:\agent\yourico.ico" | ||||
| $iconfile = "IconFile=" + $iconlocation | ||||
|   | ||||
							
								
								
									
										12
									
								
								update.sh
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								update.sh
									
									
									
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| SCRIPT_VERSION="121" | ||||
| SCRIPT_VERSION="122" | ||||
| SCRIPT_URL='https://raw.githubusercontent.com/wh1te909/tacticalrmm/master/update.sh' | ||||
| LATEST_SETTINGS_URL='https://raw.githubusercontent.com/wh1te909/tacticalrmm/master/api/tacticalrmm/tacticalrmm/settings.py' | ||||
| YELLOW='\033[1;33m' | ||||
| @@ -184,14 +184,14 @@ if ! [[ $HAS_PY39 ]]; then | ||||
|   sudo rm -rf Python-3.9.2 Python-3.9.2.tgz | ||||
| fi | ||||
|  | ||||
| HAS_NATS220=$(/usr/local/bin/nats-server -version | grep v2.2.3) | ||||
| HAS_NATS220=$(/usr/local/bin/nats-server -version | grep v2.2.6) | ||||
| if ! [[ $HAS_NATS220 ]]; then | ||||
|   printf >&2 "${GREEN}Updating nats to v2.2.3${NC}\n" | ||||
|   printf >&2 "${GREEN}Updating nats to v2.2.6${NC}\n" | ||||
|   nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX) | ||||
|   wget https://github.com/nats-io/nats-server/releases/download/v2.2.3/nats-server-v2.2.3-linux-amd64.tar.gz -P ${nats_tmp} | ||||
|   tar -xzf ${nats_tmp}/nats-server-v2.2.3-linux-amd64.tar.gz -C ${nats_tmp} | ||||
|   wget https://github.com/nats-io/nats-server/releases/download/v2.2.6/nats-server-v2.2.6-linux-amd64.tar.gz -P ${nats_tmp} | ||||
|   tar -xzf ${nats_tmp}/nats-server-v2.2.6-linux-amd64.tar.gz -C ${nats_tmp} | ||||
|   sudo rm -f /usr/local/bin/nats-server | ||||
|   sudo mv ${nats_tmp}/nats-server-v2.2.3-linux-amd64/nats-server /usr/local/bin/ | ||||
|   sudo mv ${nats_tmp}/nats-server-v2.2.6-linux-amd64/nats-server /usr/local/bin/ | ||||
|   sudo chmod +x /usr/local/bin/nats-server | ||||
|   sudo chown ${USER}:${USER} /usr/local/bin/nats-server | ||||
|   rm -rf ${nats_tmp} | ||||
|   | ||||
							
								
								
									
										1946
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1946
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -10,33 +10,27 @@ | ||||
|     "test:e2e:ci": "cross-env E2E_TEST=true start-test \"quasar dev\" http-get://localhost:8080 \"cypress run\"" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@quasar/extras": "^1.10.4", | ||||
|     "@quasar/extras": "^1.10.5", | ||||
|     "apexcharts": "^3.23.1", | ||||
|     "axios": "^0.21.1", | ||||
|     "dotenv": "^8.2.0", | ||||
|     "prismjs": "^1.22.0", | ||||
|     "qrcode.vue": "^1.7.0", | ||||
|     "quasar": "^1.15.13", | ||||
|     "quasar": "^1.15.18", | ||||
|     "vue-apexcharts": "^1.6.0", | ||||
|     "vue-prism-editor": "^1.2.2" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@quasar/app": "^2.2.6", | ||||
|     "@quasar/cli": "^1.1.3", | ||||
|     "core-js": "^3.11.2", | ||||
|     "@quasar/app": "^2.2.7", | ||||
|     "@quasar/cli": "^1.2.0", | ||||
|     "core-js": "^3.13.0", | ||||
|     "eslint-plugin-cypress": "^2.11.2", | ||||
|     "flush-promises": "^1.0.2", | ||||
|     "fs-extra": "^9.1.0" | ||||
|   }, | ||||
|   "browserslist": [ | ||||
|     "last 4 Chrome versions", | ||||
|     "last 4 Firefox versions", | ||||
|     "last 2 Edge versions", | ||||
|     "last 3 Safari versions", | ||||
|     "last 3 Android versions", | ||||
|     "last 3 ChromeAndroid versions", | ||||
|     "last 3 FirefoxAndroid versions", | ||||
|     "last 3 iOS versions", | ||||
|     "last 2 Opera versions" | ||||
|     "last 3 Chrome versions", | ||||
|     "last 3 Firefox versions", | ||||
|     "last 2 Edge versions" | ||||
|   ] | ||||
| } | ||||
| } | ||||
| @@ -261,6 +261,9 @@ | ||||
|                   @click="eventLogMoreInfo(props.row)" | ||||
|                   >Last Output</span | ||||
|                 > | ||||
|                 <span v-else-if="props.row.check_type === 'diskspace' || props.row.check_type === 'winsvc'">{{ | ||||
|                   props.row.more_info | ||||
|                 }}</span> | ||||
|               </q-td> | ||||
|               <q-td>{{ props.row.last_run || "Never" }}</q-td> | ||||
|               <q-td v-if="props.row.assigned_task !== null && props.row.assigned_task.length > 1" | ||||
|   | ||||
| @@ -12,6 +12,7 @@ | ||||
|     @input="value => $emit('input', value)" | ||||
|     :rules="[...validationRules]" | ||||
|     reactive-rules | ||||
|     autogrow | ||||
|   /> | ||||
|  | ||||
|   <q-toggle | ||||
|   | ||||
| @@ -94,7 +94,7 @@ | ||||
|                 <q-item-section>Global Settings</q-item-section> | ||||
|               </q-item> | ||||
|               <!-- code sign --> | ||||
|               <q-item v-if="!noCodeSigning" clickable v-close-popup @click="showCodeSign = true"> | ||||
|               <q-item v-if="!hosted" clickable v-close-popup @click="showCodeSign = true"> | ||||
|                 <q-item-section>Code Signing</q-item-section> | ||||
|               </q-item> | ||||
|             </q-list> | ||||
| @@ -124,7 +124,7 @@ | ||||
|           </q-menu> | ||||
|         </q-btn> | ||||
|         <!-- help --> | ||||
|         <q-btn size="md" dense no-caps flat label="Help"> | ||||
|         <q-btn v-if="!hosted" size="md" dense no-caps flat label="Help"> | ||||
|           <q-menu auto-close> | ||||
|             <q-list dense style="min-width: 100px"> | ||||
|               <q-item clickable v-close-popup @click="openHelp('docs')"> | ||||
| @@ -272,8 +272,8 @@ export default { | ||||
|     }; | ||||
|   }, | ||||
|   computed: { | ||||
|     noCodeSigning() { | ||||
|       return this.$store.state.noCodeSign; | ||||
|     hosted() { | ||||
|       return this.$store.state.hosted; | ||||
|     }, | ||||
|   }, | ||||
|   methods: { | ||||
|   | ||||
| @@ -136,7 +136,7 @@ export default { | ||||
|     getOptions() { | ||||
|       this.getClients(); | ||||
|       this.getSites(); | ||||
|       this.agentOptions = Object.freeze(this.getAgentOptions()); | ||||
|       this.agentOptions = this.getAgentOptions(); | ||||
|     }, | ||||
|     show() { | ||||
|       this.$refs.dialog.show(); | ||||
| @@ -152,7 +152,7 @@ export default { | ||||
|       this.hide(); | ||||
|     }, | ||||
|   }, | ||||
|   mounted() { | ||||
|   created() { | ||||
|     this.getOptions(); | ||||
|  | ||||
|     // copy prop data locally | ||||
|   | ||||
| @@ -143,7 +143,7 @@ export default { | ||||
|     getOptions() { | ||||
|       this.getClients(); | ||||
|       this.getSites(); | ||||
|       this.agentOptions = Object.freeze(this.getAgentOptions()); | ||||
|       this.agentOptions = this.getAgentOptions(); | ||||
|     }, | ||||
|     show() { | ||||
|       this.$refs.dialog.show(); | ||||
| @@ -159,7 +159,7 @@ export default { | ||||
|       this.hide(); | ||||
|     }, | ||||
|   }, | ||||
|   mounted() { | ||||
|   created() { | ||||
|     this.getOptions(); | ||||
|  | ||||
|     // copy prop data locally | ||||
|   | ||||
| @@ -111,6 +111,7 @@ | ||||
|                 dense | ||||
|                 options-dense | ||||
|                 outlined | ||||
|                 clearable | ||||
|                 v-model="template.action" | ||||
|                 :options="scriptOptions" | ||||
|                 map-options | ||||
| @@ -174,6 +175,7 @@ | ||||
|                 dense | ||||
|                 options-dense | ||||
|                 outlined | ||||
|                 clearable | ||||
|                 v-model="template.resolved_action" | ||||
|                 :options="scriptOptions" | ||||
|                 map-options | ||||
| @@ -696,4 +698,4 @@ export default { | ||||
|     if (this.editing) Object.assign(this.template, this.alertTemplate); | ||||
|   }, | ||||
| }; | ||||
| </script> | ||||
| </script> | ||||
|   | ||||
| @@ -138,6 +138,7 @@ | ||||
|             v-model="localField.default_value_string" | ||||
|             :rules="[...defaultValueRules]" | ||||
|             reactive-rules | ||||
|             autogrow | ||||
|           /> | ||||
|         </q-card-section> | ||||
|         <q-card-section> | ||||
|   | ||||
| @@ -73,7 +73,12 @@ | ||||
|             label="Collector Task" | ||||
|             v-model="collector" | ||||
|             class="q-pb-sm" | ||||
|             @input="autotask.custom_field = null" | ||||
|             @input=" | ||||
|               () => { | ||||
|                 autotask.custom_field = null; | ||||
|                 autotask.collector_all_ouput = false; | ||||
|               } | ||||
|             " | ||||
|           /> | ||||
|           <q-select | ||||
|             v-if="collector" | ||||
| @@ -87,6 +92,13 @@ | ||||
|             options-dense | ||||
|             hint="The last line of script output will be saved to custom field selected" | ||||
|           /> | ||||
|           <q-checkbox | ||||
|             v-if="collector" | ||||
|             dense | ||||
|             label="Save all output (Only for text area)" | ||||
|             v-model="autotask.collector_all_output" | ||||
|             class="q-py-sm" | ||||
|           /> | ||||
|         </q-card-section> | ||||
|         <q-card-section> | ||||
|           <q-select | ||||
| @@ -229,6 +241,7 @@ export default { | ||||
|         task_type: "scheduled", | ||||
|         timeout: 120, | ||||
|         alert_severity: "info", | ||||
|         collector_all_output: false, | ||||
|       }, | ||||
|       policyChecks: [], | ||||
|       severityOptions: [ | ||||
|   | ||||
| @@ -90,6 +90,13 @@ | ||||
|             options-dense | ||||
|             hint="The return value of script will be saved to custom field selected" | ||||
|           /> | ||||
|           <q-checkbox | ||||
|             v-if="collector" | ||||
|             dense | ||||
|             label="Save all output (Only for text area)" | ||||
|             v-model="autotask.collector_all_output" | ||||
|             class="q-py-sm" | ||||
|           /> | ||||
|         </q-card-section> | ||||
|         <q-card-section> | ||||
|           <q-input | ||||
| @@ -131,6 +138,7 @@ export default { | ||||
|         alert_severity: null, | ||||
|         timeout: 120, | ||||
|         custom_field: null, | ||||
|         collector_all_output: false, | ||||
|       }, | ||||
|       collector: false, | ||||
|       customFieldOptions: [], | ||||
| @@ -197,6 +205,7 @@ export default { | ||||
|     this.autotask.alert_severity = this.task.alert_severity; | ||||
|     this.autotask.timeout = this.task.timeout; | ||||
|     this.autotask.custom_field = this.task.custom_field; | ||||
|     this.autotask.collector_all_output = this.task.collector_all_output; | ||||
|   }, | ||||
| }; | ||||
| </script> | ||||
| @@ -72,18 +72,18 @@ export default { | ||||
|  | ||||
|     isValidThreshold(warning, error, diskcheck = false) { | ||||
|       if (warning === 0 && error === 0) { | ||||
|         Notify.create(notifyErrorConfig("Warning Threshold or Error Threshold need to be set", 2000)); | ||||
|         return false | ||||
|         Notify.create({ type: "negative", timeout: 2000, message: "Warning Threshold or Error Threshold need to be set" }); | ||||
|         return false; | ||||
|       } | ||||
|  | ||||
|       if (!diskcheck && warning > error && warning > 0 && error > 0) { | ||||
|         Notify.create(notifyErrorConfig("Warning Threshold must be less than Error Threshold", 2000)); | ||||
|         return false | ||||
|         Notify.create({ type: "negative", timeout: 2000, message: "Warning Threshold must be less than Error Threshold" }); | ||||
|         return false; | ||||
|       } | ||||
|  | ||||
|       if (diskcheck && warning < error && warning > 0 && error > 0) { | ||||
|         Notify.create(notifyErrorConfig("Warning Threshold must be more than Error Threshold", 2000)); | ||||
|         return false | ||||
|         Notify.create({ type: "negative", timeout: 2000, message: "Warning Threshold must be more than Error Threshold" }); | ||||
|         return false; | ||||
|       } | ||||
|  | ||||
|       return true; | ||||
|   | ||||
| @@ -35,7 +35,7 @@ export default function () { | ||||
|       defaultAgentTblTab: "server", | ||||
|       clientTreeSort: "alphafail", | ||||
|       clientTreeSplitter: 11, | ||||
|       noCodeSign: false, | ||||
|       hosted: false, | ||||
|     }, | ||||
|     getters: { | ||||
|       clientTreeSplitterModel(state) { | ||||
| @@ -159,8 +159,8 @@ export default function () { | ||||
|       SET_CLIENT_TREE_SORT(state, val) { | ||||
|         state.clientTreeSort = val | ||||
|       }, | ||||
|       SET_NO_CODE_SIGN(state, val) { | ||||
|         state.noCodeSign = val | ||||
|       SET_HOSTED(state, val) { | ||||
|         state.hosted = val | ||||
|       } | ||||
|     }, | ||||
|     actions: { | ||||
|   | ||||
| @@ -742,7 +742,7 @@ export default { | ||||
|         this.$store.commit("SET_AGENT_DBLCLICK_ACTION", r.data.dbl_click_action); | ||||
|         this.$store.commit("SET_URL_ACTION", r.data.url_action); | ||||
|         this.$store.commit("setShowCommunityScripts", r.data.show_community_scripts); | ||||
|         this.$store.commit("SET_NO_CODE_SIGN", r.data.no_code_sign); | ||||
|         this.$store.commit("SET_HOSTED", r.data.hosted); | ||||
|       }); | ||||
|     }, | ||||
|     showToggleMaintenance(node) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user