ps/Modules/Alkami.DevOps.Common/Public/Get-UserCredentialsFromSecretServer.ps1

123 lines
4.7 KiB
PowerShell
Raw Permalink Normal View History

2023-05-30 22:51:22 -07:00
function Get-UserCredentialsFromSecretServer () {
<#
.SYNOPSIS
Gets the username and password of a user secret from Secret Server.
.PARAMETER secretCredential
Credentials of the user to authenticate with on Secret Server.
.PARAMETER folderName
The name of the folder the secret is in on Secret Server.
.PARAMETER secretName
The name of the secret on Secret Server
.OUTPUTS
Either a credential object containing the username and password of the user or null.
.EXAMPLE
Get-UserCredentialsFromSecretServer -secretCredential $credential -folderName "Entrust 17-0" -secretName "Entrust 17-0 Master1 User"
Password Username
-------- --------
SecretStuffs Master1
#>
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[PSCredential]$secretCredential,
[Parameter(Mandatory=$true)]
[String]$folderName,
[Parameter(Mandatory=$true)]
[String]$secretName
)
$loglead = (Get-LogLeadName)
$secretServerUri = (Get-SecretServerUri)
# TODO: If the low-level function accepts credential objects, this can be simplified.
Write-Verbose "$loglead : Creating Secret Server Connection to $secretServerUri with UserName $($secretCredential.UserName)"
$secretServer = Get-SecretServerConnection $secretServerUri $secretCredential.UserName (Get-PasswordFromCredential $secretCredential)
Write-Verbose "$loglead : Authenticating to SecretServer with No 2FA"
$secretServer.Authenticate($false)
Write-Verbose "$loglead : Searching for folder named '$folderName'"
[array]$folderIds = $secretServer.GetFolderIdByName($folderName)
if ( Test-IsCollectionNullOrEmpty $folderIds ) {
Write-Error "$logLead : Could not find a match for folder name '$folderName'. Returning null"
return $null
}
foreach ($folderIdentifier in $folderIds) {
# This will return an array of secret records
Write-Host "$loglead Searching for secrets with name '$secretName' in folder ID '$folderIdentifier'"
$matchingSecrets = $secretServer.GetSecretByName($secretName, $folderIdentifier)
$potentialSecretsCount = $matchingSecrets.Records.Count
if($null -eq $matchingSecrets -or $potentialSecretsCount -eq 0) {
if ($folderIds.Count -eq 1) {
Write-Error "$loglead : Could not find secrets matching derived secret name '$secretName' in folder with ID $folderIdentifier"
return $null
}
Write-Host "$loglead : Could not find secrets matching derived secret name '$secretName' in folder with ID $folderIdentifier. Continuing..."
continue
}
if ($potentialSecretsCount -gt 1) {
# We found more than one secret. Look for an exact name match
Write-Verbose "$logLead : Found $potentialSecretsCount Secrets Matching Search String '$secretName'."
foreach ($potentialSecret in $matchingSecrets.Records) {
if ($potentialSecret.name -eq $secretName) {
Write-Host "$logLead : Secret with ID $($potentialSecret.Id) has an exact name match with search string '$secretName'"
$targetSecret = $potentialSecret
break
}
}
if ($null -eq $targetSecret) {
Write-Error "$logLead : Could not find an exact match to search string '$secretName' and more than one partial match was found. Returning null"
return $null
}
} else {
# Only 1 result was found, we're using it
$targetSecret = $matchingSecrets.Records | Select-Object -First 1
}
}
$targetSecretId = $targetSecret.Id
Write-Host "$logLead : Pulling secret details for secret with ID '$targetSecretId'"
$secret = $secretServer.GetSecretById($targetSecretId)
$username = ($secret.Items | Where-Object { $_.fieldName -eq "Username" } | Select-Object -First 1).ItemValue
$password = ($secret.Items | Where-Object { $_.fieldName -eq "Password" } | Select-Object -First 1).ItemValue
$returnEarly = $false
if([string]::IsNullOrWhiteSpace($username)) {
Write-Error "$loglead : Could not find Username value in secret '$($secret.Name)'"
$returnEarly = $true
} elseif([string]::IsNullOrWhiteSpace($password)) {
Write-Error "$loglead : Could not find Password value in secret '$($secret.Name)'"
$returnEarly = $true
}
if ($returnEarly) {
Write-Warning "$logLead : Either the Username or Password (or both) were null/empty for secret '$secretName'"
return $null
}
return ( New-Object System.Management.Automation.PSCredential ( $username , ( Get-SecureString $password ) ) )
}