function Set-CredentialStoreItem { <# .SYNOPSIS Changes the credentials for the given remote host in the store. .DESCRIPTION Use this function to update your already stored RemoteHost items. .PARAMETER Path Define the store in which your given host entry already exists. .PARAMETER RemoteHost Specify the host you for which you would like to change the credentials. .PARAMETER Identifier Defaults to "". Specify a string, which separates two CredentialStoreItems for the same hostname. .PARAMETER Shared Switch to shared mode with this param. This enforces the command to work with a shared CredentialStore which can be decrypted across systems. .PARAMETER Credential Provided the new credentials you want to update inside the RemoteHost item. .INPUTS [None] .OUTPUTS [None] .EXAMPLE Set-CredentialStoreItem -Path "C:\TMP\mystore.json" -RemoteHost "esx01.myside.local" .EXAMPLE Set-CredentialStoreItem -Path "C:\TMP\mystore.json" -RemoteHost "esx01.myside.local" -Identifier svc #> [CmdletBinding(DefaultParameterSetName = 'Private')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Updates existing credential object.' )] param ( [Parameter(Mandatory = $true, ParameterSetName = 'Private')] [Parameter(Mandatory = $true, ParameterSetName = 'Shared')] [string]$RemoteHost, [Parameter(Mandatory = $false, ParameterSetName = 'Private')] [Parameter(Mandatory = $false, ParameterSetName = 'Shared')] [string]$Identifier, [Parameter(Mandatory = $false, ValueFromPipeline = $true)] [ValidateNotNullOrEmpty()] [PSCredential]$Credential, [Parameter(Mandatory = $true, ParameterSetName = 'Shared')] [switch]$Shared, [Parameter(Mandatory = $false, ParameterSetName = 'Shared')] [ValidateNotNullOrEmpty()] [string]$Path ) begin { # Set the CredentialStore for private, shared or custom mode. Write-Debug ("ParameterSetName: {0}" -f $PSCmdlet.ParameterSetName) if ($PSCmdlet.ParameterSetName -eq 'Private') { $Path = Get-DefaultCredentialStorePath } elseif ($PSCmdlet.ParameterSetName -eq 'Shared') { if (!($PSBoundParameters.ContainsKey('Path'))) { $Path = Get-DefaultCredentialStorePath -Shared } } } process { # Lets do a quick test on the given CredentialStore. if (-not(Test-CredentialStore -Shared -Path $Path)) { $MessageParams = @{ Message = 'Could not add anything into the given CredentailStore.' ErrorAction = 'Stop' } Write-Error @MessageParams } # Read the file content based on the given ParameterSetName $CSContent = Get-CredentialStore -Shared -Path $Path $CurrentDate = Get-Date -Format 'u' if ($Identifier -ne "") { $CredentialName = $RemoteHost = "{0}/{1}" -f $Identifier, $RemoteHost } else { $CredentialName = $RemoteHost } if (-not($Credential)) { $Credential = Get-Credential -Message $CredentialName } if ($Credential.UserName) { if ($null -eq $CSContent.PfxCertificate) { $Cert = Get-CSCertificate -Type $CSContent.Type -Thumbprint $CSContent.Thumbprint } else { $Cert = Get-PfxCertificate -FilePath $CSContent.PfxCertificate -ErrorAction Stop } if (Get-Member -InputObject $CSContent -Name $CredentialName -MemberType Properties) { $RSAKey = Get-RandomAESKey $CSContent.$CredentialName.User = $Credential.UserName $ConvertParams = @{ SecureString = $Credential.Password Key = $RSAKey } $CSContent.$CredentialName.Password = ConvertFrom-SecureString @ConvertParams $CSContent.$CredentialName.LastChange = $CurrentDate $CSContent.$CredentialName.EncryptedKey = [Convert]::ToBase64String( $Cert.PublicKey.Key.Encrypt( $RSAKey, [System.Security.Cryptography.RSAEncryptionPadding]::Pkcs1 ) ) ConvertTo-Json -InputObject $CSContent -Depth 5 | Out-File -FilePath $Path -Encoding utf8 } } Else { $MessageParams = @{ Message = 'Please Provide at least a valid user!' ErrorAction = 'Stop' } Write-Error @MessageParams } } end { } }