logo
Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

Options
Go to last post Go to first unread
deecater  
#1 Posted : Friday, December 1, 2017 1:44:10 PM(UTC)
deecater


Rank: Administration

Medals: ScreenConnect Advisor: Focus Group Member

Joined: 6/20/2017(UTC)
Posts: 1
Woman
United States
Location: Raleigh, NC

Was thanked: 1 time(s) in 1 post(s)
I have a few remote laptops that are on at various times of the day/night. I have a trigger setup to email me when the machines come online. From that email I have a VBSscript that saves that email to a text file. At which point task scheduler on my server run a powershell script that pulls the computername and pushes a PDQ deploy command to it. Work fine and dandy except for the server isn't finding the correct name in the DNS entry..(VPN assigning new ip's) ugh!

So I am thinking if I can use the same trigger to run my CMD commands from the machine this will solve the DNS errors.

Screenconnect displays and send me the ip address, but it's the external IP not our VPN. I can run ipconfig from within SC to get the VPN IP but cant figure how to include this in my email.


If I can get the email to included the VPN ip I can tell powershell to grab that ip instead of the computername.

Running updates is a pain...


Any ideas?

Original Post
thanks 1 user thanked deecater for this useful post.
thachad on 12/1/2017(UTC)
Ben B  
#2 Posted : Friday, December 1, 2017 2:57:32 PM(UTC)
Ben B


Rank: Administration

Medals: Level 2: Lent a Helping Hand! 10 Thanks!

Joined: 10/2/2015(UTC)
Posts: 281

Thanks: 1 times
Was thanked: 58 time(s) in 54 post(s)
Originally Posted by: deecater Go to Quoted Post
I have a few remote laptops that are on at various times of the day/night. I have a trigger setup to email me when the machines come online. From that email I have a VBSscript that saves that email to a text file. At which point task scheduler on my server run a powershell script that pulls the computername and pushes a PDQ deploy command to it. Work fine and dandy except for the server isn't finding the correct name in the DNS entry..(VPN assigning new ip's) ugh!

So I am thinking if I can use the same trigger to run my CMD commands from the machine this will solve the DNS errors.

Screenconnect displays and send me the ip address, but it's the external IP not our VPN. I can run ipconfig from within SC to get the VPN IP but cant figure how to include this in my email.


If I can get the email to included the VPN ip I can tell powershell to grab that ip instead of the computername.

Running updates is a pain...


Any ideas?

Original Post


I quickly put together an extension prototype that addresses this request. The extension file content is included below (you can create a new extension and paste this content in the appropriate file to enable/tweak this functionality).

More info on how to create a new extension is found here: https://docs.connectwise...ension_development_guide

The extension will email the command output generated by running the command specified by the CommandToRun setting value whenever an access guest connects.

The extension has three settings:
1) ToAddress: Send command output to this email address (required)
2) CommandToRun: Run this commmand immediately after an access guest connects and email the result to the address specified in the ToAddress setting (default is ipconfig)
3) EmailSubjectPrefix: Email subject prefix (the session name is appended to this prefix)

Manifest.xml
Code:

<?xml version="1.0" encoding="utf-8"?>
<ExtensionManifest>
	<Version>1.0</Version>
	<Name>Email Command Result Upon Session Connection</Name>
	<Author></Author>
	<ShortDescription>Run a command on an access session immediately after the guest connects. Email the command output to the specified email address.</ShortDescription>
	<Components>
		<DynamicSessionEventTriggerDefinition SourceFile="SessionEventTrigger.cs" MinProductVersionInclusive="6.3" />
	</Components>
	<Settings>
		<Setting Name="ToAddress" IsServerOnly="true">
			<Description>Send command output to this email address</Description>
			<DefaultValue></DefaultValue>
		</Setting>
		<Setting Name="CommandToRun" IsServerOnly="true">
			<Description>Run this commmand immediately after an access guest connects and email the result to the address specified in the ToAddress setting</Description>
			<DefaultValue>ipconfig</DefaultValue>
		</Setting>
		<Setting Name="EmailSubjectPrefix" IsServerOnly="true">
			<Description>Email subject prefix</Description>
			<DefaultValue>ConnectWise Control Access Session Command Output</DefaultValue>
		</Setting>
	</Settings>
</ExtensionManifest>


SessionEventTrigger.cs
Code:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Security;
using System.Threading;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.Configuration;
using System.Xml;
using ScreenConnect;

