Functions/Import-PSCredential.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<#
    .SYNOPSIS
        Retrieves and decrypts an exported PowerShell Credential from file or Azure KeyVault back into a PSCredential object.
 
    .DESCRIPTION
        Import-PSCredential is used to retrieve a previously saved PowerShell Credential object from disk
        or from Azure KeyVault and returns a PowerShell Credential object [System.Management.Automation.PSCredential] that can be used within scripts and
        Desired State Configurations. When retrieving from disk, the method used to encrypt the credential must be used to decrypt the credential.
 
    .PARAMETER Path
        Path to the JSON file that contains the encrypted credential.
 
    .PARAMETER SecureKey
        The SecureString that was used as a Pre-Shared-Key for encrypting the credential password.
 
    .PARAMETER Thumbprint
        The Thumbprint of the certificate on the local computer that contains the private key of the certificate used to encrypt the credential password.
 
    .PARAMETER CertificateStore
        Specifies the certifcate store of the specified certificate thumbprint. Either LocalMachine or CurrentUser.
 
    .PARAMETER KeyVault
        The name of the Azure KeyVault that will that contains the exported credential secret.
 
    .PARAMETER SecretName
        The name of the Azure KeyVault secret that contains the exported credential.
 
    .EXAMPLE
        $Credential = Import-PSCredential -Path ./savedcredential.json -SecureKey ( Convertto-SecureString -String '$ecretK3y' -AsPlainText -Force )
 
        Import a credential from file using a pre-shared key.
 
    .EXAMPLE
        $Credential = Import-PSCredential -Path ./savedcredential.json -Thumbprint '87BB70A19A7671D389F49AF4C9608B2F381FDD80'
 
        Import a credential from file using a Certificate.
 
    .EXAMPLE
        $Credential = Import-PSCredential -KeyVault 'My-KeyVault' -SecretName 'SavedCred-Secret'
 
        Import a credential from an Azure KeyVault. The user executing the script must be authenticated to Azure with sufficient permissions to the KeyVault.
#>

function Import-PSCredential
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory = $true, ParameterSetName = "LocalKey", Position = 1)]
        [Parameter(Mandatory = $true, ParameterSetName = "CertificateThumbprint", Position = 1)]
        [System.String]
        $Path,

        [Parameter(Mandatory = $true, ParameterSetName = "LocalKey")]
        [System.Security.SecureString]
        $SecureKey,

        [Parameter(Mandatory = $true, ParameterSetName = "CertificateThumbprint")]
        [ValidateNotNullorEmpty()]
        [System.String]$Thumbprint,

        [Parameter(Mandatory = $false, ParameterSetName = "CertificateThumbprint")]
        [ValidateSet("LocalMachine", "CurrentUser")]
        [System.String]
        $CertificateStore,

        [Parameter(Mandatory = $true, ParameterSetName = "KeyVault")]
        [System.String]
        $KeyVault,

        [Parameter(Mandatory = $true, ParameterSetName = "KeyVault")]
        [System.String]
        $SecretName
    )


    if ($PSCmdlet.ParameterSetName -eq 'KeyVault')
    {   
        if ($null -eq $script:AzureKeyVaultModule)
        {
            throw "Cannot find module Az.KeyVault or AzureRM.KeyVault installed on this system"
        }

        try
        {
            $keyVaultObject = Get-PSCTAzKeyVault -VaultName $keyVault -ErrorAction Stop
        }
        catch
        {
            throw "Unable to access KeyVault $KeyVault, ensure that the current session has access to it. Use Add-AzureRmAccount, Login-AzureRmAccount or ConnectAzAccount to establish access for the current session. $($_)"
        }

        if ($null -eq $keyVaultObject)
        {
            throw "Unable to find KeyVault $KeyVault within the current subscription"
        }

        Write-Verbose -Message "Reading credential object data from $KeyVault"
        $SecretData = Get-PSCTAzKeyVaultSecret -VaultName $KeyVault -Name $SecretName

        if ($null -eq $SecretData)
        {
            throw "Could not read data from $SecretName in $KeyVault"
        }

        $username = ($SecretData.Attributes.Tags).username
        if ($null -eq $username)
        {
            throw "$SecretName does not have a Username tag"
        }

        New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList @($username, $SecretData.SecretValue)

    }
    elseif ($PSBoundParameters.ContainsKey('Path'))
    {
        Write-Verbose "Reading credential object data from $Path"
        $CredentialImport = Get-Content $Path -Raw | ConvertFrom-Json

        if ($PSCmdlet.ParameterSetName -eq 'LocalKey')
        {
            $SecureStringPassword = ConvertTo-FIPSsecureString -EncryptedString $CredentialImport.Password -SecureKey $SecureKey -Verbose:$Verbose
        }
        elseif ($PSCmdlet.ParameterSetName -eq 'CertificateThumbprint')
        {
            if ($PSBoundParameters.ContainsKey('CertificateStore'))
            {
                $SecureStringPassword = ConvertTo-PKISecureString -EncryptedString $CredentialImport.Password -Thumbprint $Thumbprint -CertificateStore $CertificateStore
            }

            $SecureStringPassword = ConvertTo-PKISecureString -EncryptedString $CredentialImport.Password -Thumbprint $Thumbprint
        }

        New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList @(($CredentialImport.UserName), $SecureStringPassword)
    }
}