With the new powershell module SecretsManagement it is possible to add plugins. The new module is used to get/add/remove credentials. I created a plugin for secretserver to this module.
To get started you will have to install secretsmanagement:
Install-Module -Name Microsoft.Powershell.SecretsManagement -AllowPrerelease
If -AllowPrerelase is not an option you would have to update PowershellGet first. ( install-script powershellget )
After SecretManagement has been installed you can run :
add-secret -Name "Test" -secret (get-credential) -vault -builtinlocalvault
, followed by
get-secret Test
.
But I would like to have a uniform cmdlet for all my credentials. So I used Secrets Management Module Vault Extensions to get me started.
If you would like to install my module from powershell gallery run :
install-module -name secretsmanagement.secretserver
A bit more info for those interested
First created a new folder structure below C:\Program Files\WindowsPowerShell\Modules\
Secretsmanagement\0.0.3\SecretsManagementExtension
In the version folder “0.0.3” i added 2 files : Readme.txt (How to register vault) and SecretsManagement.SecretServer.psd1 ( Datafile for the module)
# Module manifest for module 'SecretsManagement.SecretServer'
# Generated by: Atle Vatland
# Generated on: 2/12/2020
@{
# Script module or binary module file associated with this manifest.
# RootModule = ''
# Version number of this module.
ModuleVersion = '0.0.3'
# Supported PSEditions
CompatiblePSEditions = @('Desktop')
# ID used to uniquely identify this module
GUID = 'e25aacec-637f-4935-bbd9-463a75ba46ea'
# Author of this module
Author = 'Atle Vatland'
# Copyright statement for this module
Copyright = '(c) 2020 Atle Vatland. All rights reserved.'
# Description of the functionality provided by this module
Description = 'Proof of concept for Secretserver( by Thycotic ) vault extension for powershell. Remove-secret is not implemented in this test.'
# Modules that must be imported into the global environment prior to importing this module
PowershellVersion = '5.1'
}
The subfolder has to be named “SecretsManagementExtension” also the scripts has to be named SecretsManagementExtension.psm1 and .psd1
What gave me some hassle was that the add-secret cmdlet actually calls set-secret in the extension.
SecretsManagementExtension.psd1:
@{
ModuleVersion = '1.0'
RootModule = '.\SecretsManagementExtension.psm1'
PowershellVersion = '5.1'
FunctionsToExport = @('Get-Secret','Set-Secret','Remove-Secret','Get-SecretInfo')
PrivateData = @{
PSData = @{
# A URL to the license for this module.
LicenseUri = 'https://opensource.org/licenses/MIT'
} # End of PSData hashtable
} # End of PrivateData hashtable
}
Have not implemented remove-secret as we do not want to to delete any secrets.
SecretsManagementExtension.psm1:
# Licensed under the MIT License.
function Get-Secret
{
param (
[string]$Name,
[hashtable]$AdditionalParameters
)
$where = $AdditionalParameters.secretserveruri
$ws = New-WebServiceProxy -uri $where -Credential $AdditionalParameters.secretservercredential #-ErrorAction SilentlyContinue
$wsResult = $ws.GetSecret([int]$name, $false, $null)
[PSCredential]::new($wsResult.Secret.Items[1].value.ToString(), ($wsResult.Secret.Items[2].value.ToString()|ConvertTo-SecureString -AsPlainText -Force))
}
function set-secret
{
param (
[string] $Name,
[object] $Secret,
[hashtable] $AdditionalParameters
)
$where = $AdditionalParameters.secretserveruri
$cred= $AdditionalParameters.secretservercredential
$secretserverfolder=$AdditionalParameters.secretserverfolderid
if($secretserverfolder -eq $null){
$secretserverfolder=44
}
$domain=$Name
$templatename=$AdditionalParameters.secretservertemplate
if($templatename -eq $null){
$templatename= "Windows Account"
}
if($Secret -eq $null){
throw "Secret can not be null."
}
elseif($secret -is [string]){
throw "String is currently not supported"
}
elseif($secret -is [hashtable]){
throw "String is currently not supported"
}
elseif ($secret -is [PSCredential]){
$username = $Secret.username
$password = $secret.GetNetworkCredential().password
}
$ws = New-WebServiceProxy -uri $where -Credential $cred
# Get Template
$template = $ws.GetSecretTemplates().SecretTemplates | Where {$_.Name -eq $templateName}
# Set fields info
$secretName = $domain + "-" + $UserName
$secretItemFields = (($template.Fields | Where {$_.DisplayName -eq "Machine"}).Id, ($template.Fields | Where {$_.DisplayName -eq "Username"}).Id, ($template.Fields | Where {$_.DisplayName -eq "Password"}).Id, ($template.Fields | Where {$_.DisplayName -eq "Notes"}).Id)
$secretItemValues=($domain,$UserName,$password, "")
$folderId = $secretserverfolder
# Add secret to secretserver.
$addResult = $ws.AddSecret($template.Id, $secretName, $secretItemFields, $secretItemValues, $folderId)
if($addResult.Errors.Count -gt 0){
return $false
}else{
return $true
}
}
function Remove-Secret
{
param (
[string] $Name,
[hashtable] $AdditionalParameters
)
throw "Not implemented"
}
function Get-SecretInfo
{
param(
[string] $filter,
[hashtable] $AdditionalParameters
)
if ([string]::IsNullOrEmpty($filter)) { $filter = "*" }
$where = $AdditionalParameters.secretserveruri
$ws = New-WebServiceProxy -uri $where -Credential $AdditionalParameters.secretservercredential # -ErrorAction SilentlyContinue
$hits=$ws.SearchSecrets($filter,$null,$null)
$result=@()
foreach($hit in $hits.SecretSummaries){
$result+= ([pscustomobject] @{
Name = $($hit.secretid.tostring())
Value = $($hit.secretName.ToString())
})
}
$result
}
To register this extension for module for SecretsManagement there are some required parameters.
Credentials used to access secretserver, secretserver web service url, default template and default folder.
Credential and parameters are stored encrypted in Credential Manager.
[pscredential]$c=Get-Credential # Secretserver credential
Register-SecretsVault -Name "VaultName" -ModuleName secretsmanagement.secretserver -VaultParameters @{
secretservercredential=$c # Account used to connect to secret server.
secretserveruri="https://secretserver.domain.local/secretserver/winauthwebservices/sswinauthwebservice.asmx" # Webservice uri
secretserverfolderid="44" # New secrets are stored in this folder. Folder id -1 is default if not specified.
secretservertemplate="Windows Account" # Template used when creating new secrets. "Windows Account" is default if not specified.
}