148 lines
6.0 KiB
PowerShell
148 lines
6.0 KiB
PowerShell
function Publish-PodToSecretServer {
|
|
<#
|
|
.SYNOPSIS
|
|
Publish Pod's Certificates to Secret Server.
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory = $false)]
|
|
[string[]]$ADGroups,
|
|
[Parameter(Mandatory = $false)]
|
|
[PSObject]$Pod,
|
|
[Parameter (Mandatory = $false)]
|
|
[string]$PodName,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$SecretServerUserName,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$SecretServerPassword,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$SecretServerUrl ="https://alkami.secretservercloud.com",
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$TempFolder = "C:\Temp",
|
|
[Parameter(Mandatory = $false)]
|
|
[ValidateSet("Production", "Staging")]
|
|
[string]$EnvironmentType,
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$SubFolder
|
|
)
|
|
begin {
|
|
Import-AWSModule # SSM
|
|
|
|
switch ($EnvironmentType) {
|
|
"Production" {$RootFolderName = "Production-CertApi"}
|
|
"Staging" {$RootFolderName = "Staging-CertApi"}
|
|
}
|
|
|
|
# Get all parmeters which weren't supplied.
|
|
if(!$EnvironmentType)
|
|
{
|
|
$EnvironmentType = Get-AppSetting Environment.Type
|
|
}
|
|
|
|
if(!$PodName)
|
|
{
|
|
$PodName = Get-AppSetting Environment.Name
|
|
}
|
|
|
|
if(!$SubFolder)
|
|
{
|
|
$SubFolder = Get-AppSetting Environment.Server
|
|
}
|
|
|
|
if((!$SecretServerUserName -or !$SecretServerPassword))
|
|
{
|
|
if(Test-IsAws)
|
|
{
|
|
if(!$SecretServerUserName) {
|
|
$SecretServerUserName = (Get-SSMParameter -Name "secret_server_api_username" -WithDecryption $true).Value
|
|
}
|
|
|
|
if(!$SecretServerPassword) {
|
|
$SecretServerPassword = (Get-SSMParameter -Name "secret_server_api_password" -WithDecryption $true).Value
|
|
}
|
|
}
|
|
else {
|
|
Write-Error "Secret credentials must be manually provided if this is run on a non-AWS machine. They cannot be retrieved from SSM."
|
|
}
|
|
}
|
|
|
|
if (!$Pod) {
|
|
$PodName = "$PodName-CertApi" # Tack on something to make the folder name distinct from manually created folders.
|
|
$Pod = Export-CertificatesToFileSystem -PodName $PodName -ADGroups $ADGroups
|
|
}
|
|
|
|
$secretServer = [SecretServerConnection]::new($SecretServerUrl, $SecretServerUserName, $SecretServerPassword)
|
|
$UseTwoFactor = $false
|
|
$secretServer.Authenticate($UseTwoFactor)
|
|
|
|
Add-Type -Assembly System.IO.Compression.FileSystem
|
|
}
|
|
|
|
process {
|
|
|
|
#Zip certficates and their chain
|
|
$certificatesFromAllStores = $Pod.Stores.Values.Certificates.Values
|
|
Compress-Certificates $certificatesFromAllStores $TempFolder
|
|
|
|
#Create folder for this pod
|
|
$rootFolderId = $SecretServer.GetFolderIdByName($RootFolderName)
|
|
|
|
$podFolderId = $secretServer.GetFolderIdByName($Pod.PodName, $rootFolderId)
|
|
if (!$podFolderId) {
|
|
$podFolderId = $secretServer.AddFolder($rootFolderId, $Pod.PodName)
|
|
}
|
|
|
|
$subFolderId = $secretServer.GetFolderIdByName($Subfolder, $podFolderId)
|
|
if (!$subFolderId) {
|
|
$subFolderId = $secretServer.AddFolder($podFolderId, $Subfolder)
|
|
}
|
|
|
|
foreach ($store in $Pod.Stores.Keys) {
|
|
$storeFolderId = $secretServer.GetFolderIdByName($store, $subFolderId)
|
|
if (!$storeFolderId) {
|
|
$storeFolderId = $secretServer.AddFolder($subFolderId, $store)
|
|
}
|
|
$certificates = $Pod.Stores.$store.Certificates.Values
|
|
|
|
foreach ($certificate in $certificates) {
|
|
|
|
try {
|
|
#Process
|
|
#Get a new secret template
|
|
$templateId = $secretServer.GetSecretTemplateIdByName("CertificateStore")
|
|
$secret = $SecretServer.GetSecretTemplateById($templateId, $storeFolderId)
|
|
|
|
# Configure the secret
|
|
# Each of these two line blocks creates a *reference* to a specific item in the secret.items list. That reference is then set to the correct
|
|
# certificate field value, which updates the $secret.items[x].itemValue value. Clear as mud?
|
|
$certName = $secret.items | Where-Object {$_.fieldName -eq "Certificate Name"}
|
|
$certName.itemValue = $certificate.Name
|
|
|
|
$certPassword = $secret.items | Where-Object {$_.fieldName -eq "Import Password"}
|
|
$certPassword.itemValue = $certificate.Password
|
|
|
|
$certNotes = $secret.items | Where-Object {$_.fieldName -eq "Notes"}
|
|
$certNotes.itemValue = "ADGroups with access to this certificate: $($certificate.ADGroups)"
|
|
|
|
$certThumbprint = $secret.items | Where-Object {$_.fieldName -eq "Thumbprint"}
|
|
$certThumbprint.itemValue = $certificate.Thumbprint
|
|
|
|
$certExpirationDate = $secret.items | Where-Object {$_.fieldName -eq "ExperationDate"} # Yes, Expiration is mispelled, because Thycotic.
|
|
$certExpirationDate.itemValue = $certificate.ExpirationDate.ToShortDateString()
|
|
|
|
$secretName = $certificate.Name, $certificate.thumbprint, $store.ToString()[0] -join "-"
|
|
$secretId = $secretServer.CreateSecret($secret, $storeFolderId, $secretName)
|
|
|
|
#Upload certificate zip folder
|
|
Write-Output "Publishing certificate $($certificate.Name)"
|
|
$zipFilePath = $certificate.Folder, ($certificate.Name.Trim() + ".zip") -join "\"
|
|
$secretServer.UploadFile($secretId, "pfx-File", $zipFilePath)
|
|
}
|
|
catch [InvalidOperationException] {
|
|
Write-Warning "There was a problem publishing a certificate."
|
|
Write-Warning $_
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |