<# .SYNOPSIS Adds and deletes TXT record to your one.com domain with win-wacs. .DESCRIPTION Works with win-wacs to add and delete TXT records for use with Let's encrypt certificates. .NOTES File Name : onedotcom.ps1 Version : 1.0 (Initial version) Author : Morten Hansen .LINK https://github.com/morhans/win-acme_dns_one.com .EXAMPLE onedotcom.ps1 create <Identifier> <RecordName> <Token> .EXAMPLE onedotcom.ps1 delete <Identifier> <RecordName> <Token> .EXAMPLE onedotcom.ps1 setcred #> [CmdletBinding()] param( [Parameter(Position=0)] [string]$action, [Parameter(Position=1)] [string]$Identifier, [Parameter(Position=2)] [string]$RecordName, [Parameter(Position=3)] [string]$Token ) $global:apiRoot = 'https://www.one.com/admin' function Add-DnsRecord { [CmdletBinding()] param( [Parameter(Mandatory,Position=0)] [string]$Identifier, [Parameter(Mandatory,Position=1)] [string]$RecordName, [Parameter(Mandatory,Position=2)] [string]$TxtValue, [Parameter(Mandatory,Position=3)] [object]$LoginSession ) # add the new TXT record $topdomain = getTopDomain $Identifier $RecordName = $RecordName.Substring(0,$RecordName.Length-$topdomain.Length-1) $PostData = @{type="dns_custom_records";attributes=@{priority=0;ttl=600;type="TXT";prefix=$RecordName;content=$TxtValue}}|ConvertTo-Json $url = "$apiRoot/api/domains/$topdomain/dns/custom_records" Write-Debug $url Write-Verbose "Adding $RecordName with value $TxtValue to $Identifier" try { $webrequest = Invoke-WebRequest -Uri $url -Body $PostData -WebSession $LoginSession -Method POST -UseBasicParsing -ContentType "application/json" -ErrorAction Stop } catch [System.Net.WebException] { Write-Verbose "An exception was caught: $($_.Exception.Message)" $_.Exception.Response } #Check if adding was a success $Result = ConvertFrom-Json $webrequest.content if ([String]::IsNullOrWhiteSpace($Result.result.data.id)) { throw "TXT record for $RecordName ws not added!" } <# .SYNOPSIS Add a DNS TXT record to One.com. .DESCRIPTION Use One.com api to add a TXT record to a One.com DNS zone. .PARAMETER Identifier DNS name to be added a TXT record. .PARAMETER RecordName The fully qualified name of the TXT record. .PARAMETER TxtValue The value of the TXT record. .EXAMPLE Add-DnsRecord 'example.com' '_acme-challenge.site1' 'asdfqwer12345678' '$SessionID' Adds a TXT record for the specified site with the specified value. #> } function Remove-DnsRecord { [CmdletBinding()] param( [Parameter(Mandatory,Position=0)] [string]$Identifier, [Parameter(Mandatory,Position=1)] [string]$RecordName, [Parameter(Mandatory,Position=2)] [string]$TxtValue, [Parameter(Mandatory,Position=3)] [object]$LoginSession ) # check for an existing record $topdomain = getTopDomain $Identifier $RecordName = $RecordName.Substring(0,$RecordName.Length-$topdomain.Length-1) $RecId = Find-RecordId $topdomain $RecordName $TxtValue $LoginSession if ([String]::IsNullOrWhiteSpace($RecId)) { throw "Unable to find record id for $RecordName" } # remove the txt record if it exists Write-Verbose "Removing $RecordName with value $TxtValue from $Identifier" $url = "$apiRoot/api/domains/$topdomain/dns/custom_records/$RecId" Write-Debug $url try { $webrequest = Invoke-WebRequest -Uri $url -WebSession $LoginSession -Method DELETE -UseBasicParsing -ContentType "application/json" -ErrorAction Stop } catch [System.Net.WebException] { Write-Verbose "An exception was caught: $($_.Exception.Message)" $_.Exception.Response } # Check if removal was a success if (!($webrequest.content -eq '{"result":null,"metadata":null}')) { throw "Unable to delete record $RecordName!" } <# .SYNOPSIS Remove a DNS TXT record from One.com. .DESCRIPTION Use One.com api to remove a TXT record to a One.com DNS zone. .PARAMETER Identifier DNS name to have TXT record deleted. .PARAMETER RecordName The fully qualified name of the TXT record. .PARAMETER TxtValue The value of the TXT record. .EXAMPLE Remove-DnsRecord Example 'example.com' '_acme-challenge.site1' 'asdfqwer12345678' '$SessionID' Removes a TXT record for the specified site with the specified value. #> } function EncryptCred { #Ask for credentials $Credential = Get-Credential -Message "Login and password for One.com" #Save credentials $Credential | Export-CliXml -Path "${env:\userprofile}\One.com.dat" <# .SYNOPSIS Saves One.com credentials to file. .DESCRIPTION Encrypt credentials to use on One.com login. Credentials is only readable by the creating user. #> } ############################ # Helper Functions ############################ function getTopDomain { [CmdletBinding()] param( [Parameter(Mandatory,Position=0)] [string]$Identifier ) $pieces = $Identifier.Split(".") for ($i=1; $i -lt ($pieces.Count-1); $i++) { $topdomain = "$( $pieces[$i..($pieces.Count-1)] -join '.' )" } if (([String]::IsNullOrWhiteSpace($topdomain))) { $topdomain = $Identifier } return $topdomain } function getCustomRecords { [CmdletBinding()] param( [Parameter(Mandatory,Position=0)] [string]$Identifier, [Parameter(Mandatory,Position=1)] [object]$LoginSess ) $url = "$apiroot/api/domains/$topdomain/dns/custom_records" Write-Debug $url try { $webrequest = Invoke-WebRequest -Uri $url -Method Default -WebSession $LoginSess -UseBasicParsing -ErrorAction Stop } catch [System.Net.WebException] { Write-Verbose "An exception was caught: $($_.Exception.Message)" $_.Exception.Response } $jsonObj = ConvertFrom-Json $webrequest.content return $jsonObj.result.data } function Find-RecordId { [CmdletBinding()] param( [Parameter(Mandatory,Position=0)] [string]$Identifier, [Parameter(Mandatory,Position=1)] [string]$RecordName, [Parameter(Mandatory,Position=2)] [object]$TxtValue, [Parameter(Mandatory,Position=3)] [object]$LoginSess ) $RecObj = getCustomRecords $Identifier $LoginSess ForEach($rec in $RecObj) { if ($rec.attributes.prefix -eq $RecordName -and $rec.attributes.content -eq $TxtValue -and $rec.attributes.type -eq "TXT") { $RecId = $rec.id } } Write-Debug "ID (Empty if not found): $RecId" return $RecId } function DecryptCred { if (!(Test-Path "${env:\userprofile}\One.com.dat")) { throw "Login and password not set (run with option setcred to set them." } $Credential = Import-CliXml -Path "${env:\userprofile}\One.com.dat" return $Credential } function onedotcom_login { $SearchString = '<form id="kc-form-login" class="Login-form login autofill" onsubmit="login.disabled = true; return true;" action="' $odcCred = DecryptCred $usr = $odcCred.UserName $pwd = $odcCred.GetNetworkCredential().Password if (([String]::IsNullOrWhiteSpace($usr)) -or ([String]::IsNullOrWhiteSpace($pwd))) { throw "Login and/or password are not set correctly. Reissue with option setcred" } [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 try { $webrequest = Invoke-WebRequest -Uri $apiRoot -Method Default -SessionVariable websession -UseBasicParsing -ErrorAction Stop $pos = $webrequest.content.LastIndexOf($SearchString) + $SearchString.Length $resulttxt = $webrequest.content.Substring($pos) } catch [System.Net.WebException] { Write-Verbose "An exception was caught: $($_.Exception.Message)" $_.Exception.Response } try { $pos = $resulttxt.IndexOf('"') $LoginUrl = $resulttxt.Substring(0, $pos) $LoginUrl = $LoginUrl.replace('&','&') $formFields = @{username=$usr;password=$pwd;credentialId=''} $webrequest = Invoke-WebRequest -Uri $LoginUrl -Body $formFields -WebSession $websession -Method POST -UseBasicParsing -ErrorAction Stop } catch [System.Net.WebException] { Write-Verbose "An exception was caught: $($_.Exception.Message)" $_.Exception.Response } Remove-Variable usr, pwd return $websession } ############################ # Main program ############################ $ProgressPreference = 'SilentlyContinue' switch ($action) { "create" { if (!([String]::IsNullOrWhiteSpace($Identifier)) -and !([String]::IsNullOrWhiteSpace($RecordName)) -and !([String]::IsNullOrWhiteSpace($Token))) { $sess = onedotcom_login Add-DnsRecord $Identifier $RecordName $Token $Sess } else { Write-Error "Argument(s) Identifier, RecordName and/or Token were not applied!" } } "delete" { if (!([String]::IsNullOrWhiteSpace($Identifier)) -and !([String]::IsNullOrWhiteSpace($RecordName)) -and !([String]::IsNullOrWhiteSpace($Token))) { $sess = onedotcom_login Remove-DnsRecord $Identifier $RecordName $Token $Sess } else { Write-Error "Argument(s) Identifier, RecordName and/or Token were not applied!" } } "setcred" { EncryptCred } Default { Write-Error "No or wrong arguments were passed. Valid arguments are create, delete and setcred.`n Syntax:`n onedotcom.ps1 create <Identifier> <RecordName> <Token>`n onedotcom.ps1 delete <Identifier> <RecordName> <Token>`n onedotcom.ps1 setcred (Set the credentials for one.com)" } }