Certified Expert
  • Posts

  • Joined

  • Last visited

  • Days Won



11 Good

About mhashemi

  • Rank

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. +1 for mine Incidentally, I published version now. Please feel free to contribute via
  2. I do not know enough about webhooks in general, or Cisco's implementation specifically, to know if this is useful. We would need to have Cisco support authentication, right? I'm guessing I couldn't provide an LM API access id and key for authentication.
  3. I would like to alert when Cisco Air Marshal detects a rogue access point and found this Postman workspace,which indicates that Cisco will post to a webhook. I also found this LM communities post from 2018, which does not seem to have been implemented. Am I missing something or will I have to post to some other webhook (maybe Cisco supports Teams or Slack, idk) and write some script to query to webhook target (e.g. Teams), looking for the alert message?
  4. Thanks, that seems to have worked. I've published the final version to
  5. This seems to be working better (at least I can get back data). Now I am running into a problem adding the VDOMs to a list, which I will (eventually) turn into a property. I am getting the following output: Any idea why, with the code below, I am failing to append "root" and "exit" to the list of VDOMs? import com.santaba.agent.groovyapi.expect.Expect hostname = hostProps.get("system.hostname") userid = hostProps.get("ssh.user") passwd = hostProps.get("ssh.pass") def list = new ArrayList() try { ssh_connection =, userid, passwd) ssh_connection.expect("# ") ssh_connection.send("config vdom\n") ssh_connection.expect("# ") cmd_output = ssh_connection.before() if (cmd_output =~ /\(vdom\)/) { println "in vdom config, running the edit command" ssh_connection.send("edit ?\n") ssh_connection.expect("# ") } cmd_output2 = ssh_connection.before() println "attempting to parse vdoms" cmd_output2.eachLine { line -> if (!(line =~ /\<vdom\>/) && !(line =~ /^\s*$/) && !(line =~ "edit") && !(line =~ /\(vdom\)/)) { println "adding " + line + " to the list of vdoms" list.Add(line) } } ssh_connection.send("\025") ssh_connection.send("exit\n") println "returning vdoms:" println list.join(", ") return 0 } catch (Exception e) {println e;return 1} finally {if (ssh_connection){ssh_connection.expectClose()}}
  6. Just to be clear, I should add that, once this actually gets the command output, I will want to remove the "<vdom> Virtual Domain Name" lines and return the actual VDOM list as a comma-separated string.
  7. I am trying to write a Groovy PropertySource script, which will SSH into Fortigate devices and return the list of available VDOMs. In Putty, I would run the command config vdom -> Enter Then I would type "edit ?" and without hitting enter, the list of available VDOMs would appear (where each VDOM entry beginning with "<vdom> Virtual Domain Name"): I have the following Groovy script (modified from a ConfigSource in the portal): import com.santaba.agent.util.Settings import net.schmizz.sshj.SSHClient import import net.schmizz.sshj.transport.verification.PromiscuousVerifier import java.util.concurrent.TimeUnit import //def host = hostProps.get("system.hostname") def host = "<ip address>" //def user = hostProps.get("ssh.user", hostProps.get("config.user")) def user = "<username>" //def pass = hostProps.get("ssh.pass", hostProps.get("config.pass")) def pass = "<password>" //def port = hostProps.get("auto.config.port", "22") def port = "22" def time = (Settings.getSettingInt("configcollector.script.timeout", 120) - 1) * 1000 def startTime = System.currentTimeMillis() def client = new SSHClient() client.setTimeout(time) client.setConnectTimeout(time) client.addHostKeyVerifier(new PromiscuousVerifier()) try { client.loadKnownHosts() } catch (ex) { /* No Known Hosts File */ } def session try { client.connect(host, port.toInteger()) if(pKey && new File(pKey).exists()) { client.authPublickey(user, client.loadKeys(pKey)) } else { client.authPassword(user, pass) } session = client.startSession() session.allocateDefaultPTY() def cmd = session.exec("config vdom\n edit ?") cmd.join(time.toInteger(), TimeUnit.MILLISECONDS) cmd.close() def rawOut = cmd.getInputStream().text print "rawout: " + rawOut def out = rawOut.trim() if(out) { print out } } catch (Exception ex) { println ex } finally { session?.close() client?.disconnect() } The result is only "true" (from !groovy). I'm not super great with Groovy, what am I missing here? Thanks.
  8. I'm trying to write something that will support various use cases without forcing the user down any particular path. If they want to create a dynamic group, that's fine, but it seems like we oughta be able to support filtering like this without resorting to mucking about in the portal (not everyone has Manage rights either).
  9. Because I don't know where, in the group structure, the Exchange servers are located. For example, "Customer" could have "Location A" and "Location B" subgroups, each of which could have "Linux" and "Exchange" subgroups. Maybe they also have an Exchange server directly in the "Customer" folder. I could recursively search for subgroups, then for each one, use the endpoint you suggested, but that seems inefficient. This seems to work:"system.staticgroups",systemProperties.value~"CustomerName","system.categories",systemProperties.value~"IISServer" But what if I needed devices (in the CustomerName group) that had "category1" or "category" in system.categories? Both of the following filters returns zero results (in the portal right now, I am looking at one device that should be returned, but maybe there are more):"system.staticgroups",systemProperties.value~"CustomerName","system.categories",systemProperties.value~"category1","system.categories",systemProperties.value~"category2""system.staticgroups",systemProperties.value~"CustomerName","system.categories",systemProperties.value~"category1",systemProperties.value~"category2" Incidentally, while thinking of another example, I found that this works to give me 32-bit Windows servers with 3.75GB of memory (across all groups):"system.systemtype",systemProperties.value~"x86-based PC","system.sysinfo",systemProperties.value~"Windows","system.totalphysicalmemory",systemProperties.value:"3.75GB"
  10. I'm not seeing any way to return the devices I want, matching two property values. Using a filter like this works: 'filter=systemProperties.value~"DeviceGroupName"' But if I want only Exchange servers in the device group: 'filter=systemProperties.value~"DeviceGroupName",systemproperties.value~"Exchange"', does not return fewer devices. Any way to do this in a single query?
  11. Yeah, I normally work in PowerShell (and can work around it with that), but Groovy is less resource intensive. Hopefully someone else knows how make Groovy ignore the cert.
  12. I am trying to connect to a REST API running on a server with a self-signed cert. When I run the following code, I get this error: package DataSources.Groovy import org.apache.http.HttpEntity import org.apache.http.NameValuePair import org.apache.http.client.entity.UrlEncodedFormEntity import org.apache.http.client.methods.CloseableHttpResponse import org.apache.http.client.methods.HttpGet import org.apache.http.client.methods.HttpPost import org.apache.http.impl.client.BasicCookieStore import org.apache.http.impl.client.CloseableHttpClient import org.apache.http.impl.client.HttpClients import org.apache.http.impl.client.InternalHttpClient import org.apache.http.message.BasicNameValuePair import org.apache.http.util.EntityUtils import java.util.concurrent.ConcurrentHashMap.ForEachEntryTask import java.util.regex.Matcher import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import javax.xml.parsers.SAXParser import org.apache.commons.codec.binary.Hex; import groovy.json.*; import groovy.util.XmlSlurper; import groovy.xml.XmlUtil; String eol = System.getProperty("line.separator"); CloseableHttpClient httpclient = HttpClients.createDefault(); def loginurl = "https://<url>:8445/finesse/api/Users"; httpGet = new HttpGet(loginurl); httpGet.setHeader("Authorization", "Basic <token>"); response = httpclient.execute(httpGet); I did a little googling and tried the first answer from this StackOverflow post, but that was a no-go. Does the collector support any workaround?
  13. It seems like thresholds from the "Active Directory-" DataSource would be network specific.
  14. Can you put the device in SDT in the portal? What version of the module are you using?