Public/Write-InfluxUDP.ps1

Function Write-InfluxUDP {
    <#
        .SYNOPSIS
            Send metrics to the Influx UDP listener (UDP must be enabled in influxdb.conf) for writing to Influx.

        .DESCRIPTION
            Use to write data in to an Influx database via UDP by providing a hashtable of tags and values.

        .PARAMETER InputObject
            A metric object (generated by one of the Get-*Metric cmdlets from this module) which can be provided as pipeline input.

        .PARAMETER Measure
            The name of the measure to be updated or created.

        .PARAMETER Tags
            A hashtable of tag names and values.

        .PARAMETER Metrics
            A hashtable of metric names and values.

        .PARAMETER IP
            IP address for InfluxDB UDP listener.
        
        .PARAMETER ExcludeEmptyMetric
            Switch: Use to exclude null or empty metric values from being sent. Useful where a metric is initially created as an integer but then
            an empty or null instance of that metric would attempt to be sent as an empty string, resulting in a datatype conflict.
    
        .PARAMETER Port
            Port for InfluxDB UDP listener.

        .EXAMPLE
            Write-InfluxUDP -Measure WebServer -Tags @{Server='Host01'} -Metrics @{CPU=100; Memory=50} -IP 1.2.3.4 -Port 8089
            
            Description
            -----------
            This command will submit the provided tag and metric data for a measure called 'WebServer' via the endpoint 'udp://1.2.3.4:8089'
    #>
  
    [cmdletbinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    param(
        [Parameter(ParameterSetName = 'MetricObject', ValueFromPipeline = $True, Position = 0)]
        [PSTypeName('Metric')]
        $InputObject,
        
        [Parameter(ParameterSetName = 'Measure', Mandatory = $true, Position = 0)]
        [string]
        $Measure,

        [Parameter(ParameterSetName = 'Measure')]
        [hashtable]
        $Tags,
        
        [Parameter(ParameterSetName = 'Measure', Mandatory = $true)]
        [hashtable]
        $Metrics,

        [Parameter(ParameterSetName = 'Measure')]
        [datetime]
        $TimeStamp,
        
        [ipaddress]
        $IP = '127.0.0.1',
  
        [int]
        $Port = 8089,

        [switch]
        $ExcludeEmptyMetric
    )
    Process {
        if ($InputObject) {
            $Measure = $InputObject.Measure
            $Metrics = $InputObject.Metrics
            if ($InputObject.Tags) { $Tags = $InputObject.Tags }
            if ($InputObject.TimeStamp) { $TimeStamp = $InputObject.TimeStamp }
        }
    
        if ($TimeStamp) {
            $timeStampNanoSecs = $Timestamp | ConvertTo-UnixTimeNanosecond
        }
        else {
            $null = $timeStampNanoSecs
        }
        
        if ($Tags) {
            $TagData = foreach ($Tag in $Tags.Keys) {
                "$($Tag | Out-InfluxEscapeString)=$($Tags[$Tag] | Out-InfluxEscapeString)"
            }
            $TagData = $TagData -Join ','
            $TagData = ",$TagData"
        }
    
        $Body = foreach ($Metric in $Metrics.Keys) {
        
            if ($ExcludeEmptyMetric -and [string]::IsNullOrEmpty($Metrics[$Metric])) {
                Write-Verbose "$Metric skipped as -ExcludeEmptyMetric was specified and the value is null or empty."
            }
            Else {
                $MetricValue = if ($Metrics[$Metric] -isnot [ValueType]) { 
                    '"' + $Metrics[$Metric] + '"'
                }
                else {
                    $Metrics[$Metric] | Out-InfluxEscapeString
                }
        
                "$($Measure | Out-InfluxEscapeString)$TagData $($Metric | Out-InfluxEscapeString)=$MetricValue $timeStampNanoSecs"
            }
        }
    
        if ($Body) {
            $Body = $Body -Join "`n"
            
            if ($PSCmdlet.ShouldProcess("$($IP):$Port", "$Body")) {
                $Body | Invoke-UDPSendMethod -IP $IP -Port $Port
            }
        }
    }
}