CloudflareApi.psm1

#Region '.\Enum\DnsTypes.ps1' 0
enum DnsTypes
{
    A
    # AAAA
    CNAME
    # HTTPS
    TXT
    SRV
    # LOC
    MX
    # NS
    # CERT
    # DNSKEY
    # DS
    # NAPTR
    # SMIMEA
    # SSHFP
    # SVCB
    # TLSA
    # URI
}
#EndRegion '.\Enum\DnsTypes.ps1' 22
#Region '.\Classes\CloudFlareRecord.ps1' 0
class CloudFlareRecord
{
    [string]ToJson()
    {
        Return ($this.ToBody() | ConvertTo-Json -Depth 100 -Compress)
    }

    [object]GetPropertyNames()
    {
        $properties = (($this.psobject.Properties).Name)
        Return $properties
    }
}
#EndRegion '.\Classes\CloudFlareRecord.ps1' 14
#Region '.\Classes\CloudflareRecordA.ps1' 0
class CloudflareRecordA : CloudFlareRecord
{
    # Properties
    [string]$Name
    [string]$Content
    [bool]$Proxied
    [int]$TTL

    # Methods
    CloudFlareRecordA ([string]$Name, [string]$Content, [bool]$Proxied, [int]$TTL)
    {
        $this.Name = $Name
        $this.Content = $Content
        $this.proxied = if ($Proxied) { $Proxied } else { $false }
        $this.ttl = if ($ttl) { $ttl } else { 1 }
    }

    CloudFlareRecordA ()
    {
        $this.Name
        $this.Content
        $this.proxied
        $this.ttl = 1
    }

    [Object]ToBody()
    {

        $objectData = [PSCustomObject][ordered]@{
            type    = "A"
            name    = $this.name
            content = $this.Content
            proxied = $this.Proxied
            ttl     = $this.TTL
        }
        return $objectData
    }
}
#EndRegion '.\Classes\CloudflareRecordA.ps1' 39
#Region '.\Classes\CloudflareRecordCNAME.ps1' 0
class CloudflareRecordCNAME : CloudFlareRecord
{
    # Properties
    [string]$Name
    [string]$Content
    [bool]$Proxied
    [int]$TTL

    # Methods
    CloudFlareRecordCNAME ([string]$Name, [string]$Content, [bool]$Proxied, [int]$TTL)
    {
        $this.Name = $Name
        $this.Content = $Content
        $this.proxied = if ($Proxied) { $Proxied } else { $false }
        $this.ttl = if ($ttl) { $ttl } else { 1 }
    }

    CloudFlareRecordCNAME ()
    {
        $this.Name
        $this.Content
        $this.proxied
        $this.ttl = 1
    }

    [Object]ToBody()
    {

        $objectData = [PSCustomObject][ordered]@{
            type    = "CNAME"
            name    = $this.name
            content = $this.Content
            proxied = $this.Proxied
            ttl     = $this.TTL
        }
        return $objectData
    }
}
#EndRegion '.\Classes\CloudflareRecordCNAME.ps1' 39
#Region '.\Classes\CloudflareRecordMX.ps1' 0
class CloudflareRecordMX : CloudFlareRecord
{
    # Properties
    [string]$Name
    [string]$Content
    [int]$Priority
    [int]$TTL

    # Methods
    CloudFlareRecordMX ([string]$Name, [string]$Content, [int]$Priority, [int]$TTL)
    {
        $this.Name = $Name
        $this.Content = $Content
        $this.Priority = $Priority
        $this.TTL = if ($ttl) { $ttl } else { 1 }
    }
    CloudFlareRecordMX ()
    {
        $this.Name
        $this.Content
        $this.Priority
        $this.TTL = 1
    }

