In the enterprise business unit where you need to audit user login activity, create a Data Extension (DE) with the following specifications:
Name: AppUser_LoginAudit
External Key: AppUser_LoginAudit
| Field Name | Data Type | Length | Primary Key | Nullable | Default Value |
| UserID | Text | 100 | No | No | Not Applicable |
| UserName | Text | 255 | No | No | Not Applicable |
| LastLogin | Text | 100 | No | Yes | Not Applicable |
| AuditDate | Date | Not Applicable | No | No | Current Date |
NOTE: This will include ALL internal APP users which will not be visible in the Installed Package UI and can not be modified
(Note: LastLogin is set to a nullable Text field because if a user has never logged in, the API will not return a date value, and SOAP date strings are often easier to log as text before converting them later).
After the DE has been created, you will need to create an SSJS activity to query the AccountUser object and log the results. The script uses WSProxy to find any user whose Name contains "app user" and inserts their ID, Name, and LastSuccessfulLogin date into the Data Extension.
<script runat="server">
Platform.Load("Core", "1.1.1");
try {
var targetDEKey = "AppUser_LoginAudit";
var prox = new Script.Util.WSProxy();
// 1. Define the columns to retrieve from the SOAP object
var cols = ["ID", "Name", "LastSuccessfulLogin"];
// 2. Define the filter (Name contains 'app user')
var filter = {
Property: "Name",
SimpleOperator: "like",
Value: "app user"
};
var moreData = true;
var reqID = null;
var insertedCount = 0;
// 3. Loop through the AccountUser records
while (moreData) {
moreData = false;
// Use getNextBatch if paginating, otherwise retrieve the first batch
var res = reqID == null ? prox.retrieve("AccountUser", cols, filter) : prox.getNextBatch("AccountUser", reqID);
if (res != null && res.Status == "OK") {
// 4. Process the results and insert into the DE
for (var i = 0; i < res.Results.length; i++) {
var user = res.Results[i];
var userId = String(user.ID);
var userName = user.Name || "Unknown";
var lastLogin = user.LastSuccessfulLogin || "Never Logged In";
var insertProps = [
{ Name: "UserID", Value: userId },
{ Name: "UserName", Value: userName },
{ Name: "LastLogin", Value: lastLogin }
];
var insertResult = prox.createItem("DataExtensionObject", {
CustomerKey: targetDEKey,
Properties: insertProps
});
if (insertResult.Status == "OK") {
insertedCount++;
}
}
// 5. Check if there are more rows to fetch
if (res.HasMoreRows) {
moreData = true;
reqID = res.RequestID;
}
}
}
Write("Audit complete. Successfully logged " + insertedCount + " users to the Data Extension.");
} catch (error) {
Write("Error: " + Stringify(error));
}
</script>Run the above SSJS activity to query the AccountUser object and log the login details of any matching users within the DE AppUser_LoginAudit.
This script natively includes WSProxy's getNextBatch pagination method. Even if you have thousands of users that match your search string, the script will safely page through them in batches of 2500 until all matching users have been processed and logged.
005317493

We use three kinds of cookies on our websites: required, functional, and advertising. You can choose whether functional and advertising cookies apply. Click on the different cookie categories to find out more about each category and to change the default settings.
Privacy Statement
Required cookies are necessary for basic website functionality. Some examples include: session cookies needed to transmit the website, authentication cookies, and security cookies.
Functional cookies enhance functions, performance, and services on the website. Some examples include: cookies used to analyze site traffic, cookies used for market research, and cookies used to display advertising that is not directed to a particular individual.
Advertising cookies track activity across websites in order to understand a viewer’s interests, and direct them specific marketing. Some examples include: cookies used for remarketing, or interest-based advertising.