PowerShell 6 Core Support (#35)
## About This pull request reflects all changes done in the `linuxsupport` branch. ## Content - Enable PowerShell 6 Core support - Use PFX Certificate for encryption ( fixes #32 ) - Updates CI / CD pipeline ( fixes #31 ) - uses portable libressl ( fixes #34 ) - adds `-PassThru` switch for returning current `VIServer` session in `Connect-To` ( fixes #34 ) - adds git lfs for embedded libressl files - restructured internal functions into `Private` dir - added certificate related functions - adds travis build pipeline for tests
This commit is contained in:
parent
ab13962f6e
commit
afab3c870c
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
src/Vendor/libressl255/* filter=lfs diff=lfs merge=lfs -text
|
||||
*.pfx filter=lfs diff=lfs merge=lfs -text
|
43
.travis.yml
Normal file
43
.travis.yml
Normal file
@ -0,0 +1,43 @@
|
||||
|
||||
language: csharp
|
||||
dotnet: 2.2.101
|
||||
mono: none
|
||||
|
||||
git:
|
||||
depth: 1000
|
||||
|
||||
os:
|
||||
- linux
|
||||
# Disable OSX bulds for now
|
||||
# - osx
|
||||
|
||||
sudo: required
|
||||
|
||||
dist: xenial
|
||||
osx_image: xcode8.1
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
|
||||
addons:
|
||||
artifacts:
|
||||
#paths: $(ls ./../dist/PowerShellGet.zip | tr "\n" ":")
|
||||
paths: ./dist/PowerShellGet.zip
|
||||
|
||||
|
||||
install:
|
||||
# Default 2.0.0 Ruby is buggy
|
||||
# Default bundler version is buggy
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
rvm install ruby-2.3.3;
|
||||
rvm --default use 2.3.3;
|
||||
fi
|
||||
- bash <(wget -O - https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.sh)
|
||||
- pushd tools
|
||||
- chmod +x travis.sh
|
||||
- popd
|
||||
|
||||
script:
|
||||
- echo "TRAVIS_EVENT_TYPE value $TRAVIS_EVENT_TYPE"
|
||||
- ./tools/travis.sh
|
96
.vscode/launch.json
vendored
96
.vscode/launch.json
vendored
@ -1,48 +1,48 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"name": "PowerShell Launch Current File",
|
||||
"script": "${file}",
|
||||
"args": [],
|
||||
"cwd": "${file}"
|
||||
},
|
||||
{
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"name": "PowerShell Launch Current File in Temporary Console",
|
||||
"script": "${file}",
|
||||
"args": [],
|
||||
"cwd": "${file}",
|
||||
"createTemporaryIntegratedConsole": true
|
||||
},
|
||||
{
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"name": "PowerShell Launch Current File w/Args Prompt",
|
||||
"script": "${file}",
|
||||
"args": [
|
||||
"${command:SpecifyScriptArgs}"
|
||||
],
|
||||
"cwd": "${file}"
|
||||
},
|
||||
{
|
||||
"type": "PowerShell",
|
||||
"request": "attach",
|
||||
"name": "PowerShell Attach to Host Process",
|
||||
"processId": "${command:PickPSHostProcess}",
|
||||
"runspaceId": 1
|
||||
},
|
||||
{
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"name": "PowerShell Interactive Session",
|
||||
"cwd": "${workspaceRoot}"
|
||||
}
|
||||
]
|
||||
}
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"name": "PowerShell Launch Current File",
|
||||
"script": "${file}",
|
||||
"args": [],
|
||||
"cwd": "${file}"
|
||||
},
|
||||
{
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"name": "PowerShell Launch Current File in Temporary Console",
|
||||
"script": "${file}",
|
||||
"args": [],
|
||||
"cwd": "${file}",
|
||||
"createTemporaryIntegratedConsole": true
|
||||
},
|
||||
{
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"name": "PowerShell Launch Current File w/Args Prompt",
|
||||
"script": "${file}",
|
||||
"args": [
|
||||
"${command:SpecifyScriptArgs}"
|
||||
],
|
||||
"cwd": "${file}"
|
||||
},
|
||||
{
|
||||
"type": "PowerShell",
|
||||
"request": "attach",
|
||||
"name": "PowerShell Attach to Host Process",
|
||||
"processId": "${command:PickPSHostProcess}",
|
||||
"runspaceId": 1
|
||||
},
|
||||
{
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"name": "PowerShell Interactive Session",
|
||||
"cwd": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
|
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -26,7 +26,8 @@
|
||||
"powershell.codeFormatting.whitespaceAroundOperator": true,
|
||||
"powershell.codeFormatting.whitespaceAfterSeparator": true,
|
||||
"powershell.codeFormatting.ignoreOneLineBlock": true,
|
||||
"powershell.codeFormatting.alignPropertyValuePairs": false,
|
||||
"powershell.codeFormatting.alignPropertyValuePairs": true,
|
||||
"powershell.codeFormatting.preset": "Custom",
|
||||
// cspell spellchecker options
|
||||
"cSpell.enabledLanguageIds": [
|
||||
"c",
|
||||
|
28
README.md
28
README.md
@ -23,14 +23,28 @@ need to store credentials for non interactive usage like in scheduled tasks.
|
||||
For more details read the [about_PSCredentialStore](/docs/about_PSCredentialStore.md) page on github or via CLI with
|
||||
`Get-Help about_PSCredentialStore`.
|
||||
|
||||
:exclamation: Upcoming Changes :exclamation:
|
||||
================
|
||||
|
||||
The will be some breaking changes starting with the `0.5.0.xxx`:
|
||||
|
||||
- **PSCredentialStore will use PFX certificates to encrypt your credentials.**
|
||||
- This replaces the the current encryption methods and you need to recreate or upgrade your pre existing stores.
|
||||
- The changes allows the PSCredentialStore module to support the PowerShell `Core` editions.
|
||||
- Yes this means, you can use the module on any PowerShell 6 supported linux distribution.
|
||||
- It's also possible to create a shared credential store and transfer it onto a another platform like:
|
||||
`Windows -- to --> Linux` and vice versa.
|
||||
- Automatically creates self signed certificate with 2048 bits RSA keys for encryption.
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
PowerShellGallery.com (Recommended Way)
|
||||
---------------------------------------
|
||||
|
||||
* Make sure you use PowerShell 4.0 or higher with `$PSVersionTable`.
|
||||
* Use the builtin PackageManagement and install with: `Install-Module PSCredentialStore`
|
||||
* Make sure you use PowerShell 5.1 or higher with `$PSVersionTable`.
|
||||
* Use the builtin PackageManagement and install with: `Import-Module PowerShellGet; Install-Module 'PSCredentialStore' -Repository 'PSGallery'`
|
||||
* Additionally use the `-AllowPrerelease` switch until we publish the final release!
|
||||
* Done. Start exploring the Module with `Import-Module PSCredentialStore ; Get-Command -Module PSCredentialStore`
|
||||
|
||||
Manual Way
|
||||
@ -97,3 +111,13 @@ Connect-To -RemoteHost "fas.myside.local" -Type NetAppFAS
|
||||
Connect-To -RemoteHost "esx01.myside.local" -Type VMware
|
||||
Connect-To -RemoteHost "vcr.myside.local" -Type CisServer
|
||||
```
|
||||
|
||||
Credits
|
||||
-------
|
||||
|
||||
A huge thanks to all the people who helped with their projects and indirect contributions which made this possible!
|
||||
|
||||
- This module is inspired by the awesome work of @dlwyatt with articles like these:
|
||||
- https://powershell.org/2013/11/24/saving-passwords-and-preventing-other-processes-from-decrypting-them/
|
||||
- https://powershell.org/2014/02/01/revisited-powershell-and-encryption/
|
||||
- The awesome people from [LibreSSL](http://www.libressl.org/) which publishes the [portable openssl/libressl binaries](https://github.com/libressl-portable/portable)!
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: 0.2.3.{build}
|
||||
version: 0.5.0.{build}
|
||||
|
||||
#branches:
|
||||
# only:
|
||||
@ -20,6 +20,7 @@ image: Visual Studio 2017
|
||||
|
||||
install:
|
||||
- ps: Import-Module .\tools\AppVeyor.psm1
|
||||
- ps: Import-Module .\tools\CoverallsIO.psm1
|
||||
- ps: Invoke-InstallDependencies
|
||||
|
||||
environment:
|
||||
@ -37,10 +38,10 @@ build_script:
|
||||
- ps: Invoke-AppVeyorBuild
|
||||
|
||||
test_script:
|
||||
- ps: Invoke-AppVeyorTests
|
||||
- ps: |
|
||||
$CodeCoverage = Invoke-AppVeyorTests
|
||||
if ($null -ne $Env:CoverallsToken) {
|
||||
Invoke-CoverageReport
|
||||
Invoke-CoverageReport -PesterCoverageReport $CodeCoverage
|
||||
}
|
||||
else {
|
||||
Write-Warning "No CoverallsToken found. This build seems to be triggered by a PR. Skipping this step..."
|
||||
@ -60,7 +61,7 @@ deploy:
|
||||
secure: M+bBX5/nKdJB0eViP7xtrLVTwf3vGDUA9N2MMprZp2i+9ZR3CBVcJnSzJWUmalhB
|
||||
artifact: PSCredentialStore.zip # upload all NuGet packages to release assets
|
||||
draft: false
|
||||
prerelease: false
|
||||
prerelease: true
|
||||
on:
|
||||
branch: master # build release on master branch changes
|
||||
|
||||
|
BIN
assets/logo256.png
Normal file
BIN
assets/logo256.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.7 KiB |
@ -63,7 +63,7 @@ Type: SwitchParameter
|
||||
Parameter Sets: Shared
|
||||
Aliases:
|
||||
|
||||
Required: False
|
||||
Required: True
|
||||
Position: Named
|
||||
Default value: False
|
||||
Accept pipeline input: False
|
||||
|
@ -19,7 +19,7 @@ Get-CredentialStoreItem -RemoteHost <String> [-Identifier <String>] [<CommonPara
|
||||
|
||||
### Shared
|
||||
```
|
||||
Get-CredentialStoreItem [-Path <String>] -RemoteHost <String> [-Identifier <String>] [-Shared]
|
||||
Get-CredentialStoreItem -RemoteHost <String> [-Identifier <String>] [-Shared] [-Path <String>]
|
||||
[<CommonParameters>]
|
||||
```
|
||||
|
||||
@ -93,7 +93,7 @@ Type: SwitchParameter
|
||||
Parameter Sets: Shared
|
||||
Aliases:
|
||||
|
||||
Required: False
|
||||
Required: True
|
||||
Position: Named
|
||||
Default value: False
|
||||
Accept pipeline input: False
|
||||
|
@ -19,7 +19,7 @@ Get-CredentialStoreItem -RemoteHost <String> [-Identifier <String>] [<CommonPara
|
||||
|
||||
### Shared
|
||||
```
|
||||
Get-CredentialStoreItem [-Path <String>] -RemoteHost <String> [-Identifier <String>] [-Shared]
|
||||
Get-CredentialStoreItem -RemoteHost <String> [-Identifier <String>] [-Shared] [-Path <String>]
|
||||
[<CommonParameters>]
|
||||
```
|
||||
|
||||
@ -93,7 +93,7 @@ Type: SwitchParameter
|
||||
Parameter Sets: Shared
|
||||
Aliases:
|
||||
|
||||
Required: False
|
||||
Required: True
|
||||
Position: Named
|
||||
Default value: False
|
||||
Accept pipeline input: False
|
||||
|
@ -20,8 +20,8 @@ New-CredentialStoreItem -RemoteHost <String> [-Identifier <String>] [-Credential
|
||||
|
||||
### Shared
|
||||
```
|
||||
New-CredentialStoreItem [-Path <String>] -RemoteHost <String> [-Identifier <String>]
|
||||
[-Credential <PSCredential>] [-Shared] [<CommonParameters>]
|
||||
New-CredentialStoreItem -RemoteHost <String> [-Identifier <String>] [-Credential <PSCredential>] [-Shared]
|
||||
[-Path <String>] [<CommonParameters>]
|
||||
```
|
||||
|
||||
## DESCRIPTION
|
||||
@ -51,7 +51,7 @@ Aliases:
|
||||
Required: False
|
||||
Position: Named
|
||||
Default value: None
|
||||
Accept pipeline input: False
|
||||
Accept pipeline input: True (ByValue)
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
@ -111,7 +111,7 @@ Type: SwitchParameter
|
||||
Parameter Sets: Shared
|
||||
Aliases:
|
||||
|
||||
Required: False
|
||||
Required: True
|
||||
Position: Named
|
||||
Default value: False
|
||||
Accept pipeline input: False
|
||||
|
@ -19,7 +19,7 @@ Remove-CredentialStoreItem -RemoteHost <String> [-Identifier <String>] [<CommonP
|
||||
|
||||
### Shared
|
||||
```
|
||||
Remove-CredentialStoreItem [-Path <String>] -RemoteHost <String> [-Identifier <String>] [-Shared]
|
||||
Remove-CredentialStoreItem -RemoteHost <String> [-Identifier <String>] [-Shared] [-Path <String>]
|
||||
[<CommonParameters>]
|
||||
```
|
||||
|
||||
@ -94,7 +94,7 @@ Type: SwitchParameter
|
||||
Parameter Sets: Shared
|
||||
Aliases:
|
||||
|
||||
Required: False
|
||||
Required: True
|
||||
Position: Named
|
||||
Default value: False
|
||||
Accept pipeline input: False
|
||||
|
@ -14,13 +14,14 @@ Changes the credentials for the given remote host in the store.
|
||||
|
||||
### Private (Default)
|
||||
```
|
||||
Set-CredentialStoreItem -RemoteHost <String> [-Identifier <String>] [<CommonParameters>]
|
||||
Set-CredentialStoreItem -RemoteHost <String> [-Identifier <String>] [-Credential <PSCredential>]
|
||||
[<CommonParameters>]
|
||||
```
|
||||
|
||||
### Shared
|
||||
```
|
||||
Set-CredentialStoreItem [-Path <String>] -RemoteHost <String> [-Identifier <String>] [-Shared]
|
||||
[<CommonParameters>]
|
||||
Set-CredentialStoreItem -RemoteHost <String> [-Identifier <String>] [-Credential <PSCredential>] [-Shared]
|
||||
[-Path <String>] [<CommonParameters>]
|
||||
```
|
||||
|
||||
## DESCRIPTION
|
||||
@ -37,6 +38,21 @@ Set-CredentialStoreItem -Path "C:\TMP\mystore.json" -RemoteHost "esx01.myside.lo
|
||||
|
||||
## PARAMETERS
|
||||
|
||||
### -Credential
|
||||
{{Fill Credential Description}}
|
||||
|
||||
```yaml
|
||||
Type: PSCredential
|
||||
Parameter Sets: (All)
|
||||
Aliases:
|
||||
|
||||
Required: False
|
||||
Position: Named
|
||||
Default value: None
|
||||
Accept pipeline input: True (ByValue)
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
### -Identifier
|
||||
Defaults to "".
|
||||
Specify a string, which separates two CredentialStoreItems for the
|
||||
@ -94,7 +110,7 @@ Type: SwitchParameter
|
||||
Parameter Sets: Shared
|
||||
Aliases:
|
||||
|
||||
Required: False
|
||||
Required: True
|
||||
Position: Named
|
||||
Default value: False
|
||||
Accept pipeline input: False
|
||||
|
@ -63,7 +63,7 @@ Type: SwitchParameter
|
||||
Parameter Sets: Shared
|
||||
Aliases:
|
||||
|
||||
Required: False
|
||||
Required: True
|
||||
Position: Named
|
||||
Default value: False
|
||||
Accept pipeline input: False
|
||||
|
@ -1,3 +1,3 @@
|
||||
{
|
||||
"Version": "1.2.0",
|
||||
"Creation": "2016-06-14 08:41:10"
|
||||
"Version": "2.0.0",
|
||||
"Creation": "2016-06-14 08:41:10"
|
||||
|
@ -1 +0,0 @@
|
||||
!マ<><EFBE8F>゙澄H4サ<34><EFBDBB>"=w肛Sヨ2
|
Binary file not shown.
BIN
resources/cs/PSCredentialStore.pfx
(Stored with Git LFS)
Normal file
BIN
resources/cs/PSCredentialStore.pfx
(Stored with Git LFS)
Normal file
Binary file not shown.
100
src/Certificate/New-CRTAttribute.ps1
Normal file
100
src/Certificate/New-CRTAttribute.ps1
Normal file
@ -0,0 +1,100 @@
|
||||
function New-CRTAttribute {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Create required data for a certificate signing request.
|
||||
|
||||
.DESCRIPTION
|
||||
Defines the certificate related properties for an upcoming New-PfxCertificate execution.
|
||||
|
||||
.PARAMETER Country
|
||||
Provide a two letter country code.
|
||||
|
||||
.PARAMETER State
|
||||
Certificate state value.
|
||||
|
||||
.PARAMETER City
|
||||
Certificate city value.
|
||||
|
||||
.PARAMETER Organization
|
||||
Certificate organization value.
|
||||
|
||||
.PARAMETER OrganizationalUnitName
|
||||
Certificate OrganizationalUnitName value.
|
||||
|
||||
.PARAMETER CommonName
|
||||
The certificate common name.
|
||||
|
||||
.PARAMETER CSRSubject
|
||||
you can provide the needed certificate properties with in one hashtable. This hashtable has to contain the
|
||||
following keys: 'Country', 'State', 'City', 'Organization', 'OrganizationalUnitName', 'CommonName'.
|
||||
|
||||
.INPUTS
|
||||
[None]
|
||||
|
||||
.OUTPUTS
|
||||
['PSCredentialStore.Certificate.CSRDetails']
|
||||
|
||||
.EXAMPLE
|
||||
New-CRTAttribute -CSRSubject @{Country = 'DE'; State = 'BW'; City = 'Karlsruhe'; Organization = 'AwesomeIT'; OrganizationalUnitName = '';CommonName = 'MyPrivateCert'}
|
||||
|
||||
.NOTES
|
||||
File Name : New-CSRDetails.ps1
|
||||
Author : Marco Blessing - marco.blessing@googlemail.com
|
||||
Requires :
|
||||
|
||||
.LINK
|
||||
https://github.com/OCram85/PSCredentialStore
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
[OutputType('PSCredentialStore.Certificate.Attribute')]
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateLength(2, 2)]
|
||||
[ValidateNotNull()]
|
||||
[string]$Country,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNull()]
|
||||
[string]$State,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNull()]
|
||||
[string]$City,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNull()]
|
||||
[string]$Organization,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNull()]
|
||||
[string]$OrganizationalUnitName,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNull()]
|
||||
[string]$CommonName,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[ValidateNotNull()]
|
||||
[int]$Days = 365
|
||||
)
|
||||
begin {
|
||||
|
||||
}
|
||||
process {
|
||||
return [PSCustomObject]@{
|
||||
PSTypeName = 'PSCredentialStore.Certificate.Attribute'
|
||||
Subject = [PSCustomObject]@{
|
||||
PSTypeName = 'PSCredentialStore.Certificate.Attribute.Subject'
|
||||
Country = $Country
|
||||
State = $State
|
||||
City = $City
|
||||
Organization = $Organization
|
||||
OrganizationalUnitName = $OrganizationalUnitName
|
||||
CommonName = $CommonName
|
||||
}
|
||||
Days = $Days
|
||||
}
|
||||
}
|
||||
end {
|
||||
}
|
||||
}
|
142
src/Certificate/New-PfxCertificate.ps1
Normal file
142
src/Certificate/New-PfxCertificate.ps1
Normal file
@ -0,0 +1,142 @@
|
||||
function New-PfxCertificate {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Creates new PFX certificate for the CredentialStore encryption.
|
||||
|
||||
.DESCRIPTION
|
||||
Use this function to create a custom self signed certificate used by the PSCredentialStore module.
|
||||
|
||||
.PARAMETER CRTAttribute
|
||||
Provide certificate related attributes provided by function New-CRTAttribute.
|
||||
|
||||
.PARAMETER KeyName
|
||||
Provide a custom full path and name for the private key. The file extension has to be `*.key`.
|
||||
|
||||
.PARAMETER CertName
|
||||
Provide a custom full path and name for the PFX certificate file. The file extension has to be `*.pfx`
|
||||
|
||||
.INPUTS
|
||||
[PSCredentialStore.Certificate.Attribute]
|
||||
|
||||
.OUTPUTS
|
||||
[None]
|
||||
|
||||
.EXAMPLE
|
||||
New-PfxCertificate -CRTAttribute $CRTAttribute -KeyName './myprivate.key' -CertName './mycert.pfx'
|
||||
|
||||
.NOTES
|
||||
File Name : New-PfxCertificate.ps1
|
||||
Author : Marco Blessing - marco.blessing@googlemail.com
|
||||
Requires :
|
||||
|
||||
.LINK
|
||||
https://github.com/OCram85/PSCredentialStore
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess = $true)]
|
||||
[OutputType()]
|
||||
param(
|
||||
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[PSTypeName('PSCredentialStore.Certificate.Attribute')]$CRTAttribute,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]$KeyName = './private.key',
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]$CertName = './certificate.pfx'
|
||||
)
|
||||
|
||||
begin {
|
||||
$ModuleBase = Get-ModuleBase
|
||||
if ($isLinux -or $isMacOS) {
|
||||
try {
|
||||
$openssl = Get-Command -Name 'openssl' -ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
$_.Exception.Message | Write-Error
|
||||
$ErrorParams = @{
|
||||
Message = 'Can not find the openssl binary!'
|
||||
ErrorAction = 'Stop'
|
||||
Exception = [System.IO.FileNotFoundException]::new()
|
||||
}
|
||||
Write-Error @ErrorParams
|
||||
}
|
||||
}
|
||||
elseif (($PSVersionTable.PSEdition -eq 'Desktop' -and $PSVersionTable.PSVersion.Major -lt 6) -or ($IsWindows -eq $true)) {
|
||||
$openssl = Join-Path -Path $ModuleBase -ChildPath '/Vendor/libressl255/openssl.exe'
|
||||
}
|
||||
|
||||
$Env:OPENSSL_CONF = Join-Path $ModuleBase -ChildPath '/openssl.conf'
|
||||
}
|
||||
process {
|
||||
$SubjPattern = "/C={0}/ST={1}/L={2}/O={3}/OU={4}/CN={5}"
|
||||
$SubjValues = @(
|
||||
$CRTAttribute.Subject.Country,
|
||||
$CRTAttribute.Subject.State,
|
||||
$CRTAttribute.Subject.City,
|
||||
$CRTAttribute.Subject.Organization,
|
||||
$CRTAttribute.Subject.OrganizationalUnitName,
|
||||
$CRTAttribute.Subject.CommonName
|
||||
)
|
||||
$Subj = $SubjPattern -f $SubjValues
|
||||
|
||||
$PEMCertName = $CertName -replace '.pfx', '.crt'
|
||||
$ExpPattern = '& ''{0}'' req -x509 -sha256 -nodes -days {1} -newkey rsa:2048 -keyout {2} -out {3} -subj "{4}" *>$null'
|
||||
$ExpValues = @(
|
||||
$openssl,
|
||||
$CRTAttribute.Days
|
||||
$KeyName,
|
||||
$PEMCertName,
|
||||
$Subj
|
||||
)
|
||||
$PEMExp = $ExpPattern -f $ExpValues
|
||||
|
||||
Write-Verbose -Message ( 'Expr string is: {0}' -f $PEMExp)
|
||||
|
||||
# Edit the Error action for the openSLL command to make the redirect *>$null work.
|
||||
# There is always a stderr and stdout stream!
|
||||
$EAP = $ErrorActionPreference
|
||||
$ErrorActionPreference = 'Continue'
|
||||
Invoke-Expression -Command $PEMExp
|
||||
$ErrorActionPreference = $EAP
|
||||
|
||||
# manually testing the openssl command results
|
||||
|
||||
if (! (Test-Path -Path $KeyName)) {
|
||||
$ErrorParams = @{
|
||||
Message = 'Could not create the private key ${0}' -f $KeyName
|
||||
ErrorAction = 'Stop'
|
||||
Exception = [System.UnauthorizedAccessException]::new()
|
||||
}
|
||||
Write-Error @ErrorParams
|
||||
}
|
||||
if (! (Test-Path -Path $PEMCertName)) {
|
||||
$ErrorParams = @{
|
||||
Message = 'Could not create the PEM certificate ${0}' -f $PEMCertName
|
||||
ErrorAction = 'Stop'
|
||||
Exception = [System.Exception]::new()
|
||||
}
|
||||
Write-Error @ErrorParams
|
||||
}
|
||||
|
||||
$PfxPattern = '& ''{0}'' pkcs12 -export -out {1} -inkey {2} -in {3} -passout pass:'
|
||||
$PfxValues = @(
|
||||
$openssl,
|
||||
$CertName,
|
||||
$KeyName,
|
||||
($CertName -replace '.pfx', '.crt')
|
||||
)
|
||||
$PfxExp = $PfxPattern -f $PfxValues
|
||||
Write-Verbose -Message ( 'PfxExp string is: {0}' -f $PfxExp)
|
||||
Invoke-Expression -Command $PfxExp
|
||||
|
||||
# Remove private key and crt file. Always ask user
|
||||
Remove-Item -Path $KeyName
|
||||
Remove-Item -Path ($CertName -replace '.pfx', '.crt')
|
||||
}
|
||||
end {
|
||||
Remove-Item Env:\OPENSSL_CONF -Confirm:$False -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
102
src/Certificate/Use-PfxCertificate.ps1
Normal file
102
src/Certificate/Use-PfxCertificate.ps1
Normal file
@ -0,0 +1,102 @@
|
||||
function Use-PfxCertificate {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Links an existing PFX Certifiacte to a CredentialStore.
|
||||
|
||||
.DESCRIPTION
|
||||
Linking a certificate is needed if you plan to use the same CredentialStore in cross platform scenarios.
|
||||
|
||||
.PARAMETER Path
|
||||
Specify the path to the PFX Certificate you want to link for usage.
|
||||
|
||||
.INPUTS
|
||||
[None]
|
||||
|
||||
.OUTPUTS
|
||||
[None]
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
|
||||
.NOTES
|
||||
File Name : Use-PfxCertificate.ps1
|
||||
Author : Marco Blessing - marco.blessing@googlemail.com
|
||||
Requires :
|
||||
|
||||
.LINK
|
||||
https://github.com/OCram85/PSCredentialStore
|
||||
#>
|
||||
[CmdletBinding(DefaultParameterSetName = "Private")]
|
||||
[OutputType()]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")]
|
||||
param(
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "Private")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "Shared")]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]$Path,
|
||||
|
||||
[Parameter(Mandatory = $false, ParameterSetName = "Shared")]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]$CredentialStore,
|
||||
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "Shared")]
|
||||
[switch]$Shared
|
||||
)
|
||||
begin {}
|
||||
|
||||
process {
|
||||
try {
|
||||
# We need to resolve the path to make sure it has the correct platform specific syntax.
|
||||
# And it should also exist.
|
||||
$validPath = Resolve-Path -Path $Path -ErrorAction Stop
|
||||
$PfxCertificate = Get-PfxCertificate -FilePath $validPath -ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
$_.Exception.Error | Write-Error
|
||||
$ErrorParams = @{
|
||||
Message = 'The given PFX certificate does not exist!'
|
||||
ErrorAction = 'Stop'
|
||||
}
|
||||
Write-Error @ErrorParams
|
||||
}
|
||||
|
||||
try {
|
||||
if ($PSCmdlet.ParameterSetName -eq "Private") {
|
||||
$StorePath = Get-DefaultCredentialStorePath
|
||||
$CS = Get-CredentialStore
|
||||
}
|
||||
elseif ($PSCmdlet.ParameterSetName -eq "Shared" ) {
|
||||
if (!($PSBoundParameters.ContainsKey('CredentialStore'))) {
|
||||
$StorePath = Get-DefaultCredentialStorePath -Shared
|
||||
$CS = Get-CredentialStore -Shared
|
||||
}
|
||||
else {
|
||||
$StorePath = $CredentialStore
|
||||
$CS = Get-CredentialStore -Shared -Path $CredentialStore
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
$_.Exception.Error | Write-Error
|
||||
$ErrorParams = @{
|
||||
Message = 'The given CredentialStore does not exist!'
|
||||
ErrorAction = 'Stop'
|
||||
}
|
||||
Write-Error @ErrorParams
|
||||
}
|
||||
|
||||
# Lets first check if the thumbprint matches
|
||||
if (($CS.Thumbprint -notmatch $PfxCertificate.Thumbprint) -and ($CS.Thumbprint.Length -ne 0)) {
|
||||
Write-Warning @"
|
||||
You are trying to map an unknown certificate.
|
||||
Make sure you used the same AES keys for encrypting!
|
||||
"@
|
||||
}
|
||||
|
||||
$CS.PfxCertificate = $validPath.Path
|
||||
$CS.Thumbprint = $PfxCertificate.Thumbprint
|
||||
$CS | ConvertTo-Json -Depth 5 | Out-File -FilePath $StorePath -Force -Encoding utf8
|
||||
}
|
||||
|
||||
end {}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
function Get-ChallengeFile {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Reads the challenge file as binary content.
|
||||
|
||||
.DESCRIPTION
|
||||
Use this function to tread a challenge file. Returns a [Byte[]] Array.
|
||||
|
||||
.PARAMETER Path
|
||||
Specify a file to read.
|
||||
|
||||
.INPUTS
|
||||
[None]
|
||||
|
||||
.OUTPUTS
|
||||
[Byte[]]
|
||||
|
||||
.EXAMPLE
|
||||
.\Get-RandomKey -Path "C:\TMP\Challenge.bin"
|
||||
|
||||
.NOTES
|
||||
```
|
||||
File Name : Get-ChallengeFile.ps1
|
||||
Author : Marco Blessing - marco.blessing@googlemail.com
|
||||
Requires :
|
||||
```
|
||||
.LINK
|
||||
https://github.com/OCram85/PSCredentialStore
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $false)]
|
||||
[string]$Path = "{0}\PSCredentialStore\Challenge.bin" -f $env:ProgramData
|
||||
)
|
||||
|
||||
if (Test-Path $Path) {
|
||||
try {
|
||||
[io.file]::ReadAllBytes($Path)
|
||||
}
|
||||
catch {
|
||||
Write-Error ("Could not read file {0}." -f $Path) -ErrorAction Stop
|
||||
}
|
||||
}
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
Function Set-ChallengeFile() {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Writes the given key into the challenge file
|
||||
|
||||
.DESCRIPTION
|
||||
You can use the file content for ConvertTo-SecureString operations.
|
||||
|
||||
.PARAMETER Path
|
||||
The file you wish to create.
|
||||
|
||||
.PARAMETER KeySize
|
||||
Specify the key size for the encryption key.
|
||||
|
||||
.PARAMETER Force
|
||||
Use this switch to override an older file version.
|
||||
|
||||
.INPUTS
|
||||
[None]
|
||||
|
||||
.OUTPUTS
|
||||
[None]
|
||||
|
||||
.EXAMPLE
|
||||
.\Set-ChallengeFile -Path "C:\TMP\myfile.json" -Force
|
||||
|
||||
.NOTES
|
||||
File Name : Set-ChallengeFile.ps1
|
||||
Author : Marco Blessing - marco.blessing@googlemail.com
|
||||
Requires :
|
||||
|
||||
.LINK
|
||||
https://github.com/OCram85/PSCredentialStore
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $false)]
|
||||
[string]$Path = "{0}\PSCredentialStore\Challenge.bin" -f $env:ProgramData,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[ValidateSet(16, 24, 32)]
|
||||
[string]$KeySize = "24",
|
||||
|
||||
[switch]$Force
|
||||
)
|
||||
|
||||
if ((Test-Path -Path $Path)) {
|
||||
if ($Force -eq $true) {
|
||||
Remove-Item -Path $Path -Confirm:$false -Force
|
||||
}
|
||||
else {
|
||||
Write-Error "The given file already exists!. Use the -Force switch to override it." -ErrorAction Stop
|
||||
}
|
||||
}
|
||||
$PSCredentialStoreDataDir = Split-Path -Path $Path -Parent
|
||||
if (-not (Test-Path $PSCredentialStoreDataDir)) {
|
||||
try {
|
||||
New-Item -ItemType Directory -Path $PSCredentialStoreDataDir
|
||||
}
|
||||
catch {
|
||||
Write-Error ("Could not create the parent data dir {0}" -f $PSCredentialDataDir) -ErrorAction Stop
|
||||
}
|
||||
}
|
||||
try {
|
||||
$Keys = Get-RandomKey -Size $KeySize
|
||||
[io.file]::WriteAllBytes($Path, $Keys)
|
||||
}
|
||||
catch {
|
||||
$_.Exception | Format-List -Force | Out-String | Write-Error -ErrorAction Stop
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
function Test-ChallengeFile {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Simple path check for challenge file needed by the CredentialStores.
|
||||
|
||||
.DESCRIPTION
|
||||
This is supposed to be a internal function to check the existence for a challenge file.
|
||||
|
||||
.PARAMETER Path
|
||||
Specify the path to the challenge file.
|
||||
|
||||
.INPUTS
|
||||
[None]
|
||||
|
||||
.OUTPUTS
|
||||
[Bool].
|
||||
|
||||
.EXAMPLE
|
||||
If (Test-ChallengeFile) {
|
||||
Write-Host "The file exists."
|
||||
}
|
||||
Else {
|
||||
Write-Warning "Couldn't find the given file!"
|
||||
}
|
||||
|
||||
.NOTES
|
||||
File Name : Test-ChallengeFile.ps1
|
||||
Author : Marco Blessing - marco.blessing@googlemail.com
|
||||
Requires :
|
||||
|
||||
.LINK
|
||||
https://github.com/OCram85/PSCredentialStore
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $false)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]$Path = "{0}\PSCredentialStore\Challenge.bin" -f $env:ProgramData
|
||||
)
|
||||
|
||||
if (Test-Path $Path) {
|
||||
$true
|
||||
}
|
||||
else {
|
||||
$false
|
||||
}
|
||||
}
|
@ -93,15 +93,30 @@ function Connect-To {
|
||||
[Parameter(Mandatory = $False, ParameterSetName = "Private")]
|
||||
[PSCredential]$Credentials,
|
||||
|
||||
[Parameter(Mandatory = $true, ParameterSetNAme = "Shared")]
|
||||
[switch]$Shared,
|
||||
|
||||
[Parameter(Mandatory = $False, ParameterSetName = "Shared")]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]$Path = "{0}\PSCredentialStore\CredentialStore.json" -f $env:ProgramData,
|
||||
[string]$Path,
|
||||
|
||||
[Parameter(Mandatory = $false, ParameterSetNAme = "Shared")]
|
||||
[switch]$Shared
|
||||
[Parameter(Mandatory = $False, ParameterSetName = "Private")]
|
||||
[Parameter(Mandatory = $False, ParameterSetName = "Shared")]
|
||||
[switch]$PassThru
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
# First check the optional modules
|
||||
if (-not (Resolve-Dependency -Name $Type)) {
|
||||
Write-Error -Message ("Could not resolve the optional dependencies defined for {0}" -f $Type) -ErrorAction 'Stop'
|
||||
@ -118,10 +133,6 @@ function Connect-To {
|
||||
}
|
||||
|
||||
process {
|
||||
# Set the correct CredentialStore Path depending on the used ParameterSetName
|
||||
if ($PSCmdlet.ParameterSetName -eq "Private") {
|
||||
$Path = "{0}\CredentialStore.json" -f $env:APPDATA
|
||||
}
|
||||
if (-not ($Credentials)) {
|
||||
# Load the credential from the CredentialStore. If the credential doesn't exist, we need to
|
||||
# return 1, so a calling if statement can handle the failure detection.
|
||||
@ -131,16 +142,16 @@ function Connect-To {
|
||||
try {
|
||||
if ($Identifier -ne "") {
|
||||
$RemoteHostIdentifier = "{0}/{1}" -f $Identifier, $RemoteHost
|
||||
$creds = Get-CredentialStoreItem -RemoteHost $RemoteHostIdentifier -Path $Path
|
||||
$creds = Get-CredentialStoreItem -Shared -RemoteHost $RemoteHostIdentifier -Path $Path
|
||||
}
|
||||
else {
|
||||
$creds = Get-CredentialStoreItem -RemoteHost $RemoteHost -Path $Path
|
||||
$creds = Get-CredentialStoreItem -Shared -RemoteHost $RemoteHost -Path $Path
|
||||
}
|
||||
}
|
||||
|
||||
catch {
|
||||
$MessageParams = @{
|
||||
Message = "Unable to look up credential store item for RemoteHost {0}/Identifier {1}!" -f $RemoteHost, $Identifier
|
||||
Message = "Unable to look up credential store item for RemoteHost {0}/Identifier {1}!" -f $RemoteHost, $Identifier
|
||||
ErrorAction = "Stop"
|
||||
}
|
||||
Write-Error @MessageParams
|
||||
@ -152,7 +163,7 @@ function Connect-To {
|
||||
|
||||
if ($creds.UserName -eq "" -or $creds.Password.GetType().Name -ne "SecureString") {
|
||||
$MessageParams = @{
|
||||
Message = "Please provide valid credentials for RemoteHost {0}!" -f $RemoteHost
|
||||
Message = "Please provide valid credentials for RemoteHost {0}!" -f $RemoteHost
|
||||
ErrorAction = "Stop"
|
||||
}
|
||||
Write-Error @MessageParams
|
||||
@ -167,7 +178,7 @@ function Connect-To {
|
||||
|
||||
catch {
|
||||
$MessageParams = @{
|
||||
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
|
||||
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
|
||||
ErrorAction = "Stop"
|
||||
}
|
||||
Write-Error @MessageParams
|
||||
@ -177,9 +188,9 @@ function Connect-To {
|
||||
# First establish the FTP session
|
||||
$WinSCPConParams = @{
|
||||
Credential = $creds
|
||||
Hostname = $RemoteHost
|
||||
Protocol = 'Ftp'
|
||||
FtpMode = 'Passive'
|
||||
Hostname = $RemoteHost
|
||||
Protocol = 'Ftp'
|
||||
FtpMode = 'Passive'
|
||||
}
|
||||
try {
|
||||
$FTPSessionOption = New-WinSCPSessionOption @WinSCPConParams
|
||||
@ -192,7 +203,7 @@ function Connect-To {
|
||||
if (!($WinSCPSession.Opened)) {
|
||||
# Check the connection state and find out if the session is still open.
|
||||
$MessageParams = @{
|
||||
Message = "Connection to {0} using Type {1} was established. But now it seems to be lost!" -f $RemoteHost, $Type
|
||||
Message = "Connection to {0} using Type {1} was established. But now it seems to be lost!" -f $RemoteHost, $Type
|
||||
ErrorAction = "Stop"
|
||||
}
|
||||
Write-Error @MessageParams
|
||||
@ -206,7 +217,7 @@ function Connect-To {
|
||||
catch {
|
||||
# Write a error message to the log.
|
||||
$MessageParams = @{
|
||||
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
|
||||
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
|
||||
ErrorAction = "Stop"
|
||||
}
|
||||
Write-Error @MessageParams
|
||||
@ -220,7 +231,7 @@ function Connect-To {
|
||||
catch {
|
||||
# Write a error message to the log.
|
||||
$MessageParams = @{
|
||||
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
|
||||
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
|
||||
ErrorAction = "Stop"
|
||||
}
|
||||
Write-Error @MessageParams
|
||||
@ -228,13 +239,19 @@ function Connect-To {
|
||||
}
|
||||
"CisServer" {
|
||||
try {
|
||||
Connect-CisServer -Server $RemoteHost -Credential $creds -ErrorAction Stop | Out-Null
|
||||
if ($PassThru.IsPresent) {
|
||||
Connect-CisServer -Server $RemoteHost -Credential $creds -ErrorAction Stop
|
||||
}
|
||||
else {
|
||||
Connect-CisServer -Server $RemoteHost -Credential $creds -ErrorAction Stop | Out-Null
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
catch {
|
||||
# Write a error message to the log.
|
||||
$MessageParams = @{
|
||||
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
|
||||
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
|
||||
ErrorAction = "Stop"
|
||||
}
|
||||
Write-Error @MessageParams
|
||||
@ -243,17 +260,17 @@ function Connect-To {
|
||||
"ExchangeHTTP" {
|
||||
try {
|
||||
$ConnectionParams = @{
|
||||
ConnectionURI = "http://{0}/powershell" -f $RemoteHost
|
||||
ConnectionURI = "http://{0}/powershell" -f $RemoteHost
|
||||
ConfigurationName = 'Microsoft.Exchange'
|
||||
Credential = $creds
|
||||
ErrorAction = 'Stop'
|
||||
Credential = $creds
|
||||
ErrorAction = 'Stop'
|
||||
}
|
||||
$Global:PSExchangeRemote = New-PSSession @ConnectionParams
|
||||
}
|
||||
catch {
|
||||
# Write a error message to the log.
|
||||
$MessageParams = @{
|
||||
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
|
||||
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
|
||||
ErrorAction = "Stop"
|
||||
}
|
||||
Write-Error @MessageParams
|
||||
@ -262,17 +279,17 @@ function Connect-To {
|
||||
"ExchangeHTTPS" {
|
||||
try {
|
||||
$ConnectionParams = @{
|
||||
ConnectionURI = "https://{0}/powershell" -f $RemoteHost
|
||||
ConnectionURI = "https://{0}/powershell" -f $RemoteHost
|
||||
ConfigurationName = 'Microsoft.Exchange'
|
||||
Credential = $creds
|
||||
ErrorAction = 'Stop'
|
||||
Credential = $creds
|
||||
ErrorAction = 'Stop'
|
||||
}
|
||||
$Global:PSExchangeRemote = New-PSSession @ConnectionParams
|
||||
}
|
||||
catch {
|
||||
# Write a error message to the log.
|
||||
$MessageParams = @{
|
||||
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
|
||||
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
|
||||
ErrorAction = "Stop"
|
||||
}
|
||||
Write-Error @MessageParams
|
||||
@ -280,9 +297,9 @@ function Connect-To {
|
||||
}
|
||||
"SCP" {
|
||||
$WinSCPSessionParams = @{
|
||||
Credential = $creds
|
||||
Hostname = $RemoteHost
|
||||
Protocol = 'Scp'
|
||||
Credential = $creds
|
||||
Hostname = $RemoteHost
|
||||
Protocol = 'Scp'
|
||||
GiveUpSecurityAndAcceptAnySshHostKey = $True
|
||||
}
|
||||
try {
|
||||
@ -293,7 +310,7 @@ function Connect-To {
|
||||
catch {
|
||||
# Write a error message to the log.
|
||||
$MessageParams = @{
|
||||
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
|
||||
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
|
||||
ErrorAction = "Stop"
|
||||
}
|
||||
Write-Error @MessageParams
|
||||
@ -302,7 +319,7 @@ function Connect-To {
|
||||
if (!($WinSCPSession.Opened)) {
|
||||
# Check the connection state and find out if the session is still open.
|
||||
$MessageParams = @{
|
||||
Message = "Connection to {0} using Type {1} was established. But now it seems to be lost!" -f $RemoteHost, $Type
|
||||
Message = "Connection to {0} using Type {1} was established. But now it seems to be lost!" -f $RemoteHost, $Type
|
||||
ErrorAction = "Stop"
|
||||
}
|
||||
Write-Error @MessageParams
|
||||
@ -311,7 +328,7 @@ function Connect-To {
|
||||
default {
|
||||
# Write a error message to the log.
|
||||
$MessageParams = @{
|
||||
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
|
||||
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
|
||||
ErrorAction = "Stop"
|
||||
}
|
||||
Write-Error @MessageParams
|
||||
|
@ -1,50 +0,0 @@
|
||||
function Get-RandomKey {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Returns a random key
|
||||
|
||||
.DESCRIPTION
|
||||
You can use the key for further use with SecureStrings.
|
||||
|
||||
.PARAMETER Size
|
||||
Define the key size. You can choose between 16, 24 and 32
|
||||
|
||||
.INPUTS
|
||||
[None]
|
||||
|
||||
.OUTPUTS
|
||||
Returns a Random key as [Byte[]] array.
|
||||
|
||||
.EXAMPLE
|
||||
.\Get-RandomKey -Size 24
|
||||
|
||||
.NOTES
|
||||
```
|
||||
File Name : Get-RandomKey.ps1
|
||||
Author : Marco Blessing - marco.blessing@googlemail.com
|
||||
Requires :
|
||||
```
|
||||
|
||||
.LINK
|
||||
https://github.com/OCram85/PSCredentialStore
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[ValidateSet(16, 24, 32)]
|
||||
[string]$size
|
||||
)
|
||||
# Init the vars
|
||||
[Byte[]]$Key = @()
|
||||
$i = 0
|
||||
|
||||
while ($i -ne $size) {
|
||||
$element = Get-Random -Minimum 0 -Maximum 255
|
||||
Write-Debug ("The current element is {0}." -f $element)
|
||||
$Key += $element
|
||||
$i++
|
||||
}
|
||||
$Key
|
||||
}
|
@ -41,11 +41,8 @@ function Get-CredentialStoreItem {
|
||||
#>
|
||||
|
||||
[CmdletBinding(DefaultParameterSetName = "Private")]
|
||||
[OutputType([System.Management.Automation.PSCredential])]
|
||||
[OutputType([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()]
|
||||
@ -56,55 +53,72 @@ function Get-CredentialStoreItem {
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]$Identifier,
|
||||
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "Shared")]
|
||||
[switch]$Shared,
|
||||
|
||||
[Parameter(Mandatory = $false, ParameterSetName = "Shared")]
|
||||
[switch]$Shared
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]$Path
|
||||
)
|
||||
|
||||
# First set a constand path for private CredentialStore mode.
|
||||
if ($PSCmdlet.ParameterSetName -eq "Private") {
|
||||
$Path = "{0}\CredentialStore.json" -f $env:APPDATA
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($Identifier -ne "") {
|
||||
$CredentialName = $RemoteHost = "{0}/{1}" -f $Identifier, $RemoteHost
|
||||
}
|
||||
else {
|
||||
$CredentialName = $RemoteHost
|
||||
}
|
||||
process {
|
||||
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
|
||||
if (Test-CredentialStore -Shared -Path $Path) {
|
||||
$CS = Get-CredentialStore -Shared -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 -contains $CredentialName)) {
|
||||
$Cert = Get-PfxCertificate -FilePath $CS.PfXCertificate -ErrorAction Stop
|
||||
$DecryptedKey = $Cert.PrivateKey.Decrypt(
|
||||
[Convert]::FromBase64String($CS.$CredentialName.EncryptedKey),
|
||||
[System.Security.Cryptography.RSAEncryptionPadding]::Pkcs1
|
||||
)
|
||||
|
||||
if (! $ExpandOutput.isPresent) {
|
||||
[PSCredential]::new(
|
||||
$CS.$CredentialName.User,
|
||||
($CS.$CredentialName.Password | ConvertTo-SecureString -Key $DecryptedKey)
|
||||
)
|
||||
}
|
||||
}
|
||||
else {
|
||||
$Key = Get-ChallengeFile
|
||||
$CSItem = [ordered]@{
|
||||
User = $CS.$CredentialName.User
|
||||
Password = ConvertTo-SecureString -String $CS.$CredentialName.Password -Key $Key
|
||||
$MsgParams = @{
|
||||
ErrorAction = "Stop"
|
||||
Message = "Could not find credentials for the given remote host: {0}" -f $RemoteHost
|
||||
}
|
||||
Write-Error @MsgParams
|
||||
}
|
||||
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
|
||||
Message = "The given credential store ({0}) does not exist!" -f $Path
|
||||
}
|
||||
Write-Error @MsgParams
|
||||
}
|
||||
}
|
||||
else {
|
||||
$MsgParams = @{
|
||||
ErrorAction = "Stop"
|
||||
Message = "The given credential store ({0}) does not exist!" -f $Path
|
||||
}
|
||||
Write-Error @MsgParams
|
||||
|
||||
end {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -42,9 +42,6 @@ function New-CredentialStoreItem {
|
||||
|
||||
[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()]
|
||||
@ -59,78 +56,120 @@ function New-CredentialStoreItem {
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[PSCredential]$Credential,
|
||||
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "Shared")]
|
||||