Line numbers refer to Datto-RMM/scripts/InstallHuntress.dattormm.comstore.ps1 at main (1089 lines).
main masks the account key for logging at line 1037, before validation is called at line 1047:
# Hide most of the account key in the logs, keeping the front and tail end for troubleshooting
if ($AccountKey -ne "__Account_Key__") {
$masked = $AccountKey.Substring(0,4) + "************************" + $AccountKey.SubString(28,4)
LogMessage "AccountKey: '$masked'"
} else {
LogMessage "WARNING: Account key not found! Software install cannot occur without a valid account key!"
}
LogMessage "OrganizationKey: '$OrganizationKey'"
...
# check that all the parameters that were passed are valid
Test-Parameters
SubString(28,4) assumes a 32-character key. Any key shorter than 32 characters throws ArgumentOutOfRangeException at this line — which is exactly the truncated copy/paste case that Test-Parameters was written to catch:
} elseif ($AccountKey.length -ne 32) {
$err = "Invalid AccountKey specified (incorrect length)! Suggest double checking the key was copy/pasted in its entirety"
Because the throw happens first, that message (line 203) is unreachable for a short key. The exception instead propagates to the script-level catch, which logs the raw .NET exception text and calls copyLogAndExit (exit code 0). The operator gets an opaque index/length error rather than the actionable one the script already contains, and the RMM job reports success.
Fix: move the Test-Parameters call above the masking block, or length-guard the masking — e.g. only build $masked when $AccountKey.length -eq 32 and otherwise log a generic redaction.
Line numbers refer to
Datto-RMM/scripts/InstallHuntress.dattormm.comstore.ps1atmain(1089 lines).mainmasks the account key for logging at line 1037, before validation is called at line 1047:SubString(28,4)assumes a 32-character key. Any key shorter than 32 characters throwsArgumentOutOfRangeExceptionat this line — which is exactly the truncated copy/paste case thatTest-Parameterswas written to catch:Because the throw happens first, that message (line 203) is unreachable for a short key. The exception instead propagates to the script-level
catch, which logs the raw .NET exception text and callscopyLogAndExit(exit code 0). The operator gets an opaque index/length error rather than the actionable one the script already contains, and the RMM job reports success.Fix: move the
Test-Parameterscall above the masking block, or length-guard the masking — e.g. only build$maskedwhen$AccountKey.length -eq 32and otherwise log a generic redaction.