    [Object]ToBody()
    {

        $objectData = [PSCustomObject][ordered]@{
            type     = "MX"
            name     = $this.name
            content  = $this.Content
            priority = $this.priority
            ttl      = $this.TTL
        }
        return $objectData
    }
}
#EndRegion '.\Classes\CloudflareRecordMX.ps1' 38
#Region '.\Classes\CloudFlareRecordSRV.ps1' 0
class CloudFlareRecordSRV : CloudFlareRecord
{
    # Properties
    [string]$Name
    [string]$Service
    [string]$Proto
    [int]$Priority
    [int]$Weight
    [int]$Port
    [string]$Target
    [int]$TTL

    # Methods
    CloudFlareRecordSRV ([string]$Name, [string]$Service, [string]$Proto, [int]$Priority, [int]$Weight, [int]$Port, [string]$Target, [int]$TTL)
    {
        $this.Name = $Name
        $this.Service = $Service
        $this.Proto = $Proto
        $this.Priority = $Priority
        $this.Weight = $Weight
        $this.Port = $Port
        $this.Target = $Target
        $this.TTL = if ($ttl) { $ttl } else { 1 }
    }

    CloudFlareRecordSRV ()
    {
        $this.Name
        $this.Service
        $this.Proto
        $this.Priority
        $this.Weight
        $this.Port
        $this.Target
        $this.TTL = 1
    }

    # Methods
    # CloudFlareRecordSRV ([object[]]$properties)
    # {
    # $this.Name = $Name
    # $this.Service = $Service
    # $this.Proto = $Proto
    # $this.Priority = $Priority
    # $this.Weight = $Weight
    # $this.Port = $Port
    # $this.Target = $Target
    # $this.TTL = if ($ttl) { $ttl } else { 1 }
    # }

    [Object]ToBody()
    {

        $objectData = [PSCustomObject][ordered]@{
            type = 'SRV'
            data = [PSCustomObject][ordered]@{
                "service"  = $this.Service
                "proto"    = $this.proto
                "name"     = $this.name
                "priority" = $this.priority
                "weight"   = $this.weight
                "port"     = $this.port
                "target"   = $this.target
            }
            ttl  = $this.TTL
        }
        return $objectData
    }

    <#
    [void] Fill (
        $Object
    )
    {
        $this.Name = $Object.Name
        $this.Service = $Object.Service
        $this.Proto = $Object.Proto
        $this.Priority = $Object.Priority
        $this.Weight = $Object.Weight
        $this.Port = $Object.Port
        $this.Target = $Object.Target
        $this.TTL = $Object.Target
    }
 
    [void] Fill (
        [string]$Name,
        [string]$Service,
        [string]$Proto,
        [int]$Priority,
        [int]$Weight,
        [int]$Port,
        [string]$Target,
        [string]$TTL
    )
    {
        $this.Name = $Name
        $this.Service = $Service
        $this.Proto = $Proto
        $this.Priority = $Priority
        $this.Weight = $Weight
        $this.Port = $Port
        $this.Target = $Target
        $this.TTL = $TTL
    }
    #>

}
#EndRegion '.\Classes\CloudFlareRecordSRV.ps1' 107
#Region '.\Classes\CloudflareRecordTXT.ps1' 0
class CloudflareRecordTXT : CloudFlareRecord
{
    # Properties
    [string]$Name
    [string]$Content
    [int]$TTL

    # Methods
    CloudFlareRecordTXT ([string]$Name, [string]$Content, [int]$TTL)
    {
        $this.Name = $Name
        $this.Content = $Content
        $this.ttl = if ($ttl) { $ttl } else { 1 }
    }

    CloudFlareRecordTXT ()
    {
        $this.Name
        $this.Content
        $this.ttl = 1
    }

