Providers/AD/Private/New-ADTestJSONReport.ps1
|
function New-ADTestJSONReport { [CmdletBinding()] [OutputType([void])] <# .SYNOPSIS Generates a JSON report from AD test data .DESCRIPTION Creates a structured JSON report from the provided test data, suitable for programmatic consumption and integration with other tools. .PARAMETER ReportData The report data hashtable containing all collected AD test information .PARAMETER OutputPath Path where the JSON file should be saved .EXAMPLE New-ADTestJSONReport -ReportData $data -OutputPath "C:\Reports\test.json" .NOTES Author: Jeffrey Stuhr Version: 1.0.0 Last Updated: 2025-08-03 Creates a comprehensive JSON report with all available details including: - Full object attributes for all AD objects - Group membership information - Always outputs the most detailed information available #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Colour-coded console progress is intentional; results are returned as objects.')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Private formatter; writes only the report file the caller asked for.')] [CmdletBinding()] param( [Parameter(Mandatory = $true)] [PSCustomObject]$ReportData, [Parameter(Mandatory = $true)] [string]$OutputPath ) begin { Write-Verbose "Starting JSON report generation" # Ensure output directory exists $directory = Split-Path $OutputPath -Parent if ($directory -and -not (Test-Path $directory)) { try { New-Item -Path $directory -ItemType Directory -Force | Out-Null } catch { throw "Cannot create output directory: $directory" } } } process { try { Write-TestMessage -Message "Generating JSON report: $OutputPath" -Type Info # Build structured data for JSON $jsonData = @{ metadata = @{ title = "Active Directory Test Data Report" domain = $ReportData.Domain generatedOn = $ReportData.GeneratedOn correlationId = $ReportData.CorrelationId includeDetails = $true # Always include details now includeGroupMembers = $IncludeGroupMembers.IsPresent reportVersion = "2.0" } summary = @{ organizationalUnits = $ReportData.Summary.TotalOUs users = $ReportData.Summary.TotalUsers serviceAccounts = $ReportData.Summary.TotalServiceAccounts devices = $ReportData.Summary.TotalDevices groups = $ReportData.Summary.TotalGroups groupMembers = $ReportData.Summary.TotalGroupMembers } } # Always add detailed data (this is what users expect to see) $jsonData.details = @{} # Organizational Units if ($ReportData.TestOUs.Count -gt 0) { $jsonData.details.organizationalUnits = @() foreach ($ou in $ReportData.TestOUs) { $ouData = @{ name = $ou.Name distinguishedName = $ou.DistinguishedName description = $ou.Description protectedFromAccidentalDeletion = $ou.ProtectedFromAccidentalDeletion created = if ($ou.whenCreated) { $ou.whenCreated.ToString('yyyy-MM-ddTHH:mm:ss.fffZ') } else { $null } } $jsonData.details.organizationalUnits += $ouData } } # Users if ($ReportData.TestUsers.Count -gt 0) { $jsonData.details.users = @() foreach ($user in $ReportData.TestUsers) { $userData = @{ name = $user.Name displayName = $user.DisplayName samAccountName = $user.SamAccountName userPrincipalName = $user.UserPrincipalName emailAddress = $user.EmailAddress givenName = $user.GivenName surname = $user.Surname department = $user.Department title = $user.Title manager = $user.Manager enabled = $user.Enabled description = $user.Description officePhone = $user.OfficePhone mobilePhone = $user.MobilePhone office = $user.Office streetAddress = $user.StreetAddress employeeID = $user.EmployeeID employeeType = $user.EmployeeType passwordNeverExpires = $user.PasswordNeverExpires cannotChangePassword = $user.CannotChangePassword accountExpirationDate = if ($user.AccountExpirationDate) { $user.AccountExpirationDate.ToString('yyyy-MM-ddTHH:mm:ss.fffZ') } else { $null } badLogonCount = $user.BadLogonCount distinguishedName = $user.DistinguishedName created = if ($user.whenCreated) { $user.whenCreated.ToString('yyyy-MM-ddTHH:mm:ss.fffZ') } else { $null } modified = if ($user.whenChanged) { $user.whenChanged.ToString('yyyy-MM-ddTHH:mm:ss.fffZ') } else { $null } lastLogon = if ($user.LastLogonDate) { $user.LastLogonDate.ToString('yyyy-MM-ddTHH:mm:ss.fffZ') } else { $null } passwordLastSet = if ($user.PasswordLastSet) { $user.PasswordLastSet.ToString('yyyy-MM-ddTHH:mm:ss.fffZ') } else { $null } } $jsonData.details.users += $userData } } # Service Accounts if ($ReportData.TestServiceAccounts.Count -gt 0) { $jsonData.details.serviceAccounts = @() foreach ($serviceAccount in $ReportData.TestServiceAccounts) { $serviceAccountData = @{ name = $serviceAccount.Name displayName = $serviceAccount.DisplayName samAccountName = $serviceAccount.SamAccountName userPrincipalName = $serviceAccount.UserPrincipalName description = $serviceAccount.Description manager = $serviceAccount.Manager enabled = $serviceAccount.Enabled passwordNeverExpires = $serviceAccount.PasswordNeverExpires cannotChangePassword = $serviceAccount.CannotChangePassword accountExpirationDate = if ($serviceAccount.AccountExpirationDate) { $serviceAccount.AccountExpirationDate.ToString('yyyy-MM-ddTHH:mm:ss.fffZ') } else { $null } badLogonCount = $serviceAccount.BadLogonCount servicePrincipalNames = $serviceAccount.ServicePrincipalNames distinguishedName = $serviceAccount.DistinguishedName created = if ($serviceAccount.whenCreated) { $serviceAccount.whenCreated.ToString('yyyy-MM-ddTHH:mm:ss.fffZ') } else { $null } modified = if ($serviceAccount.whenChanged) { $serviceAccount.whenChanged.ToString('yyyy-MM-ddTHH:mm:ss.fffZ') } else { $null } lastLogon = if ($serviceAccount.LastLogonDate) { $serviceAccount.LastLogonDate.ToString('yyyy-MM-ddTHH:mm:ss.fffZ') } else { $null } passwordLastSet = if ($serviceAccount.PasswordLastSet) { $serviceAccount.PasswordLastSet.ToString('yyyy-MM-ddTHH:mm:ss.fffZ') } else { $null } accountType = "ServiceAccount" } $jsonData.details.serviceAccounts += $serviceAccountData } } # Devices if ($ReportData.TestDevices.Count -gt 0) { $jsonData.details.devices = @() foreach ($device in $ReportData.TestDevices) { $deviceData = @{ name = $device.Name dnsHostName = $device.DNSHostName samAccountName = $device.SamAccountName operatingSystem = $device.OperatingSystem operatingSystemVersion = $device.OperatingSystemVersion operatingSystemServicePack = $device.OperatingSystemServicePack description = $device.Description location = $device.Location managedBy = $device.ManagedBy servicePrincipalNames = $device.ServicePrincipalNames enabled = $device.Enabled distinguishedName = $device.DistinguishedName created = if ($device.whenCreated) { $device.whenCreated.ToString('yyyy-MM-ddTHH:mm:ss.fffZ') } else { $null } modified = if ($device.whenChanged) { $device.whenChanged.ToString('yyyy-MM-ddTHH:mm:ss.fffZ') } else { $null } lastLogon = if ($device.LastLogonDate) { $device.LastLogonDate.ToString('yyyy-MM-ddTHH:mm:ss.fffZ') } else { $null } passwordLastSet = if ($device.PasswordLastSet) { $device.PasswordLastSet.ToString('yyyy-MM-ddTHH:mm:ss.fffZ') } else { $null } } $jsonData.details.devices += $deviceData } } # Groups if ($ReportData.TestGroups.Count -gt 0) { $jsonData.details.groups = @() foreach ($group in $ReportData.TestGroups) { $groupData = @{ name = $group.Name displayName = $group.DisplayName samAccountName = $group.SamAccountName description = $group.Description groupScope = $group.GroupScope groupCategory = $group.GroupCategory managedBy = $group.ManagedBy info = $group.Info notes = $group.Notes distinguishedName = $group.DistinguishedName created = if ($group.whenCreated) { $group.whenCreated.ToString('yyyy-MM-ddTHH:mm:ss.fffZ') } else { $null } modified = if ($group.whenChanged) { $group.whenChanged.ToString('yyyy-MM-ddTHH:mm:ss.fffZ') } else { $null } } # Add member information (always included) $groupData.memberCount = $group.MemberCount if ($group.Members) { $groupData.members = @() foreach ($member in $group.Members) { $memberData = @{ name = $member.Name samAccountName = $member.SamAccountName objectClass = $member.objectClass distinguishedName = $member.DistinguishedName } $groupData.members += $memberData } } $jsonData.details.groups += $groupData } } # Convert to JSON with proper formatting $jsonContent = $jsonData | ConvertTo-Json -Depth 10 # Write the JSON file $jsonContent | Out-File -FilePath $OutputPath -Encoding UTF8 Write-Host "JSON report saved to: $OutputPath" -ForegroundColor Green } catch { Write-Error "Failed to generate JSON report: $($_.Exception.Message)" -ErrorAction Stop } } end { Write-Verbose "Completed JSON report generation" } } |