PowerShell: Hudu <-- >Halo PSA integration.

Continuing my playing with the Halo PSA I have been working on some bits to enhance the integration between Hudu and Halo PSA. The first thing I found which can add a lot of value is to utilise custom buttons in Halo to add direct links to Hudu items from Companies, Sites, Users and Assets.

To get this to work the first thing you need to do is configure the Halo PSA integration inside Hudu, match your companies and perform a first sync.

Once this is setup go into Halo and navigate to: Configuration>Custom Objects>Custom Buttons

Here select from the dropdown menu at the top which kind of asset you want to create the button for and choose new. Enter the name of the button, a label and an icon and then use one of the following link styles for the URL:

Companies:

https://{your.hudu.domain}/api/v1/companies/jump?integration_id={$ID}&integration_slug=halo&integration_type=company

SItes:

https://{your.hudu.domain}/api/v1/cards/jump?integration_id={$ID}&integration_slug=halo&integration_type=site

Users:

https://{your.hudu.domain}/api/v1/cards/jump?integration_id={$ID}&integration_slug=halo&integration_type=contact

Assets:

As assets don’t synchronise between Hudu and Halo you will need to synchronise your RMM to both and then lookup the replacement variable in the Halo variables page. This is the version you can use for Datto RMM:

https://{your.hudu.domain}/api/v1/cards/jump?integration_identifier={$DATTO_ID}&integration_slug=dattormm&integration_type=device

This is the version for Ninja RMM (Kindly provided by Sam James)

https://{your.hudu.domain}/api/v1/cards/jump?integration_id={$NINJARMM_ID}&integration_slug=ninja&integration_type=device

Now that accessing Hudo from Halo PSA has been made easier, I thought I would add some ticket information into Hudo so you can quickly see details when inside companies or contact. To do this I created a script to add a magic dash and to write to a field called Halo Tickets on your People asset type. You will need to make sure you have added this field as a Rich Text type to your asset layout.

Setup

The first step to this is you will need to create two new views inside Halo PSA. Navigate to Configuration > Tickets > Views. Here click the Configure Filter Profiles button. You will need to create two views here. One to show open tickets and one to show closed tickets. You will need to assign them to be viewable to the same PSA user that you set the API to use. For my views I used the following settings:

Open Tickets:

Closed Tickets:

Once you have these created you will need to get the view IDs for each. To get these click on the view from the filter screen and the ID will be in the URL:

Make a note of both of these as you will need to set them in the script.

# Add this CSS to Admin -> Design -> Custom CSS
# .custom-fast-fact.custom-fast-fact--warning {
#     background: #f5c086;
# }
#####################################################################

$HaloClientID = "Your Halo API App Client ID"
$HaloClientSecret = "Your Halo API App Client Secret"
$HaloURL = "Your Halo API URL"

# Get a Hudu API Key from https://yourhududomain.com/admin/api_keys
$HuduAPIKey = "abcdefghijklmnop"
$HuduBaseDomain = "https://your.hudu.domain"

$PeopleLayoutName = 'People'

# Get the ID of the Halo view you wish to use for tickets. Visit https://{yourHalodomain}/config/tickets/views/filters click the filter you want to use and the ID will be in the URL.
# Create two Halo ticket views, one for open tickets you want to display and one for closed tickets (eg tickets in the last month)
$OpenTicketsHaloViewID = 12
$ClosedTicketsHaloViewID = 13
$HaloDomain = 'https://your.halo.domain'
#####################################################################

function Get-FormattedTickets {
	param(
		[PSCustomObject]$Tickets
	)

	$FormattedTickets = foreach ($Ticket in $Tickets) {
		[PSCustomObject]@{
			"Ticket ID"     = "<a href=$HaloDomain/tickets?id=$($Ticket.id)>$($Ticket.id)</a>"
			"Date Created"  = $Ticket.dateoccurred
			"Last Action"   = $Ticket.lastactiondate
			"Ticket Status" = ($TicketStatus | Where-Object { $_.id -eq $Ticket.status_id } | Select-Object -first 1).name
			"Summary"       = $Ticket.summary
			"SLA Time Left" = $Ticket.slatimeleft | ForEach-Object { if ($_ -lt 0) { "<div align=center width=20px style=background-color:red;><font color=white>$_</font></div>" } else { "$_" } }
			"Contact"       = $Ticket.user_name
			"Priority"      = $Ticket.priority.name
			"Ticket Type"   = ($TicketTypes | Where-Object { $_.id -eq $Ticket.tickettype_id } | Select-Object -first 1).name
			"Team"          = $Ticket.Team
			"Category"      = $Ticket.category_1
		}
	} 

	$OutputTickets = $FormattedTickets | Sort-Object -Property "Date Created"

	Return $OutputTickets

}


#Get the Hudu API Module if not installed
if (Get-Module -ListAvailable -Name HuduAPI) {
	Import-Module HuduAPI 
} else {
	Install-Module HuduAPI -Force
	Import-Module HuduAPI
}

