{"id":5372,"date":"2021-08-04T23:52:09","date_gmt":"2021-08-04T23:52:09","guid":{"rendered":"https:\/\/pariswells.com\/blog\/?p=5372"},"modified":"2021-11-04T23:53:16","modified_gmt":"2021-11-04T23:53:16","slug":"thales-cipher-trust-manager-backup-script-via-powershell-and-api","status":"publish","type":"post","link":"https:\/\/pariswells.com\/blog\/research\/thales-cipher-trust-manager-backup-script-via-powershell-and-api","title":{"rendered":"Thales Cipher Trust Manager Backup Script via Powershell and API"},"content":{"rendered":"<p># KeySecure API endpoint and POST params<br aria-hidden=\"true\" \/>$keysecures = @(&#8220;%KeysecureIPorDNS%&#8221;)<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>#Import Credentials from Credential XML, this is protected by file level application for security Format &lt;Credentials&gt;&lt;Credential&gt;&lt;Name\\User\\Password&gt;keysecure&lt;\/Name\\User\\Password&gt;&lt;\/Credential&gt;&lt;\/Credentials&gt;<br aria-hidden=\"true\" \/>$credxml = Select-Xml -Path \u00a0&#8220;\\\\sydfileserver\\shared\\Security\\Project 2020 &#8211; Huon\\CLI\\Credentials.xml&#8221; -XPath &#8216;\/Credentials\/Credential&#8217; | Select-Object -ExpandProperty Node<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>#import credentials from XML into values to be used<br aria-hidden=\"true\" \/>$kscreds = $credxml | Where-Object {$_.Name -eq &#8220;keysecure&#8221;}<br aria-hidden=\"true\" \/>$pscpcreds = $credxml | Where-Object {$_.Name -eq &#8220;pscp&#8221;}<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>#change ks creds for Json<br aria-hidden=\"true\" \/>$kscreds = @{ username = $kscreds.User; password = $kscreds.Password; }<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>#look through all KeySecures and do<br aria-hidden=\"true\" \/>foreach ($keysecure in $keysecures) {<br aria-hidden=\"true\" \/>\u00a0 \u00a0 #Output current Keysecure<br aria-hidden=\"true\" \/>\u00a0 \u00a0 $keysecure<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>\u00a0 \u00a0 # Make API request to get bearer token valid for 300 Seconds<br aria-hidden=\"true\" \/>\u00a0 \u00a0 $bearer_token = Invoke-WebRequest https:\/\/$keysecure\/api\/v1\/auth\/tokens -Method Post -Body $kscreds -UseBasicParsing | ConvertFrom-Json<br aria-hidden=\"true\" \/>\u00a0 \u00a0 $bearer_token = $bearer_token.jwt<br aria-hidden=\"true\" \/>\u00a0 \u00a0 #Build Header with Bearer Token for Future Requests<br aria-hidden=\"true\" \/>\u00a0 \u00a0 $headers = @{Authorization = &#8220;Bearer $bearer_token&#8221;}<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>\u00a0 \u00a0 #Create Backup<br aria-hidden=\"true\" \/>\u00a0 \u00a0 $params = @{ tiedToHSM = &#8220;false&#8221;; scope = &#8220;&#8221;; backupKey =&#8221;&#8221;; }<br aria-hidden=\"true\" \/>\u00a0 \u00a0 $response = Invoke-RestMethod -Uri https:\/\/$keysecure\/api\/v1\/backups -Method Post -Headers $headers \u00a0-Body $params -UseBasicParsing<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>\u00a0 \u00a0 #Output Backup ID for Fault Finding<br aria-hidden=\"true\" \/>\u00a0 \u00a0 $<a href=\"https:\/\/protect-au.mimecast.com\/s\/BFBRCxnMPBh28o2I8DP1q?domain=response.id\" target=\"_blank\" rel=\"noopener noreferrer\" data-auth=\"NotApplicable\" data-linkindex=\"2\">response.id<\/a><br aria-hidden=\"true\" \/>\u00a0 \u00a0 $response = $<a href=\"https:\/\/protect-au.mimecast.com\/s\/BFBRCxnMPBh28o2I8DP1q?domain=response.id\" target=\"_blank\" rel=\"noopener noreferrer\" data-auth=\"NotApplicable\" data-linkindex=\"3\">response.id<\/a><br aria-hidden=\"true\" \/>\u00a0 \u00a0 #While look to check Backup status then download and delete backup once completed<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>\u00a0 \u00a0 #12 tries 5 Seconds each<br aria-hidden=\"true\" \/>\u00a0 \u00a0 $maxRetries = 12; $retryCount = 0; $completed = $false<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>\u00a0 \u00a0 #Check for Loop to complete<br aria-hidden=\"true\" \/>\u00a0 \u00a0 while (-not $completed) {<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>\u00a0 \u00a0 #Get Backup Status<br aria-hidden=\"true\" \/>\u00a0 \u00a0 $bkstaus = Invoke-RestMethod -Uri https:\/\/$keysecure\/api\/v1\/backupStatus -Method get -Headers $headers -UseBasicParsing;<br aria-hidden=\"true\" \/>\u00a0 \u00a0 #Output Backup Status for Fault Finding<br aria-hidden=\"true\" \/>\u00a0 \u00a0 $bkstaus.status<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 if ($bkstaus.status -eq &#8220;Completed&#8221;){<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 $completed = $true<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 #download File<br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Invoke-RestMethod -Uri https:\/\/$keysecure\/api\/v1\/backups\/$response\/download -Method get -Headers $headers -OutFile &#8220;C:\\Temp\\$keysecure$response.bak&#8221;<br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0<br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 #move to SCP NFS\u00a0<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 #check File Exists<br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 IF (Test-Path C:\\Temp\\$keysecure$response.bak) {<br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 #Check not 0KB<br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 If ((Get-Item C:\\Temp\\$keysecure$response.bak).length -gt 0kb) {<br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0#delete File from KeySecure<br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0Invoke-RestMethod -Uri https:\/\/$keysecure\/api\/v1\/backups\/$response -Method delete -Headers $headers \u00a0-Body $params -UseBasicParsing<br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0$body += $keysecure+&#8217; backed up using &#8216; + $response + &#8221; id&lt;br&gt;&#8221;<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 } \u00a0else { $body += &#8220;Error&#8221; + $keysecure+$response + \u00a0&#8221; File 0kb&lt;br&gt;&#8221; }<br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 } \u00a0else { $body += &#8220;Error&#8221; + $keysecure+$response + \u00a0&#8221; Backup file does not exist&lt;br&gt;&#8221; }<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 }<br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 else {<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0if ($retryCount -ge $maxRetries) {<br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0#output error for retries waiting for backup to complete<br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0$body += &#8220;Error&#8221; + $keysecure+$response+ &#8216;Max retries exceeded wating for backup&lt;br&gt;&#8217;<br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 } else {<br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 #wait 5 seconds and try again<br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Start-Sleep -Seconds &#8216;5&#8217;<br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 $retryCount++<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }<br aria-hidden=\"true\" \/>\u00a0 \u00a0 \u00a0 \u00a0 }<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>\u00a0 \u00a0 }<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>}<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>#email out<br aria-hidden=\"true\" \/><br aria-hidden=\"true\" \/>$EmailFrom = %FROMEMAIL%&#8221;;<br aria-hidden=\"true\" \/>$EmailTo = &#8221; %TOEMAIL%\u00a0 &#8220;;<br aria-hidden=\"true\" \/>#Note: Use comma separated list if more than one CC email address below:<br aria-hidden=\"true\" \/>$EmailCopies = &#8221; %TOEMAIL% &#8220;;\u00a0<br aria-hidden=\"true\" \/>if($Body -like &#8216;*Error*&#8217;) {$Subject= &#8216;Keysecure Backup Error&#8217;} Else { $Subject = &#8216;Keysecure Backup Success&#8217;} ;<br aria-hidden=\"true\" \/>$Body = $body;<br aria-hidden=\"true\" \/>$mailMessage = New-Object Net.Mail.MailMessage($EmailFrom, $EmailTo, $Subject, $Body);<br aria-hidden=\"true\" \/>foreach ($addr in $EmailCopies.split(&#8216;,&#8217;)) {<br aria-hidden=\"true\" \/>$mailMessage.CC.Add($addr );<br aria-hidden=\"true\" \/>}<br aria-hidden=\"true\" \/>$mailMessage.IsBodyHtml = $true;<br aria-hidden=\"true\" \/>$SMTPServer = &#8220;%SMTP%&#8221;;<br aria-hidden=\"true\" \/># Make Windows negotiate higher TLS version:<br aria-hidden=\"true\" \/>[System.Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;<br aria-hidden=\"true\" \/>$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer);<br aria-hidden=\"true\" \/>$SMTPClient.EnableSsl = $true;<br aria-hidden=\"true\" \/>$SMTPClient.Send($mailMessage);<\/p>","protected":false},"excerpt":{"rendered":"<p># KeySecure API endpoint and POST params$keysecures = @(&#8220;%KeysecureIPorDNS%&#8221;)#Import Credentials from Credential XML, this is protected by file level application for security Format &lt;Credentials&gt;&lt;Credential&gt;&lt;Name\\User\\Password&gt;keysecure&lt;\/Name\\User\\Password&gt;&lt;\/Credential&gt;&lt;\/Credentials&gt;$credxml = Select-Xml -Path [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-5372","post","type-post","status-publish","format-standard","hentry","category-research"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/pariswells.com\/blog\/wp-json\/wp\/v2\/posts\/5372","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pariswells.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pariswells.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pariswells.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pariswells.com\/blog\/wp-json\/wp\/v2\/comments?post=5372"}],"version-history":[{"count":1,"href":"https:\/\/pariswells.com\/blog\/wp-json\/wp\/v2\/posts\/5372\/revisions"}],"predecessor-version":[{"id":5373,"href":"https:\/\/pariswells.com\/blog\/wp-json\/wp\/v2\/posts\/5372\/revisions\/5373"}],"wp:attachment":[{"href":"https:\/\/pariswells.com\/blog\/wp-json\/wp\/v2\/media?parent=5372"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pariswells.com\/blog\/wp-json\/wp\/v2\/categories?post=5372"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pariswells.com\/blog\/wp-json\/wp\/v2\/tags?post=5372"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}