Skip to content

Commit f5ff20b

Browse files
author
Ben Small
committed
Merge branch 'bsmall_convertto_pscred_function' into 'master'
ConvertTo-PSCredential & Bugfixes See merge request Infra/module-vaultutils!4
2 parents a6be19a + 4549005 commit f5ff20b

File tree

6 files changed

+182
-11
lines changed

6 files changed

+182
-11
lines changed

.gitlab-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
variables:
22
ModuleName: 'psVaultUtils'
3-
ModuleVersion: '1.3.2'
3+
ModuleVersion: '1.4.1'
44
DevRepository: 'dev-windows-modules'
55
ProdRepository: 'prod-windows-modules'
66
Notification: "it-digest"

psVaultUtils/Public/Secrets/Cubbyhole/Get-VaultCubbyholeSecret.ps1

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,9 @@ function Get-VaultCubbyholeSecret {
7171
throw
7272
}
7373

74-
if ($MetaData) {
75-
$dataType = 'secret_metadata'
76-
}
77-
else {
78-
$dataType = 'secret_data'
79-
}
80-
8174
$formatParams = @{
8275
InputObject = $result
83-
DataType = $dataType
76+
DataType = 'data' #Cubbyhole secrets do not/cannot have metadata.
8477
JustData = $JustData.IsPresent
8578
OutputType = $OutputType
8679
}

