function Register-DSCConfigurationDataCredentialProvider { [CmdletBinding(SupportsShouldProcess=$true)] Param( [Parameter(Mandatory=$true)] [string] $Vault, [Parameter(Mandatory=$false)] [string] $KeyPath, [Parameter(Mandatory=$false)] [string] $SettingsPath, [Parameter(Mandatory=$false)] [System.Security.SecureString] $MasterKey, [Parameter(Mandatory=$false)] [string] $ModuleName, [Parameter(Mandatory=$false)] [hashtable] $VaultParameters = @{}, [Parameter(Mandatory=$false)] [switch] $RegisterVault, [Parameter(Mandatory=$false)] [switch] $DefaultVault, [Parameter(Mandatory=$false)] [switch] $AllowClobber, [Parameter(Mandatory=$false)] [switch] $ConfigureSecretStore, [Parameter(Mandatory=$false)] [ValidateSet("None", "Password")] [string] $Authentication = "None", [Parameter(Mandatory=$false)] [ValidateSet("None", "Prompt")] [string] $Interaction = "None", [Parameter(Mandatory=$false)] [System.Security.SecureString] $Password, [Parameter(Mandatory=$false)] [int] $PasswordTimeout, [Parameter(Mandatory=$false)] [switch] $Force, [Parameter(Mandatory=$false)] [switch] $PassThru ) DynamicParam { $ProviderNames = @(Get-ConfigurationDataSecretProviderName) if($ProviderNames.Count -eq 0){ $ProviderNames = @("__NoProvidersRegistered__") } $ParameterAttribute = [System.Management.Automation.ParameterAttribute]::new() $ParameterAttribute.Mandatory = $false $ParameterAttribute.Position = 0 $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute -ArgumentList (,[string[]]$ProviderNames) $Attributes = [System.Collections.ObjectModel.Collection[System.Attribute]]::new() $Attributes.Add($ParameterAttribute) $Attributes.Add($ValidateSetAttribute) $RuntimeParameter = [System.Management.Automation.RuntimeDefinedParameter]::new( "Provider", [string], $Attributes ) $Dictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() $Dictionary.Add("Provider", $RuntimeParameter) return $Dictionary } begin { $Provider = [string]$PSBoundParameters["Provider"] if([string]::IsNullOrWhiteSpace($Provider)){ $ProviderNames = @(Get-ConfigurationDataSecretProviderName) if($ProviderNames.Count -eq 1){ $Provider = $ProviderNames[0] }elseif($ProviderNames.Count -eq 0){ throw "No configuration data secret providers are registered." }else{ throw "Provider is required. Registered providers: $($ProviderNames -join ', ')." } } $SettingsPath = Resolve-ConfigurationDataProviderSettingsPath -Provider $Provider -SettingsPath $SettingsPath } process { switch($Provider){ "KeePass" { if([string]::IsNullOrWhiteSpace($KeyPath)){ throw "Provider [KeePass] requires [KeyPath]." } if($null -eq $MasterKey){ $MasterKey = Read-Host -Prompt "KeePass MasterKey for vault [$Vault]" -AsSecureString } if($PSCmdlet.ShouldProcess($SettingsPath, "Create provider settings for [$Provider]")){ $Key = New-ConfigurationDataAesKeyFile -Path $KeyPath -Force:$Force $ProtectedValue = $MasterKey | ConvertFrom-SecureString -Key $Key $ProviderSettings = [ordered]@{ KeePass = [ordered]@{ DefaultVault = $Vault MasterKey = [ordered]@{ ProtectedValue = $ProtectedValue KeyPath = $KeyPath } } } Export-PowerShellDataFile -InputObject $ProviderSettings -Path $SettingsPath -Force:$Force if($PassThru){ return $ProviderSettings } Write-Verbose "Provider settings written to [$SettingsPath]." } } "SecretManagement" { if([string]::IsNullOrWhiteSpace($ModuleName)){ $ModuleName = "Microsoft.PowerShell.SecretStore" } if($RegisterVault -or $PSBoundParameters.ContainsKey("ModuleName")){ $CommandParameters = @{ Name = $Vault ModuleName = $ModuleName } if($VaultParameters.Count -gt 0){ $CommandParameters["VaultParameters"] = $VaultParameters } if($DefaultVault){ $CommandParameters["DefaultVault"] = $true } if($AllowClobber){ $CommandParameters["AllowClobber"] = $true } if($PSCmdlet.ShouldProcess($Vault, "Register SecretManagement vault [$ModuleName]")){ Register-SecretVault @CommandParameters } } $ProviderSettings = [ordered]@{ SecretManagement = [ordered]@{ DefaultVault = $Vault } } if($PSCmdlet.ShouldProcess($SettingsPath, "Create provider settings for [$Provider]")){ Export-PowerShellDataFile -InputObject $ProviderSettings -Path $SettingsPath -Force:$Force } if($PassThru){ return $ProviderSettings } } "SecretStore" { if($ConfigureSecretStore){ $CommandParameters = @{ Authentication = $Authentication Interaction = $Interaction } if($null -ne $Password){ $CommandParameters["Password"] = $Password } if($PasswordTimeout -gt 0){ $CommandParameters["PasswordTimeout"] = $PasswordTimeout } if($PSCmdlet.ShouldProcess("SecretStore", "Configure local SecretStore")){ Set-SecretStoreConfiguration @CommandParameters -Confirm:$false } } if($RegisterVault){ $CommandParameters = @{ Name = $Vault ModuleName = "Microsoft.PowerShell.SecretStore" } if($DefaultVault){ $CommandParameters["DefaultVault"] = $true } if($AllowClobber){ $CommandParameters["AllowClobber"] = $true } if($PSCmdlet.ShouldProcess($Vault, "Register SecretStore vault")){ Register-SecretVault @CommandParameters } } $ProviderSettings = [ordered]@{ SecretStore = [ordered]@{ DefaultVault = $Vault } } if($PSCmdlet.ShouldProcess($SettingsPath, "Create provider settings for [$Provider]")){ Export-PowerShellDataFile -InputObject $ProviderSettings -Path $SettingsPath -Force:$Force } if($PassThru){ return $ProviderSettings } } default { throw "Provider [$Provider] does not provide an initialization implementation." } } } }