Dear community,
I have 1200+ clients and I should install the Assets Discovery Agent. Atlassian happily says to do this manually. The installation routine of the Agent is so bad that distributing the application via SCCM is very difficult.
I need some advice on how to uninstall the existing Discovery Agents (Version 3.1.4) and how to install the new version 3.2.0 with SCCM. What are the exact steps to do?
Thank you,
Chris
EDIT: Anybody stumbling on this: please fote for [JSDSERVER-12441] improve Discovery tool in order to fully support the deployment of agents through SCCM - Create and track feature requests for Atlassian products.
EDIT2: vote for this as well: [JSDCLOUD-12326] improve Discovery tool in order to fully support the deployment of agents through SCCM - Create and track feature requests for Atlassian products.
EDIT3: Another feature request worth voting for: [JSDSERVER-16271] Improve Assets Discovery tool in order to fully support the deployment of agents through SCCM - Create and track feature requests for Atlassian products.
Dear Community,
We recently upgraded to version 7.1.2 of the Assets Discovery Agent. Once again, deploying the software via SCCM proved challenging due to several changes. I’d like to share our approach and solutions so others can benefit. This guide is also intended for Atlassian developers, with suggestions to simplify SCCM deployment in future Discovery Agent releases.
SCCM is used to distribute applications to clients. It handles both initial installation and ongoing compliance, ensuring applications remain correctly installed, configured, and operational.
Provide an MSI installer
To enable SCCM-based deployment, we made the following adjustments:
<?xml version="1.0" encoding="utf-8"?><!-- Please make sure that you just modify values.... --><ObjectHashSettings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ClieniaVersion="7.1.2"><!-- HostInfo Attributes --><HostInfo_Hostname>true</HostInfo_Hostname><HostInfo_FQDN>false</HostInfo_FQDN>...
<?xml version="1.0" encoding="utf-8"?><Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><ScanLogLevel>Normal</ScanLogLevel><NextScanDate>2025-06-20T16:48:11.8430618+02:00</NextScanDate><ScanInterval>24</ScanInterval><AgentPort>51337</AgentPort><UseAllNetworkInterfaces>true</UseAllNetworkInterfaces><DeleteLogsAfter>7</DeleteLogsAfter><DisableTCPListener>true</DisableTCPListener><DirectCopyPath/><SFTPSettings><ExportPath>---path-to-your-server---</ExportPath><UserName>assets</UserName><Password>---password-in-plain-text---</Password><TransferReties>5</TransferReties><TranserRetryInterval>30</TranserRetryInterval></SFTPSettings><SaveTimeStamp>2025-06-20T08:00:32.3121706+02:00</SaveTimeStamp></Settings>
SCCM uses detection to verify the current configuration. The following PowerShell script can be used for this purpose.Please note: you need to adopt the length of the Hash and the size of the agent_patterns.bpat to your needs.
# The Atlassian Assets Discovery Agent is considered successfully installed if# - [A] The Agent.cfg contains an XML tag <CryptPW> and the hash of the password is 80 characters long. (Note: Number of characters depends on the chosen password!)# - [B] The ObjectHashXML contains the attribute /ObjectHashSettings/@ClieniaVersion with the value "7.1.2".# - [C] The pattern file agent_patterns.bpat exists and is between 40-50KB in size.# - [D] AssetHistory.dat is larger than 0KB.# Define status variables$agent_cfg = $false$objectHashSettings = $false$agentPatterns = $false$assetHistory = $false# Define variables$path_cfg = 'C:\Program Files\Atlassian\Discovery Agent\Agent.cfg'$CryptPW_length = 80$path_ohs_xml = 'C:\Program Files\Atlassian\Discovery Agent\ObjectHashSettings.xml'$ohs_xml_version = "7.1.2"$path_patterns = 'C:\Program Files\Atlassian\Discovery Agent\agent_patterns.bpat'$path_history = 'C:\Program Files\Atlassian\Discovery Agent\AssetHistory.dat' # Check A: Agent.cfg with CryptPW (80 characters)if (Test-Path $path_cfg) {try {$xml = [xml](Get-Content -Path $path_cfg -ErrorAction Stop)$cryptPW = $xml.SelectSingleNode('Settings/SFTPSettings/CryptPW')if ($null -ne $cryptPW -and $cryptPW.InnerText.Length -eq $CryptPW_length) {$agent_cfg = $true}} catch {$agent_cfg = $false}}# Check B: ObjectHashXML with correct ClieniaVersion presentif (Test-Path $path_ohs_xml) {try {$ohs_xml = [xml](Get-Content -Path $path_ohs_xml -ErrorAction Stop)$clieniaVersion = $ohs_xml.ObjectHashSettings.GetAttribute("ClieniaVersion")if ($clieniaVersion -eq $ohs_xml_version) {$objectHashSettings = $true}} catch {$objectHashSettings = $false}}# Check C: agent_patterns.bpat size 40-50KBif (Test-Path $path_patterns) {$fileSize = (Get-Item $path_patterns).Length$fileSizeKB = $fileSize / 1KBif ($fileSizeKB -ge 40 -and $fileSizeKB -le 50) {$agentPatterns = $true}}# Check AssetHistory.dat larger than 0KBif (Test-Path $path_history) {$historySize = (Get-Item $path_history).Lengthif ($historySize -gt 0) {$assetHistory = $true}} # Final check$allConditionsMet = $agent_cfg -and $objectHashSettings -and $agentPatterns -and $assetHistoryif ($allConditionsMet) {Write-Host "Discovery Agent installation is correct."} else {}
The rollout script is used for the initial installation of the Discovery Agent, as well as the correction of the client, if detection indicates a non compliant device.
Please note: you need to adopt the length of the Hash and the size of the agent_patterns.bpat to your needs.
# This script ensures that the required components of the Atlassian Discovery Agent are installed in the correct version.# If this is not the case, the files are updated accordingly.# The following points are checked:# - [A] Agent.cfg contains an XML tag <CryptPW> and the hash of the password is 80 characters long. (Note: Number of characters depends on the chosen password!)# If not, the file is copied to the client again and the timestamps are updated.# - [B] ObjectHashXML contains the attribute /ObjectHashSettings/@ClieniaVersion with the value "7.1.2".# If not, the file is copied to the client again.# - [C] The pattern file agent_patterns.bpat exists and is between 40-50KB in size.# If it is missing or has the wrong size, it is copied to the client again.# - [D] AssetHistory.dat must be larger than 0KB, otherwise the agent service will hang.# The file will be deleted if necessary and recreated automatically after the service restarts.# Define status variables$agent_cfg = $false$objectHashSettings = $false$agentPatterns = $false$assetHistory = $false# Define variables$serviceName = "Discovery Agent Service"$path_cfg_template = 'Agent.cfg'$path_cfg = 'C:\Program Files\Atlassian\Discovery Agent\Agent.cfg'$CryptPW_length = 80$path_bak = 'C:\Program Files\Atlassian\Discovery Agent\Agent.bak'$path_ohs_xml_template = 'ObjectHashSettings.xml'$path_ohs_xml = 'C:\Program Files\Atlassian\Discovery Agent\ObjectHashSettings.xml'$ohs_xml_version = "7.1.2"$path_patterns_template = 'agent_patterns.bpat'$path_patterns = 'C:\Program Files\Atlassian\Discovery Agent\agent_patterns.bpat'$path_history = 'C:\Program Files\Atlassian\Discovery Agent\AssetHistory.dat'$path_logs = 'C:\Program Files\Atlassian\Discovery Agent\logs\'$path_scans = 'C:\Program Files\Atlassian\Discovery Agent\scans'# Set log file path and name, create directory if necessary$logFileName = (Get-Date -Format "yyyyMMdd") + "_sccm.log"$logFilePath = Join-Path -Path $path_logs -ChildPath $logFileName# Create log directory if it does not existif (-not (Test-Path -Path $path_logs)) {New-Item -ItemType Directory -Path $path_logs -Force}# Write to log fileAdd-Content -Path $logFilePath -Value "--------------------------------------------------------------------------------" -Encoding UTF8Add-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Script start"# Stop Discovery Agent serviceStop-Service -Name $serviceName -Force# Check up to 3 times if the service has stopped$maxTries = 3$try = 0$serviceStopped = $falsewhile ($try -lt $maxTries) {$status = (Get-Service -Name $serviceName).Statusif ($status -eq 'Stopped') {$serviceStopped = $truebreak}Start-Sleep -Seconds 5$try++}if (-not $serviceStopped) {Add-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - $serviceName could not be stopped!"exit 1} else {Add-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - $serviceName stopped successfully."} # Check A: Agent.cfg with CryptPW (80 characters)if (Test-Path $path_cfg) {try {$xml = [xml](Get-Content -Path $path_cfg -ErrorAction Stop)$cryptPW = $xml.SelectSingleNode('Settings/SFTPSettings/CryptPW')if ($null -ne $cryptPW -and $cryptPW.InnerText.Length -eq $CryptPW_length) {$agent_cfg = $true}} catch {$agent_cfg = $false}}# Check B: ObjectHashSettings.xml with correct ClieniaVersion presentif (Test-Path $path_ohs_xml) {try {$ohs_xml = [xml](Get-Content -Path $path_ohs_xml -ErrorAction Stop)$clieniaVersion = $ohs_xml.ObjectHashSettings.GetAttribute("ClieniaVersion")if ($clieniaVersion -eq $ohs_xml_version) {$objectHashSettings = $true}} catch {$objectHashSettings = $false}}# Check C: agent_patterns.bpat size 40-50KBif (Test-Path $path_patterns) {$fileSize = (Get-Item $path_patterns).Length$fileSizeKB = $fileSize / 1KBif ($fileSizeKB -ge 40 -and $fileSizeKB -le 50) {$agentPatterns = $true}}Write-Host $agentPatterns# Check AssetHistory.dat larger than 0KBif (Test-Path $path_history) {$historySize = (Get-Item $path_history).Lengthif ($historySize -gt 0) {$assetHistory = $true}}... # perform necessary corrections# [A] Correction Agent.cfgif($agent_cfg -eq $true) {Add-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Agent.cfg is correct."} else {Add-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Agent.cfg does not meet requirements and must be corrected."# Delete Agent.bak if presentif (Test-Path $path_bak) {Remove-Item -Path $path_bak -ForceAdd-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Agent.bak deleted"}# Delete Agent.cfg if presentif (Test-Path $path_cfg) {Remove-Item -Path $path_cfg -ForceAdd-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Agent.cfg deleted"}# Copy Clienia version of Agent.cfg to clientCopy-Item -path $path_cfg_template -Destination "C:\Program Files\Atlassian\Discovery Agent" -ForceAdd-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Template version of Agent.cfg copied to laptop."}# [B] Correction ObjectHashSettings.xmlif($objectHashSettings -eq $true) {Add-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - ObjectHashSettings.xml is correct."} else {# Delete ObjectHashSettings.xml if presentif (Test-Path $path_ohs_xml) {Remove-Item -Path $path_ohs_xml -ForceAdd-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - ObjectHashSettings.xml deleted"}# Copy Clienia version of ObjectHashSettings.xml to clientCopy-Item -path $path_ohs_xml_template -Destination "C:\Program Files\Atlassian\Discovery Agent" -ForceAdd-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Template version of ObjectHashSettings.xml copied to laptop."}# [C] Correction agent_patterns.bpatif($agentPatterns -eq $true) {Write-Host "agent_patterns.bpat is correct."Add-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - agent_patterns.bpat is correct."} else {# Delete agent_patterns.bpat if presentif (Test-Path $path_patterns) {Write-Host "agent_patterns.bpat was deleted."Remove-Item -Path $path_patterns -ForceAdd-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - agent_patterns.bpat was deleted."}# Copy Clienia version of agent_patterns.bpat to clientCopy-Item -path $path_patterns_template -Destination "C:\Program Files\Atlassian\Discovery Agent" -ForceAdd-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Template version of agent_patterns.bpat copied to laptop."Write-Host "Template version of agent_patterns.bpat copied to laptop."} # [D] Delete AssetHistory.datif ($assetHistory -eq $true) {Add-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - AssetHistory.dat is correct."} else {if (Test-Path $path_history) { Remove-Item -Path $path_history -ForceAdd-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - AssetHistory.dat was deleted."} else {Add-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - AssetHistory.dat not found."}} $allConditionsMet = $agent_cfg -and $objectHashSettings -and $agentPatterns -and $assetHistoryif ($allConditionsMet) {Add-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - No corrections were necessary. Discovery Agent installation is correct."} else {# Check scan folder and delete old files if necessaryif (Test-Path $path_scans) {$items = Get-ChildItem -Path $path_scansif ($items.Count -eq 0) {Add-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Directory $path_scans is empty."} else {Get-ChildItem -Path $path_scans -File | Remove-Item -ForceAdd-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - All old files deleted from scan folder: $items"}} else {Add-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - $path_scans does not exist!"}# Read Agent.cfg$xml = [xml](Get-Content -Path $path_cfg)# Read Agent.cfg XML nodes$Settings = $xml.SelectSingleNode('Settings') # Function to create or update XML tags in Agent.cfgfunction Set-Or-CreateElement($parent, $name, $value) {$element = $parent.SelectSingleNode($name)if ($null -eq $element) {$element = $xml.CreateElement($name)$parent.AppendChild($element) | Out-Null}$element.InnerText = $value}# Call function and create or update individual XML tags$newTimestamp = (Get-Date).AddMinutes(5).ToString("yyyy-MM-ddTHH:mm:ss.fffffffK")Set-Or-CreateElement $Settings "NextScanDate" $newTimestampSet-Or-CreateElement $Settings "SaveTimeStamp" $newTimestampSet-Or-CreateElement $Settings "UseAllNetworkInterfaces" 'true'Add-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - NextScanDate, SaveTimeStamp and UseAllNetworkInterfaces set in Agent.cfg."# Save the updated XML file$xml.Save($path_cfg)Add-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Agent.cfg saved successfully."}... # Restart Discovery Agent Service to apply changesStart-Service -Name $serviceNameAdd-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - $serviceName is being restarted."# Verification whether the XML tag <CryptPW> exists and whether the value is 80 characters longif($agent_cfg -eq $true) {Add-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - End of script"Add-Content -Path $logFilePath -Value "--------------------------------------------------------------------------------" -Encoding UTF8} else {$maxTries = 40$maxTries_interval = 30$try = 0$pw_encrypted = $false$cryptPW = $nullwhile ($try -lt $maxTries) {# Reload XML to capture changes$xml = [xml](Get-Content -Path $path_cfg)$cryptPW = $xml.SelectSingleNode('Settings/SFTPSettings/CryptPW')if ($null -ne $cryptPW -and $cryptPW.InnerText.Length -eq $CryptPW_length) {$pw_encrypted = $trueAdd-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - SFTP password was correctly encrypted and stored in Agent.cfg."Add-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - End of script"Add-Content -Path $logFilePath -Value "--------------------------------------------------------------------------------" -Encoding UTF8break}Start-Sleep -Seconds $maxTries_interval$try++}if (-not $pw_encrypted) {Add-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - SFTP password was not correctly encrypted. The check and installation must be repeated."Add-Content -Path $logFilePath -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - End of script"Add-Content -Path $logFilePath -Value "--------------------------------------------------------------------------------" -Encoding UTF8exit 1}}
Hi Chris,
I use Intune and not SCCM, but for uninstall it should be fine to do it via Config Mgr:
To install the app it should be the same as any other app but use /quiet as argument so it runs silently.
Installation Help | Uninstall deployed products with Configuration Manager | Autodesk
Hi Chris, we were able to accomplish that after many failed attempts. The biggest problem were credentials that are kept in the agent.cfg file. Had to create two steps for the SCCM installation. First step was to deploy the package using SCCM and and later run post installation script which was configuring the agent. The command "Discovery_Agent.exe -setupsftp" generates the password in encoded form and puts it into the "agent.cfg" file. There are also few other options needed in the script to be passed beforehand.
First attempt was to deploy the package with the "agent.cfg" preconfigured but it turned out it cannot be done that way, "-setupsftp" command need to be run on each endpoint after the installation.
I just reminded, in the post installation script I passed sftp location, username and password to the ftp share where scan results should be uploaded.
Hi @Rafal Binkowski ,
Thank you for your help. Our post-installation script currently stops the Agent service, exchanges the agent.cfg and the objectHashSettings.xml and then restarts the service.
(We do this vor version 3.1.4.) This seems to work for most of the clients. There were a couple of clients, where de un-install of version 1.18 did not work properly and therefore the new version couldn't be installed. -> manual work needed.
So, for version 3.2.0:
your help is very much appreciated!
best regards from Switzerland,
We did not need to run setupsftp on the client, we simply have a script that edits the content inside Agent.cfg and Agent.bak file with the correct SFTP settings, this works fine.
Hi Chris.
I really understand your pain of upgrading 1200 agents, it's not easy to automate it at the moment. Our development team is working on improvements in this area.
In the Assets Discovery 3.1.11 we added the "Update" tab in the GUI, so that you can easily check if there is newer version available.
In the Assets Discovery 3.2.0 we added a new '-update' command-line option for agents. Running an agent with this option will trigger download of the latest binary from Atlassian Marketplace, shutdown of a running agent, updating binaries/dlls and startup of a new one. This option has not been documented in the release notes, because it will work for version 3.2.0 and later, so it's not possible to use it for older agents.
We are currently working on centralized agent management via Assets Discovery GUI. It will be possible to see online/offline status of all agents, their versions as well as trigger an update for all of them. You can expect this feature in next major release, ETA Q1 2024.
I can assure you that we will review your feature request JSDSERVER-12441 and check how can we adjust agent update mechanisms to be compatible with SCCM.
Kind regards
Marek Parfianowicz
Assets Discovery team
Hi Marek, thanks for your reply and sharing details about command line enhancements. This is actually sth what would make like easier for many people as IMHO it looks like GUI was much more promoted in the past when it comes to this asset discovery tool. For smaller entities it is perfect but for bigger companies with SCCM/Intune deployments it may become problematic. Happy to hear you are moving forward with the product development. Cheers
Hi @Marek Parfianowicz ,
good to here, that Discovery Service/Collector/Agents gets some much needed love from your side.
"centralized agent management" sounds good but to be honest, that's what we have SCCM for. Big companies don't need another tool for centralized management of clients, they already have SCCM or other tools.
It would be nice, if there was a silent mode, when installing Agents:
A GUI for updating a single Agent is nice for small companies with less then 10 devices, everybody else needs command line features.
Hey Simen, I am just about to embark on this journey of deployment via Intune - are there any pointers which you followed/ found helpful?
We’re using Atlassian cloud so will have to store the cloud token in the config for each machine to report back to our instance.
@Chris interested to know how you got on with the deployment?
For installing 3.2.0, make sure your SCCM distribution points are in top-notch shape. Prepping your environment is half the battle! Then, you can create a deployment package in SCCM and craft a neat deployment script.
Remember to test it on a smaller scale first to catch any unexpected hiccups. And, oh, don't forget to document your steps; it'll make your life easier in the long run.
If you need more detailed guidance, check out the learnmesccm channel for some golden nuggets of wisdom. Happy deploying!
In case you have already done it: would you mind sharing your script?
It looks like you're new here. Sign in or register to get started.