Skip to content

Commit f24092b

Browse files
authored
Merge pull request #21 from Techary/dev
Feat
2 parents 9991ed8 + 5e3a037 commit f24092b

File tree

5 files changed

+125
-73
lines changed

5 files changed

+125
-73
lines changed

Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-ExecScheduledCommand.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ function Push-ExecScheduledCommand {
329329
Write-Information 'Scheduler: Sending the results to the target.'
330330
Write-Information "The content of results is: $Results"
331331
switch -wildcard ($task.PostExecution) {
332-
'*psa*' { Send-CIPPAlert -Type 'psa' -Title $title -HTMLContent $HTML -TenantFilter $Tenant }
332+
'*psa*' { Send-CIPPAlert -Type 'psa' -Title $title -HTMLContent $HTML -TenantFilter $Tenant -PSATicketId $task.PostExecution.psaTicketId }
333333
'*email*' { Send-CIPPAlert -Type 'email' -Title $title -HTMLContent $HTML -TenantFilter $Tenant }
334334
'*webhook*' {
335335
$Webhook = [PSCustomObject]@{

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOffboardUser.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ function Invoke-ExecOffboardUser {
3434
Webhook = [bool]$Request.Body.PostExecution.webhook
3535
Email = [bool]$Request.Body.PostExecution.email
3636
PSA = [bool]$Request.Body.PostExecution.psa
37+
psaTicketId = [int]$Request.Body.PostExecution.psaTicketId
3738
}
3839
Reference = $Request.Body.reference
3940
}

Modules/CIPPCore/Public/Send-CIPPAlert.ps1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ function Send-CIPPAlert {
99
$TenantFilter,
1010
$altEmail,
1111
$altWebhook,
12+
$PSATicketId,
1213
$APIName = 'Send Alert',
1314
$Headers,
1415
$TableName,
@@ -171,6 +172,7 @@ function Send-CIPPAlert {
171172
TenantId = $TenantFilter
172173
AlertText = "$HTMLContent"
173174
AlertTitle = "$($Title)"
175+
TicketId = $PSATicketId
174176
}
175177
New-CippExtAlert -Alert $Alert
176178
Write-LogMessage -API 'Webhook Alerts' -tenant $TenantFilter -message "Sent PSA alert $title" -sev info
Lines changed: 115 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,103 @@
11
function 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
}

Modules/CippExtensions/Public/New-CippExtAlert.ps1

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@ function New-CippExtAlert {
2020
Write-Host "MappedId: $MappedId"
2121
if (!$mappedId) { $MappedId = 1 }
2222
Write-Host "MappedId: $MappedId"
23-
New-HaloPSATicket -Title $Alert.AlertTitle -Description $Alert.AlertText -Client $mappedId
23+
New-HaloPSATicket `
24+
-Title $Alert.AlertTitle `
25+
-Description $Alert.AlertText `
26+
-Client $mappedId `
27+
-TicketId $Alert.TicketId
28+
2429
}
2530
}
2631
'Gradient' {

0 commit comments

Comments
 (0)