What it does
Diese Ressource automatisiert die Ausstellung eines Lets Encrypt Zertifikats im Zusammenhang einer DNS Zone, welche bei Azure liegt. Der User, der hier verwendet wird, muss in Azure / Entra ID die Berechtigung besitzen DNS Einträge zu verwalten (speziell anlegen und ändern von TXT Records)
Description
Create a Lets Encrypt Certificate with Posh-ACME
Creation Details
Input Parameters
Name: domain
Description: enter the full domain name (fqdn) for the certificate
Name: leenv
Description: choose the production or the stage environment for Lets Encrypt
Name: acmecontact
Description: choose the LE ACME Account
Resource Parameters
Name: appid
Description: this AppId is the Application ID from the Azure App
Name: tenantid
Description: The Azure Active Directory / Entra ID Tenant ID
Code
[CmdletBinding()]
Param(
[Parameter(Mandatory=$false)]
[string]$installPath="not-set",
[Parameter(Mandatory=$false)]
[string]$jobId="not-set",
[Parameter(Mandatory=$false)]
[string]$action="not-set"
)
$debugScript = 0;
if ($debugScript -eq 1) {
write-host "debugging mode on" -f yellow
$installPath = "C:\addy\" #Debugging
$jobId = "jobXXXXXXX" #only for debugging
}
# Only use TLSv1.1 and TLSv1.2
$AllProtocols = [System.Net.SecurityProtocolType]'Tls11,Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
$errorCount = 0 # counting errors. If this variable is greater than 0, the script should not run
# loading functions
write-host "$(get-date -f "dd.MM.yyyy HH:mm:ss") include functions"
if (test-path "$($installPath)scripts\functions.global.ps1") {
write-host "Functions-File exists"
import-module "$($installPath)scripts\functions.global.ps1" -force
} else {
write-host "Functions file do not exist. Increasing ErrorCounter."
$errorCount++
}
set-location $installPath # setting the location
$machineId = Get-MachineId # generate a unique machineID
write-addylog "All parameter initialized" # write log
# Handling with parameters
if ($debugScript -eq 0) {
# Load parameter information about this job
$jsonBody = @{ localCurrentTime = $(get-date -f "dd.MM.yyyy HH:mm:ss")}
$body = (ConvertTo-Json -Depth 4 $jsonBody)
$resultInitializeInvoke = Invoke-RestMethod -Uri "$addyhostaddress/api/v1/heartbeat-consumer?action=checkforjobs&jobId=$jobId" -Method POST -Body $body -ContentType 'application/json; charset=UTF-8' -Headers @{"Publickey"="$publickey";"Privatekey"="$privatekey";"Machineid" = "$machineId"} # -Headers @{'Authorization'='Basic YWRtaW46YWRtaW4'}
# take a look in the answer from the addy with $resultInitializeInvoke
# Example Jobname: $resultInitializeInvoke.jobDataArray.businessAutomationJobsPendingJobname
# Example to get input parameter
# $addyPayloadResourceInput = $resultInitializeInvoke.jobDataArray.businessAutomationJobsPendingPayload.payload
# Example to get a specific input parameter
# [string]$aStringParameter = $addyPayloadResourceInput.aStringParameter # "aStringParameter" is definied in the Input Parameter. This are now a parameter for this script
# $aStringParameter = $aStringParameter.trim()
# Example to get resource parameter
# [string]$ParamAnyString = $resultInitializeInvoke.scriptParameter.anyString #"anyString" is definied in the Resource Parameter. This are now a parameter for this script
# $ParamAnyString = $ParamAnyString.trim()
# cast scriptParameter int
# [int]$ParamaNumber = "$($resultInitializeInvoke.scriptParameter.aNumber)" #"aNumber" is definied in the Resource Parameter. This are now a parameter for this script
}
###################### End header - Start main ############################
# Start: Introducing commands
write-addylog "Start the Script." #-Level "INFO","ERROR", "WARN"
$startOfScript = get-date
write-addylog "Initializing variables"
$errorCount = 0
$error.clear()
# End: Introducing commands
# Start: set a response
$jsonMessageBody = @{
message = "working"
timestamp=$(get-date -f "dd.MM.yyyy HH:mm:ss")
}
write-addylog "Set a job response. Message to `"working`""
set-JobResponse -jobId $jobId -jsonMessageBody $jsonMessageBody -publickey $publickey -privatekey $privatekey -machineId $machineId
# End: set a response
# Start: load resource parameter
write-addylog "Initializing resource parameter"
$addyPayloadResourceParameter = $resultInitializeInvoke.scriptParameter
#[string]$temp0resourceparameter = $addyPayloadResourceParameter.temp0resourceparameter #"temp0resourceparameter" is definied in the Resource Parameter. This are now a parameter for this script
#$temp0resourceparameter = $temp0resourceparameter.trim()
#write-addylog "[resource parameter] `"temp0resourceparameter`" is set to: $temp0resourceparameter"
# End: load resource parameter
[string]$resourceParameterAppId = $addyPayloadResourceParameter.appid #"appid" is definied in the Resource Parameter. This are now a parameter for this script
$resourceParameterAppId = $resourceParameterAppId.trim()
write-addylog "[resource parameter] `"AppId`" is set to: $resourceParameterAppId"
[string]$resourceParameterTenantId = $addyPayloadResourceParameter.tenantid #"appid" is definied in the Resource Parameter. This are now a parameter for this script
$resourceParameterTenantId = $resourceParameterTenantId.trim()
write-addylog "[resource parameter] `"TenantId`" is set to: $resourceParameterTenantId"
# Start: load input parameter
write-addylog "Initializing input parameter"
$addyPayloadResourceInput = $resultInitializeInvoke.jobDataArray.businessAutomationJobsPendingPayload.payload
#[string]$temp1parameter = $addyPayloadResourceInput.temp1parameter # "temp1parameter" is definied in the Resource input Parameter. This are now a parameter for this script
#$temp1parameter = $temp1parameter.trim()
#write-addylog "[input parameter] `"temp1parameter`" is set to: $temp1parameter"
[string]$inputParameterDomain = $addyPayloadResourceInput.domain # "domain" is definied in the Resource input Parameter. This are now a parameter for this script
$inputParameterDomain = $inputParameterDomain.trim()
write-addylog "[input parameter] `"domain`" is set to: $inputParameterDomain"
[string]$inputParameterLeEnv = $addyPayloadResourceInput.leenv # "leenv" is definied in the Resource input Parameter. This are now a parameter for this script
$inputParameterLeEnv = $inputParameterLeEnv.trim()
write-addylog "[input parameter] `"leenv`" is set to: $inputParainputParameterLeEnvmeterDomain"
[string]$inputParameterAcmeContact = $addyPayloadResourceInput.acmecontact # "acmecontact" is definied in the Resource input Parameter. This are now a parameter for this script
$inputParameterAcmeContact = $inputParameterAcmeContact.trim()
write-addylog "[input parameter] `"acmecontact`" is set to: $inputParameterAcmeContact"
# End: load input parameter
#
# Start Main part
#
$acmeContact = $inputParameterAcmeContact
$LeEnv = $inputParameterLeEnv
$domain= $inputParameterDomain
write-addylog "Domain: $domain"
write-addylog "LE Environment: $LeEnv"
write-addylog "Subitted ACME Contact: $acmeContact"
$servicePrincipalAppId = $resourceParameterAppId
$tenantId = $resourceParameterTenantId
write-addylog "AppId: $servicePrincipalAppId"
write-addylog "TenantId: $tenantId"
$DatasetArray = get-addydataset -datasetName "addy-dns-manage-certificates" -username "addy-dns-manage-certificates"
$servicePrincipalPassword = $DatasetArray.credential.GetNetworkCredential().password
# load the module
$ResultLoadModule = LoadModule "Posh-ACME"
if ($ResultLoadModule -eq $true) {
write-addylog "Posh-ACME module loading successfully"
} else {
write-addylog "Posh-ACME module loading failed" -level ERROR
$errorCount++
}
if ($errorCount -eq 0) {
write-addylog "Creating the credential object"
$spSecureString = ConvertTo-SecureString $servicePrincipalPassword -AsPlainText -Force
$psCredentials = New-Object System.Management.Automation.PSCredential ($servicePrincipalAppID, $spSecureString)
write-host "connecting to Azure Account (with service principal)"
$az = $NULL
$az = Connect-AzAccount -ServicePrincipal -Credential $psCredentials -Tenant $tenantId
if ($az) {
write-addylog "connect to azure successfully"
} else {
write-addylog "connect to azure failed" -level ERROR
$errorCount++
}
} #if ($errorCount -eq 0)
if ($errorCount -eq 0) {
$error.clear()
if ($LeEnv -eq "production") {
$LeServer="LE_PROD"
} elseif ($LeEnv -eq "staging") {
$LeServer="LE_STAGE"
} else {
$LeServer="LE_STAGE"
}
# Configure Posh-ACME server
write-addylog "Configure LE Server to `"$LeServer`""
Set-PAServer $LeServer
Get-PAPlugin Azure
# Configure Posh-ACME account
write-addylog "Configure Posh-ACME account. Contact: `"$($acmeContact)`""
$PaAccount = Get-PAAccount
if (-not $PaAccount) {
# New account
Write-Host "Create New Posh-ACME LE Account"
$PaAccount = New-PAAccount -Contact $acmeContact -AcceptTOS
} elseif ($PaAccount.contact -ne "mailto:$acmeContact") {
# Update account contact
Write-Host "Set Existing Account ID: $($PaAccount.id), Contact: `"$acmeContact`""
Set-PAAccount -ID $PaAccount.id -Contact $acmeContact
}
if ($error) {
write-addylog "an error occured. Error: $($error[0])" -level ERROR
$errorCount++
}
} #if ($errorCount -eq 0)
if ($errorCount -eq 0) {
# Acquire access token for Azure
Write-Host "Azure DNS Sub $($az.Context.Subscription.name)"
$AzAccessToken = $NULL
$AzAccessToken = $(Get-AzAccessToken -ResourceUrl 'https://management.core.windows.net/').Token
if ($AzAccessToken) {
write-addylog "getting access token successfully"
} else {
write-addylog "getting access token failed" -level ERROR
$errorCount++
}
} #if ($errorCount -eq 0)
if ($errorCount -eq 0) {
# Request certificate
write-addylog "requesting a new certificate. The certificate creation will create a new TXT record in the DNS Zone and sleep for 120 seconds while DNS changes propagate."
$pArgs = @{
AZSubscriptionId = $az.Context.Subscription.Id
AZAccessToken = $AzAccessToken
}
$resNewPACertificate = $NULL
$resNewPACertificate = New-PACertificate $domain -Plugin Azure -PluginArgs $pArgs -Verbose
if ($resNewPACertificate) {
write-addylog "Certificate created: `"$($resNewPACertificate.CertFile)`""
}
$PACertificateData = Get-PACertificate | Select-Object *
if ($PACertificateData) {
write-host "Certificate expiring date: $($PACertificateData.NotAfter)"
}
} #if ($errorCount -eq 0)
write-addylog "disconnecting from azure"
Disconnect-AzAccount
if ($errorCount -eq 0) {
$messageJobResponse = "done"
} else {
$messageJobResponse = "failed"
}
$jsonMessageBody = @{
message = $messageJobResponse
timestamp=$(get-date -f "dd.MM.yyyy HH:mm:ss")
}
write-addylog "Set a job response. Message to `"messageJobResponse`""
set-JobResponse -jobId $jobId -jsonMessageBody $jsonMessageBody -publickey $publickey -privatekey $privatekey -machineId $machineId
###########
# get certificate
# Get-PACertificate -list
# get data from PA Certificate
#Get-PACertificate -name "lecert01.test.cloud.adminsbuddy.com" | select *
# renew a specific certificate
#Submit-Renewal "lecert01.test.cloud.adminsbuddy.com" -Force
# renew all force
#Submit-Renewal -AllOrders -force
#
# END Main Part
#
# Start: cleanup commands
$EndOfScript = get-date
write-addylog "Start of script: $startOfScript"
write-addylog "End of script: $EndOfScript"
$errorCount = 0
$error.clear()
$addyPayloadResourceInput = ""; $addyPayloadResourceParameter = "" # Reset important variables
# End: cleanup commands
###################### End main - Start footer ############################
# setting the state
if ($debugScript -eq 0) {
write-addylog "update state of this job to done"
update-modifiedState -jobId $jobId -modifiedState "done" -publickey $publickey -privatekey $privatekey -machineId $machineId
Start-Sleep 2
write-addylog "End of script reached"
Start-Sleep 2
exit
}
login and obtain the library resource to set a rating.