Forum Discussion

Dominique's avatar
Dominique
Icon for Advisor rankAdvisor
4 years ago

Properties Content

Hello,

I have the four properties 

- Application

- Owner

- Patch Group

- Technical Group

I would like to have them

1. existing on all devices

2. the values should be mandatory and validated against a list of correct values... list of applications, list of users, list of patch group, list of technical group, ...

Is there an easy wahy to do the (1) first and when it will be existing verifying the values (2). 

I have see also some typo, misspelling in the property names how to detect them?

As it seems all these fields are free for any input it is open to a mess !!! anyway to limit this?

Thanks,

Dominique

8 Replies

  • Hello,

    I started with the last script done to owverwrite IP Address/DNS Name ...

    #########################      API Function Script      ###F######################
    #------------------------------------------------------------------------------------------------------------
    # Prerequisites:
    #
    # Requires -Version 3
    #------------------------------------------------------------------------------------------------------------
    # Initialize Variables
    <# account info #>
    $accessId = '##IP2DNS.ACCESSID##'
    $accessKey = '##IP2DNS.KEY##'
    $company = 'uclahealth'
    
    # Functionize the reusable code that builds and executes the query
    function Send-Request() {
        Param(
            [Parameter(position = 0, Mandatory = $true)]
            [string]$path,
            [Parameter(position = 1, Mandatory = $false)]
            [string]$httpVerb = 'GET',
            [Parameter(position = 2, Mandatory = $false)]
            [string]$queryParams,
            [Parameter(position = 3, Mandatory = $false)]
            [PSObject]$data
        )
        # Use TLS 1.2
        [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
        <# Construct URL #>
        $url = "https://$company.logicmonitor.com/santaba/rest$path$queryParams"
        <# 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 + $path
        <# 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')
        $headers.Add("X-version", '2')
        <# Make request & retry if failed due to rate limiting #>
        $Stoploop = $false
        do {
            try {
                <# Make Request #>
                $response = Invoke-RestMethod -Uri $url -Method $httpVerb -Body $data -Header $headers
                $Stoploop = $true
            } catch {
                switch ($_) {
                    { $_.Exception.Response.StatusCode.value__ -eq 429 } {
    #                    Write-Host "Request exceeded rate limit, retrying in 60 seconds..."
                        Start-Sleep -Seconds 60
                        $response = Invoke-RestMethod -Uri $url -Method $httpVerb -Body $data -Header $headers
                    }
                    { $_.Exception.Response.StatusCode.value__ } {
    #                    Write-Host "Request failed, not as a result of rate limiting"
                        # Dig into the exception to get the Response details.
                        # Note that value__ is not a typo.
    #                    Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
    #                    Write-Host "StatusDescription:" $_.Exception.Response.StatusCode
    #                    $_.ErrorDetails.Message -match '{"errorMessage":"([\d\S\s]+)","errorCode":(\d+),'
    #                    Write-Host "LM ErrorMessage" $matches[1]
    #                    Write-Host "LM ErrorCode" $matches[2]
                        $response = $null
                        $Stoploop = $true
                    }
                    default {
    #                    Write-Host "An Unknown Exception occurred:"
    #                    Write-Host $_ | Format-List -Force
                    $response = $null
                    $Stoploop = $true
                }
            }
        }
    } While ($Stoploop -eq $false)
    Return $response
    }
    ##
    #------------------------------------------------------------------------------------------------------------
    #  Starting Script 
    #------------------------------------------------------------------------------------------------------------
    ##
    $deviceID = '##SYSTEM.DEVICEID##'
    $currentName = '##SYSTEM.HOSTNAME##'
    $currentDisplayName = '##SYSTEM.DISPLAYNAME##'
    $oldResult = '##AUTO.APPLICATION.RESULT##'
    $oldApplication = '##AUTO.APPLICATION.NAME##'
    ##
    $applicationName = '##AUTO.APPLICATION.NAME##'
    $ownerName = '##AUTO.OWNER.NAME##'
    $technicalgroup = '##AUTO.TECHNICALGROUP.NAME##'
    $patchgroup = '##AUTO.PATCHGROUP.NAME##'
    ##
    
    if ($applicationName -eq $null) {
      #Request Info
      $httpVerb = 'PATCH'
      $resourcePath = "/device/devices/$($deviceID)"
      $queryParams = '?patchFields=name'
      $data = "{`"name`":`"$($applicationName)`"}"
      $results = Send-Request $resourcePath $httpVerb $queryParams $data
      Write-Host "application.debug=Send-Request $($resourcePath) $($httpVerb) $($queryParams) $($data)"
      Write-Host "application.result=Added Application $($applicationName) to Device $($currentDisplayName): $($results)"
      
    } else {
      if ($oldResult -like "No change to Application*"){
          Write-Host "application.result=$($oldResult)"
      } else {
          Write-Host "application.result=No change to Application. $($oldResult)"
      }
      Write-Host "application.name=$($oldapplication)"
    }

    But it is always going to "No change to application" even the property does not exist...

    Any idea?

    Thanks,

    Dom

  • Hello,

    I am testing for the application name like this:

    if ($applicationName -eq $null)

    Is it correct?

    Apparently it is always going to the line:

    else {
          Write-Host "application.result=No change to Application. $($oldResult)"

    So not sure the test is correct.?

    Any idea?

    Thanks,

    Dominique

     

  • Hello,

    with the current script:

    #########################      API Function Script      ###F######################
    #------------------------------------------------------------------------------------------------------------
    # Prerequisites:
    #
    # Requires -Version 3
    #------------------------------------------------------------------------------------------------------------
    # Initialize Variables
    <# account info #>
    $accessId = '##IP2DNS.ACCESSID##'
    $accessKey = '##IP2DNS.KEY##'
    $company = 'uclahealth'
    
    # Functionize the reusable code that builds and executes the query
    function Send-Request() {
        Param(
            [Parameter(position = 0, Mandatory = $true)]
            [string]$path,
            [Parameter(position = 1, Mandatory = $false)]
            [string]$httpVerb = 'GET',
            [Parameter(position = 2, Mandatory = $false)]
            [string]$queryParams,
            [Parameter(position = 3, Mandatory = $false)]
            [PSObject]$data
        )
        # Use TLS 1.2
        [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
        <# Construct URL #>
        $url = "https://$company.logicmonitor.com/santaba/rest$path$queryParams"
        <# 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 + $path
        <# 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')
        $headers.Add("X-version", '2')
        <# Make request & retry if failed due to rate limiting #>
        $Stoploop = $false
        do {
            try {
                <# Make Request #>
                $response = Invoke-RestMethod -Uri $url -Method $httpVerb -Body $data -Header $headers
                $Stoploop = $true
            } catch {
                switch ($_) {
                    { $_.Exception.Response.StatusCode.value__ -eq 429 } {
    #                    Write-Host "Request exceeded rate limit, retrying in 60 seconds..."
                        Start-Sleep -Seconds 60
                        $response = Invoke-RestMethod -Uri $url -Method $httpVerb -Body $data -Header $headers
                    }
                    { $_.Exception.Response.StatusCode.value__ } {
    #                    Write-Host "Request failed, not as a result of rate limiting"
                        # Dig into the exception to get the Response details.
                        # Note that value__ is not a typo.
    #                    Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
    #                    Write-Host "StatusDescription:" $_.Exception.Response.StatusCode
    #                    $_.ErrorDetails.Message -match '{"errorMessage":"([\d\S\s]+)","errorCode":(\d+),'
    #                    Write-Host "LM ErrorMessage" $matches[1]
    #                    Write-Host "LM ErrorCode" $matches[2]
                        $response = $null
                        $Stoploop = $true
                    }
                    default {
    #                    Write-Host "An Unknown Exception occurred:"
    #                    Write-Host $_ | Format-List -Force
                    $response = $null
                    $Stoploop = $true
                }
            }
        }
    } While ($Stoploop -eq $false)
    Return $response
    }
    ##
    #------------------------------------------------------------------------------------------------------------
    #  Starting Script 
    #------------------------------------------------------------------------------------------------------------
    ##
    $deviceID = '##SYSTEM.DEVICEID##'
    $currentName = '##SYSTEM.HOSTNAME##'
    $currentDisplayName = '##SYSTEM.DISPLAYNAME##'
    $oldResult = '##AUTO.APPLICATION.RESULT##'
    $oldApplication = '##AUTO.APPLICATION.NAME##'
    ##
    $applicationName = '##AUTO.APPLICATION.NAME##'
    $ownerName = '##AUTO.OWNER.NAME##'
    $technicalgroup = '##AUTO.TECHNICALGROUP.NAME##'
    $patchgroup = '##AUTO.PATCHGROUP.NAME##'
    ##
    
    if ($applicationName -eq '') {
      #Request Info
      $httpVerb = 'PATCH'
      $resourcePath = "/device/devices/$($deviceID)"
      $queryParams = '?patchFields=name'
      $data = "{`"name`":`"$($applicationName)`"}"
      $results = Send-Request $resourcePath $httpVerb $queryParams $data
      Write-Host "application.debug=Send-Request $($resourcePath) $($httpVerb) $($queryParams) $($data)"
      Write-Host "application.result=Added Application $($applicationName) to Device $($currentDisplayName): $($results)"
      
    } else { 
      if ($oldResult -like "No change to Application*"){
          Write-Host "application.result=$($oldResult)"
      } else {
          Write-Host "application.result=No change to Application. $($oldResult)"
      }
      Write-Host "application.name=$($oldapplication)"
    }

    I am getting some display:

    Nothing on the device... What could be wrong?

    Thanks,

    Dominique

  • Anonymous's avatar
    Anonymous

    You should avoid using spaces in property names. I'd have to do some testing, but i think they'd need to be escaped, but the escape character isn't accepted by our syntax checker.

     

     

  • On 8/24/2020 at 7:33 AM, Stuart Weenig said:

    You should avoid using spaces in property names. I'd have to do some testing, but i think they'd need to be escaped, but the escape character isn't accepted by our syntax checker.

     

     

    Hello Stuart,

    What will be the best way to update/clean the existing Properties having a space in their name?

    PropertySource with a script? 
    some other way(s) to do it?

    Thanks,

    Dominique

  • Anonymous's avatar
    Anonymous

    If they were created with a PropertySource, if the PS were to run again and not set/update the property, the property gets deleted.  So, just change your script to output properties without spaces. When it runs, the properties with spaces would not be set by the PS and would get deleted. New properties without spaces would get created.

  • The current properties with the space were input manually.

    this means the proposal for a PropertySource is completely new

  • Anonymous's avatar
    Anonymous

    Ah, then your only option is to rename them manually or through the API. If you do just rename them, then they will not be prepended with "auto." meaning that any propertysource you build will not affect them. If you want a PropertySource to manage them going forward, I would suggest you get the propertysource working then use the API to delete the manually created ones.