Skip to content
10 changes: 10 additions & 0 deletions resources/windows_secretstore/.project.data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"Name": "WindowsSecretStore",
"Kind": "Resource",
"CopyFiles": {
"Windows": [
"windows_secretstore.ps1",
"windows_secretstore.dsc.resource.json"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

Describe 'Windows SecretStore config tests' -Skip:(!$IsWindows) {
BeforeAll {
Set-StrictMode -Version Latest

function Install-TestModule {
param(
[Parameter(Mandatory = $true)]
[string]$Name
)

if (Get-Module -ListAvailable -Name $Name -ErrorAction SilentlyContinue | Select-Object -First 1) {
return
}

$installPsResourceCommand = Get-Command -Name Install-PSResource -ErrorAction SilentlyContinue
if (-not $installPsResourceCommand) {
throw "Install-PSResource is required to install test dependency module '$Name'."
Install-PSResource -Name $Name -Scope CurrentUser -TrustRepository -Quiet -ErrorAction Stop
}
Install-PSResource -Name $Name -Scope CurrentUser -TrustRepository -Quiet -ErrorAction Stop
}

foreach ($moduleName in @(
'Pester',
'Microsoft.PowerShell.SecretManagement',
'Microsoft.PowerShell.SecretStore'
)) {
Install-TestModule -Name $moduleName
}

Import-Module Microsoft.PowerShell.SecretManagement -Force -ErrorAction Stop
Import-Module Microsoft.PowerShell.SecretStore -Force -ErrorAction Stop

function Reset-SecretStoreForTest {
Reset-SecretStore -Authentication None -Interaction None -PasswordTimeout -1 -Force -Confirm:$false -ErrorAction Stop | Out-Null
}

# Inline DSC config: none-auth (unattended automation)
$script:configNone = @'
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Configure SecretStore for unattended automation
type: Microsoft.PowerShell/WindowsSecretStore
properties:
authentication: None
passwordTimeout: -1
interaction: None
scope: CurrentUser
'@

# Inline DSC config: password-auth with secureString parameter
$script:configPassword = @'
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
parameters:
SecretPassword:
type: secureString
defaultValue: TestSecretValue
resources:
- name: Configure SecretStore for unattended automation
type: Microsoft.PowerShell/WindowsSecretStore
properties:
authentication: Password
passwordTimeout: -1
interaction: None
scope: CurrentUser
password: "[parameters('SecretPassword')]"
'@
}

BeforeEach {
Reset-SecretStoreForTest
}

Context 'dsc config set then test (none-auth)' {
It 'applies the none-auth configuration via dsc config set' {
$null = dsc config set -i $script:configNone 2>"$TestDrive/set.stderr"
$LASTEXITCODE | Should -Be 0 -Because (Get-Content -Raw "$TestDrive/set.stderr")
}

It 'reports desired state via dsc config test' {
$null = dsc config set -i $script:configNone 2>"$TestDrive/set.stderr"
$LASTEXITCODE | Should -Be 0 -Because (Get-Content -Raw "$TestDrive/set.stderr")

$out = dsc config test -i $script:configNone 2>"$TestDrive/test.stderr" | ConvertFrom-Json -Depth 10
$LASTEXITCODE | Should -Be 0 -Because (Get-Content -Raw "$TestDrive/test.stderr")

$result = $out.results[0].result
$result.inDesiredState | Should -BeTrue
}

It 'returns current state via dsc config get' {
$null = dsc config set -i $script:configNone 2>"$TestDrive/set.stderr"
$LASTEXITCODE | Should -Be 0 -Because (Get-Content -Raw "$TestDrive/set.stderr")

$out = dsc config get -i $script:configNone 2>"$TestDrive/get.stderr" | ConvertFrom-Json -Depth 10
$LASTEXITCODE | Should -Be 0 -Because (Get-Content -Raw "$TestDrive/get.stderr")

$actualState = $out.results[0].result.actualState
$actualState.authentication | Should -BeExactly 'None'
$actualState.interaction | Should -BeExactly 'None'
$actualState.passwordTimeout | Should -Be -1
$actualState.scope | Should -BeExactly 'CurrentUser'
}
}

Context 'dsc config set then test (password-auth)' {
It 'applies the password-auth configuration via dsc config set' {
$null = dsc config set -i $script:configPassword 2>"$TestDrive/set.stderr"
$LASTEXITCODE | Should -Be 0 -Because (Get-Content -Raw "$TestDrive/set.stderr")
}

It 'reports desired state via dsc config test' {
$null = dsc config set -i $script:configPassword 2>"$TestDrive/set.stderr"
$LASTEXITCODE | Should -Be 0 -Because (Get-Content -Raw "$TestDrive/set.stderr")

$out = dsc config test -i $script:configPassword 2>"$TestDrive/test.stderr" | ConvertFrom-Json -Depth 10
$LASTEXITCODE | Should -Be 0 -Because (Get-Content -Raw "$TestDrive/test.stderr")

$result = $out.results[0].result
$result.inDesiredState | Should -BeTrue
}

It 'returns current state via dsc config get' {
$null = dsc config set -i $script:configPassword 2>"$TestDrive/set.stderr"
$LASTEXITCODE | Should -Be 0 -Because (Get-Content -Raw "$TestDrive/set.stderr")

$out = dsc config get -i $script:configPassword 2>"$TestDrive/get.stderr" | ConvertFrom-Json -Depth 10
$LASTEXITCODE | Should -Be 0 -Because (Get-Content -Raw "$TestDrive/get.stderr")

$actualState = $out.results[0].result.actualState
$actualState.authentication | Should -BeExactly 'Password'
$actualState.interaction | Should -BeExactly 'None'
$actualState.passwordTimeout | Should -Be -1
$actualState.scope | Should -BeExactly 'CurrentUser'
}
}
}
113 changes: 113 additions & 0 deletions resources/windows_secretstore/windows_secretstore.dsc.resource.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
{
"$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json",
"type": "Microsoft.PowerShell/WindowsSecretStore",
"version": "0.1.0",
"description": "Manages the configuration of the Microsoft.PowerShell.SecretStore vault (authentication mode, password timeout, interaction policy, and scope).",
"tags": [
"Windows",
"PowerShell",
"SecretStore",
"SecretManagement",
"Security"
],
"condition": "[not(equals(tryWhich('pwsh'), null()))]",
"get": {
"executable": "pwsh",
"args": [
"-NoLogo",
"-NonInteractive",
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-Command",
"$input | ./windows_secretstore.ps1 Get"
],
"input": "stdin"
},
"set": {
"executable": "pwsh",
"args": [
"-NoLogo",
"-NonInteractive",
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-Command",
"$input | ./windows_secretstore.ps1 Set"
],
"input": "stdin",
"implementsPretest": false,
"return": "state"
},
"test": {
"executable": "pwsh",
"args": [
"-NoLogo",
"-NonInteractive",
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-Command",
"$input | ./windows_secretstore.ps1 Test"
],
"input": "stdin",
"return": "state"
},
"exitCodes": {
"0": "Success",
"1": "Operation failed (module missing or cmdlet error)"
},
"schema": {
"embedded": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Microsoft.PowerShell/WindowsSecretStore",
"description": "Properties that describe the configuration of the Microsoft.PowerShell.SecretStore vault.",
"type": "object",
"properties": {
"authentication": {
"title": "Authentication",
"description": "Specifies the SecretStore authentication mode for vault access. Allowed values are 'None', 'Prompt', and 'Password'.",
"type": "string",
"enum": [
"None",
"Prompt",
"Password"
]
},
Comment thread
mimachniak marked this conversation as resolved.
"passwordTimeout": {
"title": "Password Timeout",
"description": "Specifies how many seconds the vault remains unlocked after successful authentication. Use -1 to disable the timeout (vault stays unlocked indefinitely for the session).",
"type": "integer",
"minimum": -1
},
"interaction": {
"title": "Interaction",
"description": "Controls whether the vault is allowed to prompt the user for interaction (e.g., password input). This DSC resource runs non-interactively and only supports 'None'.",
"type": "string",
"enum": [
"None"
]
},
"scope": {
"title": "Scope",
"description": "Specifies whether the SecretStore vault is configured for the current user ('CurrentUser') or all users on the machine ('AllUsers'). Changing scope may require elevated privileges.",
"type": "string",
"enum": [
"CurrentUser",
"AllUsers"
]
},
Comment thread
mimachniak marked this conversation as resolved.
"_inDesiredState": {
"title": "In Desired State",
"description": "Indicates whether the resource is in the desired state. Populated by the Test operation.",
"type": [
"boolean",
"null"
],
"default": null
},
"additionalProperties": false
}
Comment thread
mimachniak marked this conversation as resolved.
}
}
}
Loading
Loading