Skip to content

Instantly share code, notes, and snippets.

@I-Otsuki
Last active October 29, 2019 02:07
Show Gist options
  • Save I-Otsuki/bcfa69b3f8733fb5400e85c31fd5af72 to your computer and use it in GitHub Desktop.
Save I-Otsuki/bcfa69b3f8733fb5400e85c31fd5af72 to your computer and use it in GitHub Desktop.
DNS01 script for Cloundflare and [PKISharp/win-acme](https://github.com/PKISharp/win-acme)
param(
[Parameter(Mandatory = $false, Position = 0)]
[ValidateSet("create", "delete")]
[string]
$Operation = "create",
[Parameter(Mandatory = $true, Position = 1)]
[String]
$RecordName,
[Parameter(Mandatory = $true, Position = 2)]
[String]
$Token,
[Parameter(Mandatory = $true, Position = 3, HelpMessage = "Email address associated with your Cloudflare account")]
[String]
$Email,
[Parameter(Mandatory = $true, Position = 4, HelpMessage = "API key generated on Cloudflare's `"My Account`" page")]
[String]
$Key
)
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
Add-Type -AssemblyName System.Web
$ApiBaseUri = "https://api.cloudflare.com/client/v4/"
$AuthenticationHeaders = @{'X-Auth-Key' = $Key; 'X-Auth-Email' = $Email }
function Find-Record {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string]
$ZoneId,
[Parameter(Mandatory = $true)]
[string]
$RecordName,
[Parameter(Mandatory = $false)]
[string]
$RecordType = "TXT",
[Parameter(Mandatory = $false)]
[string]
$Content = ""
)
$Uri = "${ApiBaseUri}zones/${ZoneId}/dns_records?type=$([System.Web.HttpUtility]::UrlEncode($RecordType))&name=$([System.Web.HttpUtility]::UrlEncode($RecordName))"
if ($Content -ne "") {
$Uri += "&content=$([System.Web.HttpUtility]::UrlEncode($Content))"
}
$Response = Invoke-RestMethod -Uri $Uri -Headers $AuthenticationHeaders -ContentType "application/json"
if (!$Response.success) {
throw @{Message = "Query failed"; Response = $Response }
}
return $Response.result
}
function Find-Zone {
[CmdletBinding()]
param (
[Parameter(Mandatory = $false, Position = 0)]
[string]
$RecordName = ""
)
while ($RecordName -match "\.") {
$Response = Invoke-RestMethod -Uri "${ApiBaseUri}zones?name=$([System.Web.HttpUtility]::UrlEncode($RecordName))" -Headers $AuthenticationHeaders -ContentType "application/json" -Method "GET"
if (!$Response.success) {
throw @{Message = "Query failed"; Response = $Response }
}
if ($Response.result.Count -gt 0) {
return $Response.result
}
else {
$RecordName = $RecordName -replace "^[^.]*\.", ""
}
}
return @()
}
function Remove-Record {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string]
$ZoneId,
[Parameter(Mandatory = $true)]
[string]
$RecordId
)
$Response = Invoke-RestMethod -Uri "${ApiBaseUri}zones/${ZoneId}/dns_records/${RecordId}" -Headers $AuthenticationHeaders -ContentType "application/json" -Method DELETE
return $Response.result
}
function New-Record {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string]
$ZoneId,
[Parameter(Mandatory = $true)]
[string]
$RecordName,
[Parameter(Mandatory = $false)]
[string]
$RecordType = "TXT",
[Parameter(Mandatory = $false)]
[string]
$Content = ""
)
$Response = Invoke-RestMethod -Uri "${ApiBaseUri}zones/${ZoneId}/dns_records" -Headers $AuthenticationHeaders -ContentType "application/json" -Method 'POST' -Body (@{type = $RecordType; name = $RecordName; content = $Content } | ConvertTo-Json)
if (!$Response.success) {
throw @{Message = "Creation failed"; Response = $Response }
}
}
$ZoneId = (Find-Zone -RecordName $RecordName)[0].id
$ExistingRecords = @(Find-Record -ZoneId $ZoneId -RecordName $RecordName -Content $Token)
switch ($Operation.ToLower()) {
"delete" {
if ($ExistingRecords.Count -gt 0) {
ForEach-Object -InputObject $ExistingRecords { Remove-Record -ZoneId $ZoneId -RecordId $_.id } | Out-Null
}
}
Default {
if ($ExistingRecords.Count -lt 1) {
New-Record -ZoneId $ZoneId -RecordName $RecordName -Content $Token
}
Start-Sleep 15
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment