11function New-HaloPSATicket {
22 [CmdletBinding (SupportsShouldProcess )]
33 param (
4- $title ,
5- $description ,
6- $client
4+ $Title ,
5+ $Description ,
6+ $Client ,
7+ $TicketId
78 )
8- # Get HaloPSA Token based on the config we have.
9+
10+ # Load Halo configuration
911 $Table = Get-CIPPTable - TableName Extensionsconfig
1012 $Configuration = ((Get-CIPPAzDataTableEntity @Table ).config | ConvertFrom-Json ).HaloPSA
1113 $TicketTable = Get-CIPPTable - TableName ' PSATickets'
12- $token = Get-HaloToken - configuration $Configuration
13- # sha hash title
14- $TitleHash = Get-StringHash - String $title
14+ $Token = Get-HaloToken - configuration $Configuration
15+
16+ # Helper to add a note to an existing ticket
17+ function Add-HaloTicketNote {
18+ param ($TicketId , $Html )
19+
20+ $Object = [PSCustomObject ]@ {
21+ ticket_id = $TicketId
22+ outcome_id = 7
23+ hiddenfromuser = $true
24+ note_html = $Html
25+ }
26+
27+ if ($Configuration.Outcome ) {
28+ $Object.outcome_id = $Configuration.Outcome.value ?? $Configuration.Outcome
29+ }
30+
31+ $Body = ConvertTo-Json - Compress - Depth 10 - InputObject @ ($Object )
32+
33+ if ($PSCmdlet.ShouldProcess (" HaloPSA Ticket $TicketId " , ' Add note' )) {
34+ Invoke-RestMethod `
35+ - Uri " $ ( $Configuration.ResourceURL ) /actions" `
36+ - ContentType ' application/json; charset=utf-8' `
37+ - Method Post `
38+ - Body $Body `
39+ - Headers @ { Authorization = " Bearer $ ( $Token.access_token ) " }
40+ }
41+ }
42+
43+ if ($TicketId ) {
44+ Write-Information " Explicit PSA Ticket ID provided: $TicketId "
45+
46+ try {
47+ $Ticket = Invoke-RestMethod `
48+ - Uri " $ ( $Configuration.ResourceURL ) /Tickets/$TicketId ?includedetails=true&includelastaction=false" `
49+ - ContentType ' application/json; charset=utf-8' `
50+ - Method Get `
51+ - Headers @ { Authorization = " Bearer $ ( $Token.access_token ) " } `
52+ - SkipHttpErrorCheck
53+
54+ if ($Ticket.id -and -not $Ticket.hasbeenclosed ) {
55+ Write-Information " Ticket $TicketId is open. Appending note."
56+ Add-HaloTicketNote - TicketId $TicketId - Html $Description
57+ return " Note added to HaloPSA ticket $TicketId "
58+ }
59+
60+ Write-Information " Ticket $TicketId is closed or not found. Creating new ticket."
61+ }
62+ catch {
63+ $Message = $_.Exception.Message
64+ Write-LogMessage `
65+ - API ' HaloPSATicket' `
66+ - sev Error `
67+ - message " Failed to update HaloPSA ticket $TicketId : $Message " `
68+ - LogData (Get-CippException - Exception $_ )
69+ return " Failed to update HaloPSA ticket $TicketId : $Message "
70+ }
71+ }
72+
73+ $TitleHash = Get-StringHash - String $Title
1574
1675 if ($Configuration.ConsolidateTickets ) {
17- $ExistingTicket = Get-CIPPAzDataTableEntity @TicketTable - Filter " PartitionKey eq 'HaloPSA' and RowKey eq '$ ( $client ) -$ ( $TitleHash ) '"
76+ $ExistingTicket = Get-CIPPAzDataTableEntity `
77+ @TicketTable `
78+ - Filter " PartitionKey eq 'HaloPSA' and RowKey eq '$ ( $Client ) -$ ( $TitleHash ) '"
79+
1880 if ($ExistingTicket ) {
19- Write-Information " Ticket already exists in HaloPSA: $ ( $ExistingTicket.TicketID ) "
20-
21- $Ticket = Invoke-RestMethod - Uri " $ ( $Configuration.ResourceURL ) /Tickets/$ ( $ExistingTicket.TicketID ) ?includedetails=true&includelastaction=false&nocache=undefined&includeusersassets=false&isdetailscreen=true" - ContentType ' application/json; charset=utf-8' - Method Get - Headers @ {Authorization = " Bearer $ ( $token.access_token ) " } - SkipHttpErrorCheck
22- if ($Ticket.id ) {
23- if (! $Ticket.hasbeenclosed ) {
24- Write-Information ' Ticket is still open, adding new note'
25- $Object = [PSCustomObject ]@ {
26- ticket_id = $ExistingTicket.TicketID
27- outcome_id = 7
28- hiddenfromuser = $true
29- note_html = $description
30- }
31-
32- if ($Configuration.Outcome ) {
33- $Outcome = $Configuration.Outcome.value ?? $Configuration.Outcome
34- $Object.outcome_id = $Outcome
35- }
36-
37- $body = ConvertTo-Json - Compress - Depth 10 - InputObject @ ($Object )
38- try {
39- if ($PSCmdlet.ShouldProcess (' Add note to HaloPSA ticket' , ' Add note' )) {
40- $Action = Invoke-RestMethod - Uri " $ ( $Configuration.ResourceURL ) /actions" - ContentType ' application/json; charset=utf-8' - Method Post - Body $body - Headers @ {Authorization = " Bearer $ ( $token.access_token ) " }
41- Write-Information " Note added to ticket in HaloPSA: $ ( $ExistingTicket.TicketID ) "
42- }
43- return " Note added to ticket in HaloPSA: $ ( $ExistingTicket.TicketID ) "
44- }
45- catch {
46- $Message = if ($_.ErrorDetails.Message ) {
47- Get-NormalizedError - Message $_.ErrorDetails.Message
48- }
49- else {
50- $_.Exception.message
51- }
52- Write-LogMessage - message " Failed to add note to HaloPSA ticket: $Message " - API ' HaloPSATicket' - sev Error - LogData (Get-CippException - Exception $_ )
53- Write-Information " Failed to add note to HaloPSA ticket: $Message "
54- Write-Information " Body we tried to ship: $body "
55- return " Failed to add note to HaloPSA ticket: $Message "
56- }
81+ Write-Information " Consolidated ticket found: $ ( $ExistingTicket.TicketID ) "
82+
83+ try {
84+ $Ticket = Invoke-RestMethod `
85+ - Uri " $ ( $Configuration.ResourceURL ) /Tickets/$ ( $ExistingTicket.TicketID ) ?includedetails=true&includelastaction=false" `
86+ - ContentType ' application/json; charset=utf-8' `
87+ - Method Get `
88+ - Headers @ { Authorization = " Bearer $ ( $Token.access_token ) " } `
89+ - SkipHttpErrorCheck
90+
91+ if ($Ticket.id -and -not $Ticket.hasbeenclosed ) {
92+ Write-Information " Consolidated ticket open. Appending note."
93+ Add-HaloTicketNote - TicketId $ExistingTicket.TicketID - Html $Description
94+ return " Note added to HaloPSA ticket $ ( $ExistingTicket.TicketID ) "
5795 }
96+
97+ Write-Information " Consolidated ticket closed. Creating new ticket."
5898 }
59- else {
60- Write-Information ' Existing ticket could not be found . Creating a new ticket instead. '
99+ catch {
100+ Write-Information " Failed to read consolidated ticket . Creating new ticket. "
61101 }
62102 }
63103 }
@@ -69,56 +109,60 @@ function New-HaloPSATicket {
69109 id = -1
70110 lookupdisplay = ' Enter Details Manually'
71111 }
72- client_id = ($client | Select-Object - Last 1 )
112+ client_id = ($Client | Select-Object - Last 1 )
73113 _forcereassign = $true
74114 site_id = $null
75115 user_name = $null
76116 reportedby = $null
77- summary = $title
78- details_html = $description
117+ summary = $Title
118+ details_html = $Description
79119 donotapplytemplateintheapi = $true
80120 attachments = @ ()
81121 _novalidate = $true
82122 }
83123
84124 if ($Configuration.TicketType ) {
85125 $TicketType = $Configuration.TicketType.value ?? $Configuration.TicketType
86- $object | Add-Member - MemberType NoteProperty - Name ' tickettype_id' - Value $TicketType - Force
126+ $Object | Add-Member - MemberType NoteProperty - Name ' tickettype_id' - Value $TicketType - Force
87127 }
88- # use the token to create a new ticket in HaloPSA
89- $body = ConvertTo-Json - Compress - Depth 10 - InputObject @ ($Object )
90128
91- Write-Information ' Sending ticket to HaloPSA'
92- Write-Information $body
129+ $Body = ConvertTo-Json - Compress - Depth 10 - InputObject @ ($Object )
130+
131+ Write-Information ' Creating new HaloPSA ticket'
132+
93133 try {
94- if ($PSCmdlet.ShouldProcess (' Send ticket to HaloPSA' , ' Create ticket' )) {
95- $Ticket = Invoke-RestMethod - Uri " $ ( $Configuration.ResourceURL ) /Tickets" - ContentType ' application/json; charset=utf-8' - Method Post - Body $body - Headers @ {Authorization = " Bearer $ ( $token.access_token ) " }
134+ if ($PSCmdlet.ShouldProcess (' HaloPSA' , ' Create ticket' )) {
135+ $Ticket = Invoke-RestMethod `
136+ - Uri " $ ( $Configuration.ResourceURL ) /Tickets" `
137+ - ContentType ' application/json; charset=utf-8' `
138+ - Method Post `
139+ - Body $Body `
140+ - Headers @ { Authorization = " Bearer $ ( $Token.access_token ) " }
141+
96142 Write-Information " Ticket created in HaloPSA: $ ( $Ticket.id ) "
97143
98144 if ($Configuration.ConsolidateTickets ) {
99145 $TicketObject = [PSCustomObject ]@ {
100146 PartitionKey = ' HaloPSA'
101- RowKey = " $ ( $client ) -$ ( $TitleHash ) "
102- Title = $title
103- ClientId = $client
147+ RowKey = " $ ( $Client ) -$ ( $TitleHash ) "
148+ Title = $Title
149+ ClientId = $Client
104150 TicketID = $Ticket.id
105151 }
106152 Add-CIPPAzDataTableEntity @TicketTable - Entity $TicketObject - Force
107153 Write-Information ' Ticket added to consolidation table'
108154 }
155+
109156 return " Ticket created in HaloPSA: $ ( $Ticket.id ) "
110157 }
111158 }
112159 catch {
113- $Message = if ($_.ErrorDetails.Message ) {
114- Get-NormalizedError - Message $_.ErrorDetails.Message
115- }
116- else {
117- $_.Exception.message
118- }
119- Write-LogMessage - message " Failed to send ticket to HaloPSA: $Message " - API ' HaloPSATicket' - sev Error - LogData (Get-CippException - Exception $_ )
120- Write-Information " Failed to send ticket to HaloPSA: $Message "
121- Write-Information " Body we tried to ship: $body "
122- return " Failed to send ticket to HaloPSA: $Message "
160+ $Message = $_.Exception.Message
161+ Write-LogMessage `
162+ - API ' HaloPSATicket' `
163+ - sev Error `
164+ - message " Failed to create HaloPSA ticket: $Message " `
165+ - LogData (Get-CippException - Exception $_ )
166+ return " Failed to create HaloPSA ticket: $Message "
123167 }
124168}
0 commit comments