if (Get-Module -ListAvailable -Name HaloAPI) {
	Import-Module HaloAPI 
} else {
	Install-Module HaloAPI -Force
	Import-Module HaloAPI
}
  
#Set Hudu logon information
New-HuduAPIKey $HuduAPIKey
New-HuduBaseUrl $HuduBaseDomain

# Connect to Halo
Connect-HaloAPI -URL $HaloURL -ClientId $HaloClientID -ClientSecret $HaloClientSecret -Scopes "all"

# Grab data from Halo
$TicketTypes = Get-HaloTicketType
$TicketStatus = Get-HaloStatus
$HaloTickets = Get-HaloTicket -ColumnsID 1 -ViewID $OpenTicketsHaloViewID -IncludeColumns
$HaloClosedTickets = Get-HaloTicket -ColumnsID 1 -ViewID $ClosedTicketsHaloViewID -IncludeColumns

# Grab Data from Hudu
$HuduPersonLayout = Get-HuduAssetLayouts -Name $PeopleLayoutName

$HuduCompanies = Get-HuduCompanies
$HuduPeople = Get-HuduAssets -AssetLayoutId $HuduPersonLayout.id

# Create Magic Dash in each company
foreach ($company in $HuduCompanies) {

	$HaloDetails = $company.integrations | Where-Object { $_.integrator_name -eq "halo" }

	if ($HaloDetails) {
		$OpenCompanyTickets = $HaloTickets | Where-Object { $_.client_id -eq $HaloDetails.sync_id }
		$ClosedCompanyTickets = $HaloClosedTickets | Where-Object { $_.client_id -eq $HaloDetails.sync_id }

		
		$FormattedOpenCompanyTickets = [System.Net.WebUtility]::HtmlDecode($(Get-FormattedTickets -Tickets $OpenCompanyTickets | ConvertTo-Html -fragment | out-string))
		$FormattedClosedCompanyTickets = [System.Net.WebUtility]::HtmlDecode($(Get-FormattedTickets -Tickets $ClosedCompanyTickets| Select-Object -exclude "SLA Time Left" | ConvertTo-Html -fragment | out-string))

		if (!$FormattedOpenCompanyTickets){
			$FormattedOpenCompanyTickets = "No Open Tickets"
		}

		if (!$FormattedClosedCompanyTickets){
			$FormattedClosedCompanyTickets = "No Closed Tickets"
		}
	
		$Overdue = ($OpenCompanyTickets | where-object { $_.slatimeleft -lt 0 } | measure-object).count

		$MagicMessage = "$(($OpenCompanyTickets | Measure-Object).count) Open Tickets"	

		$shade = "success"
		if ($overdue -ge 1) {
			$shade = "warning"
			$MagicMessage = "$overdue / $(($OpenCompanyTickets | Measure-Object).count) Tickets Overdue"
		}
		if ($overdue -ge 2) {
			$shade = "danger"
		}
		
		$body = "<h2>Open Tickets:</h2>$FormattedOpenCompanyTickets<h2>Closed Tickets (Last 3 Months):</h2>$FormattedClosedCompanyTickets"

		$null = Set-HuduMagicDash -title "Halo - Tickets" -company_name $($company.name) -message $MagicMessage -icon "fas fa-chart-pie" -content $body -shade $shade -ea stop

	}
}

# Create tickets in each user
foreach ($Person in $HuduPeople) {

	$HaloPersonDetails = $Person.cards | Where-Object { $_.integrator_name -eq "halo" }

	foreach ($HaloPerson in $HaloPersonDetails) {
		$OpenPersonTickets = $HaloTickets | Where-Object { $_.user_id -eq $HaloPerson.sync_id }
		$ClosedPersonTickets = $HaloClosedTickets | Where-Object { $_.user_id -eq $HaloPerson.sync_id }
		
		$FormattedOpenPersonTickets = [System.Net.WebUtility]::HtmlDecode($(Get-FormattedTickets -Tickets $OpenPersonTickets | ConvertTo-Html -fragment | out-string))
		$FormattedClosedPersonTickets = [System.Net.WebUtility]::HtmlDecode($(Get-FormattedTickets -Tickets $ClosedPersonTickets| Select-Object -exclude "SLA Time Left" | ConvertTo-Html -fragment | out-string))
		
		if (!$FormattedOpenPersonTickets){
			$FormattedOpenPersonTickets = "No Open Tickets"
		}

		if (!$FormattedClosedPersonTickets){
			$FormattedClosedPersonTickets = "No Closed Tickets"
		}
		

		$body = "<h2>Open Tickets:</h2>$FormattedOpenPersonTickets<h2>Closed Tickets (Last 3 Months):</h2>$FormattedClosedPersonTickets"
		
		$UserAssetFields = @{
			halo_tickets = $body
		}

		$null = Set-HuduAsset -asset_id $Person.id -name $Person.name -company_id $Person.company_id -asset_layout_id $HuduPersonLayout.id -fields $UserAssetFields

	}
}

You may also like...