Private/ConvertTo-HypervisorPayloadJson.ps1

function ConvertTo-HypervisorPayloadJson {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [VSphereHypervisorPayload]$Payload
    )

    function Remove-NullProperties {
        param([object]$Object)

        if ($null -eq $Object) {
            return $null
        }

        if ($Object.PSObject.Properties) {
            $hash = [ordered]@{}
            foreach ($prop in $Object.PSObject.Properties) {
                if ($null -ne $prop.Value) {
                    $hash[$prop.Name] = $prop.Value
                }
            }
            return [pscustomobject]$hash
        }

        return $Object
    }

    # Build cleaned payload structure
    $cleanedPayload = [pscustomobject][ordered]@{
        schema_version       = $Payload.schema_version
        source              = $Payload.source
        customer_environment = $Payload.customer_environment
        version             = $Payload.version
        data                = [System.Collections.Generic.List[object]]::new()
    }

    foreach ($dataItem in $Payload.data) {
        $cleanedDataItem = [ordered]@{
            host = Remove-NullProperties -Object $dataItem.host
        }

        $evtList = $dataItem.events
        $cleanedDataItem.events = [System.Collections.Generic.List[object]]::new()

        foreach ($evt in $evtList) {
            $cleanedEvt = [ordered]@{}
            $cleanedEvt.start_time = $evt.start_time
            $cleanedEvt.duration = $evt.duration

            # Clean CPU metrics
            if ($null -ne $evt.cpu) {
                $cleanedEvt.cpu = Remove-NullProperties -Object $evt.cpu
            }

            # Clean Disk metrics
            if ($null -ne $evt.disk) {
                $cleanedEvt.disk = Remove-NullProperties -Object $evt.disk
            }

            # Clean Memory metrics
            if ($null -ne $evt.memory) {
                $cleanedEvt.memory = Remove-NullProperties -Object $evt.memory
            }

            [void]$cleanedDataItem.events.Add([pscustomobject]$cleanedEvt)
        }

        [void]$cleanedPayload.data.Add([pscustomobject]$cleanedDataItem)
    }

    return ($cleanedPayload | ConvertTo-Json -Depth 20 -Compress)
}