AbtPS SDK 1.3
AbtPS SDK 1.3
Version 1.3
December 2023
Absolute Persistence Status Monitor User Guide
Contents
Downloading the Persistence Status Monitor 4
Verifying the activation status of Persistence 4
System requirements 4
Running AbtPS 4
Agent error codes 6
Persistence Status error codes 6
Script samples 7
Verifying the activation status of Persistence in an application installer 12
Get DLL version 12
Get Persistence Version 13
Get Persistence Status 13
Get Persistence Firmware Version 14
Firmware Awaiting Reboot 14
Count Required Reboots 15
Using the library 16
Testing the Secure Endpoint Agent using AbtPaaSTest.dll 16
COM API 17
Registering the COM API 17
Early bound usage 17
Late bound usage 18
AbtPaaSTest interface 19
Error conditions and handling 20
C DLL API 20
Logging 21
This document describes Absolute's Persistence Status Monitor, which you can use to check the activation
status of the Absolute Persistence module embedded in the firmware of a Windows device. You can also use
the tool to invoke agent calls to the Absolute Monitoring Center.
Absolute's Persistence Status Monitor includes the following components:
Name Description
AbtPS.exe Executable to check the status of Persistence and invoke agent calls to the Absolute
Monitoring Center (wrapper for AbtPersStatusReport.dll and AbtPaasTest.dll)
AbtPersStatusReport.dll Dynamic library for checking the status of Persistence when it is integrated with an
application installer
AbtPaasTest.dll Dynamic library for invoking agent calls to the Absolute Monitoring Center
System requirements
AbtPS is a 64-bit executable that supports the following Windows operating systems:
l Windows 10
l Windows 11
Running AbtPS
To run the AbtPS executable:
1. Open a Command Prompt with administrator privileges and navigate to the location where you
extracted the contents of the AbtPS_<version>.zip file.
-IsCalling Shows whether the device is in the process of calling the 0: Not calling
or Absolute Monitoring Center 1: Calling
-I Possible values are Agent is calling and Agent is not < 0 Error
calling.
-LastCallResult Gets the result of the last call. Possible values are Success 0: Last call failed
or and Failure. Calls that are in progress are also indicated. 1: Call in progress
-L 2: Last call
successful
-CallTimes Gets the next and last call times 1: Times reported
or successfully to
-T console
< 0 Error
Value Description
-1 Call was not initiated by an Administrator
-4 General failure
-4 ERRORCODE_DW_INCOMPATIBLE AbtStatus was read but it is not compatible with any known
concrete object
Script samples
The following PowerShell scripts demonstrate how you can use the AbtPS executable.
1 #!/usr/bin/env powershell
2 # Copyright (c) 2020 Absolute Software Corporation, All rights reserved.
3 # Reproduction or transmission in whole or in part, in any form or by any means,
4 # electronic, mechanical or otherwise, is prohibited without the prior written
5 # consent of the copyright owner.
6 #
7
8 Write-Host "Activating Persistence..."
9
10 # Force an rpcnet agent call
11 Write-Host "Starting an agent call..."
12 Start-Process -FilePath .\AbtPS.exe -Wait -ArgumentList "-StartCall" -WindowStyle
Hidden
13
14 # Wait for the call to complete
15 do
16 {
17 Write-Host "Sleeping 2 seconds"
18
19 Start-Sleep -s 2
20
21 $process = Start-Process -FilePath .\AbtPS.exe -ArgumentList "-IsCalling" -
PassThru -WindowStyle Hidden
1 #!/usr/bin/env powershell
2 # Copyright (c) 2020, 2022 Absolute Software Corporation, All rights reserved.
3 # Reproduction or transmission in whole or in part, in any form or by any means,
4 # electronic, mechanical or otherwise, is prohibited without the prior written
5 # consent of the copyright owner.
6 #
7 # Force execution to be as an Administrator
8 # Info on the Requires statement:
9 # https://docs.microsoft.com/en-
us/powershell/module/microsoft.powershell.core/about/about_requires?view=powershell-
5.1
10 # Requires -RunAsAdministrator
11 #
12 # Usage:
13 # InstallAndActivate.ps1 -package <path to AbsoluteWinCoreAgent.zip>
14 # If you wish to specify a temp folder where the agent package will be extracted to,
15 # specify that using the -temp parameter, like this:
16 # InstallAndActivate.ps1 -package <path to AbsoluteWinCoreAgent.zip> -temp
"C:\agent"
17 # If the temp path doesn't exist, an attempt will be made to create it.
18 #
19 # Get command line argument
20 param(
21 [Parameter(Mandatory=$true)]$package, # path to the agent package (zip) file
22 $temp = $PSScriptRoot # temp folder path where the agent package will be
unzipped
23 );
24
25 $LogFilePath = (Join-Path $PSScriptRoot "InstallAndActivate.log")
26 function Log {
27 param ([string] $message)
28
29 Write-Host $message
30
31 # Write the log file
32 if (Test-Path $LogFilePath) {
33 Add-Content -Path $LogFilePath -Value $message
34 }
35 else {
36 Set-Content -Path $LogFilePath -Value $message
37 }
38 }
39
40 Log "Installing Persistence..."
41
42
43 # Check to see if the specified agent package exists
44 if (!(Test-Path $package))
45 {
46 Log ("The agent package was not found: " + $package)
47 exit -1;
48 }
49
50 # Check temp folder. Attempt to create it if it doesn't exist.
51 if (!(Test-Path $temp))
52 {
53 New-Item $temp -ItemType Directory
54 }
55
56 Log ("Extracting " + $package + " to " + $temp)
57 Expand-Archive $package $temp -Force # force the unzip assuming the new package is
what the user wants to install
58
59 $AgentInstaller = "AbsoluteCoreAgent.msi"
60 $AgentInstallerPath = (Join-Path $temp $AgentInstaller)
61
62 # Check to see if the Agent installer file is in the current folder
63 if (!(Test-Path $AgentInstallerPath))
64 {
65 Log ($AgentInstaller + " is missing from the agent package.")
66 exit -1;
67 }
68
69 $AgentInstallerDataFile = "AbsoluteAgent.dat"
70
71 # Check to see if the Agent installer data file is in the current folder
72 if (!(Test-Path (Join-Path $temp $AgentInstallerDataFile)))
73 {
74 Log ($AgentInstallerDataFile + " is missing from the agent package.")
75 exit -1;
76 }
77
78 $AgentInstallerSignatureFile = "AbsoluteAgent.sig"
79
80 # Check to see if the Agent installer signature file is in the current folder
81 if (!(Test-Path (Join-Path $temp $AgentInstallerSignatureFile)))
82 {
83 Log ($AgentInstallerSignatureFile + " is missing from the agent package.")
84 exit -1;
85 }
86
87 $AgentInstallerLogPath = (Join-Path $temp "AbsoluteCoreAgent.log")
88
89 # Set up the arguments to msiexec.exe
90 # Run msiexec with verbose logging to help in case of errors
91 $AgentInstallerArgs = @(
92 "/i"
93 "`"$AgentInstallerPath`""
94 "/qn"
95 " /l*V"
96 "`"$AgentInstallerLogPath`""
97 )
98
99 $timestamp = Get-Date
100 Log $timestamp
101 Log ("Agent being installed by '" + $env:USERDOMAIN + "\" + $env:UserName + "'")
102
103 # Run the agent installer using msiexec and wait for it to finish
104 Log ("Starting msiexec with args: " + $AgentInstallerArgs)
105 Write-Host "This may take a while"
106 $process = (Start-Process -FilePath msiexec.exe -ArgumentList $AgentInstallerArgs -
NoNewWindow -Wait -PassThru)
107
108 # Done. Indicate success or failure in the Event Log
109 # Only do cleanup if the agent was successfully installed. In case of an error,
110 # the logs are helpful in any diagnosis of an issue.
111 if (0 -eq $process.ExitCode) {
112 Log "msiexec returned success."
113 }
114 else {
115 Log ("msiexec returned error " + $process.ExitCode)
116 Log "Quitting"
117
118 Exit -1
119 }
120
121 Log "Checking the Persistence activation status"
122
123 $process = Start-Process -FilePath .\AbtPS.exe -Wait -ArgumentList "-Status" -
PassThru -WindowStyle Hidden
124
125 if ($process.ExitCode -eq 1)
126 {
127 Log "Persistence is activated"
128 }
129 elseif ($process.ExitCode -eq 0)
130 {
131 Log "Persistence is not activated"
132 }
133 elseif ($process.ExitCode -eq -5)
134 {
135 Log "Persistence is not installed. Quitting."
136 Exit -2
137 }
138 else {
139 Log ("Exit code " + $process.ExitCode + " returned. Quitting.")
140 Exit -2
141 }
142
143 # Force an rpcnet agent call
144 Log "Starting an Agent call..."
145 Start-Process -FilePath .\AbtPS.exe -Wait -ArgumentList "-StartCall" -PassThru -
WindowStyle Hidden
146
147 # Wait for the call to complete
148 do
149 {
150 Write-Host "Sleeping 2 seconds"
151
152 Start-Sleep -s 2
153
154 $process = Start-Process -FilePath .\AbtPS.exe -ArgumentList "-IsCalling" -
PassThru -Wait -WindowStyle Hidden
155 }
156 while ($process.ExitCode -eq 1)
157
158 Log "Call is complete"
159
160 Log "Checking to see if a reboot is necessary"
161
162 $process = Start-Process -FilePath .\AbtPS.exe -Wait -ArgumentList "-
RebootsRequired:Activated" -PassThru -WindowStyle Hidden
163
164 if ($process.ExitCode -ne 0)
165 {
166 Log "Reboot is needed. Restarting the computer..."
167 Start-Sleep 2
168 Restart-Computer -Force
169 }
170 else {
171 Log "No reboot required"
172 }
173
174 Log "Checking the Persistence activation status"
175
176 $process = Start-Process -FilePath .\AbtPS.exe -Wait -ArgumentList "-Status" -
PassThru -WindowStyle Hidden
177
178 if ($process.ExitCode -eq 1)
179 {
180 Log "Persistence is activated"
181 }
182 elseif ($process.ExitCode -eq 0)
183 {
184 Log "Persistence is not activated"
185 }
186 elseif ($process.ExitCode -eq -5)
187 {
188 Log "Persistence is not installed"
189 }
190 else {
191 Log ("Exit code " + $process.ExitCode + " returned")
192 }
You can use the following libraries to query the status of Persistence on a device when you integrate an
application installer with Absolute Persistence.
l 32-bit: AbtPersStatusReport.dll
l 64-bit: AbtPersStatusReport64.dll
You can use a few different components to determine if the installation or uninstallation process has
completed, and if Absolute Persistence is in the desired state.
This section describes the methods, which are C++ functions, that are exposed by the libraries.
DWORD GetDllVersion(VOID);
int GetPersistenceVersion(VOID);
Error codes
The Get Persistence Version function may return the following error code:
l Failure code: ERRORCODE_EFI_INIT.
NOTE This function applies to Persistence 2.x and some Persistence 1.0 devices.
int GetPersistenceStatus(VOID);
0 Persistence deactivated
1 Persistence activated
Error codes
The Get Persistence Status function may return the following error codes:
l Failure codes: ERRORCODE_GENERIC, ERRORCODE_EFI_INIT, ERRORCODE_READ_ABTSTATUS,
ERRORCODE_FW_INCOMPATIBLE, and ERRORCODE_NO_PERSISTENCE.
NOTE If a device does not support either version of Persistence, ERRORCODE_GENERIC is returned.
NOTE If Persistence 1 is detected, version 1.1.0.0 is always shown. This API is not able to detect Persistence
1 firmware information.
0 No Persistence detected
1 Persistence 1 detected
ProductGeneration Pointer to an integer that receives the production generation of the Persistence 2.x firmware
1: Persistence 1
2: Persistence 2.x
MajorVersion Pointer to an integer that receives the major version of the Persistence 2.x firmware
MinorVersion Pointer to an integer that receives the minor version of the Persistence 2.x firmware
BuildNumber Pointer to an integer that receives the build number of the Persistence 2.x firmware
NOTE This function applies to Persistence 2.x and some Persistence 1 devices.
int IsFirmwareAwaitingReboot(VOID);
1 Reboot is required
Error codes
The Firmware Awaiting Reboot function may return the following error codes:
l Failure codes: ERRORCODE_GENERIC, ERRORCODE_EFI_INIT, and ERRORCODE_NO_
PERSISTENCE.
l Any error code that GetPersistenceVersion returns.
Return
Description
value
<0 Operation failed
0 No reboot is required (the device is in the same state as the expected state)
1 One reboot is required (the AUTHKEY_READY is set and the device is in a state that is different from the
expected state)
2 Two reboots are required (the AUTHKEY_READY is not set and the device is in a state that is different
from the expected state)
expectedState Description
0 Expectation that firmware is ultimately deactivated
Error codes
The Count Required Reboots function may return the following error codes:
Static library
The library produces .lib and .dll files that can be used to statically link the library to a C/C++ project and
consume its exposed functions.
Dynamic library
The following is an example based on Python 2.7 that can load and execute the library.
1 #
2 # This sample script is provided as an example of how to use the provided APIs in
Python
3 #
4
5 import sys
6 import ctypes
7
8 # Confirm if the parameter is provided.
9 if len (sys.argv) != 2:
10 print ('Please provide path to the library to run test.')
11 sys.exit()
12
13 # Load library from the provided path.
14 libPath = str(sys.argv[1])
15 print ('Loading library at:', libPath)
16 dll = ctypes.CDLL(libPath)
17
18 # Invoke library methods:
19 print ('--------------------------')
20 print ('DLL Version:' + str(dll.GetDllVersion()))
21 print ('Persistence Version:' + str(dll.GetPersistenceVersion()))
22 print ('Persistence Status:' + str(dll.GetPersistenceStatus()))
23 print ('Firmware Awaiting Reboot:' + {True:'Yes', False:'No'}
[dll.IsFirmwareAwaitingReboot()==1])
24 print ('Reboot needed to be deactivated:' + str(dll.CountRequiredReboots(0)))
25 print ('Reboot needed to be activated:' + str(dll.CountRequiredReboots(1)))
26
27 # Dispose the object to release library.
28 del dll
29
COM API
The COM API can be used by early-binding environments, such as C# programs, with a reference. Early
binding infers that the programming environment interrogates the capabilities of the component at design
time. The COM API can also be used by late binding environments such as PowerShell or Python, where the
methods and properties are discovered on-the-fly at runtime.
Component Registration
regsvr32 -i AbtPaaSTest.dll
IsAgentCalling
if (abtPaaSTest.IsAgentCalling)
Console.WriteLine("Agent is calling");
else
Console.WriteLine("Agent is not calling");
StartAgentCall
abtPaaSTest.StartAgentCall();
C++
In C++ using ATL:
IsAgentCalling
CComPtr<IAbsolutePaaSTest> pAbtPaaSTest;
pAbtPaaSTest.CoCreateInstance(CLSID_AbsolutePaaSTest);
StartAgentCall
CComPtr<IAbsolutePaaSTest> pAbtPaaSTest;
pAbtPaaSTest.CoCreateInstance(CLSID_AbsolutePaaSTest);
pAbtPaaSTest->StartAgentCall();
PowerShell
In an elevated 64-bit PowerShell console, use the following code:
IsAgentCalling
StartAgentCall
$AbtPaaSTest.StartAgentCall()
Python
In an elevated 64-bit Python environment, use the following code:
IsAgentCalling
if abtPaaSTest.IsAgentCalling:
print("Agent is calling")
else:
print("Agent is not calling")
StartAgentCall
abtPaaSTest.StartAgentCall()
AbtPaaSTest interface
Methods
StartAgentCall(): starts an agent call and returns Success or Failure
Properties
IsAgentCalling: checks if an agent call is in progress and returns True or False
GetESN: returns the device's Absolute Identifier (ESN)
C DLL API
Using the C DLL API, the AbtPaaSTest.dll exposes three functions: StartAgentCall, IsAgentCalling and
GetESN.
StartAgentCall
The StartAgentCall function starts an agent call and returns one of the following values:
IsAgentCalling
The IsAgentCalling function checks if an agent is in progress and returns one of the following values:
GetESN
The GetESN function returns the device's Absolute Identifier (ESN). If the identifier ends with "0000", the
Secure Endpoint Agent has not yet called in to the Absolute Monitoring Center to receive its unique
Absolute Identifier.
The following parameters are supported:
l LPWSTR szESN: buffer to wchar_t array where the ESN will be placed
l DWORD szESNSize: size of the szESN buffer, expressed as a character count
NOTE The GetESN function supports the Unicode character set only.
Logging
The AbtPaaSTest component logs information and error messages in the Windows event log. You can view
entries from AbtPaaSTest in the application log.
All API calls are logged. If any errors occur, they are logged as well.