src/Set-CsEntry.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<#
.SYNOPSIS
    Set CredentialStore Entries
.DESCRIPTION
    The Set-CsEntry cmdlet adds or updates CredentialStore entries in a CredentialStore file.
.PARAMETER FilePath
    Specifies the path to the CredentialStore file.
.PARAMETER Name
    Specifies the CredentialStore entry name of entry to be added or updated.
.PARAMETER Description
    A description of the CredentialStore entry.
.PARAMETER Credential
    Specifies the PSCredential of the CredentialStore entry.
.Example
    Set-CsEntry -FilePath CredentialStore.json -Name LocalServer -Credential $cred
    This command sets the CredentialStore entry named LocalServer in the CredentialStore.json file.
.LINK
    https://github.com/fodonnel/CredentialStore
#>

function Set-CsEntry {
    [CmdletBinding(SupportsShouldProcess = $true)]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUsePSCredentialType", "")]
    param(
        [ValidateScript( {
            if (Test-CsEntryName $_) { $true }
            else { throw [System.Management.Automation.ValidationMetadataException] "The name '${_}' is invalid." }
        })]        
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 0)]
        [string] $Name,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 1)]
        [System.Management.Automation.Credential()]
        [PSCredential] $Credential,

        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, Position = 2)]
        [string] $Description,

        [ValidateScript( {
            if (Test-Path $_) { $true }
            else { throw [System.Management.Automation.ValidationMetadataException] "The path '${_}' does not exist." }
        })]
        [Parameter(Mandatory = $false, ValueFromPipeline = $false, Position = 3)]
        [Alias("File")]
        [string] $FilePath = (Get-CsDefaultStore)
    )

    begin {
        $store = Get-Content -Raw -Path $FilePath | ConvertFrom-Json
        if ($store.Username -ne $(whoami) -or $store.ComputerName -ne $(hostname)) {
            throw "Cannot access CredentialStore, it is encrypted for user $($store.UserName) on Computer $($store.ComputerName)"
        }
    }

    process {
        if ($pscmdlet.ShouldProcess($Name)) {
            $entry = $store.credentials | Where-Object {$_.name -eq $Name}

            if (-not $entry) {
                $store.credentials += @{
                    name        = $Name
                    description = $Description
                    username    = $Credential.username
                    password    = $($Credential.password | ConvertFrom-SecureString)
                }
            }
            else {
                $entry.description = $description
                $entry.username = $Credential.username
                $entry.password = $($Credential.password | ConvertFrom-SecureString)
            }
        }
    }

    end {
        $store | ConvertTo-Json | Out-File -FilePath $FilePath -Force
    }
}