mhashemi

LogicMonitor PowerShell module

Recommended Posts

@mhashemi thank you for creating this.  One question/issue.... should Update-LogicMonitorDeviceProperties support updating any system properties?  I tried to use this to update system.displayname and though the command says successful, nothing is changed.  In addition if I do system.foo, it says it works but actually doesn't.  However, any other property name (e.g. foo.system) works fine.  There is something about system.X properties that the update cmdlet (or API) doesn't seem to like.  Thoughts?

Edited by S P

Share this post


Link to post
Share on other sites

@mhashemi also, just FYI (though I don't need to use it at the moment) Get-LogicMonitorServiceProperties does not seem to work for me.  I would also think a nice compliment to this would be a new Update-LogicMonitorServiceProperties cmdlet (if you get time for it)... though the first issue I mentioned I would think is more valuable to me.  Thanks in advance!

Share this post


Link to post
Share on other sites

@mhashemi I looked at the verbose output of your command and it actually it looks like the issue is that you are using the PATCH method which only allows updating of custom properties.  If you were to change this to a PUT and instead use the path for properties, it would allow any property to be updated. 

https://www.logicmonitor.com/support/rest-api-developers-guide/devices/update-device-properties/

 

Share this post


Link to post
Share on other sites

Your experience is interesting, because I update the displayName property of our new collectors several times a week. In the script we use to deploy collectors, I use the following code:

 

$BlockLogging = $true # Just used for this example, to prevent the steps from being written to the event log.

$collectorProperties = @{"displayName" = "testdevice"; "hostGroupIds" = "<a valid group ID>"}

Foreach ($keyValuePair in $collectorProperties.GetEnumerator()) {
    Try {
        $lmResponse = Update-LogicMonitorDeviceProperties -AccessId $lmAccessId -AccessKey $lmAccessKey -AccountName <account> -DeviceId <device ID> -PropertyNames $keyValuePair.Key -PropertyValues $keyValuePair.Value
    }
    Catch {
        $message = ("{0}: Unexpected error updating the property: {1} on {2}. The value should be: {3}. The specific error is: {4}." -f (Get-Date -Format s), $keyValuePair.Key, $hubLongName, $keyValuePair.Value, $lmResponse)
        If ($BlockLogging) {Write-Host $message -ForegroundColor Red} Else {Write-Host $message -ForegroundColor Red; Write-EventLog -LogName Application -Source $EventLogSource -EntryType Error -Message $message -EventId 5417}
    }
}

 

If you put the displayName property into a hash table like I did, do you have the same problem?

 

I'll try to find some time to create the other cmdlet you suggested.

Edited by mhashemi

Share this post


Link to post
Share on other sites

Oh, you don't need the hash table. When I run with the property capitalization, the cmdlet works fine. For "display name", you need to use "displayName".

 

Update-LogicMonitorDeviceProperties -AccessId $lmAccessId -AccessKey $lmAccessKey -AccountName <account name> -DeviceId <id> -PropertyNames displayName -PropertyValues <new name>

 

Share this post


Link to post
Share on other sites

Thank you very much for the response.  You are right, it does work if I change the case.  Interestingly if I don't have the proper case, the command still says successful but I guess in the backend it's really not.  I will go ahead and make sure to use that case for the display name and will need to see how I can verify the case for other properties if/when the issue comes up.  Any way to catch that in error handling?  Thanks again for creating this though - it's something the product badly needed.

Share this post


Link to post
Share on other sites

BTW - as I continue to test it seems like the typical pipe approach is a bit different in that I need to continue to provide credentials (which is fine).  What's a bit more interesting is to try and get a list of all device properties in one object/array).  It seems like first I can get all devices (using Get-LogicMonitorDevices), but the device properties are an array... so I then use Get-LogicMonitorDeviceProperties against the previous list to expand those properties).  However, as you can guess since it runs line by line there is no longer a single array to act against.  Perhaps there is a better approach with your module commands? 

Just FYI - my goal is to update AWS device names with the tag value... so my plan was to export a list of all devices, identify those where the AWS tag name is not null and also where LM display name does not match the AWS tag name and then update the LM display name with the AWS tag name data.

Share this post


Link to post
Share on other sites

I was able to get this figured out and used the following to update the LM display names with the AWS system tag and only when the AWS tag is present.  I could use a way to better handle errors when LM finds a duplicate or when there are invalid characters in the tag, but it does the job:

#Get AWS devices with name tag set (not null)
$aws=Get-LogicMonitorDevices -AccessId $lmid -AccessKey $lmkey -AccountName $lmacct | select id,displayName,systemProperties | where {$_.systemProperties -like "*system.aws.tag.name*"}

#Build list of devices including ID, LM Display Name, and AWS Tag Name
$list = @()

foreach ($device in $aws) {
	$item = New-Object psobject 
	$item | Add-Member -type NoteProperty -Name 'id' -Value $device.id
	$item | Add-Member -type NoteProperty -Name 'displayName' -Value $device.displayName
	$item | Add-Member -type NoteProperty -Name 'awsTag' -Value (Get-LogicMonitorDeviceProperties -AccessId $lmid -AccessKey $lmkey -AccountName $lmacct -DeviceId $device.id | select name,value | where {($_.name -eq "system.aws.tag.Name")} | select value) 
	$list += $item
}

#Create list of objects to update where the display name does not currently equal the AWS tag name.
$update=$list | where {$_.displayName -ne $_.awsTag.value}

#Process Update
foreach ($item in $update) {Update-LogicMonitorDeviceProperties -AccessId $lmid -AccessKey $lmkey -AccountName $lmacct -DeviceId $item.id -PropertyNames displayName -PropertyValues $item.awsTag.value}

 

Share this post


Link to post
Share on other sites

Minor update - we found it was better to only do this for EC2 since for other devices it made it a bit harder to find things.  I've updated the script above with the following on the third line (right after the $aws= line):

$ec2=$aws | Select-Object | where {$_.systemProperties.value -eq "AWS/EC2"}

Then update the foreach loop to use $ec2 instead of $aws and you will only update EC2 devices.

Share this post


Link to post
Share on other sites
On 9/9/2017 at 10:37 PM, mhashemi said:

I have published a PowerShell module, which refactors part of the REST API, to the PowerShell gallery. Please feel free to make requests (or send me cmdlets you want added).

 

https://www.powershellgallery.com/packages/LogicMonitor/

Mike - Any interest in collaborating to build this out further?  

Share this post


Link to post
Share on other sites

As of April 19th, you'll want to add the following line at the top of the psm1 file OR any script that uses this module:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

Share this post


Link to post
Share on other sites

I see that you've added this to Github B|. I've created two PRs to address issues I've been having with 1.0.0.26. I'm assuming the Public directory scripts are "bundled" when releases are created and uploaded to PowerShell Gallery. 

  • Upvote 1

Share this post


Link to post
Share on other sites

Thanks for the input! I accepted your first one, for Add-EventLogSource. This is my first open source project, so I'm not sure what the etiquette is, on accepting code changes. Did you test your changes in hotfix/update-lmcollectorproperties-data ? This is exciting.

Yeah, I use psake to build the individual .ps1 files into the module, publish to PowerShellGallery, and push to GitHub.

Share this post


Link to post
Share on other sites
1 hour ago, mhashemi said:

This is my first open source project, so I'm not sure what the etiquette is, on accepting code changes. Did you test your changes in hotfix/update-lmcollectorproperties-data ? This is exciting.

No worries. This is my first time contributing to a public project xD

And yes, I did test it ^_^

Verbose output using current:

> $test_collector_details_update = Update-LogicMonitorCollectorProperties -AccessId $AccessId -AccessKey $AccessKey -AccountName $AccountName -CollectorId $CollectorName -PropertyNames collectorGroupId,escalatingChainId,description,resendIval -PropertyValues 3,1,'TestCollectorNewName',0 -Verbose
2018-07-18T17:32:36: Beginning Update-LogicMonitorCollectorProperties.
VERBOSE: 2018-07-18T17:32:36: Finished updating $resourcePath. The value is /setting/collectors/3.
VERBOSE: 2018-07-18T17:32:36: Finished updating $data. The value update is {"collectorGroupId":"3"}{"escalatingChainId":"1"}{"description":"TestCollectorNewName"}{"resendIval":"0"}.
VERBOSE: 2018-07-18T17:32:36: Executing the REST query.
VERBOSE: PUT https://accountname.logicmonitor.com/santaba/rest/setting/collectors/3 with -1-byte payload
VERBOSE: received 2137-byte response of content type application/json

 

Verbose output using PR:

> $test_collector_details_update = Update-LogicMonitorCollectorProperties -AccessId $AccessId -AccessKey $AccessKey -AccountName $AccountName -CollectorId $CollectorName -PropertyNames collectorGroupId,escalatingChainId,description,resendIval -PropertyValues 3,1,'TestCollectorNewName',0 -Verbose
2018-07-18T17:18:11: Beginning Update-LogicMonitorCollectorProperties.
VERBOSE: 2018-07-18T17:18:11: Finished updating $resourcePath. The value is /setting/collectors/3.
VERBOSE: 2018-07-18T17:18:11: Finished updating $data. The value update is {
    "description":  "TestCollectorNewName",
    "escalatingChainId":  "1",
    "resendIval":  "0",
    "collectorGroupId":  "3"
}.
VERBOSE: 2018-07-18T17:18:11: Executing the REST query.
VERBOSE: PUT https://accountname.logicmonitor.com/santaba/rest/setting/collectors/3 with -1-byte payload
VERBOSE: received 2123-byte response of content type application/json

In current, the REST API will only take the first json-object ({"collectorGroupId": "3"} in my example) and ignore the rest. 

Edited by Joe Tran
genericizing to protect the innocent

Share this post


Link to post
Share on other sites

Sounds good. Why did you limit the JSON depth to 6? Why define it at all?

 

Oh, you know what? Even though it isn't documented, I believe this part of the API supports the PATCH method (like devices). I was thinking of updating it to build the property/value pairs using the same code as is in the Update-LogicMonitorDeviceProperties cmdlet. As far as I can tell, it does not suffer from the same bug as you have pointed out here. Do you agree? I prefer PATCH over PUT because it is so easy to screw up when using PUT.

Edited by mhashemi

Share this post


Link to post
Share on other sites

I took your changes to Update-LogicMonitorCollectorProperties and added them, along with support for PATCH and PUT in 1.0.0.29. I have to go on a trip, but if you wanted to look at updating Update-LogicMonitorDeviceProperties, that would be cool. :)

 

Device updating has a more complicated JSON structure based on whether or not you are updating custom or standard properties.

 

Either way, thanks for the help.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.