public class SessionEventTriggerAccessor : IDynamicSessionEventTrigger
{
	public Proc GetDeferredActionIfApplicable(SessionEventTriggerEvent sessionEventTriggerEvent)
	{
		if (sessionEventTriggerEvent.Session.SessionType == SessionType.Access &&
			sessionEventTriggerEvent.SessionEvent.EventType == SessionEventType.Connected &&
			sessionEventTriggerEvent.SessionConnection.ProcessType == ProcessType.Guest
			)
		{
			return (Proc) delegate
			{
				try
				{
					var startingTime = DateTime.UtcNow; // used to get RanCommand data later
					var maxRetrieveAttempts = 10;
					var retrieveAttempt = 0; // try to retrieve command output up to 10 times before failing
					
					SessionManagerPool.Demux.AddSessionEvent(sessionEventTriggerEvent.Session.SessionID, new SessionEvent
				    {
						Host = "Email Command Result Extension",
						EventType = SessionEventType.QueuedCommand,
						Data = ExtensionContext.Current.GetSettingValue("CommandToRun"),
					});
					
					// wait for the RanCommand data
					Thread.Sleep(5000);
					
					var ranCommandText = default(string);
					
					while (retrieveAttempt < maxRetrieveAttempts && ranCommandText == default(string))
					{
						var sessionConnectionEventReport = SessionManagerPool.Demux.RunReport(new ReportDefinition
						{
							ReportType = "SessionConnectionEvent",
							GroupFieldNames = null,
							SelectFieldNames = new[] { "Data" },
							FilterExpression = "SessionID='" + sessionEventTriggerEvent.Session.SessionID + string.Format("' AND EventType='RanCommand' AND Time >= '{0}'", startingTime.ToString("yyyy-MM-dd HH:mm:ss")),
							AggregateFilterExpression = null,
							ItemLimit = 2,
						});
						
						if (sessionConnectionEventReport.Items.Count > 0)
							ranCommandText = (string)sessionConnectionEventReport.Items[0][0];
						else
						{
							retrieveAttempt++;
							Thread.Sleep(5000);
						}
					}
					
					if (ranCommandText != default(string))
					{
						using (var client = new SmtpClient())
						using (var mailMessage = ServerToolkit.Instance.CreateMailMessage())
						{
							mailMessage.To.Add(ExtensionContext.Current.GetSettingValue("ToAddress"));
							
							mailMessage.Subject = string.Format("{0} {1}", ExtensionContext.Current.GetSettingValue("EmailSubjectPrefix"), sessionEventTriggerEvent.Session.Name);
							
							mailMessage.Body = ranCommandText;
							mailMessage.IsBodyHtml = false;
								
							client.Send(mailMessage);
						}
					}
				}
				catch (Exception)
				{
					// ignore...perhaps email address is incorrect
				}
			};
		}
		else
			return null;
	}
}

Edited by user Friday, December 1, 2017 3:00:24 PM(UTC)  | Reason: details

ScreenConnect Team
thanks 1 user thanked Ben B for this useful post.
thachad on 12/1/2017(UTC)
thachad  
#3 Posted : Friday, December 1, 2017 3:04:46 PM(UTC)
thachad


Rank: Guest

Joined: 11/30/2017(UTC)
Posts: 7
United States

Thanks: 6 times
Thanks guys..

I got a question on what this extension is actually doing.

Will it run the ipconfig from the remote machine as it comes online then send me the ip via email? Some machines don't instantly connect to the VPN, can a delay be set giving time for the user to actually connect to the vpn?
Ben B  
#4 Posted : Friday, December 1, 2017 3:14:41 PM(UTC)
Ben B


Rank: Administration

Medals: Level 2: Lent a Helping Hand! 10 Thanks!

Joined: 10/2/2015(UTC)
Posts: 281

Thanks: 1 times
Was thanked: 58 time(s) in 54 post(s)
Originally Posted by: thachad Go to Quoted Post
Thanks guys..

I got a question on what this extension is actually doing.

Will it run the ipconfig from the remote machine as it comes online then send me the ip via email? Some machines don't instantly connect to the VPN, can a delay be set giving time for the user to actually connect to the vpn?


As it is, the command runs pretty much immediately after the session connects. If you need to force some delay....say 5 minutes, you could add the following immediately before the call to "var startingTime = DateTime.UtcNow;" at line 32 (300000 ms = 5 mins):

Code:

Thread.Sleep(300000);
ScreenConnect Team
thanks 1 user thanked Ben B for this useful post.
thachad on 12/1/2017(UTC)
thachad  
#5 Posted : Friday, December 1, 2017 3:24:06 PM(UTC)
thachad


Rank: Guest

Joined: 11/30/2017(UTC)
Posts: 7
United States

Thanks: 6 times
I am currently on version 6.0.11299.6071, reading the extension it appears 6.3 is required. I reckon we need to update?
Ben B  
#6 Posted : Friday, December 1, 2017 3:28:08 PM(UTC)
Ben B


Rank: Administration

Medals: Level 2: Lent a Helping Hand! 10 Thanks!

Joined: 10/2/2015(UTC)
Posts: 281

Thanks: 1 times
Was thanked: 58 time(s) in 54 post(s)
Originally Posted by: thachad Go to Quoted Post
I am currently on version 6.0.11299.6071, reading the extension it appears 6.3 is required. I reckon we need to update?


