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 ) ) ) }