Logic.Monitor.psm1

Function Connect-LMAccount {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory)]
        [String]$AccessId,

        [Parameter(Mandatory)]
        [String]$AccessKey,

        [Parameter(Mandatory)]
        [String]$AccountName
    )
    
    #Convert to secure string
    [SecureString]$AccessKey = $AccessKey | ConvertTo-SecureString -AsPlainText -Force

    #Create Credential Object for reuse in other functions
    $global:LMAuth = [PSCustomObject]@{
        Id      = $AccessId
        Key     = $AccessKey
        Portal  = $AccountName
        Valid   = $false
    }

    Try {
        #Build header and uri
        $ResourcePath = "/setting/companySetting"
        $Headers = New-LMHeader -Auth $global:LMAuth -Method "GET" -ResourcePath $ResourcePath
        $Uri = "https://$($global:LMAuth.Portal).logicmonitor.com/santaba/rest" + $ResourcePath

        #Issue request
        $Request = Invoke-WebRequest -Uri $Uri -Method "GET" -Headers $Headers
        $Response = $Request.Content | ConvertFrom-Json
        Write-Host "Connected to LM portal $($Response.companyDisplayName) using account $($Response.name) - ($($Response.numberOfDevices) devices)." -ForegroundColor Green
        
        #Set valid flag so we dont prompt for auth details on future requests
        $global:LMAuth.Valid = $true
    }
    Catch {
        Write-Error "Unable to login to account, please ensure your access info and account name are correct: $($_.Exception.Message)"
        #Clear credential object from environment
        Remove-Variable LMAuth -Scope Global
    }
}

Function Disconnect-LMAccount {
    
    #Clear credential object from environment
    Remove-Variable LMAuth -Scope Global
    Write-Host "Successfully cleared login credentials for LM account." -ForegroundColor Green
}

Function New-LMHeader {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory)]
        $Auth,

        [Parameter(Mandatory)]
        [String]$Method,

        [Parameter(Mandatory)]
        [String]$ResourcePath,

        [Hashtable]$Data
    )

    # 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 general request details...
    If($Method -eq "GET" -or $Method -eq "DELETE"){
        $RequestVars = $Method + $Epoch + $ResourcePath
    }
    Else{
        $RequestVars = $Method + $Epoch + $Data + $ResourcePath
    }

    # Construct signature...
    $Hmac = New-Object System.Security.Cryptography.HMACSHA256
    $Hmac.Key = [Text.Encoding]::UTF8.GetBytes($($Auth.Key | ConvertFrom-SecureString -AsPlainText))

    $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...
    $LMAuth = 'LMv1 ' + $Auth.Id + ':' + $Signature + ':' + $Epoch
    $Header = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $Header.Add("Authorization",$LMAuth)
    $Header.Add("Content-Type",'application/json')
    $Header.Add("X-Version",3)

    Return $Header
}