I recommend upgrading to the latest stable version of Control; however, the extension should work on version 5.6+. Just modify MinProductVersionInclusive="6.3" to MinProductVersionInclusive="5.6" in the Manifest.

Cheers,
Ben
ScreenConnect Team
thanks 1 user thanked Ben B for this useful post.
thachad on 12/1/2017(UTC)
thachad  
#7 Posted : Friday, December 1, 2017 3:52:34 PM(UTC)
thachad


Rank: Guest

Joined: 11/30/2017(UTC)
Posts: 7
United States

Thanks: 6 times
getting error on the manifest.

(0,0) : error CS2001: Source file /opt/screenconnect/App_Extensions/3ffa3a70-0564-49-d9-8962-6b4468c8642e/sessionEventTrigger.cs could not be found


NVM started over from a blank template and no error.. Time to test!

Edited by user Friday, December 1, 2017 4:02:23 PM(UTC)  | Reason: Not specified

thachad  
#8 Posted : Friday, December 1, 2017 4:20:47 PM(UTC)
thachad


Rank: Guest

Joined: 11/30/2017(UTC)
Posts: 7
United States

Thanks: 6 times
working as expected!! AWESOME!

Another question.. I have session groups with these remote machines 1 for my windows 10 and 1 for Windows 7, I need this to run only on these session groups. Am I missing something simple here?
Currently I am getting emails from all machines...
Ben B  
#9 Posted : Friday, December 1, 2017 4:50:38 PM(UTC)
Ben B


Rank: Administration

Medals: Level 2: Lent a Helping Hand! 10 Thanks!

Joined: 10/2/2015(UTC)
Posts: 281

Thanks: 1 times
Was thanked: 58 time(s) in 54 post(s)
Originally Posted by: thachad Go to Quoted Post
working as expected!! AWESOME!

Another question.. I have session groups with these remote machines 1 for my windows 10 and 1 for Windows 7, I need this to run only on these session groups. Am I missing something simple here?
Currently I am getting emails from all machines...


You can change the filter in SessionEventTrigger.cs to pick out only machines in one of those two session groups. For example, if those sessions groups are defined by a custom property value, you could update this if statement:

Code:

if (sessionEventTriggerEvent.Session.SessionType == SessionType.Access &&
   sessionEventTriggerEvent.SessionEvent.EventType == SessionEventType.Connected &&
   sessionEventTriggerEvent.SessionConnection.ProcessType == ProcessType.Guest
   )


to:

Code:

if (sessionEventTriggerEvent.Session.SessionType == SessionType.Access &&
   (sessionEventTriggerEvent.Session.CustomPropertyValues[0] == "CustomProperty1Value1" || sessionEventTriggerEvent.Session.CustomPropertyValues[0] == "CustomProperty1Value2") &&
   sessionEventTriggerEvent.SessionEvent.EventType == SessionEventType.Connected &&
   sessionEventTriggerEvent.SessionConnection.ProcessType == ProcessType.Guest
   )


This will only fire the trigger on sessions with custom property 1 (CustomPropertyValues[0]) equal to CustomProperty1Value1 or CustomProperty1Value2. If you're using a different custom property to identify these Windows 7/10 machines, simply update the index, e.g. change CustomPropertyValues[0] to CustomPropertyValues[1] if you're using custom property 2.
ScreenConnect Team
thanks 1 user thanked Ben B for this useful post.
thachad on 12/1/2017(UTC)
thachad  
#10 Posted : Friday, December 1, 2017 5:07:37 PM(UTC)
thachad


Rank: Guest

Joined: 11/30/2017(UTC)
Posts: 7
United States

Thanks: 6 times
Currently my sessions are simple notes added to the machines allowing me to simply delete the note once the machine has been updated.
Ben B  
#11 Posted : Friday, December 1, 2017 9:17:22 PM(UTC)
Ben B


Rank: Administration

Medals: Level 2: Lent a Helping Hand! 10 Thanks!

Joined: 10/2/2015(UTC)
Posts: 281

Thanks: 1 times
Was thanked: 58 time(s) in 54 post(s)
Originally Posted by: thachad Go to Quoted Post
Currently my sessions are simple notes added to the machines allowing me to simply delete the note once the machine has been updated.


If you're using notes to identify the sessions, then update the if statement in SessionEventTrigger.cs to something like the following (replace TheNoteSubstringThatTriggersTheEmail with whatever note text you use):

Code:

if (sessionEventTriggerEvent.Session.SessionType == SessionType.Access &&
   sessionEventTriggerEvent.SessionEvent.EventType == SessionEventType.Connected &&
   sessionEventTriggerEvent.SessionConnection.ProcessType == ProcessType.Guest &&
   sessionEventTriggerEvent.Session.Notes.Contains("TheNoteSubstringThatTriggersTheEmail")
)
{
ScreenConnect Team
thanks 1 user thanked Ben B for this useful post.
thachad on 12/4/2017(UTC)
Users browsing this topic
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.