Recent Discussions
Modules for Citrix Cloud/DaaS/VAD monitoring
Hi, here are some modules to monitor Citrix DaaS/VAD via the Citrix Monitor API. These might be helpful with mixture of DaaS and on-prem VAD environments as the same modules can be used for both. Setup details are in the module notes, see the CitrixDaaS_Token notes for the Citrix Cloud API setup. I have made the .xml export of each module available on Github, they can be downloaded from here: https://github.com/chrisred/logicmonitor-citrixdaas The modules are: CitrixDaaS_ApplicationUsage.xml CitrixDaaS_ConnectionFailures.xml CitrixDaaS_DeliveryGroups.xml CitrixDaaS_LogonPerformace.xml CitrixDaaS_Machines.xml CitrixDaaS_Token.xml I'll try to keep an eye on this post for any questions.267Views21likes8CommentsLinux services and autodiscovery
Hey guys, I just wanted to let you know that I took LogicMonitor's default datasource, "Linux_SSH_ServiceStatus", and added auto discovery to it. The only thing that is needed at the resource or group level is that the following three properties are set: ssh.user ssh.pass linux.ssh.services.regex ( default: "sshd\.service" ) I published the datasource under 93Y4PC (currently under security review as of this post) The discovery script gets the output of systemctl list-units --all --type=service --plain --state=loaded | egrep service Loop through each line of the output and see if it matches the regex from the property, "linux.ssh.services.regex" A person could even set the regex to be ".*" which would grab all of the services.. then turn around and create a filter to exclude certain things. For example if I wanted everything but services with the name ssh in them, I could create a filter that says ##WILDVALUE## not contain ssh.23Views1like2CommentsRubrik: Cloud Data Management & Enterprise Backup
* FYI: Official LogicMonitor supported Rubrik modules are now in CORE * Here's some Rubrik LogicModules. *NOTE: Alert thresholds have been lightly/conservatively set. Requires rubrik.user & rubrik.pass be set. PropertySources Rubrik_Product_Info CDA9LK addCategory_Rubrik NGLPWA DataSources Rubrik_Archive_UnmanagedObjects 4376C6 Rubrik_Cluster_Hosts X6CXZN Rubrik_Cluster_Nodes 6D43GA Rubrik_Global_IOStatistics PGJYTY Rubrik_Global_PhysicalHostIngest 6RGWMJ Rubrik_Global_Storage EZHJFX Rubrik_Global_Streams EHX4RZ Rubrik_JobMonitoring_ActivePast24Hours 2NP6RY Rubrik_MSSQL_Databases Z622YK Rubrik_Node_Drives RHZT4F Rubrik_Reports_ObjectBackupTaskSummaryBySLADomain MH2Y6J Rubrik_Reports_ObjectProtectionSummaryBySLADomain TDXHH9 Rubrik_Reports_SLAComplianceSummaryBySLADomain 6Y9NNM Rubrik_SAML_SSOStatus TFHRFN Rubrik_SLA_Domains 44THK9 Rubrik_Storage_CompressionStatistics AC7WEE Rubrik_Storage_ManagedVolumes RW6ZCA Rubrik_VMware_VMs XLT9LL241Views9likes33CommentsPowershell in five easy steps
A few years ago, I wrote a powershell tutorial. Thought some may find it useful. On to the Future with Powershell – PowerShell.org It's less programming tutorial than other programming tutorials. I wrote it for the "you can tear this mouse from my cold hands" type of admin who are being forced to learn powershell to do their jobs. It's peppered with some nuggets of geeky humor to keep it rolling forward and is just enough to get someone started using powershell (or any other programming language) by focusing on the larger concepts of Storage, Input, Output, Decisions, Loops... the building blocks of every language from assembly to applescript.18Views1like0CommentsPrint Spooler
Has anyone been able to get a non-cluster print spooler to work? I’m trying to list out the printers connected to the print spooler so I don’t have to manually maintain an individual printer list and have been unable to get custom scripting to work by adjusting the cluster code. Let me know if anyone has a better way to do this.58Views3likes5CommentsNOC Rollup Status Dashboards for MSPs
LM doesn't come with it out of the box, so I built the NOC Dashboard I've wanted. It provides high level, at-a-glance health indicators for each of our client environments we manage. This makes a great "big board" for a NOC room or a second screen status board for work from home NOC/Support folks. I do have three examples in this code for ways to filter for specific teams/purposes. This all collapses for ease of reference correctly in Powershell ISE on windows. Line 282 references a dataSource I wrote that counts frequency of specific eventlog events to illustrate potential brute force attempts (CTM are my initials, we tag our scripts to make finding the best source of answers faster in the future - old habit from pen & paper change logs from a previous job). As any screenshots would contain client names, I'm unable to post any screen shots of the results of this, but my current settings for my Main dashboard are (This is the first Dashboard I've made that looks better in UIv4 than 3): ... #!!! These two need to be changed. First is a string, second an integer #!!! See the comment block below for instructions # The first chunk of your company's logicmonitor URL $company = "yourCompanyNameHere" # ID of the group to be used as a source for the NOC widget items $parentGroupID = <parentGroupID> <# Netgain Technology, llc ( https://netgaincloud.com ) 2/26/2024 - Developed by Cole McDonald Disclaimer: Neither Netgain nor Cole McDonald are not responsible for any unexpected results this script may cause in your environment. To deploy this: - COLLECTOR: you will need a collector for scripting, this will be the single applies to target. You may need to increase the script timeout depending on the size of your device deployment. - DASHBOARD: you will need a Dashboard with a NOC widget on it. The name can be whatever you'd like, there will be a name change in the "name" property for the initial array. In the case of the first example here, "NOC - Master" - PARENT GROUP: you will need to identify the ID# of the group you wish to use as the source for the subgroup list and set the $parentGroupID to the appropriate ID# Purpose: Create an auto-updating high level NOC dashboard that can show - Rollup state for a list of client subgroups from our \Clients group - Group Indicators for a specific dataSource - Group indicators for a subset of devices within each group After the API region, there are three separate dashboards referenced to illustrate the 3 methods for using this dataSource. NOTE: my code uses backticks for line continuation. Where possible in my code, each line indicates a single piece of information about the script's algorithm and the first character in each line from a block indicates the line's relationship to the one above it. #> #region Rest API Initialization and Functions # Init variables used in the RESTApi functions $URLBase = "https://$company.logicmonitor.com/santaba/rest" $accessID = "##ApiAccessID.key##" $accessKey = "##ApiAccessKey.key##" #-------- The Functions ---------- function Send-Request { param ( $cred , $URL , $accessid = $null, $accesskey = $null, $data = $null, $version = '3' , $httpVerb = "GET" ) if ( $accessId -eq $null) { exit 1 } <# Use TLS 1.2 #> [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 <# Get current time in milliseconds #> $epoch = [Math]::Round( ( New-TimeSpan ` -start (Get-Date -Date "1/1/1970") ` -end (Get-Date).ToUniversalTime()).TotalMilliseconds ) <# Concatenate Request Details #> $requestVars = $httpVerb + $epoch + $data + $resourcePath <# Construct Signature #> $hmac = New-Object System.Security.Cryptography.HMACSHA256 $hmac.Key = [Text.Encoding]::UTF8.GetBytes( $accessKey ) $signatureBytes = $hmac.ComputeHash( [Text.Encoding]::UTF8.GetBytes( $requestVars ) ) $signatureHex = [System.BitConverter]::ToString( $signatureBytes ) -replace '-' $signature = [System.Convert]::ToBase64String( [System.Text.Encoding]::UTF8.GetBytes( $signatureHex.ToLower() ) ) <# Construct Headers #> $auth = 'LMv1 ' + $accessId + ':' + $signature + ':' + $epoch $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" $headers.Add( "Authorization", $auth ) $headers.Add( "Content-Type" , 'application/json' ) # uses version 2 of the API $headers.Add( "X-version" , $version ) <# Make Request #> $response = Invoke-RestMethod ` -Uri $URL ` -Method $httpVerb ` -Body $data ` -Header $headers ` -erroraction SilentlyContinue ` -warningaction SilentlyContinue Return $response } function Get-LMRestAPIObjectListing { param ( $URLBase , $resourcePathRoot , # "/device/devices" $size = 1000 , $accessKey , $accessId , $version = '2' ) $output = @() $looping = $true $counter = 0 while ($looping) { #re-calc offset based on iteration $offset = $counter * $size $resourcePath = $resourcePathRoot $queryParam = "?size=$size&offset=$offset" $url = $URLBase + $resourcePath + $queryParam # Make Request $response = Send-Request ` -accesskey $accessKey ` -accessid $accessId ` -URL $url ` -version $version if ( $response.items.count -eq $size ) { # Return set is full, more items to retrieve $output += $response.items $counter++ } elseif ( $response.items.count -gt 0 ) { # Return set is not full, store date, end loop $output += $response.items $looping = $false } else { # Return set is empty, no data to store, end loop $looping = $false } } write-output $output } # Get Dashboards $resourcePath = "/dashboard/dashboards" $dashboards = Get-LMRestAPIObjectListing ` -resourcePathRoot $resourcePath ` -accessKey $accessKey ` -accessId $accessID ` -URLBase $URLBase # Get Widgets $resourcePath = "/dashboard/widgets" $widgets = Get-LMRestAPIObjectListing ` -resourcePathRoot $resourcePath ` -accessKey $accessKey ` -accessId $accessID ` -URLBase $URLBase # Get Groups $resourcePath = "/device/groups" $Groups = Get-LMRestAPIObjectListing ` -resourcePathRoot $resourcePath ` -accessKey $accessKey ` -accessId $accessID ` -URLBase $URLBase #endregion function generateJSON { param( $dashInfo, $clientnames, $deviceDisplayName = "*", $DSDisplayName = "*" ) $itemArray = @() foreach ($name in $clientnames) { $itemArray += @{ "type" = "device" "deviceGroupFullPath" = "Clients/$name" "deviceDisplayName" = $deviceDisplayName "dataSourceDisplayName" = $DSDisplayName "instanceName" = "*" "dataPointName" = "*" "groupBy" = "deviceGroup" "name" = "`#`#RESOURCEGROUP`#`#" } } # Write JSON back to the API for that widget $outputJSON = "`n`t{`n`t`t`"items`" : [`n" foreach ($item in $itemArray) { $elementJSON = @" { `"type`" : `"$($item.type)`", `"dataPointName`" : `"$($item.dataPointName)`", `"instanceName`" : `"$($item.instanceName)`", `"name`" : `"$($item.name)`", `"dataSourceDisplayName`" : `"$($item.dataSourceDisplayName)`", `"groupBy`" : `"$($item.groupBy)`", `"deviceGroupFullPath`" : `"$($item.deviceGroupFullPath)`", `"deviceDisplayName`" : `"$($item.deviceDisplayName)`" } "@ if ($item -ne $itemArray[-1]) { $outputJSON += "$elementJSON,`n" } else { # Last Item $outputJSON += "$elementJSON`n`t`t]`n`t}" } } write-output $outputJSON } # Get Client Names from groups $clientnames = ( $groups ` | where parentid -eq $parentGroupID ` | where name -notmatch "^\." ).name | sort #ID Master Dashboard # declare dashboard name and set default id and widgetid to use in the loop later $masterDash = @{ id=0; widgetid=0; name="NOC - Master" } $master = $dashboards | ? name -eq $masterDash.name if (($master.name).count -eq 1) { $masterDash.id = $master.id $masterDash.widgetid = $master.widgetsConfig[0].psobject.Properties.name $outputJSON = generateJSON ` -dashInfo $masterDash ` -clientnames $clientnames $resourcePath = "/dashboard/widgets/$($masterDash.widgetid)" $url = $URLBase + $resourcePath $widget = Send-Request ` -accessKey $accessKey ` -accessId $accessID ` -data $outputJSON ` -URL $URL ` -httpVerb "PATCH" } #ID Network Dashboard # declare dashboard name and set default id and widgetid to use in the loop later $networkDash = @{ id=0; widgetid=0; name="NOC - Network" } # preset filters for specific dashboard targeting by device $networkDeviceDisplayNameString = "*(meraki|kemp)*" $network = $dashboards | ? name -eq $networkDash.name if (($network.name).count -eq 1) { $networkDash.id = $network.id $networkDash.widgetid = $network.widgetsConfig[0].psobject.Properties.name $outputJSON = generateJSON ` -dashInfo $networkDash ` -clientnames $clientnames ` -deviceDisplayName $networkDeviceDisplayNameString $resourcePath = "/dashboard/widgets/$($networkDash.widgetid)" $url = $URLBase + $resourcePath $widget = Send-Request ` -accessKey $accessKey ` -accessId $accessID ` -data $outputJSON ` -URL $URL ` -httpVerb "PATCH" } #ID Security Dashboard # declare dashboard name and set default id and widgetid to use in the loop later $securityDash = @{ id=0; widgetid=0; name="NOC - Security" } # preset filters for specific dashboard targeting by datasource $securityDataSourceDisplayNameString = "Event Frequency Sec:4625 CTM" $security = $dashboards | ? name -eq $securityDash.name if (($security.name).count -eq 1) { $securityDash.id = $security.id $securityDash.widgetid = $security.widgetsConfig[0].psobject.Properties.name $outputJSON = generateJSON ` -dashInfo $securityDash ` -clientnames $clientnames ` -DSDisplayName $securityDataSourceDisplayNameString $resourcePath = "/dashboard/widgets/$($securityDash.widgetid)" $url = $URLBase + $resourcePath $widget = Send-Request ` -accessKey $accessKey ` -accessId $accessID ` -data $outputJSON ` -URL $URL ` -httpVerb "PATCH" }49Views0likes3CommentsProgrammatic Ping Alert
We currently lack the ability to white list domain names on our firewall, so I have to do everything via IP. Recently I’ve come across an issue where a company won’t give me their external IP’s because they can change, or so they say. For several weeks I’ve pinged the IP’s and it has always been 1 of 4 IPs. Has anyone created some kind of ping alert that does something like “ping easypost.com and api.easypost.com if the IP’s returned are not in 169.62.110.130-169.62.110.133, alert me” I’m not much of a programmer myself so I’d need something pretty “plug and play”. TIA!Solved58Views6likes3CommentsHow to redirect the output of the groovy script to the collector log file using groovy script?
In my groovy script, I want to redirect the output from the groovy script into the collectors log file? What should be the groovy code, to redirect the output to the collectors log file? Can anyone help me here?18Views4likes1Comment