Function Get-LMDevice {
    [CmdletBinding(DefaultParameterSetName = 'All')]
    Param (
        [Parameter(Mandatory, ParameterSetName = 'Id')]
        [Alias("DeviceId")]
        [Int]$Id,

        [Parameter(Mandatory, ParameterSetName = 'DisplayName')]
        [Alias("DeviceDisplayName")]
        [String]$DisplayName,

        [Parameter(Mandatory, ParameterSetName = 'Name')]
        [Alias("DeviceName")]
        [String]$Name,

        [Parameter(Mandatory, ParameterSetName = 'Filter')]
        [String]$Filter,

        [Int]$BatchSize = 1000
    )
    #Check if we are logged in and have valid api creds
    If($global:LMAuth.Valid){
        
        #Build header and uri
        $ResourcePath = "/device/devices"

        #Initalize vars
        $QueryParams = ""
        $Count = 0
        $Done = $false
        $Results = @()

        #Loop through requests
        While(!$Done){
            #Build query params
            Switch($PSCmdlet.ParameterSetName){
                "All" {$QueryParams = "?size=$BatchSize&offset=$Count&sort=+id"}
                "Id" {$resourcePath += "/$Id"}
                "DisplayName" {$QueryParams = "?filter=displayName:`"$DisplayName`"&size=$BatchSize&offset=$Count&sort=+id"}
                "Name" {$QueryParams = "?filter=name:`"$Name`"&size=$BatchSize&offset=$Count&sort=+id"}
                "Filter" {$QueryParams = "?$Filter&size=$BatchSize&offset=$Count&sort=+id"}
            }
            Try{
                $Headers = New-LMHeader -Auth $global:LMAuth -Method "GET" -ResourcePath $ResourcePath
                $Uri = "https://$($global:LMAuth.Portal).logicmonitor.com/santaba/rest" + $ResourcePath + $QueryParams
    
                #Issue request
                $Request = Invoke-WebRequest -Uri $Uri -Method "GET" -Headers $Headers
                $Response = $Request.Content | ConvertFrom-Json

                #Stop looping if single device, no need to continue
                If($PSCmdlet.ParameterSetName -eq "Id"){
                    $Done = $true
                    Return $Response
                }
                #Check result size and if needed loop again
                Else{
                    [Int]$Total = $Response.Total
                    [Int]$Count += ($Response.Items | Measure-Object).Count
                    $Results += $Response.Items
                    If($Count -ge $Total){
                        $Done = $true
                    }
                }
            }
            Catch{
                $LMError = $_.ErrorDetails | ConvertFrom-Json
                Write-Error "Failed to execute query: $($LMError.errorMessage) - $($LMError.errorCode)"
                $Done = $true
            }
        }
        Return $Results
    }
    Else{
        Write-Host "Please ensure you are logged in before running any comands, use Connect-LMAccount to login and try again." -ForegroundColor Yellow
    }
}

Function Get-LMWebsite {
    [CmdletBinding(DefaultParameterSetName = 'All')]
    Param (
        [Parameter(Mandatory, ParameterSetName = 'Id')]
        [Alias("WebsiteId")]
        [Int]$Id,

        [Parameter(Mandatory, ParameterSetName = 'Name')]
        [Alias("WebsiteName")]
        [String]$Name,

        [Parameter(Mandatory, ParameterSetName = 'Type')]
        [ValidateSet("Webcheck", "PingCheck")]
        [String]$Type,

        [Parameter(Mandatory, ParameterSetName = 'Filter')]
        [String]$Filter,

        [Int]$BatchSize = 1000
    )
    #Check if we are logged in and have valid api creds
    If($global:LMAuth.Valid){
        
        #Build header and uri
        $ResourcePath = "/website/websites"

        #Initalize vars
        $QueryParams = ""
        $Count = 0
        $Done = $false
        $Results = @()

        #Loop through requests
        While(!$Done){
            #Build query params
            Switch($PSCmdlet.ParameterSetName){
                "All" {$QueryParams = "?size=$BatchSize&offset=$Count&sort=+id"}
                "Id" {$resourcePath += "/$Id"}
                "Type" {$QueryParams = "?filter=type:`"$Type`"&size=$BatchSize&offset=$Count&sort=+id"}
                "Name" {$QueryParams = "?filter=name:`"$Name`"&size=$BatchSize&offset=$Count&sort=+id"}
                "Filter" {$QueryParams = "?$Filter&size=$BatchSize&offset=$Count&sort=+id"}
            }
            Try{
                $Headers = New-LMHeader -Auth $global:LMAuth -Method "GET" -ResourcePath $ResourcePath
                $Uri = "https://$($global:LMAuth.Portal).logicmonitor.com/santaba/rest" + $ResourcePath + $QueryParams
    
                #Issue request
                $Request = Invoke-WebRequest -Uri $Uri -Method "GET" -Headers $Headers
                $Response = $Request.Content | ConvertFrom-Json

                #Stop looping if single device, no need to continue
                If($PSCmdlet.ParameterSetName -eq "Id"){
                    $Done = $true
                    Return $Response
                }
                #Check result size and if needed loop again
                Else{
                    [Int]$Total = $Response.Total
                    [Int]$Count += ($Response.Items | Measure-Object).Count
                    $Results += $Response.Items
                    If($Count -ge $Total){
                        $Done = $true
                    }
                }
            }
            Catch{
                $LMError = $_.ErrorDetails | ConvertFrom-Json
                Write-Error "Failed to execute query: $($LMError.errorMessage) - $($LMError.errorCode)"
                $Done = $true
            }
        }
        Return $Results
    }
    Else{
        Write-Host "Please ensure you are logged in before running any comands, use Connect-LMAccount to login and try again." -ForegroundColor Yellow
    }
}

Function Get-LMAlert {
    [CmdletBinding(DefaultParameterSetName = 'All')]
    Param (
        [Parameter(ParameterSetName = 'Range')]
        [Datetime]$StartDate,

        [Parameter(ParameterSetName = 'Range')]
        [Datetime]$EndDate,

        [Parameter(ParameterSetName = 'Id')]
        [String]$Id,

        [ValidateSet("*", "Warning","Error","Critical")]
        [String]$Severity="*",

        [ValidateSet("*", "WebsiteAlert","DataSourceAlert","EventSourceAlert")]
        [String]$Type="*",

        [Parameter(Mandatory, ParameterSetName = 'Filter')]
        [String]$Filter,

        [Int]$BatchSize = 1000
    )
    #Check if we are logged in and have valid api creds
    If($global:LMAuth.Valid){
        
        #Build header and uri
        $ResourcePath = "/alert/alerts"

        #Initalize vars
        $QueryParams = ""
        $Count = 0
        $Done = $false
        $Results = @()

        #Convert to epoch, if not set use defaults
        If(!$StartDate){
            [int]$StartDate = 0
        }
        Else{
            [int]$StartDate = ([DateTimeOffset]$($StartDate)).ToUnixTimeSeconds()
        }

        If(!$EndDate){
            [int]$EndDate = ([DateTimeOffset]$(Get-Date)).ToUnixTimeSeconds()
        }
        Else{
            [int]$EndDate = ([DateTimeOffset]$($EndDate)).ToUnixTimeSeconds()
        }

        #Loop through requests
        While(!$Done){
            #Build query params

            Switch($PSCmdlet.ParameterSetName){
                "Id" {$resourcePath += "/$Id"}
                "Range" {$QueryParams = "?filter=startEpoch%3E%3A`"$StartDate`"%2CstartEpoch%3C%3A`"$EndDate`",rule:`"$Severity`",type:`"$Type`"&size=$BatchSize&offset=$Count&sort=+resourceId"}
                "Filter" {$QueryParams = "?$Filter&size=$BatchSize&offset=$Count&sort=+resourceId"}
                "All" {$QueryParams = "?filter=rule:`"$Severity`",type:`"$Type`"&size=$BatchSize&offset=$Count&sort=+resourceId"}
            }
            Try{
                $Headers = New-LMHeader -Auth $global:LMAuth -Method "GET" -ResourcePath $ResourcePath
                $Uri = "https://$($global:LMAuth.Portal).logicmonitor.com/santaba/rest" + $ResourcePath + $QueryParams
    
                #Issue request
                $Request = Invoke-WebRequest -Uri $Uri -Method "GET" -Headers $Headers
                $Response = $Request.Content | ConvertFrom-Json

                #Stop looping if single device, no need to continue
                If($PSCmdlet.ParameterSetName -eq "Id"){
                    $Done = $true
                    Return $Response
                }
                #Check result size and if needed loop again
                Else{
                    [Int]$Total = $Response.Total
                    [Int]$Count += ($Response.Items | Measure-Object).Count
                    
                    $Results += $Response.Items
                    If($Count -ge $Total){
                        $Done = $true
                    }
                }
            }
            Catch{
                $LMError = $_.ErrorDetails | ConvertFrom-Json
                Write-Error "Failed to execute query: $($LMError.errorMessage) - $($LMError.errorCode)"
                $Done = $true
            }
        }
        Return $Results
    }
    Else{
        Write-Host "Please ensure you are logged in before running any comands, use Connect-LMAccount to login and try again." -ForegroundColor Yellow
    }
}

Function Get-LMAlertRule {
    [CmdletBinding(DefaultParameterSetName = 'All')]
    Param (
        [Parameter(Mandatory, ParameterSetName = 'Id')]
        [Alias("RuleId")]
        [Int]$Id,

        [Parameter(Mandatory, ParameterSetName = 'Name')]
        [Alias("RuleName")]
        [String]$Name,

        [Parameter(Mandatory, ParameterSetName = 'Filter')]
        [String]$Filter,

        [Int]$BatchSize = 1000
    )
    #Check if we are logged in and have valid api creds
    If($global:LMAuth.Valid){
        
        #Build header and uri
        $ResourcePath = "/setting/alert/rules"

        #Initalize vars
        $QueryParams = ""
        $Count = 0
        $Done = $false
        $Results = @()

        #Loop through requests
        While(!$Done){
            #Build query params
            Switch($PSCmdlet.ParameterSetName){
                "All" {$QueryParams = "?size=$BatchSize&offset=$Count&sort=+id"}
                "Id" {$resourcePath += "/$Id"}
                "Name" {$QueryParams = "?filter=name:`"$Name`"&size=$BatchSize&offset=$Count&sort=+id"}
                "Filter" {$QueryParams = "?$Filter&size=$BatchSize&offset=$Count&sort=+id"}
            }
            Try{
                $Headers = New-LMHeader -Auth $global:LMAuth -Method "GET" -ResourcePath $ResourcePath
                $Uri = "https://$($global:LMAuth.Portal).logicmonitor.com/santaba/rest" + $ResourcePath + $QueryParams
    
                #Issue request
                $Request = Invoke-WebRequest -Uri $Uri -Method "GET" -Headers $Headers
                $Response = $Request.Content | ConvertFrom-Json

                #Stop looping if single device, no need to continue
                If($PSCmdlet.ParameterSetName -eq "Id"){
                    $Done = $true
                    Return $Response
                }
                #Check result size and if needed loop again
                Else{
                    [Int]$Total = $Response.Total
                    [Int]$Count += ($Response.Items | Measure-Object).Count
                    $Results += $Response.Items
                    If($Count -ge $Total){
                        $Done = $true
                    }
                }
            }
            Catch{
                $LMError = $_.ErrorDetails | ConvertFrom-Json
                Write-Error "Failed to execute query: $($LMError.errorMessage) - $($LMError.errorCode)"
                $Done = $true
            }
        }
        Return $Results
    }
    Else{
        Write-Host "Please ensure you are logged in before running any comands, use Connect-LMAccount to login and try again." -ForegroundColor Yellow
    }
}

Function Get-LMAPIToken {
    [CmdletBinding(DefaultParameterSetName = 'All')]
    Param (
        [Parameter(Mandatory, ParameterSetName = 'AdminId')]
        [Alias("UserId")]
        [Int]$AdminId,

        [Parameter(Mandatory, ParameterSetName = 'Filter')]
        [String]$Filter,

        [Int]$BatchSize = 1000
    )
    #Check if we are logged in and have valid api creds
    If($global:LMAuth.Valid){
        
        #Build header and uri
        $ResourcePath = "/setting/admins/apitokens"

        #Initalize vars
        $QueryParams = ""
        $Count = 0
        $Done = $false
        $Results = @()

        #Loop through requests
        While(!$Done){
            #Build query params
            Switch($PSCmdlet.ParameterSetName){
                "All" {$QueryParams = "?size=$BatchSize&offset=$Count&sort=+id"}
                "AdminId" {$resourcePath = "/setting/admins/$AdminId/apitokens"}
                "Filter" {$QueryParams = "?$Filter&size=$BatchSize&offset=$Count&sort=+id"}
            }
            Try{
                $Headers = New-LMHeader -Auth $global:LMAuth -Method "GET" -ResourcePath $ResourcePath
                $Uri = "https://$($global:LMAuth.Portal).logicmonitor.com/santaba/rest" + $ResourcePath + $QueryParams
    
                #Issue request
                $Request = Invoke-WebRequest -Uri $Uri -Method "GET" -Headers $Headers
                $Response = $Request.Content | ConvertFrom-Json

                #Stop looping if single device, no need to continue
                If($PSCmdlet.ParameterSetName -eq "Id"){
                    $Done = $true
                    Return $Response
                }
                #Check result size and if needed loop again
                Else{
                    [Int]$Total = $Response.Total
                    [Int]$Count += ($Response.Items | Measure-Object).Count
                    $Results += $Response.Items
                    If($Count -ge $Total){
                        $Done = $true
                    }
                }
            }
            Catch{
                $LMError = $_.ErrorDetails | ConvertFrom-Json
                Write-Error "Failed to execute query: $($LMError.errorMessage) - $($LMError.errorCode)"
                $Done = $true
            }
        }
        Return $Results
    }
    Else{
        Write-Host "Please ensure you are logged in before running any comands, use Connect-LMAccount to login and try again." -ForegroundColor Yellow
    }
}

Function Get-LMAppliesToFunction {
    [CmdletBinding(DefaultParameterSetName = 'All')]
    Param (
        [Parameter(Mandatory, ParameterSetName = 'Id')]
        [Alias("FunctionId")]
        [Int]$Id,

        [Parameter(Mandatory, ParameterSetName = 'Name')]
        [Alias("FunctionName")]
        [String]$Name,

        [Parameter(Mandatory, ParameterSetName = 'Filter')]
        [String]$Filter,

        [Int]$BatchSize = 1000
    )
    #Check if we are logged in and have valid api creds
    If($global:LMAuth.Valid){
        
        #Build header and uri
        $ResourcePath = "/setting/functions"

        #Initalize vars
        $QueryParams = ""
        $Count = 0
        $Done = $false
        $Results = @()

        #Loop through requests
        While(!$Done){
            #Build query params
            Switch($PSCmdlet.ParameterSetName){
                "All" {$QueryParams = "?size=$BatchSize&offset=$Count&sort=+id"}
                "Id" {$resourcePath += "/$Id"}
                "Name" {$QueryParams = "?filter=name:`"$Name`"&size=$BatchSize&offset=$Count&sort=+id"}
                "Filter" {$QueryParams = "?$Filter&size=$BatchSize&offset=$Count&sort=+id"}
            }
            Try{
                $Headers = New-LMHeader -Auth $global:LMAuth -Method "GET" -ResourcePath $ResourcePath
                $Uri = "https://$($global:LMAuth.Portal).logicmonitor.com/santaba/rest" + $ResourcePath + $QueryParams
    
                #Issue request
                $Request = Invoke-WebRequest -Uri $Uri -Method "GET" -Headers $Headers
                $Response = $Request.Content | ConvertFrom-Json

                #Stop looping if single device, no need to continue
                If($PSCmdlet.ParameterSetName -eq "Id"){
                    $Done = $true
                    Return $Response
                }
                #Check result size and if needed loop again
                Else{
                    [Int]$Total = $Response.Total
                    [Int]$Count += ($Response.Items | Measure-Object).Count
                    $Results += $Response.Items
                    If($Count -ge $Total){
                        $Done = $true
                    }
                }
            }
            Catch{
                $LMError = $_.ErrorDetails | ConvertFrom-Json
                Write-Error "Failed to execute query: $($LMError.errorMessage) - $($LMError.errorCode)"
                $Done = $true
            }
        }
        Return $Results
    }
    Else{
        Write-Host "Please ensure you are logged in before running any comands, use Connect-LMAccount to login and try again." -ForegroundColor Yellow
    }
}

Function Get-LMAuditLogs {
    [CmdletBinding(DefaultParameterSetName = 'All')]
    Param (
        [Parameter(Mandatory, ParameterSetName = 'Id')]
        [Alias("AuditId")]
        [String]$Id,

        [Parameter(ParameterSetName = 'Range')]
        [Datetime]$StartDate,

        [Parameter(ParameterSetName = 'Range')]
        [Datetime]$EndDate,

        [Parameter(Mandatory, ParameterSetName = 'Filter')]
        [String]$Filter,

        [Int]$BatchSize = 1000
    )
    #Check if we are logged in and have valid api creds
    If($global:LMAuth.Valid){
        
        #Build header and uri
        $ResourcePath = "/setting/accesslogs"

        #Initalize vars
        $QueryParams = ""
        $Count = 0
        $Done = $false
        $Results = @()

        #Convert to epoch, if not set use defaults
        If(!$StartDate){
            [int]$StartDate = 0
        }
        Else{
            [int]$StartDate = ([DateTimeOffset]$($StartDate)).ToUnixTimeSeconds()
        }

        If(!$EndDate){
            [int]$EndDate = ([DateTimeOffset]$(Get-Date)).ToUnixTimeSeconds()
        }
        Else{
            [int]$EndDate = ([DateTimeOffset]$($EndDate)).ToUnixTimeSeconds()
        }

        #Loop through requests
        While(!$Done){
            #Build query params
            Switch($PSCmdlet.ParameterSetName){
                "All" {$QueryParams = "?filter=happenedOn%3E%3A`"$StartDate`"%2ChappenedOn%3C%3A`"$EndDate`",size=$BatchSize&offset=$Count&sort=+happenedOn"}
                "Id" {$resourcePath += "/$Id"}
                "Filter" {$QueryParams = "?$Filter&size=$BatchSize&offset=$Count&sort=+happenedOn"}
            }
            Try{
                $Headers = New-LMHeader -Auth $global:LMAuth -Method "GET" -ResourcePath $ResourcePath
                $Uri = "https://$($global:LMAuth.Portal).logicmonitor.com/santaba/rest" + $ResourcePath + $QueryParams
    
                #Issue request
                $Request = Invoke-WebRequest -Uri $Uri -Method "GET" -Headers $Headers
                $Response = $Request.Content | ConvertFrom-Json

                #Stop looping if single device, no need to continue
                If($PSCmdlet.ParameterSetName -eq "Id"){
                    $Done = $true
                    Return $Response
                }
                #Check result size and if needed loop again
                Else{
                    [Int]$Total = $Response.Total
                    [Int]$Count += ($Response.Items | Measure-Object).Count
                    $Results += $Response.Items
                    If($Count -ge $Total){
                        $Done = $true
                    }
                }
            }
            Catch{
                $LMError = $_.ErrorDetails | ConvertFrom-Json
                Write-Error "Failed to execute query: $($LMError.errorMessage) - $($LMError.errorCode)"
                $Done = $true
            }
        }
        Return $Results
    }
    Else{
        Write-Host "Please ensure you are logged in before running any comands, use Connect-LMAccount to login and try again." -ForegroundColor Yellow
    }
}

Function Get-LMCollectorGroup {
    [CmdletBinding(DefaultParameterSetName = 'All')]
    Param (
        [Parameter(Mandatory, ParameterSetName = 'Id')]
        [Alias("CollectorId")]
        [Int]$Id,

        [Parameter(Mandatory, ParameterSetName = 'Name')]
        [Alias("CollectorName")]
        [String]$Name,

        [Parameter(Mandatory, ParameterSetName = 'Filter')]
        [String]$Filter,

        [Int]$BatchSize = 1000
    )
    #Check if we are logged in and have valid api creds
    If($global:LMAuth.Valid){
        
        #Build header and uri
        $ResourcePath = "/setting/collector/groups"

        #Initalize vars
        $QueryParams = ""
        $Count = 0
        $Done = $false
        $Results = @()

        #Loop through requests
        While(!$Done){
            #Build query params
            Switch($PSCmdlet.ParameterSetName){
                "All" {$QueryParams = "?size=$BatchSize&offset=$Count&sort=+id"}
                "Id" {$resourcePath += "/$Id"}
                "Name" {$QueryParams = "?filter=name:`"$Name`"&size=$BatchSize&offset=$Count&sort=+id"}
                "Filter" {$QueryParams = "?$Filter&size=$BatchSize&offset=$Count&sort=+id"}
            }
            Try{
                $Headers = New-LMHeader -Auth $global:LMAuth -Method "GET" -ResourcePath $ResourcePath
                $Uri = "https://$($global:LMAuth.Portal).logicmonitor.com/santaba/rest" + $ResourcePath + $QueryParams
    
                #Issue request
                $Request = Invoke-WebRequest -Uri $Uri -Method "GET" -Headers $Headers
                $Response = $Request.Content | ConvertFrom-Json

                #Stop looping if single device, no need to continue
                If($PSCmdlet.ParameterSetName -eq "Id"){
                    $Done = $true
                    Return $Response
                }
                #Check result size and if needed loop again
                Else{
                    [Int]$Total = $Response.Total
                    [Int]$Count += ($Response.Items | Measure-Object).Count
                    $Results += $Response.Items
                    If($Count -ge $Total){
                        $Done = $true
                    }
                }
            }
            Catch{
                $LMError = $_.ErrorDetails | ConvertFrom-Json
                Write-Error "Failed to execute query: $($LMError.errorMessage) - $($LMError.errorCode)"
                $Done = $true
            }
        }
        Return $Results
    }
    Else{
        Write-Host "Please ensure you are logged in before running any comands, use Connect-LMAccount to login and try again." -ForegroundColor Yellow
    }
}

Function Get-LMCollector {
    [CmdletBinding(DefaultParameterSetName = 'All')]
    Param (
        [Parameter(Mandatory, ParameterSetName = 'Id')]
        [Alias("CollectorId")]
        [Int]$Id,

        [Parameter(Mandatory, ParameterSetName = 'Name')]
        [Alias("CollectorName")]
        [String]$Name,

        [Parameter(Mandatory, ParameterSetName = 'Filter')]
        [String]$Filter,

        [Int]$BatchSize = 1000
    )
    #Check if we are logged in and have valid api creds
    If($global:LMAuth.Valid){
        
        #Build header and uri
        $ResourcePath = "/setting/collector/collectors"

        #Initalize vars
        $QueryParams = ""
        $Count = 0
        $Done = $false
        $Results = @()

        #Loop through requests
        While(!$Done){
            #Build query params
            Switch($PSCmdlet.ParameterSetName){
                "All" {$QueryParams = "?size=$BatchSize&offset=$Count&sort=+id"}
                "Id" {$resourcePath += "/$Id"}
                "Name" {$QueryParams = "?filter=hostname:`"$Name`"&size=$BatchSize&offset=$Count&sort=+id"}
                "Filter" {$QueryParams = "?$Filter&size=$BatchSize&offset=$Count&sort=+id"}
            }
            Try{
                $Headers = New-LMHeader -Auth $global:LMAuth -Method "GET" -ResourcePath $ResourcePath
                $Uri = "https://$($global:LMAuth.Portal).logicmonitor.com/santaba/rest" + $ResourcePath + $QueryParams
    
                #Issue request
                $Request = Invoke-WebRequest -Uri $Uri -Method "GET" -Headers $Headers
                $Response = $Request.Content | ConvertFrom-Json

                #Stop looping if single device, no need to continue
                If($PSCmdlet.ParameterSetName -eq "Id"){
                    $Done = $true
                    Return $Response
                }
                #Check result size and if needed loop again
                Else{
                    [Int]$Total = $Response.Total
                    [Int]$Count += ($Response.Items | Measure-Object).Count
                    $Results += $Response.Items
                    If($Count -ge $Total){
                        $Done = $true
                    }
                }
            }
            Catch{
                $LMError = $_.ErrorDetails | ConvertFrom-Json
                Write-Error "Failed to execute query: $($LMError.errorMessage) - $($LMError.errorCode)"
                $Done = $true
            }
        }
        Return $Results
    }
    Else{
        Write-Host "Please ensure you are logged in before running any comands, use Connect-LMAccount to login and try again." -ForegroundColor Yellow
    }
}

Function Get-LMCollectorVersions {
    [CmdletBinding(DefaultParameterSetName = 'All')]
    Param (
        [Parameter(Mandatory, ParameterSetName = 'Filter')]
        [String]$Filter,

        [Int]$BatchSize = 1000
    )
    #Check if we are logged in and have valid api creds
    If($global:LMAuth.Valid){
        
        #Build header and uri
        $ResourcePath = "/setting/collector/collectors/versions"

        #Initalize vars
        $QueryParams = ""
        $Count = 0
        $Done = $false
        $Results = @()

        #Loop through requests
        While(!$Done){
            #Build query params
            Switch($PSCmdlet.ParameterSetName){
                "All" {$QueryParams = "?size=$BatchSize&offset=$Count&sort=+id"}
                "Filter" {$QueryParams = "?$Filter&size=$BatchSize&offset=$Count"}
            }
            Try{
                $Headers = New-LMHeader -Auth $global:LMAuth -Method "GET" -ResourcePath $ResourcePath
                $Uri = "https://$($global:LMAuth.Portal).logicmonitor.com/santaba/rest" + $ResourcePath + $QueryParams
    
                #Issue request
                $Request = Invoke-WebRequest -Uri $Uri -Method "GET" -Headers $Headers
                $Response = $Request.Content | ConvertFrom-Json

                #Stop looping if single device, no need to continue
                If($PSCmdlet.ParameterSetName -eq "Id"){
                    $Done = $true
                    Return $Response
                }
                #Check result size and if needed loop again
                Else{
                    [Int]$Total = $Response.Total
                    [Int]$Count += ($Response.Items | Measure-Object).Count
                    $Results += $Response.Items
                    If($Count -ge $Total){
                        $Done = $true
                    }
                }
            }
            Catch{
                $LMError = $_.ErrorDetails | ConvertFrom-Json
                Write-Error "Failed to execute query: $($LMError.errorMessage) - $($LMError.errorCode)"
                $Done = $true
            }
        }
        Return $Results
    }
    Else{
        Write-Host "Please ensure you are logged in before running any comands, use Connect-LMAccount to login and try again." -ForegroundColor Yellow
    }
}

Function Get-LMCollectorInstaller {
    [CmdletBinding(DefaultParameterSetName = 'Id')]
    Param (

        [Parameter(Mandatory, ParameterSetName = "Id")]
        [Alias("CollectorID")]
        [int]$Id,

        [Parameter(Mandatory, ParameterSetName = "Name")]
        [Alias("CollectorHostName")]
        [string]$Name,

        [ValidateSet("nano", "small", "medium", "large")]
        [string]$Size = "medium",

        [ValidateSet("Win32", "Win64", "Linux32", "Linux64")]
        [string]$OSandArch = "Win64",

        [boolean]$UseEA = $false,

        [string]$DownloadPath = $PSScriptRoot
    )
    #Check if we are logged in and have valid api creds
    If($global:LMAuth.Valid){

        If($Name){
            $Id = (Get-LMCollector -Name $Name | Select-Object -First 1 ).Id
            If(!$Id){
                Write-Host "Unable to find collector host with name: $Name, please check spelling and try again." -ForegroundColor Yellow
                return
            }
        }
        
        #Build header and uri
        $ResourcePath = "/setting/collector/collectors/$Id/installers/$OSandArch"
        $QueryParams = "?useEA=$UseEA&collectorSize=$Size"

        If($OSandArch -like "Linux*"){
            $DownloadPath += "\LogicMonitor_Collector_$OSandArch($Size).bin"
        }
        Else{
            $DownloadPath += "\LogicMonitor_Collector_$OSandArch($Size).exe"
        }

        Try{
            $Headers = New-LMHeader -Auth $global:LMAuth -Method "GET" -ResourcePath $ResourcePath
            $Uri = "https://$($global:LMAuth.Portal).logicmonitor.com/santaba/rest" + $ResourcePath + $QueryParams

            #Issue request
            Invoke-WebRequest -Uri $Uri -Method "GET" -Headers $Headers -OutFile $DownloadPath
            
            Return $DownloadPath

        }
        Catch{
            Write-Error "Failed to execute query: $($_.ErrorDetails)"
        }
    }
    Else{
        Write-Host "Please ensure you are logged in before running any comands, use Connect-LMAccount to login and try again." -ForegroundColor Yellow
    }
}