From 7416c2e5d3988fcf4adf79f022c4b9e4b899deb4 Mon Sep 17 00:00:00 2001 From: OCram85 Date: Thu, 27 Jul 2017 15:35:31 +0200 Subject: [PATCH] adds item related functions --- src/Item/Get-CredentialStoreItem.ps1 | 109 +++++++++++++++++++ src/Item/New-CredentialStoreItem.ps1 | 135 ++++++++++++++++++++++++ src/Item/Remove-CredentialStoreItem.ps1 | 94 +++++++++++++++++ src/Item/Set-CredentialStoreItem.ps1 | 114 ++++++++++++++++++++ src/Item/Test-CredentialStoreItem.ps1 | 93 ++++++++++++++++ 5 files changed, 545 insertions(+) create mode 100644 src/Item/Get-CredentialStoreItem.ps1 create mode 100644 src/Item/New-CredentialStoreItem.ps1 create mode 100644 src/Item/Remove-CredentialStoreItem.ps1 create mode 100644 src/Item/Set-CredentialStoreItem.ps1 create mode 100644 src/Item/Test-CredentialStoreItem.ps1 diff --git a/src/Item/Get-CredentialStoreItem.ps1 b/src/Item/Get-CredentialStoreItem.ps1 new file mode 100644 index 0000000..4236c50 --- /dev/null +++ b/src/Item/Get-CredentialStoreItem.ps1 @@ -0,0 +1,109 @@ +function Get-CredentialStoreItem { + <# + .SYNOPSIS + Returns the Credential from a given remote host item. + + .DESCRIPTION + Return the credential as PSCredential object. + + + .PARAMETER RemoteHost + Specify the host, for which you would like to change the credentials. + + .PARAMETER Identifier + Provide a custom identifier to the given remote host key. This enables you to store multiple credentials + for a single remote host entry. For example ad/sys1, ftp/sys1, mssql/sys1 + + .PARAMETER Path + Define a custom path to a shared CredentialStore. + + .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. + + .INPUTS + [None] + + .OUTPUTS + [System.Management.Automation.PSCredential] + + .EXAMPLE + $myCreds = Get-CredentialStoreItem -Path "C:\TMP\mystore.json" -RemoteHost "esx01.myside.local" + + .NOTES + File Name : Get-CredentialStoreItem.ps1 + Author : Marco Blessing - marco.blessing@googlemail.com + Requires : + + .LINK + https://github.com/OCram85/PSCredentialStore + #> + + [CmdletBinding(DefaultParameterSetName = "Private")] + [OutputType([System.Management.Automation.PSCredential])] + param( + [Parameter(Mandatory = $false, ParameterSetName = "Shared")] + [string]$Path = "{0}\PSCredentialStore\CredentialStore.json" -f $env:ProgramData, + + [Parameter(Mandatory = $true, ParameterSetName = "Shared")] + [Parameter(Mandatory = $true, ParameterSetName = "Private")] + [ValidateNotNullOrEmpty()] + [string]$RemoteHost, + + [Parameter(Mandatory = $false, ParameterSetName = "Shared")] + [Parameter(Mandatory = $false, ParameterSetName = "Private")] + [ValidateNotNullOrEmpty()] + [string]$Identifier, + + [Parameter(Mandatory = $false, ParameterSetName = "Shared")] + [switch]$Shared + ) + + # First set a constand path for private CredentialStore mode. + if ($PSCmdlet.ParameterSetName -eq "Private") { + $Path = "{0}\CredentialStore.json" -f $env:APPDATA + } + + if ($Identifier -ne "") { + $CredentialName = $RemoteHost = "{0}/{1}" -f $Identifier, $RemoteHost + } + else { + $CredentialName = $RemoteHost + } + + if (Test-CredentialStore -Path $Path) { + $CS = Get-CredentialStore -Path $Path + $CSMembers = Get-Member -InputObject $CS + # Let`s first check if the given remote host exists as object property + if (($CSMembers.MemberType -eq "NoteProperty") -and ($CSMembers.Name -eq $CredentialName)) { + if ($CS.Type -eq "Private") { + $CSItem = [ordered]@{ + User = $CS.$CredentialName.User + Password = ConvertTo-SecureString -String $CS.$CredentialName.Password + } + } + else { + $Key = Get-ChallengeFile + $CSItem = [ordered]@{ + User = $CS.$CredentialName.User + Password = ConvertTo-SecureString -String $CS.$CredentialName.Password -Key $Key + } + } + New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $CSItem.User, $CSItem.Password + } + else { + $MsgParams = @{ + ErrorAction = "Stop" + Message = "Could not find credentials for the given remote host: {0}" -f $RemoteHost + } + Write-Error @MsgParams + } + } + else { + $MsgParams = @{ + ErrorAction = "Stop" + Message = "The given credential store ({0}) does not exist!" -f $Path + } + Write-Error @MsgParams + } +} diff --git a/src/Item/New-CredentialStoreItem.ps1 b/src/Item/New-CredentialStoreItem.ps1 new file mode 100644 index 0000000..b643659 --- /dev/null +++ b/src/Item/New-CredentialStoreItem.ps1 @@ -0,0 +1,135 @@ +function New-CredentialStoreItem { + <# + .SYNOPSIS + Adds a credential store item containing host, user and password to the given store. + + .DESCRIPTION + The credentials are stored without any relations to it's further use. If you need to change an existing + item please use Set-CredentialStoreItem. You need to decide afterwards, whether to use the credential for + a VIConnection, NetApp FAS or UCS Fabric Interconnect. + + .PARAMETER Path + Define the store in which you would like to add a new item. + + .PARAMETER RemoteHost + The identifier or rather name for the given credentials. + + .PARAMETER Identifier + Provide a custom identifier to the given remote host key. This enables you to store multiple credentials + for a single remote host entry. For example ad/sys1, ftp/sys1, mssql/sys1 + + .PARAMETER Credential + You can provide credentials optionally as pre existing pscredential object. + + .INPUTS + [None] + + .OUTPUTS + [None] + + .EXAMPLE + New-CredentialStoreItem -Path "C:\TMP\mystore.json" -RemoteHost "esx01.myside.local" + + .NOTES + File Name : New-CredentialStoreItem.ps1 + Author : Marco Blessing - marco.blessing@googlemail.com + Requires : + + .LINK + https://github.com/OCram85/PSCredentialStore + #> + + [CmdletBinding(DefaultParameterSetName = "Private")] + param( + [Parameter(Mandatory = $false, ParameterSetName = "Shared")] + [string]$Path = "{0}\PSCredentialStore\CredentialStore.json" -f $env:ProgramData, + + [Parameter(Mandatory = $true, ParameterSetName = "Shared")] + [Parameter(Mandatory = $true, ParameterSetName = "Private")] + [ValidateNotNullOrEmpty()] + [string]$RemoteHost, + + [Parameter(Mandatory = $false, ParameterSetName = "Shared")] + [Parameter(Mandatory = $false, ParameterSetName = "Private")] + [ValidateNotNullOrEmpty()] + [string]$Identifier, + + [Parameter(Mandatory = $false)] + [ValidateNotNullOrEmpty()] + [pscredential]$Credential, + + [Parameter(Mandatory = $false, ParameterSetName = "Shared")] + [switch]$Shared + ) + + # First set a constand path for private CredentialStore mode. + if ($PSCmdlet.ParameterSetName -eq "Private") { + $Path = "{0}\CredentialStore.json" -f $env:APPDATA + } + + # Lets do a quick test on the given CredentialStore. + if (-not(Test-CredentialStore -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 -Path $Path + + $CurrentDate = Get-Date -UFormat "%Y-%m-%d %H:%M:%S" + + 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 ($CSContent.Type -eq "Shared") { + $Key = Get-ChallengeFile + $encypted = ConvertFrom-SecureString -SecureString $Credential.Password -Key $Key + } + else { + $encypted = ConvertFrom-SecureString -SecureString $Credential.Password + } + if (Get-Member -InputObject $CSContent -Name $CredentialName -Membertype Properties) { + $MessageParams = @{ + Message = "The given host already exists. Nothing to do here." + } + Write-Warning @MessageParams + } + else { + $CredentialHash = [ordered]@{ + User = $Credential.UserName + Password = $encypted + Creation = $CurrentDate + } + Add-Member -InputObject $CSContent -Name $CredentialName -MemberType NoteProperty -Value $CredentialHash + try { + ConvertTo-Json -InputObject $CSContent | Out-File -FilePath $Path + } + catch [System.Exception] { + $MessageParams = @{ + Message = "Couldn't add item into credential store!" + ErrorAction = "Stop" + } + Write-Error @MessageParams + } + } + } + else { + $MessageParams = @{ + Message = "Please Provide at least a valid user!" + ErrorAction = "Stop" + } + Write-Error @MessageParams + } +} diff --git a/src/Item/Remove-CredentialStoreItem.ps1 b/src/Item/Remove-CredentialStoreItem.ps1 new file mode 100644 index 0000000..b82cd27 --- /dev/null +++ b/src/Item/Remove-CredentialStoreItem.ps1 @@ -0,0 +1,94 @@ +function Remove-CredentialStoreItem { + <# + .SYNOPSIS + Remove the given credentials from the credential store. + + .DESCRIPTION + Use this CMDLet to completely remove an credential store item. + + .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. + + .INPUTS + [None] + + .OUTPUTS + [None] + + .EXAMPLE + Remove-CredentialStoreItem -Path "C:\TMP\mystore.json" -RemoteHost "esx01.myside.local" + Remove-CredentialStoreItem -Path "C:\TMP\mystore.json" -RemoteHost "esx01.myside.local" -Identifier svc + + .NOTES + File Name : Remove-CredentialStoreItem.ps1 + Author : Marco Blessing - marco.blessing@googlemail.com + Requires : + + .LINK + https://github.com/OCram85/PSCredentialStore + #> + + [CmdletBinding(DefaultParameterSetName = "Private")] + param( + [Parameter(Mandatory = $false, ParameterSetName = "Shared")] + [string]$Path = "{0}\PSCredentialStore\CredentialStore.json" -f $env:ProgramData, + + [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, ParameterSetName = "Shared")] + [switch]$Shared + ) + + # First set a constand path for private CredentialStore mode. + if ($PSCmdlet.ParameterSetName -eq "Private") { + $Path = "{0}\CredentialStore.json" -f $env:APPDATA + } + + # Lets do a quick test on the given CredentialStore. + if (-not(Test-CredentialStore -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 -Path $Path + + if ($Identifier -ne "") { + $CredentialName = $RemoteHost = "{0}/{1}" -f $Identifier, $RemoteHost + } + else { + $CredentialName = $RemoteHost + } + + if (Get-Member -InputObject $CSContent -Name $CredentialName -Membertype Properties) { + # We need to use the .NET Method because there is no easier way in PowerShell. + $CSContent.PSObject.Properties.Remove($CredentialName) + ConvertTo-Json -InputObject $CSContent | Out-File -FilePath $Path + } + else { + $MessageParams = @{ + Message = "The given CredentailStoreItem does not exist." + } + Write-Warning @MessageParams + } +} diff --git a/src/Item/Set-CredentialStoreItem.ps1 b/src/Item/Set-CredentialStoreItem.ps1 new file mode 100644 index 0000000..6f35fe8 --- /dev/null +++ b/src/Item/Set-CredentialStoreItem.ps1 @@ -0,0 +1,114 @@ +function Set-CredentialStoreItem { + <# + .SYNOPSIS + Changes the credentials for the given remote host in the store. + + .DESCRIPTION + + .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. + + .INPUTS + [None] + + .OUTPUTS + [None] + + .EXAMPLE + Set-CredentialStoreItem -Path "C:\TMP\mystore.json" -RemoteHost "esx01.myside.local" + Set-CredentialStoreItem -Path "C:\TMP\mystore.json" -RemoteHost "esx01.myside.local" -Identifier svc + + .NOTES + File Name : Set-CredentialStoreItem.ps1 + Author : Marco Blessing - marco.blessing@googlemail.com + Requires : + + .LINK + https://github.com/OCram85/PSCredentialStore + #> + + [CmdletBinding(DefaultParameterSetName = "Private")] + param( + [Parameter(Mandatory = $false, ParameterSetName = "Shared")] + [string]$Path = "{0}\PSCredentialStore\CredentialStore.json" -f $env:ProgramData, + + [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, ParameterSetName = "Shared")] + [switch]$Shared + ) + + # First set a constant path for private CredentialStore mode. + if ($PSCmdlet.ParameterSetName -eq "Private") { + $Path = "{0}\CredentialStore.json" -f $env:APPDATA + } + + # Lets do a quick test on the given CredentialStore. + if (-not(Test-CredentialStore -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 -Path $Path + + $CurrentDate = Get-Date -UFormat "%Y-%m-%d %H:%M:%S" + + if ($Identifier -ne "") { + $CredentialName = $RemoteHost = "{0}/{1}" -f $Identifier, $RemoteHost + } + else { + $CredentialName = $RemoteHost + } + + $Creds = Get-Credential -Message $CredentialName + + if ($Creds.UserName) { + if ($CSContent.Type -eq "Shared") { + $Key = Get-ChallengeFile + $encypted = ConvertFrom-SecureString -SecureString $Creds.Password -Key $Key + } + else { + $encypted = ConvertFrom-SecureString -SecureString $Creds.Password + } + if (Get-Member -InputObject $CSContent -Name $CredentialName -Membertype Properties) { + $CSContent.$CredentialName.User = $Creds.UserName + $CSContent.$CredentialName.Password = $encypted + $CSContent.$CredentialName.Creation = $CurrentDate + ConvertTo-Json -InputObject $CSContent | Out-File -FilePath $Path + } + else { + $MessageParams = @{ + Message = "The given CredentailStoreItem does not exist." + } + Write-Warning @MessageParams + } + } + Else { + $MessageParams = @{ + Message = "Please Provide at least a valid user!" + ErrorAction = "Stop" + } + Write-Error @MessageParams + } +} diff --git a/src/Item/Test-CredentialStoreItem.ps1 b/src/Item/Test-CredentialStoreItem.ps1 new file mode 100644 index 0000000..56e9c9d --- /dev/null +++ b/src/Item/Test-CredentialStoreItem.ps1 @@ -0,0 +1,93 @@ +function Test-CredentialStoreItem() { + <# + .SYNOPSIS + Checks if the given RemoteHost identifier combination exists in the credential store. + + .DESCRIPTION + Use this cmdlet for basic checks with a single item. Check the item first with this function before + you try to interact with it. + + .PARAMETER Path + Define a custom credential store you try to read from. Without the `-Path` parameter + `Test-CredentialStoreItem` tries to read from the default private store. + + .PARAMETER RemoteHost + Specify the host, for which you would like to change the credentials. + + .PARAMETER Identifier + Adds an optional identifier to the given RemoteHost. Makes it possible to store multiple credentials + for a single host. + + .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. + + .INPUTS + [None] + + .OUTPUTS + [None] + + .EXAMPLE + If (Test-CredentialStoreItem -RemoteHost "Default") { + Get-CredentialStoreItem -RemoteHost "Default" + } + Else { + Write-Warning ("The given Remote Host {0} does not exist in the credential Store!" -f $RemoteHost) + } + + .NOTES + File Name : Test-CredentialStoreItem.ps1 + Author : Marco Blessing - marco.blessing@googlemail.com + Requires : + + .LINK + https://github.com/OCram85/PSCredentialStore + #> + [CmdletBinding(DefaultParameterSetName = "Private")] + [OutputType([Boolean])] + param( + [Parameter(Mandatory = $false, ParameterSetName = "Shared")] + [string]$Path = "{0}\PSCredentialStore\CredentialStore.json" -f $env:ProgramData, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string]$RemoteHost, + + [Parameter(Mandatory = $false)] + [ValidateNotNullOrEmpty()] + [string]$Identifier, + + [Parameter(Mandatory = $false, ParameterSetName = "Shared")] + [switch]$Shared + ) + + if ($PSCmdlet.ParameterSetName -eq "Private") { + $Path = "{0}\CredentialStore.json" -f $env:APPDATA + } + + if ($Identifier -ne "") { + $CredentialName = $RemoteHost = "{0}/{1}" -f $Identifier, $RemoteHost + } + else { + $CredentialName = $RemoteHost + } + + if (Test-CredentialStore -Path $Path) { + $CS = Get-CredentialStore -Path $Path + $CSMembers = Get-Member -InputObject $CS + if (($CSMembers.MemberType -eq "NoteProperty") -and ($CSMembers.Name -eq $CredentialName)) { + return $true + } + else { + return $false + } + } + else { + $MsgParams = @{ + ErrorAction = "Stop" + Message = "The given credential store ({0}) does not exist!" -f $Path + } + Write-Error @MsgParams + } +}