    [Object]ToBody()
    {

        $objectData = [PSCustomObject][ordered]@{
            type    = "TXT"
            name    = $this.name
            content = $this.Content
            ttl     = $this.TTL
        }
        return $objectData
    }
}
#EndRegion '.\Classes\CloudflareRecordTXT.ps1' 35
#Region '.\Private\ConvertFrom-Base64.ps1' 0
function ConvertFrom-Base64
{
    [CmdletBinding()]
    param (
        [Parameter(ValueFromPipeline)]
        [string]
        $string,
        [switch]$asBytes
    )

    process
    {
        if ($asBytes)
        {
            return ([byte[]][System.Convert]::FromBase64String($string))
        }
        else
        {
            return [string](([System.Convert]::FromBase64String($string) | % { [char]$_ }) -join '')
        }
    }

}
#EndRegion '.\Private\ConvertFrom-Base64.ps1' 24
#Region '.\Private\ConvertTo-Base64.ps1' 0
function ConvertTo-Base64
{
    [CmdletBinding()]
    param (
        [Parameter(ValueFromPipeline)]
        [string]
        $string
    )

    process
    {
        [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($string))
    }
}
#EndRegion '.\Private\ConvertTo-Base64.ps1' 15
#Region '.\Public\Get-CloudflareDnsZone.ps1' 0
function Get-CloudflareDnsZone()
{
    [CmdletBinding()]
    Param (
        [Parameter(Position = 0)]
        $All,
        $Zone
    )
    begin
    {
        if (!$cfApiToken) { Throw "No token. Use the 'Set-CloudflareApiToken' command to add the Token." }
        else
        {
            $token = ($cfApiToken | ConvertFrom-Base64)
        }
    }
    process
    {
        $All = $true
        $headers = @{
            'Authorization' = "Bearer $token"
        }
        $baseUri = "https://api.cloudflare.com/client/v4/zones"
        if ($Zone)
        {
            $cfUriGetZones = $baseUri + "?name=$zone"
            $zoneInfo = irm -Uri $cfUriGetZones -Headers $headers -ContentType 'application/json'
            $zoneInfo.result
        }
        else
        {
            $zoneInfo = irm -Uri $baseUri -Headers $headers -ContentType 'application/json'
            $zoneInfo.result
            Write-Host -f Yellow "FEATURE not implemented"
        }
    }
}
#EndRegion '.\Public\Get-CloudflareDnsZone.ps1' 38
#Region '.\Public\Get-CloudflareDnsZoneRecord.ps1' 0
function Get-CloudflareDnsZoneRecord()
{
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [string[]]
        $Zone
    )
    begin
    {
        if (!$cfApiToken) { Throw "No token. Use the 'Set-CloudflareApiToken' command to add the Token." }
        else
        {
            $token = ($cfApiToken | ConvertFrom-Base64)
        }
    }
    process
    {
        $headers = @{
            'Authorization' = "Bearer $token"
        }
        $zoneId =
        if ($PSCmdlet.MyInvocation.ExpectingInput -eq $true)
        {
            $zone
        }
        else
        {
            (Get-CloudflareDnsZone -Zone $Zone).id
        }
        $cfUriGetZones = "https://api.cloudflare.com/client/v4/zones/$($zoneId)/dns_records"
        $zoneRecords = irm -Uri $cfUriGetZones -Headers $headers -ContentType 'application/json'
        $zoneRecords.result
    }
}
#EndRegion '.\Public\Get-CloudflareDnsZoneRecord.ps1' 37
#Region '.\Public\Invoke-CloudflareDnsZoneCommand.ps1' 0
function Invoke-CloudflareDnsZoneCommand
{
    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'HIGH')]
    param (
        [Parameter()]
        [uri]$Uri,
        [Parameter()]
        [string]$Body,
        [Parameter()]
        [ValidateSet("GET", "DELETE", "PATCH", "POST", "PUT")]
        $Method = "GET"
    )

    try
    {
        if ($PSCmdlet.ShouldProcess("$uri", "$Method"))
        {
            if ($Method -in "PATCH", "DELETE", "PUT")
            {
                $rawContent = iwr -Uri "https://api.cloudflare.com/client/v4/zones/6d7c62048f94a6477d8c8b7d9cb1e6d4/dns_records" -Headers $headers -ContentType 'application/json' -Method $Method -Body $Body -ea 1
                $encodedResult = [System.Text.Encoding]::UTF8.GetString($rawContent.RawContentStream.ToArray()) | ConvertFrom-Json -ea 1
                $encodedResult.result
            }
            else
            {
                $rawContent = iwr -Uri "https://api.cloudflare.com/client/v4/zones/6d7c62048f94a6477d8c8b7d9cb1e6d4/dns_records" -Headers $headers -ContentType 'application/json' -Method $Method -Body $Body -ea 1
                $encodedResult = [System.Text.Encoding]::UTF8.GetString($rawContent.RawContentStream.ToArray()) | ConvertFrom-Json -ea 1
                $encodedResult.result
            }
        }

    }
    catch
    {
        $err = $_
        $reader = New-Object System.IO.StreamReader($err.Exception.Response.GetResponseStream())
        $reader.BaseStream.Position = 0
        $reader.DiscardBufferedData()

        $expandedErrorMsg = ($reader.ReadToEnd() | ConvertFrom-Json)

        if ($expandedErrorMsg.errors.error_chain)
        {
            $errorOutput = ($expandedErrorMsg.errors.error_chain | % { "[{0}] {1}" -f $_.code, $_.message }) -join "`n"
            Throw $errorOutput
        }
        else
        {
            Throw $expandedErrorMsg.errors.message
        }
    }
}
#EndRegion '.\Public\Invoke-CloudflareDnsZoneCommand.ps1' 53
#Region '.\Public\New-CloudflareDnsRecordObject.ps1' 0
function New-CloudflareDnsRecordObject()
{
    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Low',DefaultParameterSetName = 'Blank')]
    Param (
        [Parameter(Mandatory = $true, Position = 1, HelpMessage = "The DNS pointer's RR type.")]
        [DNSTypes]$RecordType
    )

    DynamicParam
    {
        $props = Invoke-Command -ScriptBlock ([Scriptblock]::Create(("[CloudflareRecord{0}].GetProperties()" -f $RecordType)))

        $dynParams = @()
        foreach ($prop in $props)
        {
            $dynParams += [pscustomobject]@{Type = $recordType ; ParameterName = $prop.Name; DataType = $prop.PropertyType ; ValidateSet = $null }
        }

        $attributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary

        foreach ($param in $dynParams)
        {
            #ParameterAttribute Objects
            $Attr = New-Object System.Management.Automation.ParameterAttribute
            $Attr.Mandatory = $true
            $Attr.ParameterSetName = $RecordType
            # $Attr.HelpMessage = $param.HelpMessage
            #Attributecollection object for the attributes we just created.
            $attributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
            #add our custom attributes
            $attributeCollection.Add($Attr)
            if ($param.ValidateSet)
            {
                # Generate and set the ValidateSet
                $arrSet = $param.ValidateSet
                $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet)
                # Add the ValidateSet to the attributes collection
                $AttributeCollection.Add($ValidateSetAttribute)
            }
            #add our parameter specifying the attribute collection
            $definedParam = New-Object System.Management.Automation.RuntimeDefinedParameter($param.ParameterName, $param.DataType, $attributeCollection)
            #$pwParam = New-Object System.Management.Automation.RuntimeDefinedParameter('password', [string], $attributeCollection)
            #expose the name of our parameter
            # $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
            $paramDictionary.Add($param.ParameterName, $definedParam)
            #$paramDictionary.Add('password', $pwParam)
        }
        return $paramDictionary
    }

    process
    {
        if ($pscmdlet.ParameterSetName -eq 'Blank')
        {
            $Object = Invoke-Command -ScriptBlock ([Scriptblock]::Create(("[CloudflareRecord{0}]::New()" -f $RecordType)))
            Return $Object
        }
        else
        {
            $Object = Invoke-Command -ScriptBlock ([Scriptblock]::Create(("[CloudflareRecord{0}]::New()" -f $RecordType)))
            $Object.GetPropertyNames() | % { $Object.$_ = $PSBoundParameters.$_ }

            Return $Object
        }
    }
}
#EndRegion '.\Public\New-CloudflareDnsRecordObject.ps1' 68
#Region '.\Public\New-CloudflareDnsZoneRecord.ps1' 0
<#
.SYNOPSIS
    Add Cloudflare DNS records to a specified zone.
