Public/Get-RemedyProblem.ps1

Function Get-RemedyProblem {
<#
.SYNOPSIS
    Retrieves BMC Remedy Problem details via the API by ID number or other specified criteria such as Assignee, Customer, Team.
 
.DESCRIPTION
    This cmdlet queries the Remedy API for Problems as specified by ID number or by combining one or more of the filter parameters.
    Beware that the Remedy API will return a maximum of 5000 incidents in a single request. If you need to exceed this, make multiple
    requests (e.g by separating by date range) and then combine the results.
 
.EXAMPLE
    Get-RemedyProblem -ID 1234567
 
    Returns the specified Problem.
 
.EXAMPLE
    Get-RemedyProblem -Status Open -Team Windows
 
    Returns all open Problems for the specified team.
 
.EXAMPLE
    Get-RemedyProblem -Status Open -Customer 'Contoso'
 
    Returns all open Problems for the specified customer.
 
.EXAMPLE
    Get-RemedyProblem -Status Open -Team Windows -Customer 'Fabrikam'
 
    Returns all open problems for the specified customer assigned to the specfied team.
 
.EXAMPLE
    Get-RemedyProblem -Team Windows -After 01/15/2017 -Before 02/15/2017
 
    Returns all problems for the specified team between the specified dates.
#>

    [cmdletbinding()]
    Param(
        # One or more Problem ID numbers.
        [Parameter(Position=0,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [String[]]$ID = '',
        
        # Problems assigned to the specified team.
        [String]$Team,
        
        # Problems raised by the specified customer.
        [String]$Customer,
        
        # Problems raised for a specific configuration item, e.g a server or other device.
        [Alias('CI')]
        [String]$ConfigurationItem,
        
        # Problems assigned to the specified individual.
        [String[]]$Assignee,

        # Problems submitted by the specified individual.
        [String[]]$Submitter,

        # Problems filtered by specified status. You can also specific 'AllOpen' or 'AllClosed': AllOpen = ('Draft','Under Review','Request For Authorization','Assigned','Under Investigation','Pending','Rejected'); AllClosed = ('Completed','Closed','Cancelled')
        [ValidateSet('AllOpen','AllClosed','Draft','Under Review','Request For Authorization','Assigned','Under Investigation','Pending','Rejected','Completed','Closed','Cancelled','')] 
        [String]$Status,
        
        # Include Problems of one or more specific types: Normal, Standard, Expedited.
        [ValidateSet('Incident','Change','Problem Investigation','Known Error','Knowledge','Task','CI Unavailability','Purchase Requisition','Release','Activity','')]
        [String[]]$Type,

        # Exclude Problems of one or more specific types: Normal, Standard, Expedited.
        [ValidateSet('Incident','Change','Problem Investigation','Known Error','Knowledge','Task','CI Unavailability','Purchase Requisition','Release','Activity','')]
        [String[]]$ExcludeType,

        # Include Problems of one or more specific priorities: Low, Medium, High, Critical.
        [ValidateSet('Low','Medium','High','Critical','')]
        [String[]]$Priority = '',
        
        # Problems with a 'submit date' that is after this date. Use US date format: mm/dd/yyyy
        [DateTime]$After,
        
        # Problems with a 'submit date' that is before this date. Use US date format: mm/dd/yyyy
        [DateTime]$Before,

        # Return all available data fields from Remedy.
        [Switch]$Full,

        # Match the string exactly.
        [Switch]$Exact,

        # An encoded string representing your Remedy Credentials as generated by the Set-RemedyApiConfig cmdlet.
        [String]$EncodedCredentials = (Get-RemedyApiConfig).Credentials,

        # The Remedy API URL. E.g: https://<localhost>:<port>/api
        [String]$APIURL = (Get-RemedyApiConfig).APIURL
    )
    
    If (-not $EncodedCredentials -or -not $APIURL) { Throw 'Remedy API Config not set. Set-RemedyApiConfig first.' }
    
    If (-not (Test-RemedyApiConfig)) { Throw 'Remedy API Test failed. Ensure the config has been set correctly via Set-RemedyApiConfig.' }

    Switch ($Status) {
        'AllOpen'   { $Filter = 'Draft','Under Review','Request For Authorization','Assigned','Under Investigation','Pending','Rejected' }
        'AllClosed' { $Filter = 'Completed','Closed','Cancelled' }
        Default     { $Filter = $Status }  
    }
    
    If ($Filter) { $StatusString = ($Filter | ForEach-Object { "('Investigation Status'=""$_"")" }) -join 'OR' }
    If ($Type)           { $TypeString = ($Type | ForEach-Object { "('TicketType'=""$_"")" }) -join 'OR' }
    If ($ExcludeType)    { $ExcludeTypeString = ($ExcludeType | ForEach-Object { "('TicketType'!=""$_"")" }) -join 'AND' }
    
    If ($Priority) { $PriorityString = ($Priority | ForEach-Object { "('Priority'=""$_"")" }) -join 'OR' }
     
    ForEach ($IDNum in $ID) {
        Write-Verbose "$IDNum"
        
        $Filter = @()
        
        If ($Exact) { $Op = '='; $Wc = '' } Else { $Op = 'LIKE'; $Wc = '%25' }
        If ($Exact -or $IDNum -match '^PBI\d{12}') { $IDOp = '='; $IDWc = '' } Else { $IDOp = 'LIKE'; $IDWc = '%25' }
        
        If ($IDNum)    { $Filter += "'Problem Investigation ID'$IDOp""$IDWc$IDNum""" }
        If ($Team)     { $Filter += "'Assigned Group'=""$Team""" }
        If ($Customer) { $Filter += "'Company'$Op""$Wc$Customer$Wc""" }
        If ($ConfigurationItem) { $Filter += "'PBM_CI'$Op""$Wc$ConfigurationItem$Wc""" }
        
        If ($Assignee -is [Array]) { 
            $AssigneeString = ($Assignee | ForEach-Object { "('Assignee'$Op""$Wc$_$Wc"")" }) -join 'OR'
            $Filter += "($AssigneeString)"
        } ElseIf ($Assignee -is [String]) {
             $Filter += "'Assignee'$Op""$Wc$Assignee$Wc""" 
        }
        
        If ($Submitter -is [Array]) { 
            $SubmitterString = ($Submitter | ForEach-Object { "('Submitter'$Op""$Wc$_$Wc"")" }) -join 'OR'
            $Filter += "($SubmitterString)"
        } ElseIf ($Submitter -is [String]) {
             $Filter += "'Submitter'$Op""$Wc$Submitter$Wc""" 
        }
         
        If ($Type)          { $Filter += "($TypeString)" }
        If ($ExcludeType)   { $Filter += "($ExcludeTypeString)" }
        
        If ($Priority)      { $Filter += "($PriorityString)" }
        
        If ($After)  { $Filter += "'Submit Date'>""$($After.ToString("yyyy-MM-dd"))""" }
        If ($Before) { $Filter += "'Submit Date'<""$($Before.ToString("yyyy-MM-dd"))""" }

        If ($StatusString) { $Filter += "($StatusString)" }
        $FilterString = $Filter -Join 'AND'

        $Headers = @{
            Authorization = "Basic $EncodedCredentials"
        }

        If (-not $FilterString) { Throw 'Please provide at least one search criteria. Enter Help Get-RemedyProblem for further guidance.' }

        $URL = "$APIURL/PBM:Problem Investigation/$FilterString"
    
    
        Try {
            $Result = Invoke-RestMethod -URI $URL -Headers $Headers -ErrorAction Stop

            $Problems = @()
            $Result.PSObject.Properties | ForEach-Object { $Problems += $_.Value }
            
            #Convert all date containing fields to PS datetime
            ForEach ($Problem in $Problems) { 
                
                $Problem.PSObject.Properties.Name -like '* Date*' | ForEach-Object {
                        
                    If ($Problem.$_ -match 'UTC'){
                        $Problem.$_ = [datetime]::ParseExact(($Problem.$_ -Replace 'UTC ',''), 'ddd MMM dd HH:mm:ss yyyy', $null)
                    }
                }
            }
                                
            #Could replace this with a format.ps1.xml
            If (-not $Full){
                $Problems = $Problems |  Select-Object 'Problem Investigation ID','Priority','Company',
                                                       'Description',@{N='Status';E={$_.'Investigation Status'}},'Assigned Group','Assignee',
                                                       @{N='CI';E={$_.PBM_CI}},'Submit Date','Last Modified Date','Last Modified By'
            }
        } Catch {
            
            Write-Error "Error: $_"
        }

        If ($null -ne $Problems<#.'Problem Investigation ID'#>) {
            $Problems.psobject.TypeNames.Insert(0, 'RemedyProblem')
            $Problems
        } Else {
            Write-Verbose 'No problem data returned'
        }
    }
}