psVaultUtils/Public/Secrets/KV/New-VaultKVSecret.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ function New-VaultKVSecret {
5858
param(
5959
#Specifies a KV engine to write secrets to.
6060
[Parameter(
61-
Mandatoy = $true,
61+
Mandatory = $true,
6262
Position = 0
6363
)]
6464
[String] $Engine,
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#Credit: https://4sysops.com/archives/convert-json-to-a-powershell-hash-table/
2+
#This function is the result of reverse engineering ConvertTo-Hashtable, written by Adam Bertram
3+
4+
#BUG: ConvertFrom-Hashtable currently does not support pipeline input;
5+
#Sub-hashtables are not successfully converted to pscustomobjects.
6+
7+
function ConvertFrom-Hashtable {
8+
<#
9+
.Synopsis
10+
Converts a Hashtable into a PSObject.
11+
12+
.DESCRIPTION
13+
ConvertFrom-Hashtable converts a Hashtable into a PSObject.
14+
15+
The function does not currently support pipeline input.
16+
17+
.EXAMPLE
18+
PS> $secret = Get-VaultKVSecret -Engine 'KVStore' -SecretsPath 'ServiceAccounts/DSCSvcAccount' -OutputType Hashtable
19+
20+
PS> ConvertFrom-Hashtable $secret
21+
22+
renewable : False
23+
data : @{metadata=; data=}
24+
warnings :
25+
wrap_info :
26+
request_id : e7450e9e-e48c-e17d-8c16-db7d38790d64
27+
lease_duration : 0
28+
auth :
29+
lease_id :
30+
31+
This example demonstrates converting a Hashtable to a PSObject.
32+
The example is impractical because Get-VaultKVSecret supports returning results as PSObjects.
33+
34+
#>
35+
[CmdletBinding()]
36+
[OutputType('pscustomobject')]
37+
param (
38+
[Parameter()]
39+
$InputObject
40+
)
41+
42+
process {
43+
## Return null if the input is null. This can happen when calling the function
44+
## recursively and a property is null
45+
if ($null -eq $InputObject) {
46+
return $null
47+
}
48+
49+
## Check if the input is an array or collection. If so, we also need to convert
50+
## those types into psobjects as well. This function will convert all child
51+
## hashtables into psobjects (if applicable)
52+
if ($InputObject -is [pscustomobject] -and $InputObject -isnot [string]) {
53+
$collection = @(
54+
foreach ($object in $InputObject.GetEnumerator()) {
55+
ConvertFrom-Hashtable -InputObject $object
56+
}
57+
)
58+
59+
## Return the array but don't enumerate it because the object may be pretty complex
60+
Write-Output -NoEnumerate $collection
61+
} elseif ($InputObject -is [hashtable]) { ## If the hashtable has properties that need enumeration
62+
## Convert it to its own hash table and return it as an object
63+
$hash = @{}
64+
foreach ($property in $InputObject.GetEnumerator()) {
65+
$hash[$property.Name] = ConvertFrom-Hashtable -InputObject $property.Value
66+
}
67+
68+
New-Object 'pscustomobject' -Property $hash
69+
} else {
70+
## If the object isn't an array, collection, or other object, it's already a psobject
71+
## So just return it.
72+
$InputObject
73+
}
74+
}
75+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
function ConvertTo-PSCredential {
2+
<#
3+
.Synopsis
4+
Converts the result of Get-VaultKVSecret or Get-VaultCubbyhole into a PSCredential.
5+
6+
.DESCRIPTION
7+
ConvertTo-PSCredential consumes the result of Get-VaultKVSecret or Get-VaultCubbyhole and converts the resulting object into a PSCredential.
8+
9+
.EXAMPLE
10+
PS> Get-VaultKVSecret -Engine dsc -SecretsPath DSCSvcAccount | ConvertTo-PSCredential
11+
12+
UserName Password
13+
-------- --------
14+
WAYFAIRDEV\sa_dscadmin System.Security.SecureString
15+
16+
.EXAMPLE
17+
PS> ConvertTo-PSCredential -InputObject $(Get-VaultKVSecret -Engine dsc -SecretsPath DSCSvcAccount)
18+
19+
UserName Password
20+
-------- --------
21+
WAYFAIRDEV\sa_dscadmin System.Security.SecureString
22+
23+
#>
24+
[CmdletBinding()]
25+
param(
26+
#Specifies the Input Object. The input object can be in the form of a Hashtable, PSObject or JSON string.
27+
[Parameter(
28+
ValueFromPipeline = $true,
29+
Position = 0
30+
)]
31+
$InputObject
32+
)
33+
34+
begin {
35+
#Array of supported functions.
36+
$supportedFunctions = @(
37+
'Get-VaultKVSecret'
38+
'Get-VaultCubbyholeSecret'
39+
)
40+
41+
$psCallStack = Get-PSCallStack
42+
43+
foreach ($funct in $supportedFunctions) {
44+
$callStackPosition = $psCallStack | Where-Object 'Position' -match $funct
45+
46+
if ($callStackPosition) {
47+
break
48+
}
49+
}
50+
51+
if ($psCallStack -notmatch "|") {
52+
#Pipeline was present.
53+
if (-not $callStackPosition) {
54+
Write-Error "ConvertTo-PSCredential does not support the specified pipeline input." -ErrorAction 'Stop'
55+
return
56+
}
57+
}
58+
#else Pipeline not present.
59+
60+
}
61+
62+
process {
63+
if ($InputObject -is [Hashtable]) {
64+
Write-verbose 'Input is hashtable'
65+
$InputObject = ConvertFrom-Hashtable $([hashtable] $InputObject)
66+
}
67+
elseif ($InputObject -is [String]) {
68+
Write-verbose 'Input is string'
69+
try {
70+
$InputObject = $InputObject | ConvertFrom-Json
71+
Write-verbose 'converted json to psobject'
72+
}
73+
catch {
74+
Write-Error "The specified JSON is malformed and could not be converted to a PSCredential"
75+
return
76+
}
77+
}
78+
else {
79+
Write-verbose 'Input is psobject'
80+
}
81+
82+
$result = Format-VaultOutput -InputObject $InputObject -DataType 'secret_data' -OutputType 'Hashtable' -JustData:$true
83+
84+
if (-not $result) {
85+
#If there was no result, the secret could be a Cubbyhole secret; try a different DataType.
86+
$result = Format-VaultOutput -InputObject $InputObject -DataType 'data' -OutputType 'Hashtable' -JustData:$true
87+
}
88+
89+
if ($result) {
90+
New-Object System.Management.Automation.PSCredential (
91+
$result.Keys[0],
92+
(ConvertTo-SecureString ($result.Values[0]) -AsPlainText -Force)
93+
)
94+
}
95+
96+
}
97+
98+
end {
99+
100+
}
101+
}

psVaultUtils/psVaultUtils.psd1

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
RootModule = 'psVaultUtils.psm1'
1313

1414
# Version number of this module.
15-
ModuleVersion = '1.3.2'
15+
ModuleVersion = '1.4.1'
1616

1717
# Supported PSEditions
1818
# CompatiblePSEditions = @()
@@ -108,8 +108,10 @@
108108
'Submit-VaultRootTokenGeneration'
109109
'Unprotect-VaultRootToken'
110110

111+
'ConvertFrom-Hashtable'
111112
'ConvertTo-Hashtable'
112113
'ConvertTo-Base64'
114+
'ConvertTo-PSCredential'
113115
'Get-VaultRandomBytes'
114116
'Get-VaultDataHash'
115117

0 commit comments

Comments
 (0)