.DESCRIPTION
    Add Cloudflare DNS records to a specified zone.
.EXAMPLE
    C:\> New-CloudflareDnsZoneRecord -Zone "zonename.com" -Type SRV -Name testSrv -Service _service -Proto _tcp -Priority 12 -Weight 120 -Port 1231 -Target vg.no -TTL 3600
    Adds a new SRV record for to target "1.2.3.4" with TTL set to 1 hour (3600 seconds)
.EXAMPLE
    C:\> $obj = [CloudflareRecordA]::new('test19','1.2.3.4',$false,1)
    C:\> New-CloudflareDnsZoneRecord -Zone "zonename.com" -RecordObject $obj
    Adds a new A record for subdomain "test19" to target "1.2.3.4" with no proxy and TTL set to Auto
.INPUTS
    Inputs (if any)
.OUTPUTS
    Output (if any)
.NOTES
    General notes
#>

function New-CloudflareDnsZoneRecord()
{
    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Low')]
    Param (
        [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName, Position = 1)]
        [Alias('id')]
        [string[]]
        $Zone,
        [Parameter(ParameterSetName = "ManualInput", Mandatory = $true, Position = 2, HelpMessage = "The DNS pointer's RR type. Must be one of: A AAAA CNAME ANAME TLSA MX SRV DS CAA NS TXT.")]
        [DNSTypes]$Type,
        [Parameter(ParameterSetName = "ObjectInput", Mandatory = $true, Position = 2, HelpMessage = "Record object with a CloudflareRecord type")]
        [CloudflareRecord]$RecordObject
        # [ValidateSet('A', 'AAAA', 'CNAME', 'ANAME', 'TLSA', 'MX', 'SRV', 'DS', 'CAA', 'NS', 'TXT')]$Type,
        # [Parameter(Mandatory, Position = 2)]
        # [String]
        # $Name,
        # [Parameter(Mandatory = $true, Position = 3, HelpMessage = "Value / data. Valid values depend on the pointer's RR type.")]
        # $Content,
        # [Parameter(Mandatory = $False, Position = 4, HelpMessage = "TTL in seconds. 1 for AUTO")]
        # $TTL = 1,
        # [Parameter()]
        # [bool]
        # $Proxied
    )

    DynamicParam
    {
        # $dynParams = @()
        # $dynParams += [pscustomobject]@{Type = "SRV" ; ParameterName = 'Priority'; DataType = [int] ; ValidateSet = $null ; HelpMessage = 'Required for MX and SRV pointers. Preference/Priority for the pointer.' }
        # $dynParams += [pscustomobject]@{Type = "SRV" ; ParameterName = 'Weight'; DataType = [int] ; ValidateSet = $null ; HelpMessage = 'Required for SRV pointers. A number value that indicates the weight of the pointer.' }
        # $dynParams += [pscustomobject]@{Type = "SRV" ; ParameterName = 'Port'; DataType = [int] ; ValidateSet = $null ; HelpMessage = 'Required for SRV pointers. A port number for the SRV pointer.' }
        # $dynParams += [pscustomobject]@{Type = "SRV" ; ParameterName = 'Service'; DataType = [string] ; ValidateSet = $null ; HelpMessage = 'Required for SRV pointers. A port number for the SRV pointer.' }
        # $dynParams += [pscustomobject]@{Type = "SRV" ; ParameterName = 'Proto'; DataType = [string] ; ValidateSet = $null ; HelpMessage = 'Required for SRV pointers. A port number for the SRV pointer.' }
        # $dynParams += [pscustomobject]@{Type = "SRV" ; ParameterName = 'Target'; DataType = [string] ; ValidateSet = $null ; HelpMessage = 'Required for SRV pointers. A port number for the SRV pointer.' }
        # $dynParams += [pscustomobject]@{Type = "TLSA" ; ParameterName = 'Usage'; DataType = [int] ; ValidateSet = 1, 2, 3 ; HelpMessage = 'Required for TLSA pointers. TLSA usage. Numeric value, 1 , 2 or 3.' }
        # $dynParams += [pscustomobject]@{Type = "TLSA" ; ParameterName = 'Selector'; DataType = [int] ; ValidateSet = 0, 1 ; HelpMessage = 'Required for TLSA pointers. TLSA selector. Numeric value, 0 or 1.' }
        # $dynParams += [pscustomobject]@{Type = "TLSA" ; ParameterName = 'Dtype'; DataType = [int] ; ValidateSet = 0, 1, 2 ; HelpMessage = 'Required for TLSA pointers. TLSA matching type. Numeric value, 0, 1 or 2.' }
        # $dynParams += [pscustomobject]@{Type = "DS" ; ParameterName = 'Tag'; DataType = [string] ; ValidateSet = $null ; HelpMessage = 'Required for DS and CAA pointers.' }
        # $dynParams += [pscustomobject]@{Type = "DS" ; ParameterName = 'Alg'; DataType = [string] ; ValidateSet = $null ; HelpMessage = 'Required for DSpointers. See RFC3658 for details.' }
        # $dynParams += [pscustomobject]@{Type = "DS" ; ParameterName = 'Digest'; DataType = [string] ; ValidateSet = $null ; HelpMessage = 'Required for DSpointers. See RFC3658 for details.' }
        # $dynParams += [pscustomobject]@{Type = "CAA" ; ParameterName = 'Tag'; DataType = [string] ; ValidateSet = $null ; HelpMessage = 'Required for DS and CAA pointers.' }
        # $dynParams += [pscustomobject]@{Type = "CAA" ; ParameterName = 'Flags'; DataType = [string] ; ValidateSet = $null ; HelpMessage = 'Required for CAA pointers. See RFC3658 for details.' }
        # $dynParams += [pscustomobject]@{Type = "MX"; ParameterName = 'Priority'; DataType = [string] ; ValidateSet = $null ; HelpMessage = 'Required for MX and SRV pointers. Preference/Priority for the pointer.' }

        $dynParams = @()
        foreach ($recordType in ([DNSTypes].GetFields() | ? isStatic).Name)
        {
            $props = Invoke-Command -ScriptBlock ([Scriptblock]::Create(("[CloudflareRecord{0}].GetProperties()" -f $recordType)))

            foreach ($prop in $props)
            {
                $dynParams += [pscustomobject]@{Type = $recordType ; ParameterName = $prop.Name; DataType = $prop.PropertyType ; ValidateSet = $null }
            }
        }

        $attributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
        foreach ($param in ($dynParams | ? Type -EQ $Type))
        {
            #ParameterAttribute Objects
            $Attr = New-Object System.Management.Automation.ParameterAttribute
            $Attr.Mandatory = $true
            $Attr.ParameterSetName = "ManualInput"
            # $Attr.HelpMessage = $param.HelpMessage
            #Attributecollection object for the attributes we just created.
            $attributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
            #add our custom attributes
            $attributeCollection.Add($Attr)
            if ($param.ValidateSet)
            {
                # Generate and set the ValidateSet
                $arrSet = $param.ValidateSet
                $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet)
                # Add the ValidateSet to the attributes collection
                $AttributeCollection.Add($ValidateSetAttribute)
            }
            #add our parameter specifying the attribute collection
            $definedParam = New-Object System.Management.Automation.RuntimeDefinedParameter($param.ParameterName, $param.DataType, $attributeCollection)
            #$pwParam = New-Object System.Management.Automation.RuntimeDefinedParameter('password', [string], $attributeCollection)
            #expose the name of our parameter
            # $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
            $paramDictionary.Add($param.ParameterName, $definedParam)
            #$paramDictionary.Add('password', $pwParam)
        }
        return $paramDictionary
    }

    begin
    {
        if (!$cfApiToken) { Throw "No token. Use the 'Set-CloudflareApiToken' command to add the Token." }
        else
        {
            $token = ($cfApiToken | ConvertFrom-Base64)
        }
    }
    process
    {
        $headers = @{
            'Authorization' = "Bearer $token"
        }
        $zoneId =
        if ($PSCmdlet.MyInvocation.ExpectingInput -eq $true)
        {
            $zone
        }
        else
        {
            (Get-CloudflareDnsZone -Zone $Zone).id
        }

        $cfUriGetZones = "https://api.cloudflare.com/client/v4/zones/$($zoneId)/dns_records"

        # Creating record

        switch ($PSCmdlet.ParameterSetName)
        {
            "ManualInput"
            {
                $RecordObj = New-CloudflareDnsRecordObject -RecordType $Type
                $RecordObj.GetPropertyNames() | % { $RecordObj.$_ = $PSBoundParameters.$_ }
            }
            "ObjectInput"
            {
                $RecordObj = $RecordObject
                $Type = $RecordObj.ToBody().type
            }
            Default
            {
                Throw "Unknown parameterset used."
            }
        }

        $operationInfo = ((@("Type = $Type") + ($RecordObj.psobject.Properties | % { "{0} [{1}]" -f $_.Name, $_.Value })) -join " // ")

        Write-Verbose $RecordObj.ToJson()

        if ($PSCmdlet.ShouldProcess($zoneId, "Adding $operationInfo"))
        {
            # $newZoneInfo = irm -Method Post -Body $RecordObj.ToJson() -Uri $cfUriGetZones -Headers $headers -ContentType 'application/json'
            $newZoneInfo = Invoke-CloudflareDnsZoneCommand -Uri $cfUriGetZones -Body $RecordObj.ToJson() -Method POST

            if ($newZoneInfo.sucess -eq $true)
            {
                $newZoneInfo.result
            }
        }
    }
}
#EndRegion '.\Public\New-CloudflareDnsZoneRecord.ps1' 168
#Region '.\Public\Set-CloudflareApiToken.ps1' 0
function Set-CloudflareApiToken
{
    [CmdletBinding(SupportsShouldProcess = $true)]
    param (
        [Parameter(Mandatory = $true)]
        [string]
        $Token
    )
    process
    {
        $b64Token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($token))

        $Global:cfApiToken = $b64Token
    }
}
#EndRegion '.\Public\Set-CloudflareApiToken.ps1' 16
#Region '.\Public\Test-CloudflareApi.ps1' 0
function Test-CloudflareApi()
{
    [CmdletBinding()]
    Param ()

    if ($cfApiToken)
    {
        $Token = [string](([System.Convert]::FromBase64String($cfApiToken) | % { [char]$_ }) -join '')
        $headers = @{
            'Authorization' = "Bearer $token"
        }
        $cfUriVerifyToken = "https://api.cloudflare.com/client/v4/user/tokens/verify"
        try
        {
            $verify = irm -Uri $cfUriVerifyToken -Headers $headers -ContentType 'application/json'
            if ($verify.success -eq $true)
            {
                $verify
            }
        }
        catch
        {
            Throw $_
        }
    }
    else
    {
        Throw "No token found. Connect to Cloudflare by using 'Set-CloudflareApiToken' first."
    }
}
#EndRegion '.\Public\Test-CloudflareApi.ps1' 31