Disclaimer: This issue was identified and written by Claude Code (model: claude-opus-4-6-1m) during an automated code review, and has had a cursory review by a human before submission.
Summary
In the Managed Identities report detail section, .ToString() is called on StartDateTime and EndDateTime properties without a null check. Microsoft Graph API documentation confirms these properties can be null (e.g., credentials with no expiration). When null, .ToString() throws a NullReferenceException (or produces unexpected output depending on PowerShell version and strict mode).
Affected file
modules/check_ManagedIdentities.psm1
Evidence
Report detail rendering (lines 891-899)
# Lines 891-899
if ($($item.AppCredentialsDetails | Measure-Object).count -ge 1) {
$ReportingCredentials = foreach ($object in $($item.AppCredentialsDetails)) {
[pscustomobject]@{
"Type" = $($object.Type)
"DisplayName" = $($object.DisplayName)
"StartDateTime" = $($object.StartDateTime.ToString()) # <-- null risk
"EndDateTime" = $($object.EndDateTime.ToString()) # <-- null risk
}
}
Where the credential data originates (lines 430-445)
# Lines 430-445
$AppCredentialsSecrets = foreach ($creds in $item.PasswordCredentials) {
[pscustomobject]@{
Type = "Secret"
DisplayName = $creds.DisplayName
EndDateTime = $creds.EndDateTime # Directly from API — can be null
StartDateTime = $creds.StartDateTime # Directly from API — can be null
}
}
$AppCredentialsCertificates = foreach ($creds in $item.KeyCredentials) {
[pscustomobject]@{
Type = "Certificate"
DisplayName = $creds.DisplayName
EndDateTime = $creds.EndDateTime # Directly from API — can be null
StartDateTime = $creds.StartDateTime # Directly from API — can be null
}
}
The EndDateTime and StartDateTime values come directly from the Microsoft Graph API PasswordCredentials and KeyCredentials collections. The Graph API can return null for these fields (e.g., a credential with no expiration date has endDateTime: null).
Comparison with Enterprise Apps module
check_EnterpriseApps.psm1 handles the same scenario differently — it processes EndDateTime inside a null check (if ($null -ne $creds.EndDateTime)) before calling date arithmetic.
Impact
When a managed identity has a credential with a null StartDateTime or EndDateTime, the TXT report generation for that identity's detail section will either:
- Throw a runtime error (in strict mode or certain PowerShell versions)
- Output an empty or misleading string
This only affects the detail section of identities that have credentials — most managed identities do not have manually added credentials, so this is a low-frequency issue.
Suggested fix
"StartDateTime" = if ($null -ne $object.StartDateTime) { $object.StartDateTime.ToString() } else { "-" }
"EndDateTime" = if ($null -ne $object.EndDateTime) { $object.EndDateTime.ToString() } else { "-" }
Version
V20260316
Summary
In the Managed Identities report detail section,
.ToString()is called onStartDateTimeandEndDateTimeproperties without a null check. Microsoft Graph API documentation confirms these properties can be null (e.g., credentials with no expiration). When null,.ToString()throws aNullReferenceException(or produces unexpected output depending on PowerShell version and strict mode).Affected file
modules/check_ManagedIdentities.psm1Evidence
Report detail rendering (lines 891-899)
Where the credential data originates (lines 430-445)
The
EndDateTimeandStartDateTimevalues come directly from the Microsoft Graph APIPasswordCredentialsandKeyCredentialscollections. The Graph API can return null for these fields (e.g., a credential with no expiration date hasendDateTime: null).Comparison with Enterprise Apps module
check_EnterpriseApps.psm1handles the same scenario differently — it processes EndDateTime inside a null check (if ($null -ne $creds.EndDateTime)) before calling date arithmetic.Impact
When a managed identity has a credential with a null
StartDateTimeorEndDateTime, the TXT report generation for that identity's detail section will either:This only affects the detail section of identities that have credentials — most managed identities do not have manually added credentials, so this is a low-frequency issue.
Suggested fix
Version
V20260316