LogicMonitor Collector installation on Windows Server Core
Windows Server Core and (the free) Hyper-V Server Core are GUI-less versions of Windows that can be administered remotely with GUI tools. We've recently seen an uptick in requests for deployment of the collector to these platforms, as Windows introduces a lot of overhead with the addition of the GUI; the other compelling reason to go this route being that Hyper-V Core is a free license of Windows from Microsoft (similar to the free flavor of ESXi, only it can run a Windows collector!) Microsoft Documentation: Managing a Server Core Server Configure Server Core with the SConfig command Option A: Remote Desktop Install Establish a remote desktop session to the Server Core server using the instructions provided by Microsoft. Within the standard Command shell, type the word "PowerShell" to load a PowerShell session. Add a new (Windows) LogicMonitor Collector in your portal, and select the PowerShell command instead of the download. Paste (and run) the PowerShell command into the open PowerShell windows within the Remote Desktop Session on the Server Core server. You'll see a message indicating that the download has started, and after some time, the normal InstallShield Wizard will launch as expected. Complete the collector account configuration and proceed as you would with an OS with a GUI. Collect on! Additional methods are certainly possible (Windows Admin Center, Remote PowerShell, more?) and as I have a chance to test/ validate, I will continue to update this post.111Views0likes0CommentsRunning powershell scripts with encrypted passwords.
We sometimes see datasource scripts with passwords in the body of their script. For testing this is fine, but in production datasource scripts, passwords in plain view isn’t just bad, it should be a cardinal sin. You can use Powershell to secure a password by creating a PSCredential object that uses the cmdlet Get-Credential and stores the output into a file. Note that it saves as a System.Security.SecureString. Now you can use the file in your script: $hostname= "##HOSTNAME##" $pass= Get-Content "\\Encryptedfile.txt" $user= "##PS.USER##" $password1= ConvertTo-SecureString -String $pass When your script is finished just run it in powershell GUI to check it works fine. Make sure you alter our tokens to the correct values. We had a recent case that when the collector tries to run the datasource script it failed. The below error was in the logs. New-PSSession : [PROD-TP-DB01] Connecting to remote server HOST failed with the following error message : WinRM cannot process the request. The following error with errorcode 0x8009030e occurred while using Negotiate authentication: A specified logon session does not exist. It may already have been terminated. Possible causes are: -The user name or password specified are invalid. -Kerberos is used when no authentication method and no user name are specified. -Kerberos accepts domain user names, but not local user names. -The Service Principal Name (SPN) for the remote computer name and port does not exist. -The client and remote computers are in different domains and there is no trust between the two domains. The script is failing with an authentication error. Even though it works fine in the Powershell GUI. The reason for this was the account the collector ran under. PowerShell uses the Windows Data Protection API (DPAPI) to encrypt/decrypt your strings. That means if you created the file using one user account only the same user account on the same computer will be able to use this encrypted string. So the collector account cannot read the file Encryptedfile.txt. We proved this by running the Powershell GUI under the same account your collector uses. So make sure that you create the file using the same account. Keep in mind that if you change the collector account, the script will fail. It is possible that you can encrypt the file using a machine key, which means any user on the collector can use the file and decrypt it, but that’s for another post!65Views0likes0CommentsSDT scheduling using REST API and PowerShell
Trying to schedule a new SDT for January 1, 2018 1:00 AM to 1:30 AM for a device group, but getting a Status:1007 and a blank response. <# account info #> $accessId = 'SHj6Hub8e63FUwkc5' $accessKey = 'xz37=(][{qb6ANLp}5$-S9Hvn6HV292P' $company = 'api' # stdTYpe (integer) # 1 - one time, 2 - Weekly SDT, 3 - Monthly SDT, 4 - Daily SDT # we have to use "one time" style values because LM has no concept of day of month $stdTYpe = 1 # type (string) # ServiceGroupSDT, DeviceGroupSDT, CollectorSDT $type = "DeviceGroupSDT" # deviceGroupId (string) # $deviceGroupId = 18 # dataSourceId (integer) # 0 = ALL $dataSourceId = 0 <# request details #> $httpVerb = 'POST' $resourcePath = '/sdt/sdts' #serviceGroupSDTs # data $data = '{"sdtType":'+$stdTYpe+',"type":"'+ $type +'","deviceGroupId":'+ $deviceGroupId +',"dataSourceId":'+ $dataSourceId +',"startDateTime":1514786400,"endDateTime":1514788200}' <# Construct URL #> $url = 'https://' + $company + '.logicmonitor.com/santaba/rest' + $resourcePath <# 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') <# Make Request #> $response = Invoke-RestMethod -Uri $url -Method $httpVerb -Body $data -Header $headers <# Print status and body of response #> $status = $response.status $body = $response.data| ConvertTo-Json -Depth 5 Write-Host "Status:$status" Write-Host "Response:$body"46Views0likes5CommentsImport Datasource via API and PowerShell
Hello All, I'm attempting to import datasources into our LogicMonitor instance, using the API and PowerShell. The following documentation only provides a CURL example, which isn't really sufficient for us. https://www.logicmonitor.com/support/rest-api-developers-guide/datasources/import-datasources-from-xml/ Usage: Import-LMDatasource -Credential $credentials -FilePath 'c:\repositories\LogicModules\DataSources\CustomDataSource.xml' I am assuming that you have an array containing your accessId, accessKey and company name, prior to calling the function. The parameter FilePath is the full path to the XML file to be uploaded. function Import-LMDatasource { [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [array]$Credential, [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$FilePath ) Begin { if(-not($Credential)) { $accessId = Read-Host -Prompt "Please supply accessId:" $accessKey = Read-Host -Prompt "Please supply accessKey:" $company = Read-Host -Prompt "Please supply company:" } else { $accessId = $Credential.accessId $accessKey = $Credential.accessKey $company = $Credential.company } $httpVerb = 'POST' $resourcePath = '/setting/datasources' $queryParams = '/importxml' $data = '' $url = 'https://' + $company + '.logicmonitor.com/santaba/rest' + $resourcePath + $queryParams $epoch = [Math]::Round((New-TimeSpan -Start (Get-Date -Date '1/1/1970') -End (Get-Date).ToUniversalTime()).TotalMilliseconds) $contentType = [System.Web.MimeMapping]::GetMimeMapping($FilePath) } Process { $requestVars = $httpVerb + $epoch + $data + $resourcePath $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())) $auth = 'LMv1 ' + $accessId + ':' + $signature + ':' + $epoch Add-Type -AssemblyName System.Net.Http $httpClientHandler = New-Object System.Net.Http.HttpClientHandler $httpClient = New-Object System.Net.Http.HttpClient $httpClientHandler $httpClient.DefaultRequestHeaders.Authorization = $auth $packageFileStream = New-Object System.IO.FileStream @($filePath, [System.IO.FileMode]::Open) $contentDispositionHeaderValue = New-Object System.Net.Http.Headers.ContentDispositionHeaderValue 'form-data' $contentDispositionHeaderValue.Name = 'file' $contentDispositionHeaderValue.FileName = (Split-Path -Path $FilePath -Leaf) $streamContent = New-Object System.Net.Http.StreamContent $packageFileStream $streamContent.Headers.ContentDisposition = $contentDispositionHeaderValue $streamContent.Headers.ContentType = New-Object System.Net.Http.Headers.MediaTypeHeaderValue $contentType $content = New-Object System.Net.Http.MultipartFormDataContent $content.Add($streamContent) $response = $httpClient.PostAsync($url, $content).Result if(!$response.IsSuccessStatusCode) { $responseBody = $response.Content.ReadAsStringAsync().Reult $errorMessage = "Status code {0}. Reason {1}. Server reported the following message: {2}." -f $response.StatusCode, $response.ReasonPhrase, $responseBody throw [System.Net.Http.HttpRequestException] $errorMessage } return $response.Content.ReadAsStringAsync().Result # $httpClient.Dispose() # $response.Dispose() } End { } } Result: {"errmsg":"Request content is too large, max allowed size is 10240","status":1007} Dot Sourcing the function at runtime allows me to inspect the variables set during execution: $response Version : 1.1 Content : System.Net.Http.StreamContent StatusCode : OK ReasonPhrase : OK Headers : {[Date, System.String[]], [Server, System.String[]]} RequestMessage : Method: POST, RequestUri: 'https://<instance>.logicmonitor.com/santaba/rest/setting/datasources/importxml', Version: 1.1, Content: System.Net.Http.MultipartFormDataContent, Headers: { Authorization: LMv1 <ACCESSTOKEN-OBFUSCATED> Content-Type: multipart/form-data; boundary="17ba48f6-b5e9-48c6-9002-7544d99025d8" Content-Length: 11858 } IsSuccessStatusCode : True Uploading the exact same datasource XML via the GUI works. I think I'm most of the way there, but obviously something I'm doing is bloating the request size and tripping this limit. Has anyone had any success with uploading datasources via the API? Many Thanks, ~Nick30Views0likes4CommentsHTTP Authentication Required?
I have two sets of code. 1 pulls all 'Services' or Website groups. The other is supposed to just pull the group name and id. The first works, the second doesn't. I am using the base PowerShell script laid out in the documentation. If I remove the ?fields=name,id it works without issue. If I add it back it gives me this error "HTTP Status 401 - Unauthorizedtype Status reportmessage Unauthorizeddescription This request requires HTTP authentication.LogicMonitor Technical Operations". Any help would be awesome. <# request details #> $httpVerb = 'GET' $resourcePath = '/service/groups?fields=name,id' $status = $null $body = $null $response = $null <# Construct URL #> $url = 'https://' + $company + '.logicmonitor.com/santaba/rest' + $resourcePathSolved23Views0likes2CommentsUpdating Escalation Chains via REST
I am attempting to adjust an escalation chain via PowerShell and REST. I am currently getting back a 1007 and can't seem to figure out what is wrong. Below is what I am using, I have tried different forms of $data. Our main goal is to change CC. We have tried these two and then the 1 in the script below. Just not sure what is coming up wrong. $data = '"ccDestinations":[{"type":"arbitrary","method":"email","addr":"test@test.com"}]' $data = '"destinations":[{"type":"single","stages":[[{"type":"arbitrary","method":"email","addr":"test@test.com"}]]}]' <# Use TLS 1.2 #> [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 <# account info #> $accessId = '' $accessKey = '' $company = '' <# request details #> $httpVerb = 'PUT' $resourcePath = '/setting/alert/chains/4' $data = '"name":"Chain 1","ccDestinations":[{"type":"arbitrary","method":"email","addr":"fakeemail@email.com"}],"destinations":[{"type":"single","stages":[[{"type":"arbitrary","method":"email","addr":"anotherfakeemail@email.com"}]]}]' <# Construct URL #> $url = 'https://' + $company + '.logicmonitor.com/santaba/rest' + $resourcePath <# 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') <# Make Request #> $response = Invoke-RestMethod -Uri $url -Method $httpVerb -Body $data -Header $headers <# Print status and body of response #> $status = $response.status $status $body = $response.data | ConvertTo-Json -Depth 5 $bodySolved14Views0likes1CommentDownload Speed
WALDXL - Download Speed This datasource will run a PowerShell script that downloads a 10MB file and then figures out the speed in Mbps that it was downloaded. CAUTION: This datasource will download a 10Mb file for every Windows machine specified in the applies to field(default is not applied),every poll(deafult is 20 minutes), depending on your environment this could raise the price for your monthly ISP bill. Specifically if your ISP speeds ramp up when needed. I would recommend applying this to: hasCategory("speed") and isWindows() The of course you just need to add the system.property of speed to any Windows machine you want to monitor Download Speed on.14Views2likes4CommentsAPI - Posting widget updates via powershell
Hello, Trying to get the below script to work, but hitting a snag. I've tried to repurpose the DataSource Upload Example script from this page to get the desired result but no dice. Param([Parameter(Mandatory=$true)][string]$name,[string]$GetInstance,[string]$GetType,[string]$Computername)<# Use TLS 1.2 #>[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $accessId = '###'$accessKey = '###'$company = '###'$httpVerb = 'PUT'$widgetID = "350"$resourcePath = "/dashboard/widgets/$widgetID"$queryParams = ''$boundary = [System.Guid]::NewGuid().ToString()$LF = "\r\n"$data = @" "items":[{"deviceGroupFullPath":"*","deviceDisplayName":"$computername","dataSourceDisplayName":"$name","instanceName":"$Name","dataPointName":"FolderGT60","groupBy":"instance","name":"$getinstance"}]"@$url = 'https://' + $company + '.logicmonitor.com/santaba/rest' + $resourcePath + $queryParams$epoch = [Math]::Round((New-TimeSpan -start (Get-Date -Date "1/1/1970") -end (Get-Date).ToUniversalTime()).TotalMilliseconds)$requestVars = $httpVerb + $epoch + $data + $resourcePath$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()))$auth = 'LMv1 ' + $accessId + ':' + $signature + ':' + $epoch$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"$headers.Add("Authorization",$auth)$headers.Add("Content-Type","multipart/form-data; boundary=----$boundary")$response = Invoke-RestMethod -Uri $url -Method $httpVerb -body $data -Header $headers $status = $response.status$body = $response.dataWrite-Host "Status:$status"Write-Host "Response:$body" I assume that the '$headers.Add("Content-Type","multipart/form-data; boundary=----$boundary")' section, or '$boundary', is incorrect but have only really been looking into anything Logicmonitor-API-Powershell in the last 24 hours. I'm getting HTTP 415 error Unsupported Media Typeh1 which I thought originally was from the $data section but I can't figure out any other way to pass the JSON into the variable. Thanks, Amir.13Views0likes2Comments