endpoints/Tickets.ps1
<# .Synopsis Get a list of all tickets in Atera. Defaults to open and pending tickets when no options provided. .Parameter Open Queries tickets with the open status .Parameter Pending Queries tickets with the pending status .Parameter Resolved Queries tickets with the resolved status .Parameter Closed Queries tickets with the closed status .Parameter CustomStatuses Queries tickets with custom statuses, ex: -CustomStatuses "Waiting customer,Waiting order" .Parameter CustomerID #> function Get-AteraTickets { param( [Parameter(ParameterSetName="Filtered")] [switch] $Open, [Parameter(ParameterSetName="Filtered")] [switch] $Pending, [Parameter(ParameterSetName="Filtered")] [switch] $Resolved, [Parameter(ParameterSetName="Filtered")] [switch] $Closed, [Parameter(ParameterSetName="Filtered")] [string[]] $CustomStatuses, [int] $CustomerID ) if ($PSCmdlet.ParameterSetName -ne "Filtered") { $PSBoundParameters["Open"] = $true $PSBoundParameters["Pending"] = $true } $Tickets = @() $Query = @{} if ($PSBoundParameters.ContainsKey("CustomerID")) { $Query.Add("customerId", $CustomerID) } if ($CustomStatuses) { $CustomStatuses = $CustomStatuses -join "," foreach ($ticketStatus in $CustomStatuses.Split(",")) { if ($ticketStatus) { $Tickets += New-AteraGetRequest -Endpoint "/tickets" -Query ($Query + @{ "ticketStatus" = $ticketStatus }) } } } @("Open", "Pending", "Resolved", "Closed") | ForEach-Object { if ($PSBoundParameters[$_]) { $Tickets += New-AteraGetRequest -Endpoint "/tickets" -Query ($Query + @{"ticketStatus" = $_}) } } $Tickets } <# .Synopsis Get a single ticket by it's ID .Parameter TicketID #> function Get-AteraTicket { param( # ID of ticket to retrieve [int]$TicketID ) return New-AteraGetRequest -Endpoint "/tickets/$TicketID" -Paginate $false } <# .Synopsis Get the billable time spent on a ticket .Parameter TicketID #> function Get-AteraTicketBillableDuration { param( # ID of ticket to retrieve [int]$TicketID ) return New-AteraGetRequest -Endpoint "/tickets/$TicketID/billableduration" -Paginate $false } <# .Synopsis Get the nonbillable time spent on a ticket .Parameter TicketID #> function Get-AteraTicketNonBillableDuration { param( # ID of ticket to retrieve [int]$TicketID ) return New-AteraGetRequest -Endpoint "/tickets/$TicketID/nonbillableduration" -Paginate $false } <# .Synopsis Get both the billable and nonbillable time spent on a ticket .Parameter TicketID #> function Get-AteraTicketWorkHours { param( # ID of ticket to retrieve [int]$TicketID ) return New-AteraGetRequest -Endpoint "/tickets/$TicketID/workhours" -Paginate $false } <# .Synopsis Get a list of time sheets for a ticket .Parameter TicketID #> function Get-AteraTicketWorkHoursList { param( # ID of ticket to retrieve [int]$TicketID ) return New-AteraGetRequest -Endpoint "/tickets/$TicketID/workhoursrecords" } <# .Synopsis Get all comments on a ticket .Parameter TicketID #> function Get-AteraTicketComments { param( # ID of ticket to retrieve [int]$TicketID ) return New-AteraGetRequest -Endpoint "/tickets/$TicketID/comments" } <# .Synopsis [Deprecated] Use `Get-AteraTickets` instead #> function Get-AteraTicketsFiltered { param( # Get Open tickets [switch] $Open, # Get Pending tickets [switch] $Pending, # Get Resolved tickets [switch] $Resolved, # Get Closed tickets [switch] $Closed ) Get-AteraTickets @PSBoundParameters } <# .Synopsis Create a new ticket .Parameter TicketTitle .Parameter Description .Parameter EndUserID ID of the contact submitting the ticket .Parameter EndUserFirstName If the contact does not exist, one will be created using this value as the first name .Parameter EndUserLastName If the contact does not exist, one will be created using this value as the last name .Parameter EndUserEmail Create a new or search for a contact by email .Parameter TicketPriority Priority level for new ticket. Defaults to Low. Options: Low, Medium, High, Critical .Parameter TicketImpact Impact of the issue reported. Defaults to Minor. Options: NoImpact, Minor, Major, Site Down, Server Issue, Crisis .Parameter TicketStatus Current status of ticket. Defaults to Open. Options: Open, Pending, Resolved, Closed .Parameter TicketType Type of ticket being reported. Defaults to Problem. Options: Problem, Bug, Request, Other, Incident, Change .Parameter TechnicianContactID .Example Get-AteraContacts | Where-Object Email -eq "john@example.com" | New-AteraTicket -TicketTitle "Computer won't turn on" -Description "Some long description" # Create a new ticket for a user who's email is john@example.com .Example New-AteraTicket -TicketTitle "Update Sage Server" -Description "Some long description" -TicketType Change -EndUserEmail john@example.com -EndUserFirstName John -EndUserLastName Smith # Create a new ticket for John Smith, creating his contact if it doesn't exist. #> function New-AteraTicket { [CmdletBinding(DefaultParameterSetName='ExistingContact')] param ( [Parameter(Mandatory)] [string] $TicketTitle, [Parameter(Mandatory)] [string] $Description, [Parameter(Mandatory, ParameterSetName='ExistingContact', ValueFromPipelineByPropertyName)] [int] $EndUserID, [Parameter(Mandatory, ParameterSetName='NewContact')] [string] $EndUserFirstName, [Parameter(Mandatory, ParameterSetName='NewContact')] [string] $EndUserLastName, [Parameter(Mandatory, ParameterSetName='NewContact')] [string] $EndUserEmail, [Parameter()] [ValidateSet("Low", "Medium", "High", "Critical")] [string] $TicketPriority = "Low", [Parameter()] [ValidateSet("NoImpact", "SiteDown", "ServerIssue", "Minor", "Major", "Crisis")] [string] $TicketImpact = "Minor", [Parameter()] [ValidateSet("Open", "Pending", "Resolved", "Closed")] [string] $TicketStatus = "Open", [Parameter()] [ValidateSet("Problem" ,"Bug", "Request", "Other", "Incident", "Change")] [string] $TicketType = "Problem", [Parameter()] [int] $TechnicianContactID ) New-AteraPostRequest -Endpoint "/tickets" -Body $PSBoundParameters } <# .Synopsis Updates details about a ticket .Parameter TicketID ID of the ticket to update .Parameter TicketTitle New title for ticket .Parameter TicketStatus New status for ticket (Options: Open, Pending, Resolved, Closed) .Parameter TicketType New type for ticket (Options: Problem, Bug, Question, Request, Other, Incident, Change) .Parameter TicketPriority New priority for ticket (Options: Low, Medium, High, Critical) .Parameter TicketImpact New impact for ticket (Options: NoImpact, SiteDown, ServiceIssue, Minor, Major, Crisis) .Parameter TechnicianContactID New technician ID to assign ticket to #> function Set-AteraTicket { [CmdletBinding()] param ( [Parameter(Mandatory)] [string] $TicketID, [Parameter()] [string] $TicketTitle, [Parameter()] [ValidateSet("Open", "Pending", "Resolved", "Closed")] [string] $TicketStatus, [Parameter()] [ValidateSet("Problem" ,"Bug", "Request", "Other", "Incident", "Change")] [string] $TicketType, [Parameter()] [ValidateSet("Low", "Medium", "High", "Critical")] [string] $TicketPriority, [Parameter()] [ValidateSet("NoImpact", "SiteDown", "ServerIssue", "Minor", "Major", "Crisis")] [string] $TicketImpact, [Parameter()] [int] $TechnicianContactID ) $Body = @{} if ($TickeTitle -ne "") { $Body["TicketTitle"] = $TicketTitle } if ($TicketStatus -ne "") { $Body.TicketStatus = $TicketStatus } if ($TicketType -ne "") { $Body.TicketType = $TicketType } if ($TicketPriority -ne "") { $Body.TicketPriority = $TicketPriority } if ($TicketImpact -ne "") { $Body.TicketImpact = $TicketImpact } if ($TechnicianContactID -ne "") { $Body.TechnicianContactID = $TechnicianContactID } if (!$Body.Count) { throw "At least one update parameter needs to be set" } New-AteraPostRequest -Endpoint "/tickets/$($TicketID)" -Body $Body } <# .Synopsis Adds a comment into a ticket, you need to set at least one technician or user ID .Parameter TicketID ID of the ticket to update; Mandatory .Parameter CommentText Comment text to add to the ticket; Mandatory .Parameter CommentTimestampUTC UTC timestamp of the comment, ex: 2024-10-15T20:19:01.845Z; if not set, the current time will be used .Parameter TechnicianID ID of the technician adding the comment .Parameter IsInternal If the comment is internal or not (Options: $true, $false, default: $false) .Parameter EnduserId ID of the user adding the comment #> function New-AteraTicketComment { [CmdletBinding()] param ( [Parameter(Mandatory)] [string] $TicketID, [Parameter(Mandatory)] [string] $CommentText, [Parameter()] [string] $CommentTimestampUTC, [Parameter()] [int] $TechnicianID, [Parameter()] [bool] $IsInternal=$false, [Parameter()] [int] $EnduserId ) $Body = @{} if ($CommentText -ne "") { $Body["CommentText"] = $CommentText } if ($CommentTimestampUTC -ne "") { $Body.CommentTimestampUTC = $CommentTimestampUTC } # We don't set both Technician and User ID if ($TechnicianID -ne "") { $Body["TechnicianCommentDetails"] = @{} if ($TechnicianID -ne "") { $Body.TechnicianCommentDetails.TechnicianID = $TechnicianID } $Body.TechnicianCommentDetails.IsInternal = $IsInternal } elseif ($EnduserId -ne "") { $Body["EnduserCommentDetails"] = @{} if ($EnduserId -ne "") { $Body.EnduserCommentDetails.EnduserId = $EnduserId } } else { throw "At least one parameter (TechnicianID or EnduserId) needs to be set" } if (!$Body.Count) { throw "At least one update parameter needs to be set" } New-AteraPostRequest -Endpoint "/tickets/$($TicketID)/comments" -Body $Body } |