diff --git a/.drone.yml b/.drone.yml
index 8e876df..1a9e24e 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -1,32 +1,63 @@
----
-kind: pipeline
-type: docker
-name: Linux_PWSH7_Build
-
-platform:
- os: linux
- arch: amd64
-
-steps:
- - name: Environments
- image: mcr.microsoft.com/powershell:latest
- commands:
- - pwsh -NonInteractive -c "& {Import-Module './tools/DroneIO.psm1' -Verbose; Invoke-ShowEnv -Verbose}"
- - pwsh -NonInteractive -c "& {Import-Module './tools/DroneIO.psm1' -Verbose; Invoke-InstallDependencies -Verbose}"
- - name: LintTests
- image: mcr.microsoft.com/powershell:latest
- commands:
- - pwsh -NonInteractive -c "& {Import-Module './tools/DroneIO.psm1'; Invoke-InstallDependencies}"
- - pwsh -NonInteractive -c "& {Import-Module './tools/DroneIO.psm1'; Invoke-Linter}"
- - name: UnitTests
- image: mcr.microsoft.com/powershell:latest
- commands:
- - pwsh -NonInteractive -c "& {Import-Module './tools/DroneIO.psm1'; Invoke-InstallDependencies}"
- - pwsh -NonInteractive -c "& {Import-Module './tools/DroneIO.psm1'; Invoke-UnitTests}"
- - name: coverage
- image: plugins/codecov
- settings:
- token:
- from_secret: CodeCovToken
- files:
- - coverage.xml
+---
+kind: pipeline
+type: docker
+name: PWSH_LTS_7.2_Ubuntu-focal
+
+platform:
+ os: linux
+ arch: amd64
+
+steps:
+ - name: Environments
+ image: mcr.microsoft.com/powershell:lts-7.2-ubuntu-focal
+ commands:
+ - |
+ pwsh -NonInteractive -c "& {
+ Import-Module './tools/DroneIO.psm1' -Verbose;
+ Invoke-ShowEnv -Verbose
+ }"
+
+ - name: LintTests
+ image: mcr.microsoft.com/powershell:lts-7.2-ubuntu-focal
+ failure: ignore
+ commands:
+ - |
+ pwsh -NonInteractive -c "& {
+ Import-Module './tools/DroneIO.psm1';
+ Invoke-InstallDependencies;
+ Invoke-Linter -ErrorAction 'Stop'
+ }"
+
+ - name: UnitTests
+ image: mcr.microsoft.com/powershell:lts-7.2-ubuntu-focal
+ failure: ignore
+ commands:
+ - |
+ pwsh -NonInteractive -c "& {
+ Import-Module './tools/DroneIO.psm1';
+ Invoke-InstallDependencies;
+ Invoke-UnitTest -Verbosity 'Normal' -ExcludeTag @( 'Integration', 'Disabled') -ErrorAction 'Stop'
+ }"
+
+ - name: Coverage
+ image: plugins/codecov
+ settings:
+ token:
+ from_secret: CodeCovToken
+ files:
+ - coverage.xml
+ depends_on:
+ - UnitTests
+
+ - name: SetPipelineState
+ image: mcr.microsoft.com/powershell:lts-7.2-ubuntu-focal
+ commands:
+ - |
+ pwsh -NonInteractive -c "& {
+ Import-Module './tools/DroneIO.psm1';
+ Invoke-BuildState -ErrorAction 'Stop'
+ }"
+ depends_on:
+ - LintTests
+ - UnitTests
+ - Coverage
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..b09ffcf
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,31 @@
+root = true
+
+[*]
+indent_style = space
+indent_size = 4
+end_of_line = crlf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+
+[*.yml]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[{.gitattributes,.gitignore,.gitkeep}]
+end_of_line = lf
+trim_trailing_whitespace = true
+insert_final_newline = true
diff --git a/.gitattributes b/.gitattributes
index 5520579..48c4df2 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,2 +1,24 @@
-src/Vendor/libressl255/* filter=lfs diff=lfs merge=lfs -text
-*.pfx filter=lfs diff=lfs merge=lfs -text
+# images
+*.jpg binary
+*.jpeg binary
+*.bmp binary
+*.tiff binary
+*.png binary
+*.svg binary
+*.ico binary
+
+# binary files
+*.exe binary
+*.dll binary
+
+# PowerShell specific
+*.ps1 working-tree-encoding=UTF-8
+*.psm1 working-tree-encoding=UTF-8
+*.psd1 working-tree-encoding=UTF-8
+
+# set markdown to lf for online editing
+*.md working-tree-encoding=UTF-8
+
+# Vendor resources config
+src/Vendor/libressl255/* filter=lfs diff=lfs merge=lfs -text
+*.pfx filter=lfs diff=lfs merge=lfs -text
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000..f1d8d08
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,50 @@
+---
+name: Bug report
+about: This template is used to report bugs!
+title: ":lady_beetle: "
+labels: bug
+assignees: OCram85
+
+---
+
+
+
+#### :bomb: Steps to reproduce
+
+```bash
+
+```
+
+#### :rocket: Expected behavior
+
+```bash
+
+```
+
+#### :boom: Actual behavior
+
+```bash
+
+```
+
+#### :notebook: Environment data
+
+
+
+```bash
+
+```
+
+#### :framed_picture: Screenshots
+
+
+
+#### :bookmark: Refs
+
+
diff --git a/.github/ISSUE_TEMPLATE/default.md b/.github/ISSUE_TEMPLATE/default.md
new file mode 100644
index 0000000..c458e70
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/default.md
@@ -0,0 +1,12 @@
+---
+name: Default
+about: Use this template if nothing seems to work.
+title: ":question: "
+labels: question
+assignees: ''
+
+---
+
+#### :grey_question: Simply ask your question here: :grey_question:
+
+
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..1fdbdfd
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,26 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ":flying_saucer: "
+labels: enhancement
+assignees: ''
+
+---
+
+
+
+#### :satellite: Suggestion
+
+
+
+#### :artificial_satellite: Implementation ideas
+
+
+
+#### :framed_picture: Mock-up Images
+
+
+
+#### :bookmark: Refs.
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000..02b8ef6
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,19 @@
+#### :book: Summary
+
+
+
+#### :bookmark_tabs: Test Plan
+
+> :bulb: Select your test plan for the code changes.
+
+- [ ] Tested via Drone.io pipeline
+- [ ] Custom test
+- [ ] No test plan
+
+##### Details / Justification
+
+
+
+#### :books: Additional Notes
+
+
diff --git a/.gitignore b/.gitignore
index 45b36c1..fc98b4f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,21 @@
-# Don't local track test builds
-bin/PSCredentialStore.zip
-bin/PSCredentialStore/*
+# Don't local track test builds
+bin/PSCredentialStore.zip
+bin/PSCredentialStore/*
+
+# Basic ignore patterns
+*.log
+*.secret
+
+# data dir related prod files
+data/*.csv
+
+# Ignore templ build artifacts
+/bin/*
+!bin/.gitkeep
+
+# Ignore Unit Test result files
+coverage.xml
+testResults.xml
+
+# Optional build state file
+STATE.xml
diff --git a/.vscode/cSpell.json b/.vscode/cSpell.json
index 40cc042..b4e5b04 100644
--- a/.vscode/cSpell.json
+++ b/.vscode/cSpell.json
@@ -1,40 +1,22 @@
-// cSpell Settings
-{
- // Version of the setting file. Always 0.1
- "version": "0.1",
- // language - current active spelling language
- "language": "en",
- // words - list of words to be always considered correct
- "words": [
- "Cmdlet",
- "Cmdlets",
- "GUID",
- "Hashtable",
- "Httpclient",
- "Multipart",
- "NTFS",
- "Params",
- "Ponduit",
- "Repo",
- "Veyor",
- "appveyor",
- "callsign",
- "choco",
- "chocolatey",
- "codecoverage",
- "creds",
- "formdata",
- "googlemail",
- "notlike",
- "notmatch",
- "powershellgallery",
- "testresults",
- "wildcards"
- ],
- // flagWords - list of words to be always considered incorrect
- // This is useful for offensive words and common spelling errors.
- // For example "hte" should be "the"
- "flagWords": [
- "hte"
- ]
-}
\ No newline at end of file
+// cSpell Settings
+{
+ // Version of the setting file. Always 0.1
+ "version": "0.2",
+ // language - current active spelling language
+ "language": "en,de,de-DE",
+ // words - list of words to be always considered correct
+ "words": [],
+ // flagWords - list of words to be always considered incorrect
+ // This is useful for offensive words and common spelling errors.
+ // For example "hte" should be "the"
+ "flagWords": [],
+ "dictionaryDefinitions": [
+ {
+ "name": "default",
+ "path": "./dictionaries/default.txt"
+ }
+ ],
+ "dictionaries": [
+ "default"
+ ]
+}
diff --git a/tests/.gitkeep b/.vscode/dictionaries/default.txt
similarity index 100%
rename from tests/.gitkeep
rename to .vscode/dictionaries/default.txt
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 0000000..073c578
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,13 @@
+{
+ "recommendations": [
+ "streetsidesoftware.code-spell-checker",
+ "streetsidesoftware.code-spell-checker-german",
+ "hediet.vscode-drawio",
+ "editorconfig.editorconfig",
+ "eamodio.gitlens",
+ "vscode-icons-team.vscode-icons",
+ "redhat.vscode-xml",
+ "redhat.vscode-yaml",
+ "ryanluker.vscode-coverage-gutters"
+ ]
+}
diff --git a/.vscode/launch.json b/.vscode/launch.json
index affb74a..de0c692 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -42,7 +42,7 @@
"type": "PowerShell",
"request": "launch",
"name": "PowerShell Interactive Session",
- "cwd": ""
+ "cwd": "${workspaceRoot}"
}
]
}
diff --git a/.vscode/pwsh.code-snippets b/.vscode/pwsh.code-snippets
new file mode 100644
index 0000000..563cf11
--- /dev/null
+++ b/.vscode/pwsh.code-snippets
@@ -0,0 +1,31 @@
+{
+ // Place your PowerShell-Module workspace snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
+ // description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
+ // is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
+ // used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
+ // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
+ // Placeholders with the same ids are connected.
+ // Example:
+ // "Print to console": {
+ // "scope": "javascript,typescript",
+ // "prefix": "log",
+ // "body": [
+ // "console.log('$1');",
+ // "$2"
+ // ],
+ // "description": "Log output to console"
+ // }
+ // PSScriptAnalyzder Rule Suppression
+ "Rule Suppression": {
+ "scope": "powershell",
+ "prefix": "[Diag",
+ "description": "Suppresses Scriptanalyzer Rules",
+ "body": [
+ "[Diagnostics.CodeAnalysis.SuppressMessageAttribute(",
+ " '${1|PSProvideCommentHelp,PSAvoidLongLines,PSAvoidUsingWriteHost,PSUseShouldProcessForStateChangingFunctions|}',",
+ " '',",
+ " Justification = '${justification}'",
+ ")]"
+ ]
+ }
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 39b2319..56b9a63 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,51 +1,52 @@
-// Place your settings in this file to overwrite default and user settings.
-{
- // Set basic file related options:
- "files.encoding": "utf8",
- "files.eol": "\r\n",
- "files.trimTrailingWhitespace": true,
- "files.insertFinalNewline": true,
- // Formation and editor options
- "editor.renderWhitespace": "boundary",
- "editor.formatOnSave": true,
- "editor.formatOnType": true,
- "editor.rulers": [
- 116
- ],
- // powershell general
- "powershell.startAutomatically": true,
- "powershell.useX86Host": false,
- "powershell.enableProfileLoading": true,
- "powershell.scriptAnalysis.enable": true,
- // powershell code Formatting
- "powershell.codeFormatting.openBraceOnSameLine": true,
- "powershell.codeFormatting.newLineAfterOpenBrace": true,
- "powershell.codeFormatting.newLineAfterCloseBrace": true,
- "powershell.codeFormatting.whitespaceBeforeOpenBrace": true,
- "powershell.codeFormatting.whitespaceBeforeOpenParen": true,
- "powershell.codeFormatting.whitespaceAroundOperator": true,
- "powershell.codeFormatting.whitespaceAfterSeparator": true,
- "powershell.codeFormatting.ignoreOneLineBlock": true,
- "powershell.codeFormatting.alignPropertyValuePairs": true,
- "powershell.codeFormatting.preset": "Custom",
- // cspell spellchecker options
- "cSpell.enabledLanguageIds": [
- "c",
- "cpp",
- "csharp",
- "go",
- "javascript",
- "javascriptreact",
- "json",
- "latex",
- "markdown",
- "php",
- "plaintext",
- "powershell",
- "python",
- "text",
- "typescript",
- "typescriptreact",
- "yml"
- ]
-}
+{
+ "files.encoding": "utf8",
+ "files.eol": "auto",
+ "files.trimTrailingWhitespace": true,
+ "files.insertFinalNewline": true,
+ "editor.renderWhitespace": "boundary",
+ "editor.formatOnSave": true,
+ "editor.formatOnType": true,
+ "editor.rulers": [
+ 116
+ ],
+ "cSpell.enabled": true,
+ "cSpell.enabledLanguageIds": [
+ "c",
+ "cpp",
+ "csharp",
+ "go",
+ "javascript",
+ "javascriptreact",
+ "json",
+ "latex",
+ "markdown",
+ "php",
+ "plaintext",
+ "powershell",
+ "python",
+ "text",
+ "typescript",
+ "typescriptreact",
+ "yaml",
+ "yml"
+ ],
+ "cSpell.language": "en,de,de-DE",
+ // powershell general
+ "powershell.startAutomatically": true,
+ "powershell.useX86Host": false,
+ "powershell.enableProfileLoading": true,
+ "powershell.scriptAnalysis.enable": true,
+ // powershell code Formatting
+ "powershell.codeFormatting.openBraceOnSameLine": true,
+ "powershell.codeFormatting.newLineAfterOpenBrace": true,
+ "powershell.codeFormatting.newLineAfterCloseBrace": true,
+ "powershell.codeFormatting.whitespaceBeforeOpenBrace": true,
+ "powershell.codeFormatting.whitespaceBeforeOpenParen": true,
+ "powershell.codeFormatting.whitespaceAroundOperator": true,
+ "powershell.codeFormatting.whitespaceAfterSeparator": true,
+ "powershell.codeFormatting.ignoreOneLineBlock": true,
+ "powershell.codeFormatting.alignPropertyValuePairs": true,
+ "powershell.scriptAnalysis.settingsPath": "./tools/PSScriptAnalyzerSettings.psd1",
+ "coverage-gutters.showGutterCoverage": false,
+ "coverage-gutters.showLineCoverage": true
+}
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index d8fd688..f16fd23 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -1,56 +1,121 @@
+// A task runner that invokes Pester to run all Pester tests under the
+// current workspace folder.
+// NOTE: This Test task runner requires an updated version of Pester (>=4.0.3)
+// in order for the problemMatcher to find failed test information (message, line, file).
+// If you don't have that version, you can update Pester from the PowerShell Gallery
+// with this command:
+//
+// PS C:\> Update-Module Pester
+//
+// If that gives an error like:
+// "Module 'Pester' was not installed by using Install-Module, so it cannot be updated."
+// then execute:
+//
+// PS C:\> Install-Module Pester -Scope CurrentUser -Force
+//
+// NOTE: The Clean, Build and Publish tasks require PSake. PSake can be installed
+// from the PowerShell Gallery with this command:
+//
+// PS C:\> Install-Module PSake -Scope CurrentUser -Force
+//
+// Available variables which can be used inside of strings:
+// ${workspaceFolder} the path of the workspace folder that contains the tasks.json file
+// ${workspaceFolderBasename} the name of the workspace folder that contains the tasks.json file without any slashes (/)
+// ${file} the current opened file
+// ${relativeFile} the current opened file relative to the workspace folder containing the file
+// ${fileBasename} the current opened file's basename
+// ${fileBasenameNoExtension} the current opened file's basename without the extension
+// ${fileDirname} the current opened file's dirname
+// ${fileExtname} the current opened file's extension
+// ${cwd} the task runner's current working directory on startup
+// ${lineNumber} the current selected line number in the active file
{
- // See https://go.microsoft.com/fwlink/?LinkId=733558
- // for the documentation about the tasks.json format
"version": "2.0.0",
- // Start PowerShell
- "windows": {
- "command": "${env:windir}/System32/WindowsPowerShell/v1.0/powershell.exe",
- "args": [
- "-NoProfile",
- "-ExecutionPolicy",
- "Bypass"
- ]
- },
+ //"windows": {
+ // "options": {
+ // "shell": {
+ // // switch back to windows powershell 5.1
+ // // "executable": "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
+ // "executable": "pwsh.exe",
+ // "args": [
+ // "-NoProfile",
+ // "-ExecutionPolicy",
+ // "Bypass",
+ // "-Command"
+ // ]
+ // }
+ // }
+ //},
"linux": {
- "command": "/usr/bin/powershell",
- "args": [
- "-NoProfile"
- ]
- },
- "osx": {
- "command": "/usr/local/bin/powershell",
- "args": [
- "-NoProfile"
- ]
+ "options": {
+ "shell": {
+ "executable": "/usr/bin/pwsh",
+ "args": [
+ "-NoProfile",
+ "-Command"
+ ]
+ }
+ }
},
+ //"osx": {
+ // "options": {
+ // "shell": {
+ // "executable": "/usr/local/bin/pwsh",
+ // "args": [
+ // "-NoProfile",
+ // "-Command"
+ // ]
+ // }
+ // }
+ //},
"tasks": [
{
- "taskName": "Test",
- "suppressTaskName": true,
- "args": [
- "Write-Host 'Invoking Pester...'; $ProgressPreference = 'SilentlyContinue'; Invoke-Pester -Script ( Get-ChildItem -Path '.\\tests\\*.Tests.ps1' -Recurse | Sort-Object -Property Name ) -EnableExit $flase -PesterOption @{IncludeVSCodeMarker=$true};",
- "Invoke-Command { Write-Host 'Completed Test task in task runner.' }"
+ "label": "DroneIO: Invoke-Linter",
+ "type": "shell",
+ "command": [
+ "Import-Module ./tools/DroneIO.psm1;",
+ "Invoke-Linterq | Format-Table -AutoSize"
],
- "problemMatcher": "$pester",
- "group": {
- "kind": "test",
- "isDefault": true
- }
+ "group": "test",
+ "problemMatcher": [
+ "$pester"
+ ]
},
{
- "taskName": "DebugBuild",
- "suppressTaskName": true,
- "args": [
- "Write-Host 'Invoking Build...';",
- "Write-Host -Object 'Test previous builds.' -ForegroundColor Blue;",
- "If (Test-Path -Path '.\\bin\\PSCredentialStore.zip') { Remove-Item -Path '.\\bin\\PSCredentialStore.zip' -Verbose};",
- "Copy-Item -Path '.\\src\\' -Destination '.\\bin\\PSCredentialStore' -Recurse -Verbose -Force;",
- "Compress-Archive -Path '.\\src\\*' -DestinationPath '.\\bin\\PSCredentialStore.zip' -Update -Verbose;"
+ "label": "DroneIO: Invoke-UnitTest",
+ "type": "shell",
+ "command": [
+ "Remove-Item ./coverage.xml -ErrorAction 'SilentlyContinue';",
+ "Remove-Item ./testResults.xml -ErrorAction 'SilentlyContinue';",
+ "Import-Module ./tools/DroneIO.psm1;",
+ "Invoke-UnitTest -CoverageFormat 'CoverageGutters' -Verbosity 'Diagnostic'"
],
- "group": {
- "kind": "build",
- "isDefault": true
- }
+ "group": "test",
+ "problemMatcher": [
+ "$pester"
+ ]
+ },
+ {
+ "label": "Add dictionary item",
+ "type": "shell",
+ "command": [
+ "$DefaultFile = Get-ChildItem -Path './.vscode/dictionaries/default.txt';",
+ "$Content = Get-Content -Path $DefaultFile;",
+ "$Content += '${input:DictionaryItem}';",
+ "$Content = $Content | Sort-Object -Unique;",
+ "Set-Content -Value $Content -Path $DefaultFile"
+ ],
+ "group": "none",
+ "problemMatcher": [
+ "$pester"
+ ]
+ }
+ ],
+ "inputs": [
+ {
+ "id": "DictionaryItem",
+ "type": "promptString",
+ "description": "Input for dictionary file default.txt"
}
]
}
diff --git a/README.md b/README.md
index 864d043..d518ebb 100644
--- a/README.md
+++ b/README.md
@@ -1,166 +1,181 @@
-[](https://ci.appveyor.com/project/OCram85/pscredentialstore/branch/master)
-[](https://ci.appveyor.com/project/OCram85/pscredentialstore/branch/master/tests)
-[](https://coveralls.io/github/OCram85/PSCredentialStore?branch=master)
-[](https://codecov.io/gh/OCram85/PSCredentialStore)
-[](https://www.powershellgallery.com/packages/PSCredentialStore)
-[](https://www.powershellgallery.com/packages/PSCredentialStore)
-[](https://www.powershellgallery.com/packages/PSCredentialStore)
-
-
-
-
-
-
-:key: General
-=======
-
-The PSCredentialStore is a simple credential manager for `PSCredential` objects. It stores PSCredentials in a simple json
-file. You can choose between a private and shared credential store. The private one exists in your profile and can
-ony accessed by your account on the same machine. The shared store enables you to use different credentials for your
-scripts without exposing them as plain text.
-
-PSCredentialStore was developed to simplify the delegation of complex powershell scripts. In this case you often
-need to store credentials for non interactive usage like in scheduled tasks.
-
-Starting with version `1.0.0` PSCredential uses Pfx certificates fo encryption. You can use Pfx certificate files
-or certificates stored in the certificate store.
-
-For more details read the [about_PSCredentialStore](/docs/about_PSCredentialStore.md) page on github or via CLI with
-`Get-Help about_PSCredentialStore`.
-
-You can find the [reference](/docs/PSCredentialStore.md) in the /docs/ path as well.
-
-:vulcan_salute: Requirements
-============
-
-- PowerShell >= `5.1`
-- .NET Framework >= `4.6` or .NET Core >= `1.0`
-
-:bomb: About Security
-============
-
->This section explains some security topics and the the design decisions we made to balance the usage and security needs.
-
-To be able to delegate `PSCredentials` objects we can't exclusively rely on the `SecureString` cmdlets. You can't
-decrypt and reuse such credentials from a different user account or even machine. This is caused by automatically
-generated encryption key which, is used create a `Secure String` based encrypted string.
-
-In order to delegate a password, while still using the underlying security framework, we have to provide a custom
-encryption key. This leads to the fact, that everyone who has access to the key could encrypt or decrypt your data.
-
-So we decided to use the public and private keys from valid certificates as part of the custom encryption keys to encrypt your data.
-
-This means clearly: Everyone who has access to the `CredentialStore` needs also access to the certificate file to work with it.
-
-Keep in mind you need to secure the access with your NTFS file permissions to avoid unwanted usage. Another option is
-to import the certificate into your certification vaults of you operating system. In this case you can grand the
-permission to the certificates itself.
-
-Here is s brief hierarchy description of the certificate location: *(First match wins)*
-
-| CredentialStore Type | Certificate Location |
-| -------------------- | ---------------------- |
-| Private | `CurrentUser`\\`My` |
-| Shared (Windows) | `CurrentUser`\\`My` |
-| | `LocalMachine`\\`Root` |
-| Shared (Linux) | `LocalMachine`\\`My` |
-| | `LocalMachine`\\`Root` |
-
-
-
-:hammer_and_wrench: Installation
-============
-
-:artificial_satellite: PowerShellGallery.com (Recommended Way)
----------------------------------------
-
-* 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`
-
-:building_construction: Manual Way
-----------
-
-* Take a look at the [Latest Release](https://github.com/OCram85/PSCredentialStore/releases/latest) page.
-* Download the `PSCredentialStore.zip`.
-* Unpack the zip file and put it in your Powershell module path.
- * Don't forget to change the NTFS permission flag in the context menu.
-* Start with `Import-Module PSCredentialStore`
-
-:sparkles: Quick Start
------------
-
-**1.** First we need a blank credential store. You can decide between a *private* or *shared* store. The private
-Credential Store can only be accessed with your profile on the machine you created it.
-
-Starting with version `1.0.0` you can decide the storage type of your fresh created certificate. As default
-PSCredentialStore creates a new pfx certificate file beside the credential store itself. Optionally you can provide
-the parameter `-UseCertStore`. This imports the new certificate in the user or machine certificate store as well.
-
-```powershell
-# Private credential store
-New-CredentialStore
-
-# Private credential store with certificate store usage
-New-CredentialStore -UseCertStore
-
-# Shared credential store
-New-CredentialStore -Shared
-
-#Shared credential store in custom location
-New-CredentialStore -Shared -Path 'C:\CredentialStore.json'
-```
-
-**2.** Now you can manage your credential store items:
-```powershell
-# This will prompt for credentials and stores it in a private store
-New-CredentialStoreItem -RemoteHost 'dc01.myside.local' -Identifier 'AD'
-
-# You can now use it in other scripts like this:
-$DCCreds = Get-CredentialStoreItem -RemoteHost 'dc01.myside.local' -Identifier 'AD'
-Invoke-Command -ComputerName 'dc01.myside.local' -Credential $DCCreds -ScripBlock {Get-Process}
-```
-
-The credential store contains also a simple function to establish a connection with several systems or protocols.
-If you have already installed the underlying framework / modules, you can connect these endpoints:
-
-* **CiscoUcs** - Establish a connection to a Cisco UCS fabric interconnect.
- * Required Modules: [`Cisco.UCS.Core`, `Cisco.UCSManager`](https://software.cisco.com/download/release.html?i=!y&mdfid=286305108&softwareid=284574017&release=2.1.1)
-* **FTP** - Establish a connection to a FTP host.
- * Required Modules: [`WinSCP`](https://www.powershellgallery.com/packages/WinSCP)
-* **NetAppFAS** - Establish a connection to a NetApp Clustered ONTAP filer.
- * Required Modules: [`DataONTAP`](http://mysupport.netapp.com/tools/info/ECMLP2310788I.html?productID=61926)
-* **VMware** - Establish a connection to a VMware vCenter or ESXi host.
- * Required Modules: [`VMware.VimAutomation.Core`](https://www.powershellgallery.com/packages/VMware.PowerCLI)
-* **CisServer** - Establish a connection to the CisServer Service on vCenter Host.
- * Required Modules: [`VMware.VimAutomation.Cis.Core`](https://www.powershellgallery.com/packages/VMware.PowerCLI)
-* **ExchangeHTTP** - Establish a remote connection with an Exchange endpoint via http.
- * Requires PowerShell remoting
-* **ExchangeHTTPS** - Establish a remote connection with an Exchange endpoint via https.
- * Requires PowerShell remoting
-* **SCP** - Establish a SCP connection.
- * Required Modules: [`WinSCP`](https://www.powershellgallery.com/packages/WinSCP)
-
-Here are some basic examples:
-
-```powershell
-Connect-To -RemoteHost "ucs.myside.local" -Type CiscoUcs
-Connect-To -RemoteHost "ftp.myside.local" -Type FTP
-Connect-To -RemoteHost "fas.myside.local" -Type NetAppFAS
-Connect-To -RemoteHost "esx01.myside.local" -Type VMware
-Connect-To -RemoteHost "vcr.myside.local" -Type CisServer
-Connect-To -RemoteHost "exchange1.myside.local" -Type ExchangeHTTP
-Connect-To -RemoteHost "exchange1.myside.local" -Type ExchangeHTTPS
-Connect-To -RemoteHost "ubuntu.myside.local" -Type SCP
-```
-
-:pushpin: 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 Dave Wyatt ([@dlwyatt](https://github.com/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)!
+
+
+
+
+
+
+
+
+
+
+
+
+ PSCredentialStore
+
+
+
+ 🔐 A simple credential manager to store and reuse multiple PSCredential objects.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## :key: General
+
+The PSCredentialStore is a simple credential manager for `PSCredential` objects. It stores PSCredentials in a simple json
+file. You can choose between a private and shared credential store. The private one exists in your profile and can
+ony accessed by your account on the same machine. The shared store enables you to use different credentials for your
+scripts without exposing them as plain text.
+
+PSCredentialStore was developed to simplify the delegation of complex powershell scripts. In this case you often
+need to store credentials for non interactive usage like in scheduled tasks.
+
+Starting with version `1.0.0` PSCredential uses Pfx certificates fo encryption. You can use Pfx certificate files
+or certificates stored in the certificate store.
+
+For more details read the [about_PSCredentialStore](/docs/about_PSCredentialStore.md) page on github or via CLI with
+`Get-Help about_PSCredentialStore`.
+
+You can find the [reference](/docs/PSCredentialStore.md) in the /docs/ path as well.
+
+## :vulcan_salute: Requirements
+
+- PowerShell >= `5.1`
+- .NET Framework >= `4.6` or .NET Core >= `1.0`
+
+## :bomb: About Security
+
+>This section explains some security topics and the the design decisions we made to balance the usage and security needs.
+
+To be able to delegate `PSCredentials` objects we can't exclusively rely on the `SecureString` cmdlets. You can't
+decrypt and reuse such credentials from a different user account or even machine. This is caused by automatically
+generated encryption key which, is used create a `Secure String` based encrypted string.
+
+In order to delegate a password, while still using the underlying security framework, we have to provide a custom
+encryption key. This leads to the fact, that everyone who has access to the key could encrypt or decrypt your data.
+
+So we decided to use the public and private keys from valid certificates as part of the custom encryption keys to encrypt your data.
+
+This means clearly: Everyone who has access to the `CredentialStore` needs also access to the certificate file to work with it.
+
+Keep in mind you need to secure the access with your NTFS file permissions to avoid unwanted usage. Another option is
+to import the certificate into your certification vaults of you operating system. In this case you can grand the
+permission to the certificates itself.
+
+Here is s brief hierarchy description of the certificate location: *(First match wins)*
+
+| CredentialStore Type | Certificate Location |
+| -------------------- | ---------------------- |
+| Private | `CurrentUser`\\`My` |
+| Shared (Windows) | `CurrentUser`\\`My` |
+| | `LocalMachine`\\`Root` |
+| Shared (Linux) | `LocalMachine`\\`My` |
+| | `LocalMachine`\\`Root` |
+
+## :hammer_and_wrench: Installation
+
+### :artificial_satellite: PowerShellGallery.com (Recommended Way)
+
+* 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`
+
+### :building_construction: Manual Way
+
+* Take a look at the [Latest Release](https://github.com/OCram85/PSCredentialStore/releases/latest) page.
+* Download the `PSCredentialStore.zip`.
+* Unpack the zip file and put it in your Powershell module path.
+ * Don't forget to change the NTFS permission flag in the context menu.
+* Start with `Import-Module PSCredentialStore`
+
+### :sparkles: Quick Start
+
+**1.** First we need a blank credential store. You can decide between a *private* or *shared* store. The private
+Credential Store can only be accessed with your profile on the machine you created it.
+
+Starting with version `1.0.0` you can decide the storage type of your fresh created certificate. As default
+PSCredentialStore creates a new pfx certificate file beside the credential store itself. Optionally you can provide
+the parameter `-UseCertStore`. This imports the new certificate in the user or machine certificate store as well.
+
+```powershell
+# Private credential store
+New-CredentialStore
+
+# Private credential store with certificate store usage
+New-CredentialStore -UseCertStore
+
+# Shared credential store
+New-CredentialStore -Shared
+
+#Shared credential store in custom location
+New-CredentialStore -Shared -Path 'C:\CredentialStore.json'
+```
+
+**2.** Now you can manage your credential store items:
+```powershell
+# This will prompt for credentials and stores it in a private store
+New-CredentialStoreItem -RemoteHost 'dc01.myside.local' -Identifier 'AD'
+
+# You can now use it in other scripts like this:
+$DCCreds = Get-CredentialStoreItem -RemoteHost 'dc01.myside.local' -Identifier 'AD'
+Invoke-Command -ComputerName 'dc01.myside.local' -Credential $DCCreds -ScripBlock {Get-Process}
+```
+
+The credential store contains also a simple function to establish a connection with several systems or protocols.
+If you have already installed the underlying framework / modules, you can connect these endpoints:
+
+* **CiscoUcs** - Establish a connection to a Cisco UCS fabric interconnect.
+ * Required Modules: [`Cisco.UCS.Core`, `Cisco.UCSManager`](https://software.cisco.com/download/release.html?i=!y&mdfid=286305108&softwareid=284574017&release=2.1.1)
+* **FTP** - Establish a connection to a FTP host.
+ * Required Modules: [`WinSCP`](https://www.powershellgallery.com/packages/WinSCP)
+* **NetAppFAS** - Establish a connection to a NetApp Clustered ONTAP filer.
+ * Required Modules: [`DataONTAP`](http://mysupport.netapp.com/tools/info/ECMLP2310788I.html?productID=61926)
+* **VMware** - Establish a connection to a VMware vCenter or ESXi host.
+ * Required Modules: [`VMware.VimAutomation.Core`](https://www.powershellgallery.com/packages/VMware.PowerCLI)
+* **CisServer** - Establish a connection to the CisServer Service on vCenter Host.
+ * Required Modules: [`VMware.VimAutomation.Cis.Core`](https://www.powershellgallery.com/packages/VMware.PowerCLI)
+* **ExchangeHTTP** - Establish a remote connection with an Exchange endpoint via http.
+ * Requires PowerShell remoting
+* **ExchangeHTTPS** - Establish a remote connection with an Exchange endpoint via https.
+ * Requires PowerShell remoting
+* **SCP** - Establish a SCP connection.
+ * Required Modules: [`WinSCP`](https://www.powershellgallery.com/packages/WinSCP)
+
+Here are some basic examples:
+
+```powershell
+Connect-To -RemoteHost "ucs.myside.local" -Type CiscoUcs
+Connect-To -RemoteHost "ftp.myside.local" -Type FTP
+Connect-To -RemoteHost "fas.myside.local" -Type NetAppFAS
+Connect-To -RemoteHost "esx01.myside.local" -Type VMware
+Connect-To -RemoteHost "vcr.myside.local" -Type CisServer
+Connect-To -RemoteHost "exchange1.myside.local" -Type ExchangeHTTP
+Connect-To -RemoteHost "exchange1.myside.local" -Type ExchangeHTTPS
+Connect-To -RemoteHost "ubuntu.myside.local" -Type SCP
+```
+
+### :pushpin: 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 Dave Wyatt ([@dlwyatt](https://github.com/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)!
diff --git a/STATE.xml b/STATE.xml
new file mode 100644
index 0000000..debbefc
--- /dev/null
+++ b/STATE.xml
@@ -0,0 +1,20 @@
+
+
+
+ System.Management.Automation.PSCustomObject
+ System.Object
+
+
+
+
+ System.Object[]
+ System.Array
+ System.Object
+
+
+ lint
+
+
+
+
+
\ No newline at end of file
diff --git a/_.travis.yml b/_.travis.yml
deleted file mode 100644
index 2a043d4..0000000
--- a/_.travis.yml
+++ /dev/null
@@ -1,42 +0,0 @@
-
-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: ./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
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index 5b9615d..0000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,74 +0,0 @@
-# pre release version:
-version: 1.0.{build}
-
-#cache:
-
-#branches:
-# only:
-# - master
-# - dev
-# - debug
-
-skip_tags: true
-
-image: Visual Studio 2019
-
-# Install pester module and init the Appveyor support.
-
-# Enable RDP connection for debugging
-#init:
-# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
-
-install:
- - ps: Import-Module .\tools\AppVeyor.psm1
- - ps: Invoke-InstallDependencies
-
-environment:
- NuGetToken:
- secure: 835qfZIkC9mE7QhkYfOZVAdR8rZhPvxG8BO4CbeaelRQOhlqmaSr8G1DWRJzZ/bS
- CoverallsToken:
- secure: eTjWqHL48MBr8wp1rSgLrXHdtpfDV/uClacP3svlWJfCvn/zVokpuaMnWM5RoyIY
- CodeCovToken:
- secure: LJOvamWIlVORDE7120KcmWVkHxOFYBSN99linyICXXmXLtYm81K/31YeMGiPlgTm
-
-build: false
-
-before_build:
- - ps: Invoke-AppVeyorBumpVersion
-
-build_script:
- - ps: Invoke-AppVeyorBuild
-
-test_script:
- - ps: |
- $CodeCoverage = Invoke-AppVeyorTests
- if ($null -ne $Env:CoverallsToken) {
- Invoke-CoverageReport -PesterCoverageReport $CodeCoverage
- }
- else {
- Write-Warning "No CoverallsToken found. This build seems to be triggered by a PR. Skipping this step..."
- }
-
-deploy:
- #- provider: GitHub
- # auth_token:
- # secure: M+bBX5/nKdJB0eViP7xtrLVTwf3vGDUA9N2MMprZp2i+9ZR3CBVcJnSzJWUmalhB
- # artifact: PSCredentialStore.zip # upload all NuGet packages to release assets
- # draft: true
- # prerelease: true
- # on:
- # branch: dev
- - provider: GitHub
- auth_token:
- secure: M+bBX5/nKdJB0eViP7xtrLVTwf3vGDUA9N2MMprZp2i+9ZR3CBVcJnSzJWUmalhB
- artifact: PSCredentialStore.zip # upload all NuGet packages to release assets
- draft: false
- prerelease: false
- on:
- branch: master # build release on master branch changes
-
-after_deploy:
- - ps: Invoke-AppVeyorPSGallery -OnBranch 'master'
-# Pause build until `lock` on desktop is deleted.
-#on_finish:
-# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
diff --git a/src/Certificate/Get-CSCertificate.ps1 b/src/Certificate/Get-CSCertificate.ps1
index 5bb654b..7db89f1 100644
--- a/src/Certificate/Get-CSCertificate.ps1
+++ b/src/Certificate/Get-CSCertificate.ps1
@@ -20,18 +20,11 @@ function Get-CSCertificate {
.EXAMPLE
Get-CSCertificate -Type 'Shared' -Thumbprint '12334456'
-
- .NOTES
- - File Name : Get-CSCertificate.ps1
- - Author : Marco Blessing - marco.blessing@googlemail.com
- - Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
+
[CmdletBinding()]
[OutputType([System.Security.Cryptography.X509Certificates.X509Certificate2])]
- param(
+ param (
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[ValidateSet('Private', 'Shared')]
@@ -42,8 +35,8 @@ function Get-CSCertificate {
[string]$Thumbprint
)
- begin {
- }
+ begin {}
+
process {
if ($Type -eq 'Private') {
Get-CSPfXCertificate -Thumbprint $Thumbprint -StoreName 'My' -StoreLocation 'CurrentUser'
@@ -69,6 +62,5 @@ function Get-CSCertificate {
}
}
}
- end {
- }
+ end {}
}
diff --git a/src/Certificate/Import-CSCertificate.ps1 b/src/Certificate/Import-CSCertificate.ps1
index 244eb63..fc391c2 100644
--- a/src/Certificate/Import-CSCertificate.ps1
+++ b/src/Certificate/Import-CSCertificate.ps1
@@ -21,18 +21,10 @@ function Import-CSCertificate {
.EXAMPLE
Import-CSCertificate -Type 'Private' -Path (Join-Path -Path $Env:APPDATA -ChildItem 'PfxCertificate.pfx')
-
- .NOTES
- - File Name : Import-CSCertificate.ps1
- - Author : Marco Blessing - marco.blessing@googlemail.com
- - Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
+
[CmdletBinding()]
- [OutputType()]
- param(
+ param (
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[ValidateSet('Private', 'Shared')]
diff --git a/src/Certificate/New-CSCertAttribute.Tests.ps1 b/src/Certificate/New-CSCertAttribute.Tests.ps1
new file mode 100644
index 0000000..50a966a
--- /dev/null
+++ b/src/Certificate/New-CSCertAttribute.Tests.ps1
@@ -0,0 +1,20 @@
+BeforeAll {
+ $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName
+ Import-Module $ManifestFile -Force
+}
+
+Describe "New-CSCertAttribute" {
+ Context "Basis Tests" -Tag 'Unit' {
+ It "Should not throw" {
+ $AttribParams = @{
+ Country = 'DE'
+ State = 'BW'
+ City = 'KA'
+ Organization = 'IT'
+ OrganizationalUnitName = 'foo'
+ CommonName = 'MyCert'
+ }
+ { New-CSCertAttribute @AttribParams } | Should -Not -Throw
+ }
+ }
+}
diff --git a/src/Certificate/New-CSCertAttribute.ps1 b/src/Certificate/New-CSCertAttribute.ps1
index e199a83..ab77fd6 100644
--- a/src/Certificate/New-CSCertAttribute.ps1
+++ b/src/Certificate/New-CSCertAttribute.ps1
@@ -35,18 +35,11 @@ function New-CSCertAttribute {
.EXAMPLE
New-CSCertAttribute -Country 'DE' -State 'BW' -City 'Karlsruhe' -Organization 'AwesomeIT' -OrganizationalUnitName '' -CommonName 'MyPrivateCert'
-
- .NOTES
- - File Name : New-CSCertAttribute.ps1
- - Author : Marco Blessing - marco.blessing@googlemail.com
- - Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
+
[CmdletBinding()]
[OutputType('PSCredentialStore.Certificate.Attribute')]
- param(
+ param (
[Parameter(Mandatory = $true)]
[ValidateLength(2, 2)]
[ValidateNotNull()]
@@ -76,9 +69,8 @@ function New-CSCertAttribute {
[ValidateNotNull()]
[int]$Days = 365
)
- begin {
+ begin {}
- }
process {
return [PSCustomObject]@{
PSTypeName = 'PSCredentialStore.Certificate.Attribute'
@@ -94,6 +86,5 @@ function New-CSCertAttribute {
Days = $Days
}
}
- end {
- }
+ end {}
}
diff --git a/src/Certificate/New-CSCertificate.Tests.ps1 b/src/Certificate/New-CSCertificate.Tests.ps1
new file mode 100644
index 0000000..250612f
--- /dev/null
+++ b/src/Certificate/New-CSCertificate.Tests.ps1
@@ -0,0 +1,33 @@
+BeforeAll {
+ $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName
+ Import-Module $ManifestFile -Force
+
+ $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object {
+ $_.BaseName -notmatch '.Tests'
+ }
+ ).FullName
+ foreach ( $func in $PrivateFunctions) {
+ . $func
+ }
+}
+
+Describe "New-CSCertificate" {
+ Context "Basic Tests" -Tag 'Unit' {
+ It "Should not throw" {
+ $attribs = @{
+ Country = 'DE'
+ State = 'BW'
+ City = 'KA'
+ Organization = 'IT'
+ OrganizationalUnitName = 'foo'
+ CommonName = 'MyCert'
+ }
+ $CertAttribs = @{
+ CRTAttribute = New-CSCertAttribute @attribs
+ KeyName = Join-Path -Path (Get-TempDir) -ChildPath '/foo.key'
+ CertName = Join-Path -Path (Get-TempDir) -ChildPath '/cert.pfx'
+ }
+ { New-CSCertificate @CertAttribs } | Should -Not -Throw
+ }
+ }
+}
diff --git a/src/Certificate/New-CSCertificate.ps1 b/src/Certificate/New-CSCertificate.ps1
index 91d5554..6e93ef0 100644
--- a/src/Certificate/New-CSCertificate.ps1
+++ b/src/Certificate/New-CSCertificate.ps1
@@ -23,18 +23,11 @@ function New-CSCertificate {
.EXAMPLE
New-CSCertificate -CRTAttribute $CRTAttribute -KeyName './myprivate.key' -CertName './mycert.pfx'
-
- .NOTES
- - File Name : New-CSCertificate.ps1
- - Author : Marco Blessing - marco.blessing@googlemail.com
- - Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
+
[CmdletBinding(SupportsShouldProcess = $true)]
[OutputType()]
- param(
+ param (
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[ValidateNotNullOrEmpty()]
[PSTypeName('PSCredentialStore.Certificate.Attribute')]$CRTAttribute,
@@ -70,6 +63,7 @@ function New-CSCertificate {
$Env:OPENSSL_CONF = Join-Path $ModuleBase -ChildPath '/openssl.conf'
}
+
process {
$SubjPattern = "/C={0}/ST={1}/L={2}/O={3}/OU={4}/CN={5}"
$SubjValues = @(
diff --git a/src/Certificate/Test-CSCertificate.ps1 b/src/Certificate/Test-CSCertificate.ps1
index 4ef34f6..ed9b45f 100644
--- a/src/Certificate/Test-CSCertificate.ps1
+++ b/src/Certificate/Test-CSCertificate.ps1
@@ -17,18 +17,11 @@ function Test-CSCertificate {
.EXAMPLE
Test-CSCertificate -Type 'Shared'
-
- .NOTES
- - File Name : Test-CSCertificate.ps1
- - Author : Marco Blessing - marco.blessing@googlemail.com
- - Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
+
[CmdletBinding()]
[OutputType([bool])]
- param(
+ param (
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[ValidateSet('Private', 'Shared')]
diff --git a/src/Certificate/Use-CSCertificate.ps1 b/src/Certificate/Use-CSCertificate.ps1
index 76f0f40..0bd993b 100644
--- a/src/Certificate/Use-CSCertificate.ps1
+++ b/src/Certificate/Use-CSCertificate.ps1
@@ -26,36 +26,28 @@ function Use-CSCertificate {
.EXAMPLE
Use-CSCertificate -Path 'C:\cert.pfx'
-
- .NOTES
- File Name : Use-CSCertificate.ps1
- Author : Marco Blessing - marco.blessing@googlemail.com
- Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
- [CmdletBinding(DefaultParameterSetName = "Private")]
- [OutputType()]
+
+ [CmdletBinding(DefaultParameterSetName = 'Private')]
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")]
- param(
- [Parameter(Mandatory = $true, ParameterSetName = "Private")]
- [Parameter(Mandatory = $true, ParameterSetName = "Shared")]
+ param (
+ [Parameter(Mandatory = $true, ParameterSetName = 'Private')]
+ [Parameter(Mandatory = $true, ParameterSetName = 'Shared')]
[ValidateNotNullOrEmpty()]
[string]$Path,
- [Parameter(Mandatory = $false, ParameterSetName = "Shared")]
+ [Parameter(Mandatory = $false, ParameterSetName = 'Shared')]
[ValidateNotNullOrEmpty()]
[string]$CredentialStore,
- [Parameter(Mandatory = $true, ParameterSetName = "Shared")]
+ [Parameter(Mandatory = $true, ParameterSetName = 'Shared')]
[switch]$Shared,
- [Parameter(Mandatory = $false, ParameterSetName = "Private")]
- [Parameter(Mandatory = $false, ParameterSetName = "Shared")]
- [Switch]$UseCertStore
+ [Parameter(Mandatory = $false, ParameterSetName = 'Private')]
+ [Parameter(Mandatory = $false, ParameterSetName = 'Shared')]
+ [switch]$UseCertStore
)
- begin { }
+ begin {}
process {
try {
@@ -74,11 +66,11 @@ function Use-CSCertificate {
}
try {
- if ($PSCmdlet.ParameterSetName -eq "Private") {
+ if ($PSCmdlet.ParameterSetName -eq 'Private') {
$StorePath = Get-DefaultCredentialStorePath
$CS = Get-CredentialStore
}
- elseif ($PSCmdlet.ParameterSetName -eq "Shared" ) {
+ elseif ($PSCmdlet.ParameterSetName -eq 'Shared' ) {
if (!($PSBoundParameters.ContainsKey('CredentialStore'))) {
$StorePath = Get-DefaultCredentialStorePath -Shared
$CS = Get-CredentialStore -Shared
@@ -117,5 +109,5 @@ Make sure you used the same AES keys for encrypting!
$CS | ConvertTo-Json -Depth 5 | Out-File -FilePath $StorePath -Force -Encoding utf8
}
- end { }
+ end {}
}
diff --git a/src/Connection/Connect-To.ps1 b/src/Connection/Connect-To.ps1
index b7e1abb..815cd08 100644
--- a/src/Connection/Connect-To.ps1
+++ b/src/Connection/Connect-To.ps1
@@ -58,28 +58,20 @@ function Connect-To {
.EXAMPLE
Connect-To -RemoteHost "exchange01.myside.local" -Type ExchangeHTTPS
-
- .NOTES
- - File Name : Connect-To.ps1
- - Author : Marco Blessing - marco.blessing@googlemail.com
- - Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
- [CmdletBinding(DefaultParameterSetName = "Private")]
- param(
- [Parameter(Mandatory = $true, ParameterSetName = "Shared")]
- [Parameter(Mandatory = $true, ParameterSetName = "Private")]
+ [CmdletBinding(DefaultParameterSetName = 'Private')]
+ param (
+ [Parameter(Mandatory = $true, ParameterSetName = 'Shared')]
+ [Parameter(Mandatory = $true, ParameterSetName = 'Private')]
[string]$RemoteHost,
- [Parameter(Mandatory = $false, ParameterSetName = "Shared")]
- [Parameter(Mandatory = $false, ParameterSetName = "Private")]
+ [Parameter(Mandatory = $false, ParameterSetName = 'Shared')]
+ [Parameter(Mandatory = $false, ParameterSetName = 'Private')]
[string]$Identifier,
- [Parameter(Mandatory = $true, ParameterSetName = "Shared")]
- [Parameter(Mandatory = $true, ParameterSetName = "Private")]
+ [Parameter(Mandatory = $true, ParameterSetName = 'Shared')]
+ [Parameter(Mandatory = $true, ParameterSetName = 'Private')]
[ValidateSet(
'CiscoUcs',
'FTP',
@@ -92,29 +84,29 @@ function Connect-To {
)]
[string]$Type,
- [Parameter(Mandatory = $False, ParameterSetName = "Shared")]
- [Parameter(Mandatory = $False, ParameterSetName = "Private")]
+ [Parameter(Mandatory = $False, ParameterSetName = 'Shared')]
+ [Parameter(Mandatory = $False, ParameterSetName = 'Private')]
[PSCredential]$Credentials,
- [Parameter(Mandatory = $true, ParameterSetNAme = "Shared")]
+ [Parameter(Mandatory = $true, ParameterSetNAme = 'Shared')]
[switch]$Shared,
- [Parameter(Mandatory = $False, ParameterSetName = "Shared")]
+ [Parameter(Mandatory = $False, ParameterSetName = 'Shared')]
[ValidateNotNullOrEmpty()]
[string]$Path,
- [Parameter(Mandatory = $False, ParameterSetName = "Private")]
- [Parameter(Mandatory = $False, ParameterSetName = "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") {
+ if ($PSCmdlet.ParameterSetName -eq 'Private') {
$Path = Get-DefaultCredentialStorePath
}
- elseif ($PSCmdlet.ParameterSetName -eq "Shared") {
+ elseif ($PSCmdlet.ParameterSetName -eq 'Shared') {
if (!($PSBoundParameters.ContainsKey('Path'))) {
$Path = Get-DefaultCredentialStorePath -Shared
}
@@ -155,7 +147,7 @@ function Connect-To {
catch {
$MessageParams = @{
Message = "Unable to look up credential store item for RemoteHost {0}/Identifier {1}!" -f $RemoteHost, $Identifier
- ErrorAction = "Stop"
+ ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
@@ -164,10 +156,10 @@ function Connect-To {
$creds = $Credentials
}
- if ($creds.UserName -eq "" -or $creds.Password.GetType().Name -ne "SecureString") {
+ if ($creds.UserName -eq "" -or $creds.Password.GetType().Name -ne 'SecureString') {
$MessageParams = @{
Message = "Please provide valid credentials for RemoteHost {0}!" -f $RemoteHost
- ErrorAction = "Stop"
+ ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
@@ -176,13 +168,13 @@ function Connect-To {
"CiscoUcs" {
try {
$handle = Connect-Ucs -Name $RemoteHost -Credential $creds -ErrorAction Stop
- $ExecutionContext.SessionState.PSVariable.Set("DefaultUcs", $handle)
+ $ExecutionContext.SessionState.PSVariable.Set('DefaultUcs', $handle)
}
catch {
$MessageParams = @{
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
- ErrorAction = "Stop"
+ ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
@@ -207,7 +199,7 @@ function Connect-To {
# 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
- ErrorAction = "Stop"
+ ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
@@ -221,7 +213,7 @@ function Connect-To {
# Write a error message to the log.
$MessageParams = @{
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
- ErrorAction = "Stop"
+ ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
@@ -235,7 +227,7 @@ function Connect-To {
# Write a error message to the log.
$MessageParams = @{
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
- ErrorAction = "Stop"
+ ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
@@ -255,7 +247,7 @@ function Connect-To {
# Write a error message to the log.
$MessageParams = @{
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
- ErrorAction = "Stop"
+ ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
@@ -274,7 +266,7 @@ function Connect-To {
# Write a error message to the log.
$MessageParams = @{
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
- ErrorAction = "Stop"
+ ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
@@ -293,7 +285,7 @@ function Connect-To {
# Write a error message to the log.
$MessageParams = @{
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
- ErrorAction = "Stop"
+ ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
@@ -314,7 +306,7 @@ function Connect-To {
# Write a error message to the log.
$MessageParams = @{
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
- ErrorAction = "Stop"
+ ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
@@ -323,7 +315,7 @@ function Connect-To {
# 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
- ErrorAction = "Stop"
+ ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
@@ -332,7 +324,7 @@ function Connect-To {
# Write a error message to the log.
$MessageParams = @{
Message = "Unable to connect to {0} using Type {1}." -f $RemoteHost, $Type
- ErrorAction = "Stop"
+ ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
diff --git a/src/Connection/Disconnect-From.ps1 b/src/Connection/Disconnect-From.ps1
index 57139b9..509ef4b 100644
--- a/src/Connection/Disconnect-From.ps1
+++ b/src/Connection/Disconnect-From.ps1
@@ -49,18 +49,10 @@ function Disconnect-From {
.EXAMPLE
Disconnect-From -RemoteHost "exchange01.myside.local" -Type ExchangeHTTPS
-
- .NOTES
- - File Name : Disconnect-From.ps1
- - Author : Marco Blessing - marco.blessing@googlemail.com
- - Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
[CmdletBinding()]
- param(
+ param (
[Parameter(Mandatory = $true)]
[string]$RemoteHost,
@@ -81,126 +73,132 @@ function Disconnect-From {
[switch]$Force
)
- switch -Regex ($Type) {
- "VMware" {
- try {
- if ($Force) {
- Disconnect-VIServer -Server $RemoteHost -Confirm:$false -ErrorAction Stop -Force:$true
- }
- else {
- Disconnect-VIServer -Server $RemoteHost -Confirm:$false -ErrorAction Stop
+ begin {}
+
+ process {
+ switch -Regex ($Type) {
+ "VMware" {
+ try {
+ if ($Force) {
+ Disconnect-VIServer -Server $RemoteHost -Confirm:$false -ErrorAction Stop -Force:$true
+ }
+ else {
+ Disconnect-VIServer -Server $RemoteHost -Confirm:$false -ErrorAction Stop
+ }
}
- }
- catch {
- # Write a error message to the log.
- $MessageParams = @{
- Message = "Unable to disconnect from {0} using Type {1}." -f $RemoteHost, $Type
- ErrorAction = "Stop"
+ catch {
+ # Write a error message to the log.
+ $MessageParams = @{
+ Message = "Unable to disconnect from {0} using Type {1}." -f $RemoteHost, $Type
+ ErrorAction = 'Stop'
+ }
+ Write-Error @MessageParams
}
- Write-Error @MessageParams
}
- }
- "CisServer" {
- try {
- if ($Force) {
- Disconnect-CisServer -Server $RemoteHost -Confirm:$false -ErrorAction Stop -Force:$true
+ "CisServer" {
+ try {
+ if ($Force) {
+ Disconnect-CisServer -Server $RemoteHost -Confirm:$false -ErrorAction Stop -Force:$true
+ }
+ else {
+ Disconnect-CisServer -Server $RemoteHost -Confirm:$false -ErrorAction Stop
+ }
}
- else {
- Disconnect-CisServer -Server $RemoteHost -Confirm:$false -ErrorAction Stop
- }
- }
- catch {
- # Write a error message to the log.
- $MessageParams = @{
- Message = "Unable to disconnect from {0} using Type {1}." -f $RemoteHost, $Type
- ErrorAction = "Stop"
+ catch {
+ # Write a error message to the log.
+ $MessageParams = @{
+ Message = "Unable to disconnect from {0} using Type {1}." -f $RemoteHost, $Type
+ ErrorAction = 'Stop'
+ }
+ Write-Error @MessageParams
}
- Write-Error @MessageParams
}
- }
- # Check for an existing WinSCP Session var
- "FTP" {
- if ($Global:WinSCPSession.Opened) {
- Remove-WinSCPSession -WinSCPSession $Global:WinSCPSession
- }
- else {
- $MessageParams = @{
- Message = "There is no open WinSCP Session"
- ErrorAction = "Stop"
+ # Check for an existing WinSCP Session var
+ "FTP" {
+ if ($Global:WinSCPSession.Opened) {
+ Remove-WinSCPSession -WinSCPSession $Global:WinSCPSession
}
- Write-Error @MessageParams
- }
- }
- # DataONTAP doesn't have a CmdLet `Disconnect-NcController`.
- # So we go ahead and clear the CurrentNcController variable.
- "NetAppFAS" {
- try {
- $MessageParams = @{
- Message = "Setting {0} to `$null, which will disconnect NetAppFAS" -f $Global:CurrentNcController
- ErrorAction = "Continue"
+ else {
+ $MessageParams = @{
+ Message = 'There is no open WinSCP Session'
+ ErrorAction = 'Stop'
+ }
+ Write-Error @MessageParams
}
- Write-Verbose @MessageParams
- $Global:CurrentNcController = $null
}
+ # DataONTAP doesn't have a CmdLet `Disconnect-NcController`.
+ # So we go ahead and clear the CurrentNcController variable.
+ "NetAppFAS" {
+ try {
+ $MessageParams = @{
+ Message = "Setting {0} to `$null, which will disconnect NetAppFAS" -f $Global:CurrentNcController
+ ErrorAction = 'Continue'
+ }
+ Write-Verbose @MessageParams
+ $Global:CurrentNcController = $null
+ }
- catch {
- # Write a error message to the log.
- $MessageParams = @{
- Message = "Unable to disconnect from {0} using Type {1}." -f $RemoteHost, $Type
- ErrorAction = "Stop"
+ catch {
+ # Write a error message to the log.
+ $MessageParams = @{
+ Message = "Unable to disconnect from {0} using Type {1}." -f $RemoteHost, $Type
+ ErrorAction = 'Stop'
+ }
+ Write-Error @MessageParams
}
- Write-Error @MessageParams
- }
- }
- "CiscoUcs" {
- try {
- Disconnect-Ucs -Ucs $RemoteHost
}
+ "CiscoUcs" {
+ try {
+ Disconnect-Ucs -Ucs $RemoteHost
+ }
- catch {
- # Write a error message to the log.
- $MessageParams = @{
- Message = "Unable to disconnect from {0} using Type {1}." -f $RemoteHost, $Type
- ErrorAction = "Stop"
+ catch {
+ # Write a error message to the log.
+ $MessageParams = @{
+ Message = "Unable to disconnect from {0} using Type {1}." -f $RemoteHost, $Type
+ ErrorAction = 'Stop'
+ }
+ Write-Error @MessageParams
}
- Write-Error @MessageParams
- }
- }
- "ExchangeHTTP*" {
- try {
- Get-Variable -Name 'PSExchangeRemote' -Scope Global -ErrorAction Stop
- Remove-PSSession -Session $Global:PSExchangeRemote -ErrorAction Stop
}
- catch {
- $MessageParams = @{
- Message = "Unable to disconnect from {0} using Type {1}." -f $RemoteHost, $Type
- ErrorAction = "Stop"
+ "ExchangeHTTP*" {
+ try {
+ Get-Variable -Name 'PSExchangeRemote' -Scope Global -ErrorAction Stop
+ Remove-PSSession -Session $Global:PSExchangeRemote -ErrorAction Stop
+ }
+ catch {
+ $MessageParams = @{
+ Message = "Unable to disconnect from {0} using Type {1}." -f $RemoteHost, $Type
+ ErrorAction = 'Stop'
+ }
+ Write-Error @MessageParams
}
- Write-Error @MessageParams
}
- }
- "SCP" {
- if ($Global:WinSCPSession.Opened) {
- Remove-WinSCPSession -WinSCPSession $Global:WinSCPSession
+ "SCP" {
+ if ($Global:WinSCPSession.Opened) {
+ Remove-WinSCPSession -WinSCPSession $Global:WinSCPSession
+ }
+ else {
+ $MessageParams = @{
+ Message = 'There is no open WinSCP Session'
+ ErrorAction = 'Stop'
+ }
+ Write-Error @MessageParams
+ }
}
- else {
+ default {
+ # Write a error message to the log.
$MessageParams = @{
- Message = "There is no open WinSCP Session"
- ErrorAction = "Stop"
+ Message = "Unable to disconnect from {0} using Type {1}." -f $RemoteHost, $Type
+ ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
}
- default {
- # Write a error message to the log.
- $MessageParams = @{
- Message = "Unable to disconnect from {0} using Type {1}." -f $RemoteHost, $Type
- ErrorAction = "Stop"
- }
- Write-Error @MessageParams
- }
}
+
+ end {}
}
diff --git a/src/Connection/Test-CSConnection.ps1 b/src/Connection/Test-CSConnection.ps1
index 08b483e..f33f14f 100644
--- a/src/Connection/Test-CSConnection.ps1
+++ b/src/Connection/Test-CSConnection.ps1
@@ -21,24 +21,16 @@ function Test-CSConnection {
.EXAMPLE
Test-CMConnection -RemoteHost "vcr01.internal.net" -Type VMware
-
- .NOTES
- - File Name : Test-CSConnection.ps1
- - Author : Marco Blessing - marco.blessing@googlemail.com
- - Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
[CmdletBinding()]
[OutputType([bool])]
- param(
+ param (
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$RemoteHost,
- [Parameter(Mandatory = $True)]
+ [Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[ValidateSet("CiscoUcs", "FTP", "NetAppFAS", "VMware")]
[string]$Type
diff --git a/src/Formats/PSCredentialStore.Certificate.Attribute.ps1xml b/src/Formats/PSCredentialStore.Certificate.Attribute.ps1xml
index d75dee6..a9ef0fe 100644
--- a/src/Formats/PSCredentialStore.Certificate.Attribute.ps1xml
+++ b/src/Formats/PSCredentialStore.Certificate.Attribute.ps1xml
@@ -11,22 +11,28 @@
- Country
+
+ $_.Subject.Country
- State
+
+ $_.Subject.State
- City
+
+ $_.Subject.City
- Organization
+
+ $_.Subject.Organization
- OrganizationalUnitName
+
+ $_.Subject.OrganizationalUnitName
- CommonName
+
+ $_.Subject.CommonName
diff --git a/src/Item/Get-CredentialStoreItem.ps1 b/src/Item/Get-CredentialStoreItem.ps1
index bf32e1a..db0e63f 100644
--- a/src/Item/Get-CredentialStoreItem.ps1
+++ b/src/Item/Get-CredentialStoreItem.ps1
@@ -29,33 +29,25 @@ function Get-CredentialStoreItem {
.EXAMPLE
$myCreds = Get-CredentialStoreItem -Path "C:\TMP\mystore.json" -RemoteHost "esx01.myside.local"
-
- .NOTES
- - File Name : Get-CredentialStoreItem.ps1
- - Author : Messing - marco.blessing@googlemail.com
- - Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
- [CmdletBinding(DefaultParameterSetName = "Private")]
+ [CmdletBinding(DefaultParameterSetName = 'Private')]
[OutputType([PSCredential])]
- param(
- [Parameter(Mandatory = $true, ParameterSetName = "Shared")]
- [Parameter(Mandatory = $true, ParameterSetName = "Private")]
+ param (
+ [Parameter(Mandatory = $true, ParameterSetName = 'Shared')]
+ [Parameter(Mandatory = $true, ParameterSetName = 'Private')]
[ValidateNotNullOrEmpty()]
[string]$RemoteHost,
- [Parameter(Mandatory = $false, ParameterSetName = "Shared")]
- [Parameter(Mandatory = $false, ParameterSetName = "Private")]
+ [Parameter(Mandatory = $false, ParameterSetName = 'Shared')]
+ [Parameter(Mandatory = $false, ParameterSetName = 'Private')]
[ValidateNotNullOrEmpty()]
[string]$Identifier,
- [Parameter(Mandatory = $true, ParameterSetName = "Shared")]
+ [Parameter(Mandatory = $true, ParameterSetName = 'Shared')]
[switch]$Shared,
- [Parameter(Mandatory = $false, ParameterSetName = "Shared")]
+ [Parameter(Mandatory = $false, ParameterSetName = 'Shared')]
[ValidateNotNullOrEmpty()]
[string]$Path
)
@@ -63,10 +55,10 @@ function Get-CredentialStoreItem {
begin {
# Set the CredentialStore for private, shared or custom mode.
Write-Debug ("ParameterSetName: {0}" -f $PSCmdlet.ParameterSetName)
- if ($PSCmdlet.ParameterSetName -eq "Private") {
+ if ($PSCmdlet.ParameterSetName -eq 'Private') {
$Path = Get-DefaultCredentialStorePath
}
- elseif ($PSCmdlet.ParameterSetName -eq "Shared") {
+ elseif ($PSCmdlet.ParameterSetName -eq 'Shared') {
if (!($PSBoundParameters.ContainsKey('Path'))) {
$Path = Get-DefaultCredentialStorePath -Shared
}
@@ -85,7 +77,7 @@ function Get-CredentialStoreItem {
$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)) {
+ if (($CSMembers.MemberType -eq 'NoteProperty') -and ($CSMembers.Name -contains $CredentialName)) {
if ($null -eq $CS.PfxCertificate) {
$Cert = Get-CSCertificate -Type $CS.Type -Thumbprint $CS.Thumbprint
}
@@ -106,16 +98,16 @@ function Get-CredentialStoreItem {
}
else {
$MsgParams = @{
- ErrorAction = "Stop"
- Message = "Could not find credentials for the given remote host: {0}" -f $RemoteHost
+ 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
+ ErrorAction = 'Stop'
+ Message = 'The given credential store ({0}) does not exist!' -f $Path
}
Write-Error @MsgParams
}
diff --git a/tests/Item/03_New-CredentialStoreItem.Tests.ps1 b/src/Item/New-CredentialStoreItem.Tests.ps1
similarity index 71%
rename from tests/Item/03_New-CredentialStoreItem.Tests.ps1
rename to src/Item/New-CredentialStoreItem.Tests.ps1
index 56ce83b..02d1188 100644
--- a/tests/Item/03_New-CredentialStoreItem.Tests.ps1
+++ b/src/Item/New-CredentialStoreItem.Tests.ps1
@@ -1,6 +1,31 @@
+[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
+ 'PSAvoidUsingConvertToSecureStringWithPlainText',
+ '',
+ Justification = 'just used in pester tests.'
+)]
+[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
+ 'PSProvideCommentHelp',
+ '',
+ Justification = 'no need in internal pester helpers.'
+)]
+param ()
+
+BeforeAll {
+ $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName
+ Import-Module $ManifestFile -Force
+
+ $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object {
+ $_.BaseName -notmatch '.Tests'
+ }
+ ).FullName
+ foreach ( $func in $PrivateFunctions) {
+ . $func
+ }
+}
+
Describe "New-CredentialStoreItem" {
Context "Private Credential Store tests" {
- It "Test1: Add entry to existing private store." {
+ It "Add entry to existing private store." {
# Creat a fresh CredentialStore first
New-CredentialStore -Force
@@ -20,7 +45,7 @@ Describe "New-CredentialStoreItem" {
}
}
Context "Test with new shared Credential Store" {
- It "Test2: Create new RemoteHost entry" {
+ It "Create new RemoteHost entry" {
# prepare test environment
$tmpCS = Join-Path -Path (Get-TempDir) -ChildPath '/CredentialStore.json'
New-CredentialStore -Shared -Path $tmpCS -Force
@@ -29,9 +54,11 @@ Describe "New-CredentialStoreItem" {
$Password = ConvertTo-SecureString -String "mypasswd" -AsPlainText -Force
$mycreds = [PSCredential]::new($UserName, $Password)
$RemoteHost = "foobar"
- { New-CredentialStoreItem -Shared -Path $tmpCS -RemoteHost $RemoteHost -Credential $mycreds } | Should -Not -Throw
+ {
+ New-CredentialStoreItem -Shared -Path $tmpCS -RemoteHost $RemoteHost -Credential $mycreds
+ } | Should -Not -Throw
$tmpCS = Get-Content -Path $tmpCS -Raw | ConvertFrom-Json
- $res = Get-Member -InputObject $tmpCS -Name $RemoteHost -Membertype Properties
+ $res = Get-Member -InputObject $tmpCS -Name $RemoteHost -MemberType Properties
$res.Name | Should -Be $RemoteHost
}
It "Adds Item with identifier to shared store" {
@@ -42,13 +69,19 @@ Describe "New-CredentialStoreItem" {
$Password = ConvertTo-SecureString -String "mypasswd" -AsPlainText -Force
$mycreds = [PSCredential]::new($UserName, $Password)
$RemoteHost = "foobar2"
- New-CredentialStoreItem -Shared -Path $tmpCS -RemoteHost $RemoteHost -Credential $mycreds -Identifier 'Foo'
+ $StoreItemParam = @{
+ Shared = $true
+ Path = $tmpCS
+ RemoteHost = $RemoteHost
+ Credential = $mycreds
+ identifier = 'Foo'
+ }
+ New-CredentialStoreItem @StoreItemParam
$writtenItem = Get-CredentialStoreItem -Shared -Path $tmpCS -RemoteHost $RemoteHost -Identifier 'Foo'
($writtenItem.UserName -eq $UserName) -and ($writtenItem.Password.Length -gt 0) | Should -Be $true
}
}
Context "Test optional parameter lookup" {
-
It "Test missing Credential" {
function global:Get-Credential ([string]$Message) {
$UserName = 'testuser'
@@ -65,16 +98,20 @@ Describe "New-CredentialStoreItem" {
}
Context "General Exception handling" {
- Mock Test-CredentialStore { return $false }
+ Mock Test-CredentialStore { return $false } -ModuleName 'PSCredentialStore'
It "Missing CredentialStore should throw" {
- { New-CredentialStoreItem -Shared -Path 'C:\missingStore.json' -RemoteHost 'notrelevant' } | Should -Throw "Could not add anything"
+ {
+ New-CredentialStoreItem -Shared -Path '/tmp/missingStore.json' -RemoteHost 'notrelevant'
+ } | Should -Throw "Could not add anything into the given CredentialStore."
}
}
Context "Testing pipeline paramter" {
It "Add the item with credential value from pipe" {
$UserName = 'pipeUser'
$Password = ConvertTo-SecureString -String "pipePasswd" -AsPlainText -Force
- { [PSCredential]::new($UserName, $Password) | New-CredentialStoreItem -RemoteHost 'PipeHost' } | Should -Not -Throw
+ {
+ [PSCredential]::new($UserName, $Password) | New-CredentialStoreItem -RemoteHost 'PipeHost'
+ } | Should -Not -Throw
}
It "Testing written item" {
diff --git a/src/Item/New-CredentialStoreItem.ps1 b/src/Item/New-CredentialStoreItem.ps1
index a95c2d4..a01d417 100644
--- a/src/Item/New-CredentialStoreItem.ps1
+++ b/src/Item/New-CredentialStoreItem.ps1
@@ -33,25 +33,17 @@ function New-CredentialStoreItem {
.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 = $true, ParameterSetName = "Shared")]
- [Parameter(Mandatory = $true, ParameterSetName = "Private")]
+ [CmdletBinding(DefaultParameterSetName = 'Private')]
+ param (
+ [Parameter(Mandatory = $true, ParameterSetName = 'Shared')]
+ [Parameter(Mandatory = $true, ParameterSetName = 'Private')]
[ValidateNotNullOrEmpty()]
[string]$RemoteHost,
- [Parameter(Mandatory = $false, ParameterSetName = "Shared")]
- [Parameter(Mandatory = $false, ParameterSetName = "Private")]
+ [Parameter(Mandatory = $false, ParameterSetName = 'Shared')]
+ [Parameter(Mandatory = $false, ParameterSetName = 'Private')]
[ValidateNotNullOrEmpty()]
[string]$Identifier,
@@ -59,10 +51,10 @@ function New-CredentialStoreItem {
[ValidateNotNullOrEmpty()]
[PSCredential]$Credential,
- [Parameter(Mandatory = $true, ParameterSetName = "Shared")]
+ [Parameter(Mandatory = $true, ParameterSetName = 'Shared')]
[switch]$Shared,
- [Parameter(Mandatory = $false, ParameterSetName = "Shared")]
+ [Parameter(Mandatory = $false, ParameterSetName = 'Shared')]
[ValidateNotNullOrEmpty()]
[string]$Path
@@ -72,10 +64,10 @@ function New-CredentialStoreItem {
begin {
# Set the CredentialStore for private, shared or custom mode.
Write-Debug ("ParameterSetName: {0}" -f $PSCmdlet.ParameterSetName)
- if ($PSCmdlet.ParameterSetName -eq "Private") {
+ if ($PSCmdlet.ParameterSetName -eq 'Private') {
$Path = Get-DefaultCredentialStorePath
}
- elseif ($PSCmdlet.ParameterSetName -eq "Shared") {
+ elseif ($PSCmdlet.ParameterSetName -eq 'Shared') {
if (!($PSBoundParameters.ContainsKey('Path'))) {
$Path = Get-DefaultCredentialStorePath -Shared
}
@@ -96,7 +88,7 @@ function New-CredentialStoreItem {
$CSContent = Get-CredentialStore -Shared -Path $Path
- $CurrentDate = Get-Date -UFormat "%Y-%m-%d %H:%M:%S"
+ $CurrentDate = Get-Date -Format 'u'
if ($Identifier -ne "") {
$CredentialName = $RemoteHost = "{0}/{1}" -f $Identifier, $RemoteHost
@@ -119,7 +111,7 @@ function New-CredentialStoreItem {
if (Get-Member -InputObject $CSContent -Name $CredentialName -Membertype Properties) {
$MessageParams = @{
- Message = "The given host already exists. Nothing to do here."
+ Message = 'The given host already exists. Nothing to do here.'
}
Write-Warning @MessageParams
}
@@ -139,8 +131,8 @@ function New-CredentialStoreItem {
}
catch {
$MessageParams = @{
- Message = "Couldn't add item into credential store!"
- ErrorAction = "Stop"
+ Message = 'Could not add item into credential store!'
+ ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
@@ -148,15 +140,13 @@ function New-CredentialStoreItem {
}
else {
$MessageParams = @{
- Message = "Please Provide at least a valid user!"
- ErrorAction = "Stop"
+ Message = 'Please Provide at least a valid user!'
+ ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
}
- end {
-
- }
+ end {}
}
diff --git a/src/Item/Remove-CredentialStoreItem.ps1 b/src/Item/Remove-CredentialStoreItem.ps1
index f3296b7..253d501 100644
--- a/src/Item/Remove-CredentialStoreItem.ps1
+++ b/src/Item/Remove-CredentialStoreItem.ps1
@@ -37,30 +37,22 @@ function Remove-CredentialStoreItem {
.EXAMPLE
Remove-CredentialStoreItem -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 = $true, ParameterSetName = "Private")]
- [Parameter(Mandatory = $true, ParameterSetName = "Shared")]
+ [CmdletBinding(DefaultParameterSetName = 'Private')]
+ param (
+ [Parameter(Mandatory = $true, ParameterSetName = 'Private')]
+ [Parameter(Mandatory = $true, ParameterSetName = 'Shared')]
[string]$RemoteHost,
- [Parameter(Mandatory = $false, ParameterSetName = "Private")]
- [Parameter(Mandatory = $false, ParameterSetName = "Shared")]
+ [Parameter(Mandatory = $false, ParameterSetName = 'Private')]
+ [Parameter(Mandatory = $false, ParameterSetName = 'Shared')]
[string]$Identifier,
- [Parameter(Mandatory = $true, ParameterSetName = "Shared")]
+ [Parameter(Mandatory = $true, ParameterSetName = 'Shared')]
[switch]$Shared,
- [Parameter(Mandatory = $false, ParameterSetName = "Shared")]
+ [Parameter(Mandatory = $false, ParameterSetName = 'Shared')]
[ValidateNotNullOrEmpty()]
[string]$Path
)
@@ -68,10 +60,10 @@ function Remove-CredentialStoreItem {
begin {
# Set the CredentialStore for private, shared or custom mode.
Write-Debug ("ParameterSetName: {0}" -f $PSCmdlet.ParameterSetName)
- if ($PSCmdlet.ParameterSetName -eq "Private") {
+ if ($PSCmdlet.ParameterSetName -eq 'Private') {
$Path = Get-DefaultCredentialStorePath
}
- elseif ($PSCmdlet.ParameterSetName -eq "Shared") {
+ elseif ($PSCmdlet.ParameterSetName -eq 'Shared') {
if (!($PSBoundParameters.ContainsKey('Path'))) {
$Path = Get-DefaultCredentialStorePath -Shared
}
@@ -82,8 +74,8 @@ function Remove-CredentialStoreItem {
# 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 CredentialStore."
- ErrorAction = "Stop"
+ Message = 'Could not add anything into the given CredentialStore.'
+ ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
@@ -105,7 +97,7 @@ function Remove-CredentialStoreItem {
}
else {
$MessageParams = @{
- Message = "The given CredentialStoreItem does not exist."
+ Message = 'The given CredentialStoreItem does not exist.'
}
Write-Warning @MessageParams
}
diff --git a/src/Item/Set-CredentialStoreItem.ps1 b/src/Item/Set-CredentialStoreItem.ps1
index 3194d58..73c87cf 100644
--- a/src/Item/Set-CredentialStoreItem.ps1
+++ b/src/Item/Set-CredentialStoreItem.ps1
@@ -34,34 +34,26 @@ function Set-CredentialStoreItem {
.EXAMPLE
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 = $true, ParameterSetName = "Private")]
- [Parameter(Mandatory = $true, ParameterSetName = "Shared")]
+ [CmdletBinding(DefaultParameterSetName = 'Private')]
+ param (
+ [Parameter(Mandatory = $true, ParameterSetName = 'Private')]
+ [Parameter(Mandatory = $true, ParameterSetName = 'Shared')]
[string]$RemoteHost,
- [Parameter(Mandatory = $false, ParameterSetName = "Private")]
- [Parameter(Mandatory = $false, ParameterSetName = "Shared")]
+ [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")]
+ [Parameter(Mandatory = $true, ParameterSetName = 'Shared')]
[switch]$Shared,
- [Parameter(Mandatory = $false, ParameterSetName = "Shared")]
+ [Parameter(Mandatory = $false, ParameterSetName = 'Shared')]
[ValidateNotNullOrEmpty()]
[string]$Path
)
@@ -69,10 +61,10 @@ function Set-CredentialStoreItem {
begin {
# Set the CredentialStore for private, shared or custom mode.
Write-Debug ("ParameterSetName: {0}" -f $PSCmdlet.ParameterSetName)
- if ($PSCmdlet.ParameterSetName -eq "Private") {
+ if ($PSCmdlet.ParameterSetName -eq 'Private') {
$Path = Get-DefaultCredentialStorePath
}
- elseif ($PSCmdlet.ParameterSetName -eq "Shared") {
+ elseif ($PSCmdlet.ParameterSetName -eq 'Shared') {
if (!($PSBoundParameters.ContainsKey('Path'))) {
$Path = Get-DefaultCredentialStorePath -Shared
}
@@ -83,8 +75,8 @@ function Set-CredentialStoreItem {
# 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"
+ Message = 'Could not add anything into the given CredentailStore.'
+ ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
@@ -92,7 +84,7 @@ function Set-CredentialStoreItem {
# Read the file content based on the given ParameterSetName
$CSContent = Get-CredentialStore -Shared -Path $Path
- $CurrentDate = Get-Date -UFormat "%Y-%m-%d %H:%M:%S"
+ $CurrentDate = Get-Date -Format 'u'
if ($Identifier -ne "") {
$CredentialName = $RemoteHost = "{0}/{1}" -f $Identifier, $RemoteHost
@@ -129,8 +121,8 @@ function Set-CredentialStoreItem {
}
Else {
$MessageParams = @{
- Message = "Please Provide at least a valid user!"
- ErrorAction = "Stop"
+ 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
index a248f0e..d516f6f 100644
--- a/src/Item/Test-CredentialStoreItem.ps1
+++ b/src/Item/Test-CredentialStoreItem.ps1
@@ -29,25 +29,18 @@ function Test-CredentialStoreItem {
[None]
.EXAMPLE
- If (Test-CredentialStoreItem -RemoteHost "Default") {
+ if (Test-CredentialStoreItem -RemoteHost "Default") {
Get-CredentialStoreItem -RemoteHost "Default"
}
- Else {
+ 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")]
+
+ [CmdletBinding(DefaultParameterSetName = 'Private')]
+ [OutputType([bool])]
+ param (
+ [Parameter(Mandatory = $false, ParameterSetName = 'Shared')]
[string]$Path = "{0}\PSCredentialStore\CredentialStore.json" -f $env:ProgramData,
[Parameter(Mandatory = $true)]
@@ -58,17 +51,17 @@ function Test-CredentialStoreItem {
[ValidateNotNullOrEmpty()]
[string]$Identifier,
- [Parameter(Mandatory = $false, ParameterSetName = "Shared")]
+ [Parameter(Mandatory = $false, ParameterSetName = 'Shared')]
[switch]$Shared
)
begin {
# Set the CredentialStore for private, shared or custom mode.
Write-Debug ("ParameterSetName: {0}" -f $PSCmdlet.ParameterSetName)
- if ($PSCmdlet.ParameterSetName -eq "Private") {
+ if ($PSCmdlet.ParameterSetName -eq 'Private') {
$Path = Get-DefaultCredentialStorePath
}
- elseif ($PSCmdlet.ParameterSetName -eq "Shared") {
+ elseif ($PSCmdlet.ParameterSetName -eq 'Shared') {
if (!($PSBoundParameters.ContainsKey('Path'))) {
$Path = Get-DefaultCredentialStorePath -Shared
}
@@ -86,7 +79,7 @@ function Test-CredentialStoreItem {
if (Test-CredentialStore -Shared -Path $Path) {
$CS = Get-CredentialStore -Shared -Path $Path
$CSMembers = Get-Member -InputObject $CS
- if (($CSMembers.MemberType -eq "NoteProperty") -and ($CSMembers.Name -contains $CredentialName)) {
+ if (($CSMembers.MemberType -eq 'NoteProperty') -and ($CSMembers.Name -contains $CredentialName)) {
return $true
}
else {
@@ -95,15 +88,13 @@ function Test-CredentialStoreItem {
}
else {
$MsgParams = @{
- ErrorAction = "Stop"
+ ErrorAction = 'Stop'
Message = "The given credential store ({0}) does not exist!" -f $Path
}
Write-Error @MsgParams
}
}
- end {
-
- }
+ end {}
}
diff --git a/src/ModuleRoot.psm1 b/src/ModuleRoot.psm1
new file mode 100644
index 0000000..abeede9
--- /dev/null
+++ b/src/ModuleRoot.psm1
@@ -0,0 +1,11 @@
+#region module-definition
+
+#endregion module-definition
+Set-Variable -Name "CSVersion" -Value "2.0.0" -Option Constant -Scope 'Script' -ErrorAction Stop
+
+# Get all child items in the Script path and exclude the Deploy script (if present.)
+$Functions = Get-ChildItem -Path $PSScriptRoot\*.ps1 -Recurse | Where-Object { $_.BaseName -notmatch '.Tests' }
+
+foreach ($Item in $Functions) {
+ . $Item.FullName
+}
diff --git a/src/PSCredentialStore.psd1 b/src/PSCredentialStore.psd1
index e77283e..d2f11b7 100644
--- a/src/PSCredentialStore.psd1
+++ b/src/PSCredentialStore.psd1
@@ -1,7 +1,7 @@
@{
# Script module or binary module file associated with this manifest.
- RootModule = 'PSCredentialStore.psm1'
+ RootModule = 'ModuleRoot.psm1'
# Version number of this module.
ModuleVersion = '0.0.9999'
@@ -19,7 +19,7 @@
CompanyName = ''
# Copyright statement for this module
- Copyright = '(c) 2020 OCram85. All rights reserved.'
+ Copyright = '(c) 2022 OCram85. All rights reserved.'
# Description of the functionality provided by this module
Description = 'A simple credential manager to store and reuse multiple credential objects.'
diff --git a/src/PSCredentialStore.psm1 b/src/PSCredentialStore.psm1
deleted file mode 100644
index 21ddd38..0000000
--- a/src/PSCredentialStore.psm1
+++ /dev/null
@@ -1,18 +0,0 @@
-#region module-definition
-
-#endregion module-definition
-Set-Variable -Name "CSVersion" -Value "2.0.0" -Option Constant -Scope 'Script' -ErrorAction Stop
-
-
-
-#region dot-sourcing
-# dot-sourcing all module functions. The export is handled via manifest file.
-
-$Items = (Get-ChildItem -Path (Join-Path -Path $PSScriptRoot -ChildPath '*.ps1') -Recurse ).FullName | Where-Object {
- $_ -notmatch "(Classes|Init)"
-}
-foreach ($Item in $Items) {
- # Write-Verbose ("dot sourcing file {0}" -f $Item)
- . $Item
-}
-#endregion dot-sourcing
diff --git a/src/PSModule.Tests.ps1 b/src/PSModule.Tests.ps1
new file mode 100644
index 0000000..34dc6e4
--- /dev/null
+++ b/src/PSModule.Tests.ps1
@@ -0,0 +1,12 @@
+Describe 'Test module meta' {
+ Context 'Default tests' -Tag 'Default' {
+ It 'Test manifest file' {
+ $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName
+ Test-ModuleManifest -Path $ManifestFile | Should -Be $true
+ }
+ It 'Import Module' {
+ $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName
+ { Import-Module $ManifestFile } | Should -Not -Throw
+ }
+ }
+}
diff --git a/src/Private/Get-CSPfxCertificate.ps1 b/src/Private/Get-CSPfxCertificate.ps1
index 9afe659..e3e384b 100644
--- a/src/Private/Get-CSPfxCertificate.ps1
+++ b/src/Private/Get-CSPfxCertificate.ps1
@@ -23,18 +23,11 @@ function Get-CSPfxCertificate {
.EXAMPLE
Get-CSPfxCertificate -Thumbprint '12345678' -StoreName 'My' -StoreLocation 'CurrentUser'
-
- .NOTES
- - File Name : Get-CSPfxCertificate.ps1
- - Author : Marco Blessing - marco.blessing@googlemail.com
- - Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
+
[CmdletBinding()]
[OutputType([System.Security.Cryptography.X509Certificates.X509Certificate2])]
- param(
+ param (
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[ValidateNotNullOrEmpty()]
[string[]]$Thumbprint,
diff --git a/tests/Private/01_Get-DefaultCredentialStorePath.Tests.ps1 b/src/Private/Get-DefaultCredentialStorePath.Tests.ps1
similarity index 83%
rename from tests/Private/01_Get-DefaultCredentialStorePath.Tests.ps1
rename to src/Private/Get-DefaultCredentialStorePath.Tests.ps1
index ac4b6dc..ee892fe 100644
--- a/tests/Private/01_Get-DefaultCredentialStorePath.Tests.ps1
+++ b/src/Private/Get-DefaultCredentialStorePath.Tests.ps1
@@ -1,3 +1,16 @@
+BeforeAll {
+ $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName
+ Import-Module $ManifestFile -Force
+
+ $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object {
+ $_.BaseName -notmatch '.Tests'
+ }
+ ).FullName
+ foreach ( $func in $PrivateFunctions) {
+ . $func
+ }
+}
+
Describe "Get-DefaultCredentialStorePath" {
Context "Basic syntax test" {
It "Test1: Should not throw" {
diff --git a/src/Private/Get-DefaultCredentialStorePath.ps1 b/src/Private/Get-DefaultCredentialStorePath.ps1
index 2ee5dc5..f235ce3 100644
--- a/src/Private/Get-DefaultCredentialStorePath.ps1
+++ b/src/Private/Get-DefaultCredentialStorePath.ps1
@@ -14,23 +14,16 @@ function Get-DefaultCredentialStorePath {
.EXAMPLE
$Path = Get-DefaultCredentialStorePath
-
- .NOTES
- - File Name : Get-DefaultCredentialStorePath.ps1
- - Author : Marco Blessing - marco.blessing@googlemail.com
- - Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
+
[CmdletBinding()]
[OutputType([string])]
- param(
+ param (
[Parameter(Mandatory = $false)]
[switch]$Shared
)
- begin { }
+ begin {}
process {
if ($Shared.IsPresent) {
@@ -57,5 +50,5 @@ function Get-DefaultCredentialStorePath {
}
}
- end { }
+ end {}
}
diff --git a/src/Private/Get-ModuleBase.Tests.ps1 b/src/Private/Get-ModuleBase.Tests.ps1
new file mode 100644
index 0000000..73f9c53
--- /dev/null
+++ b/src/Private/Get-ModuleBase.Tests.ps1
@@ -0,0 +1,20 @@
+BeforeAll {
+ $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName
+ Import-Module $ManifestFile -Force
+
+ $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object {
+ $_.BaseName -notmatch '.Tests'
+ }
+ ).FullName
+ foreach ( $func in $PrivateFunctions) {
+ . $func
+ }
+}
+
+Describe "Get-ModuleBase" {
+ Context "Basic syntax check" {
+ It "Test1: Should not throw" {
+ { Get-ModuleBase } | Should -Not -Throw
+ }
+ }
+}
diff --git a/src/Private/Get-ModuleBase.ps1 b/src/Private/Get-ModuleBase.ps1
index acb2451..9f8392c 100644
--- a/src/Private/Get-ModuleBase.ps1
+++ b/src/Private/Get-ModuleBase.ps1
@@ -6,24 +6,16 @@ function Get-ModuleBase {
.DESCRIPTION
This is just a wrapper for enabling pester tests.
-
.OUTPUTS
Returns the base path as string
+ #>
- .NOTES
- - File Name : Get-ModuleBase.ps1
- - Author : Marco Blessing - marco.blessing@googlemail.com
- - Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
-#>
[CmdletBinding()]
- [OutputType()]
- param()
- begin { }
+ [OutputType([string])]
+ param ()
+ begin {}
process {
return $MyInvocation.MyCommand.Module.ModuleBase
}
- end { }
+ end {}
}
diff --git a/src/Private/Get-RandomAESKey.Tests.ps1 b/src/Private/Get-RandomAESKey.Tests.ps1
new file mode 100644
index 0000000..21b6046
--- /dev/null
+++ b/src/Private/Get-RandomAESKey.Tests.ps1
@@ -0,0 +1,26 @@
+BeforeAll {
+ $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName
+ Import-Module $ManifestFile -Force
+
+ $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object {
+ $_.BaseName -notmatch '.Tests'
+ }
+ ).FullName
+ foreach ( $func in $PrivateFunctions) {
+ . $func
+ }
+}
+
+Describe "Get-RandomKey" {
+ Context "Basic input tests" {
+ It "Test1: Should not throw " {
+ { Get-RandomAESKey } | Should -Not -Throw
+ }
+ }
+ Context "Basic syntax check" {
+ It "Test2: Should return a key with a length of 32 bytes" {
+ $Key = Get-RandomAESKey
+ $Key.length | Should -Be 32
+ }
+ }
+}
diff --git a/src/Private/Get-RandomAESKey.ps1 b/src/Private/Get-RandomAESKey.ps1
index aff07b5..868300d 100644
--- a/src/Private/Get-RandomAESKey.ps1
+++ b/src/Private/Get-RandomAESKey.ps1
@@ -14,21 +14,13 @@ function Get-RandomAESKey {
.EXAMPLE
.\Get-RandomAESKey
-
- .NOTES
- - File Name : Get-RandomAESKey.ps1
- - Author : Marco Blessing - marco.blessing@googlemail.com
- - Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
[CmdletBinding()]
[OutputType([byte[]])]
- param()
+ param ()
- begin { }
+ begin {}
process {
$key = [byte[]]::new(32)
@@ -40,5 +32,5 @@ function Get-RandomAESKey {
}
}
- end { }
+ end {}
}
diff --git a/tests/Private/01_Get-TempDir.Tests.ps1 b/src/Private/Get-TempDir.Tests.ps1
similarity index 54%
rename from tests/Private/01_Get-TempDir.Tests.ps1
rename to src/Private/Get-TempDir.Tests.ps1
index 34a3d5e..336471b 100644
--- a/tests/Private/01_Get-TempDir.Tests.ps1
+++ b/src/Private/Get-TempDir.Tests.ps1
@@ -1,7 +1,20 @@
+BeforeAll {
+ $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName
+ Import-Module $ManifestFile -Force
+
+ $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object {
+ $_.BaseName -notmatch '.Tests'
+ }
+ ).FullName
+ foreach ( $func in $PrivateFunctions) {
+ . $func
+ }
+}
+
Describe "Get-TempDir" {
Context "Basic tests" {
It "Should not throw" {
- {Get-TempDir} | Should -Not -Throw
+ { Get-TempDir } | Should -Not -Throw
}
It "Should return the correct os tmp path" {
$Path = Get-TempDir
@@ -17,7 +30,11 @@ Describe "Get-TempDir" {
}
}
if ($Env:APPVEYOR) {
- if (($isWindows) -or ($PSVersionTable.PSVersion.Major -lt 6) -or ($PSVersionTable.PSEdition -eq 'Desktop')) {
+ if (
+ ($isWindows) -or
+ ($PSVersionTable.PSVersion.Major -lt 6) -or
+ ($PSVersionTable.PSEdition -eq 'Desktop')
+ ) {
$RefPath = (Resolve-Path -Path $env:TEMP).Path
$Path | Should -Be $RefPath
}
diff --git a/src/Private/Get-TempDir.ps1 b/src/Private/Get-TempDir.ps1
index b3db4d9..59a7311 100644
--- a/src/Private/Get-TempDir.ps1
+++ b/src/Private/Get-TempDir.ps1
@@ -13,21 +13,14 @@ function Get-TempDir {
.EXAMPLE
Get-TempDir
-
- .NOTES
- - File Name : Get-TempDir.ps1
- - Author : Marco Blessing - marco.blessing@googlemail.com
- - Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
+
[CmdletBinding()]
[OutputType([string])]
- param()
- begin {
+ param ()
+
+ begin {}
- }
process {
if ($IsLinux) {
return (Resolve-Path -Path '/tmp/').Path
@@ -35,10 +28,14 @@ function Get-TempDir {
if ($IsMacOS) {
return (Resolve-Path -Path '/tmp/').Path
}
- elseif (($isWindows) -or ($PSVersionTable.PSVersion.Major -lt 6) -or ($PSVersionTable.PSEdition -eq 'Desktop')) {
+ elseif (
+ ($isWindows) -or
+ ($PSVersionTable.PSVersion.Major -lt 6) -or
+ ($PSVersionTable.PSEdition -eq 'Desktop')
+ ) {
return (Resolve-Path -Path $env:TEMP).Path
}
}
- end {
- }
+
+ end {}
}
diff --git a/src/Private/Import-CSPfxCertificate.ps1 b/src/Private/Import-CSPfxCertificate.ps1
index b261c49..f1decc3 100644
--- a/src/Private/Import-CSPfxCertificate.ps1
+++ b/src/Private/Import-CSPfxCertificate.ps1
@@ -22,18 +22,10 @@ function Import-CSPfxCertificate {
.EXAMPLE
Import-CSPfxCertificate -Path (Join-Path -Path $Env:APPDATA -ChildPath '/PSCredentialStore.pfx')
-
- .NOTES
- File Name : Import-CSPfxCertificate.ps1
- Author : Marco Blessing - marco.blessing@googlemail.com
- Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
+
[CmdletBinding()]
- [OutputType()]
- param(
+ param (
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$Path,
@@ -68,6 +60,7 @@ function Import-CSPfxCertificate {
)]
[string]$OpenFlags = 'ReadWrite'
)
+
begin {
$Store = [System.Security.Cryptography.X509Certificates.X509Store]::new($StoreName, $StoreLocation)
try {
@@ -77,6 +70,7 @@ function Import-CSPfxCertificate {
$_.Exception.Message | Write-Error -ErrorAction Stop
}
}
+
process {
try {
$cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new(
diff --git a/src/Private/Resolve-Dependency.Tests.ps1 b/src/Private/Resolve-Dependency.Tests.ps1
new file mode 100644
index 0000000..53ee91e
--- /dev/null
+++ b/src/Private/Resolve-Dependency.Tests.ps1
@@ -0,0 +1,60 @@
+BeforeAll {
+ $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName
+ Import-Module $ManifestFile -Force
+
+ $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object {
+ $_.BaseName -notmatch '.Tests'
+ }
+ ).FullName
+ foreach ( $func in $PrivateFunctions) {
+ . $func
+ }
+}
+
+Describe "Resolve-Dependency" {
+ Context "Basic syntax check" {
+ BeforeAll {
+ Mock Get-ModuleBase {
+ return (Join-Path -Path $PWD -ChildPath '/resources')
+ }
+ Mock Test-Module {
+ return $true
+ }
+ }
+
+ It "Test1: Should not throw" {
+ { Resolve-Dependency -Name 'foobar2000' } | Should -Not -Throw
+ }
+ It "Test2: Output type should be bool" {
+ Resolve-Dependency -Name 'foobar2000' | Should -BeOfType bool
+ }
+ }
+ Context "Enforce Error" {
+ # Return incorrect module base to enforce there is no config file.
+ Mock Get-ModuleBase {
+ if ($IsWindows) { return "C:\" }
+ elseif ($isLinux) { return "/" }
+ }
+ It "Missing dependency file should not cause an error" {
+ { Resolve-Dependency -Name 'awesome' } | Should -Not -Throw
+ }
+
+ It "Missing dependency file should return true" {
+ Resolve-Dependency -Name 'awesome' | Should -Be $true
+ }
+ }
+ Context "Testing input variations" {
+ It "Should return true if all given dependencies exist" {
+ Mock Get-ModuleBase {
+ return (Join-Path -Path $PWD -ChildPath '/resources')
+ }
+ Resolve-Dependency -Name 'Existing' | Should -Be $true
+ }
+ It "Mixed results should return false" {
+ Mock Get-ModuleBase {
+ return (Join-Path -Path $PWD -ChildPath '/resources')
+ }
+ Resolve-Dependency -Name 'PSGetMixed' | Should -Be $false
+ }
+ }
+}
diff --git a/src/Private/Resolve-Dependency.ps1 b/src/Private/Resolve-Dependency.ps1
index 4b82922..8b7cc77 100644
--- a/src/Private/Resolve-Dependency.ps1
+++ b/src/Private/Resolve-Dependency.ps1
@@ -38,15 +38,8 @@ function Resolve-Dependency {
If (-not (Resolve-Dependency -Name 'VMware')) {
Write-Error -Message ("Could not resolve the optional dependencies defined for {0}" -f 'VMware') -ErrorAction 'Stop'
}
-
- .NOTES
- - File Name : ResolveDependency.ps1
- - Author : Marco Blessing - marco.blessing@googlemail.com
- - Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
+
[OutputType([bool])]
[CmdletBinding()]
param (
@@ -86,6 +79,5 @@ function Resolve-Dependency {
}
}
- end {
- }
+ end {}
}
diff --git a/src/Private/Test-CSPfxCertificate.Tests.ps1 b/src/Private/Test-CSPfxCertificate.Tests.ps1
new file mode 100644
index 0000000..f1405d1
--- /dev/null
+++ b/src/Private/Test-CSPfxCertificate.Tests.ps1
@@ -0,0 +1,25 @@
+BeforeAll {
+ $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName
+ Import-Module $ManifestFile -Force
+
+ $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object {
+ $_.BaseName -notmatch '.Tests'
+ }
+ ).FullName
+ foreach ( $func in $PrivateFunctions) {
+ . $func
+ }
+}
+
+Describe "Test-CSPfxCertificate" {
+ Context "Basic Tests" {
+ It "Should not Throw" {
+ {
+ Test-CSPfxCertificate -Thumbprint '12345' -StoreName My -StoreLocation CurrentUser
+ } | Should -Not -Throw
+ }
+ It "Should return false" {
+ Test-CSPfxCertificate -Thumbprint '12345' -StoreName My -StoreLocation CurrentUser | Should -Be $false
+ }
+ }
+}
diff --git a/src/Private/Test-CSPfxCertificate.ps1 b/src/Private/Test-CSPfxCertificate.ps1
index d03fdf5..64c427b 100644
--- a/src/Private/Test-CSPfxCertificate.ps1
+++ b/src/Private/Test-CSPfxCertificate.ps1
@@ -23,18 +23,11 @@ function Test-CSPfxCertificate {
.EXAMPLE
Test-CSPfxCertificate -Thumbprint '12345678' -StoreName 'My' -StoreLocation 'CurrentUser'
-
- .NOTES
- File Name : Test-CSPfxCertificate.ps1
- Author : Marco Blessing - marco.blessing@googlemail.com
- Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
+
[CmdletBinding()]
[OutputType([bool])]
- param(
+ param (
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[ValidateNotNullOrEmpty()]
[string]$Thumbprint,
diff --git a/tests/Private/01_Test-Module.Tests.ps1 b/src/Private/Test-Module.Tests.ps1
similarity index 68%
rename from tests/Private/01_Test-Module.Tests.ps1
rename to src/Private/Test-Module.Tests.ps1
index c5747c8..1805d12 100644
--- a/tests/Private/01_Test-Module.Tests.ps1
+++ b/src/Private/Test-Module.Tests.ps1
@@ -1,3 +1,16 @@
+BeforeAll {
+ $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName
+ Import-Module $ManifestFile -Force
+
+ $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object {
+ $_.BaseName -notmatch '.Tests'
+ }
+ ).FullName
+ foreach ( $func in $PrivateFunctions) {
+ . $func
+ }
+}
+
Describe "Test-ModuleName" {
Context "Basic input tests" {
It "Testing standard module should not throw" {
@@ -20,7 +33,7 @@ Describe "Test-ModuleName" {
Test-Module -Name 'foobar2000' | Should -Be $false
}
It "StopifFails switch should thrown an error" {
- {Test-Module -Name 'foobar2000' -StopIfFails }| Should -Throw
+ { Test-Module -Name 'foobar2000' -StopIfFails } | Should -Throw
}
}
}
diff --git a/src/Private/Test-Module.ps1 b/src/Private/Test-Module.ps1
index ab68198..67cbba1 100644
--- a/src/Private/Test-Module.ps1
+++ b/src/Private/Test-Module.ps1
@@ -32,18 +32,11 @@ function Test-Module {
.EXAMPLE
.\Test-Dependency -Name 'VMware.PowerCLI' -Type 'Module' -StopIfFails
-
- .NOTES
- - File Name : Test-Module.ps1
- - Author : Marco Blessing - marco.blessing@googlemail.com
- - Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
+
[OutputType([bool])]
[CmdletBinding()]
- param(
+ param (
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$Name,
@@ -56,7 +49,8 @@ Could not find the required {0} called {1}. Please install the required {0} to r
[Parameter(Mandatory = $false)]
[switch]$StopIfFails
)
- begin { }
+
+ begin {}
process {
$Message = $MessagePattern -f $Type, $Name
@@ -73,5 +67,5 @@ Could not find the required {0} called {1}. Please install the required {0} to r
}
}
- end { }
+ end {}
}
diff --git a/src/Store/Get-CredentialStore.Tests.ps1 b/src/Store/Get-CredentialStore.Tests.ps1
new file mode 100644
index 0000000..bb940a0
--- /dev/null
+++ b/src/Store/Get-CredentialStore.Tests.ps1
@@ -0,0 +1,47 @@
+BeforeAll {
+ $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName
+ Import-Module $ManifestFile -Force
+
+ $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object {
+ $_.BaseName -notmatch '.Tests'
+ }
+ ).FullName
+ foreach ( $func in $PrivateFunctions) {
+ . $func
+ }
+}
+
+Describe "Get-CredentialStore" {
+ Context "Basic logic tests" {
+ It "Read CS without params" {
+ $TestCredentialStore = './resources/cs/CredentialStore.json'
+ $TestPfxCert = './resources/cs/PSCredentialStore.pfx'
+ if (! (Test-Path -Path (Get-DefaultCredentialStorePath)) ) {
+ { New-CredentialStore -Force } | Should -Not -Throw
+ }
+ { Get-CredentialStore } | Should -Not -Throw
+ }
+ It "Read Credential Store with testing data" {
+ $TestCredentialStore = './resources/cs/CredentialStore.json'
+ $TestPfxCert = './resources/cs/PSCredentialStore.pfx'
+ {
+ Use-CSCertificate -Shared -CredentialStore $TestCredentialStore -Path $TestPfxCert
+ } | Should -Not -Throw
+ { Get-CredentialStore -Shared -Path $TestCredentialStore } | Should -Not -Throw
+ }
+ It "Test3: Not existing path should return false" {
+ {
+ Get-CredentialStore -Shared -Path './CredentialStore.json'
+ } | Should -Throw "Could not find the CredentialStore."
+ }
+ }
+ Context "Testing invalid json data" {
+ It "Should throw with invalid CredentialStore" {
+ $BrokenCS = './resources/cs/Broken_CS.json'
+ Write-Verbose -Message ('BrokenCS Path: {0}' -f $BrokenCS) -Verbose
+ {
+ Get-CredentialStore -Path -Shared $BrokenCS
+ } | Should -Throw
+ }
+ }
+}
diff --git a/src/Store/Get-CredentialStore.ps1 b/src/Store/Get-CredentialStore.ps1
index a30de5f..9966875 100644
--- a/src/Store/Get-CredentialStore.ps1
+++ b/src/Store/Get-CredentialStore.ps1
@@ -23,35 +23,28 @@ function Get-CredentialStore {
.EXAMPLE
$CSContent = Get-CredentialStore -Path "C:\TMP\mystore.json"
-
- .NOTES
- - File Name : Get-CredentialStore.ps1
- - Author : Marco Blessing - marco.blessing@googlemail.com
- - Requires :
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
- [CmdletBinding(DefaultParameterSetName = "Private")]
- [OutputType("PSCredentialStore.Store")]
- param(
- [Parameter(Mandatory = $false, ParameterSetName = "Shared")]
+ [CmdletBinding(DefaultParameterSetName = 'Private')]
+ [OutputType('PSCredentialStore.Store')]
+ param (
+ [Parameter(Mandatory = $false, ParameterSetName = 'Shared')]
[string]$Path,
- [Parameter(Mandatory = $true, ParameterSetName = "Shared")]
+ [Parameter(Mandatory = $true, ParameterSetName = 'Shared')]
[switch]$Shared
)
- begin { }
+ begin {}
process {
# Set the CredentialStore for private, shared or custom mode.
Write-Debug ("ParameterSetName: {0}" -f $PSCmdlet.ParameterSetName)
- if ($PSCmdlet.ParameterSetName -eq "Private") {
+ if ($PSCmdlet.ParameterSetName -eq 'Private') {
$Path = Get-DefaultCredentialStorePath
}
- elseif ($PSCmdlet.ParameterSetName -eq "Shared") {
+ elseif ($PSCmdlet.ParameterSetName -eq 'Shared') {
if (!($PSBoundParameters.ContainsKey('Path'))) {
$Path = Get-DefaultCredentialStorePath -Shared
}
@@ -61,26 +54,26 @@ function Get-CredentialStore {
try {
$FileContent = Get-Content -Path $Path -Raw
$CS = ConvertFrom-Json $FileContent
- $CS.PSObject.TypeNames.Insert(0, "PSCredentialStore.Store")
- return $CS
+ $CS.PSObject.TypeNames.Insert(0, 'PSCredentialStore.Store')
+ Write-Output $CS
}
catch [System.Exception] {
$MessageParams = @{
- Message = "Unknown CredentialStore format. Invalid JSON file."
- ErrorAction = "Stop"
+ Message = 'Unknown CredentialStore format. Invalid JSON file.'
+ ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
}
else {
$MessageParams = @{
- Message = "Could not find the CredentialStore."
- ErrorAction = "Stop"
+ Message = 'Could not find the CredentialStore.'
+ ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
}
- end { }
+ end {}
}
diff --git a/src/Store/New-CredentialStore.Tests.ps1 b/src/Store/New-CredentialStore.Tests.ps1
new file mode 100644
index 0000000..9cc5b88
--- /dev/null
+++ b/src/Store/New-CredentialStore.Tests.ps1
@@ -0,0 +1,141 @@
+BeforeAll {
+ $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName
+ Import-Module $ManifestFile -Force
+
+ $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object {
+ $_.BaseName -notmatch '.Tests'
+ }
+ ).FullName
+ foreach ( $func in $PrivateFunctions) {
+ . $func
+ }
+
+ # Backup existing credential stores
+ $VerbosePreference = "Continue"
+ Write-Verbose "Backup private Credential Store..."
+ $CSPath = Get-DefaultCredentialStorePath
+ $BackupFile = "{0}.back" -f $CSPath
+ if (Test-Path -Path $CSPath) {
+ Move-Item -Path $CSPath -Destination $BackupFile
+ }
+ Write-Verbose "Backup shared CredentialStore..."
+ $CSShared = Get-DefaultCredentialStorePath -Shared
+ $BackupSharedFile = "{0}.back" -f $CSShared
+ if (Test-Path -Path $CSShared) {
+ Move-Item -Path $CSShared -Destination $BackupSharedFile
+ }
+ Write-Verbose "Remove old CredentialStore in Temp dir"
+ $CSTemp = Join-Path -Path (Get-TempDir) -ChildPath '/CredentialStore.json'
+ if (Test-Path -Path $CSTemp) {
+ Remove-Item -Path $CSTemp
+ }
+ $VerbosePreference = "SilentlyContinue"
+}
+
+Describe "New-CredentialStore" {
+ Context "Private CS tests" {
+ It "Create new private CredentialStore" {
+ $pCS = Get-DefaultCredentialStorePath
+ { New-CredentialStore -Confirm:$false -Force } | Should -Not -Throw
+ $result = Test-Path -Path $pCS
+ $CS = Get-Content -Path $pCS -Raw | ConvertFrom-Json
+ ($result -eq $true) -and ($CS.Type -eq "Private") | Should -Be $true
+ }
+ It "Try to override private Store" {
+ { New-CredentialStore -Confirm:$false } | Should -Throw
+ }
+ It "Reset existing Credential Store" {
+ $pCS = Get-DefaultCredentialStorePath
+ $now = Get-Date
+ $CS = Get-Content -Path $pCS -Raw | ConvertFrom-Json
+ $CSCreation = [DateTime]$CS.Created
+ New-CredentialStore -Confirm:$false -Force
+ $now -gt $csCreation | Should -Be $true
+ }
+ }
+ Context "Shared CS tests" {
+ It "Create a new Shared Credential Store" {
+ $sCS = Get-DefaultCredentialStorePath -Shared
+ { New-CredentialStore -Confirm:$false -Shared } | Should -Not -Throw
+ Test-Path -Path $sCS | Should -Be $true
+ }
+ It "Try to override existing shared CS" {
+ { New-CredentialStore -Shared -Confirm:$false } | Should -Throw
+ }
+ It "Reset shared CredentialStore" {
+ $sCS = Get-DefaultCredentialStorePath -Shared
+ $now = Get-Date
+ $CS = Get-Content -Path $sCS -Raw | ConvertFrom-Json
+ $CSCreation = [DateTime]$CS.Created
+ New-CredentialStore -Force -Shared -Confirm:$false
+ $now -gt $csCreation | Should -Be $true
+ }
+ }
+ Context "Custom Shared CS tests" {
+ It "Create new custom shared" {
+ $cCS = Join-Path -Path (Get-TempDir) -ChildPath "CredentialStore.json"
+ { New-CredentialStore -Path $cCS -Shared -Confirm:$false -SkipPFXCertCreation } | Should -Not -Throw
+ }
+ It "Try to override exiting one" {
+ $cCS = Join-Path -Path (Get-TempDir) -ChildPath "CredentialStore.json"
+ { New-CredentialStore -Path $cCS -Shared -Confirm:$false } | Should -Throw
+ }
+ It "Reset existing custom CredentialStore" {
+ $cCS = Join-Path -Path (Get-TempDir) -ChildPath "CredentialStore.json"
+ { New-CredentialStore -Path $cCS -Shared -Force -Confirm:$false } | Should -Not -Throw
+ }
+ }
+ Context "Test exception handling" {
+ Mock Out-File { throw "foobar exception" }
+ It "JSON Conversion should fail and throw" {
+ {
+ New-CredentialStore -Path (
+ Join-Path -Path (Get-TempDir) -ChildPath '/dummy.json'
+ ) -Shared -Confirm:$false
+ } | Should -Throw
+ }
+ }
+ Context "Tests for Windows certificate store" {
+ It "Create new private store and skip certificate linking" {
+ { New-CredentialStore -UseCertStore -Force } | Should -Not -Throw
+ $CS = Get-CredentialStore
+ $CS.PfxCertificate | Should -Be $null
+ $CS.Thumbprint | Should -Not -Be $null
+ $res = Test-CSCertificate -Type Private
+ #Write-Verbose -Message ('res: {0}' -f $res) -Verbose
+ $res | Should -Be $true
+
+ }
+ It "Create new shared store and skipt certificate linking" {
+ { New-CredentialStore -Shared -UseCertStore -Force } | Should -Not -Throw
+ $CS = Get-CredentialStore -Shared
+ $CS.PfxCertificate | Should -Be $null
+ $CS.Thumbprint | Should -Not -Be $null
+ $res = Test-CSCertificate -Type Shared
+ #Write-Verbose -Message ('res: {0}' -f $res) -Verbose
+ $res | Should -Be $true
+ }
+ }
+}
+
+AfterAll {
+ # Cleanup test stores and restore existing ones.
+ $VerbosePreference = "Continue"
+ Write-Verbose "Restoring private CredentialStore"
+ If (Test-Path -Path $BackupFile) {
+ If (Test-Path -Path $CSPath) {
+ Remove-Item -Path $CSPath
+ Move-Item -Path $BackupFile -Destination $CSPath
+ }
+ }
+
+ Write-Verbose "Restoring shared CredentialStore"
+ If (Test-Path -Path $BackupSharedFile) {
+ If (Test-Path -Path $CSShared) {
+ Remove-Item -Path $CSShared
+ Move-Item -Path $BackupSharedFile -Destination $CSShared
+ }
+ }
+ $VerbosePreference = "SilentlyContinue"
+
+}
diff --git a/src/Store/New-CredentialStore.ps1 b/src/Store/New-CredentialStore.ps1
index cfa1ce2..d18433a 100644
--- a/src/Store/New-CredentialStore.ps1
+++ b/src/Store/New-CredentialStore.ps1
@@ -49,49 +49,38 @@ function New-CredentialStore {
.EXAMPLE
New-CredentialStore -Shared -Path "C:\TMP\CredentialStore.json"
# Creates a new shared CredentialStore in the given location.
-
- .NOTES
- - File Name : New-CredentialStore.ps1
- - Author : Marco Blessing - marco.blessing@googlemail.com
- - Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
- [CmdletBinding(SupportsShouldProcess = $true, DefaultParameterSetName = "Private")]
- [OutputType("PSCredentialStore.Store")]
- param(
- [Parameter(Mandatory = $true, ParameterSetName = "Shared")]
+ [CmdletBinding(SupportsShouldProcess = $true, DefaultParameterSetName = 'Private')]
+ [OutputType('PSCredentialStore.Store')]
+ param (
+ [Parameter(Mandatory = $true, ParameterSetName = 'Shared')]
[switch]$Shared,
- [Parameter(Mandatory = $false, ParameterSetName = "Shared")]
+ [Parameter(Mandatory = $false, ParameterSetName = 'Shared')]
[ValidateNotNullOrEmpty()]
[System.IO.FileInfo]$Path,
- [Parameter(Mandatory = $false, ParameterSetName = "Private")]
- [Parameter(Mandatory = $false, ParameterSetName = "Shared")]
- [Switch]$Force,
+ [Parameter(Mandatory = $false, ParameterSetName = 'Private')]
+ [Parameter(Mandatory = $false, ParameterSetName = 'Shared')]
+ [switch]$Force,
- [Parameter(Mandatory = $false, ParameterSetName = "Private")]
- [Parameter(Mandatory = $false, ParameterSetName = "Shared")]
- [Switch]$PassThru,
+ [Parameter(Mandatory = $false, ParameterSetName = 'Private')]
+ [Parameter(Mandatory = $false, ParameterSetName = 'Shared')]
+ [switch]$PassThru,
- [Parameter(Mandatory = $false, ParameterSetName = "Private")]
- [Parameter(Mandatory = $false, ParameterSetName = "Shared")]
- [Switch]$SkipPFXCertCreation,
+ [Parameter(Mandatory = $false, ParameterSetName = 'Private')]
+ [Parameter(Mandatory = $false, ParameterSetName = 'Shared')]
+ [switch]$SkipPFXCertCreation,
- [Parameter(Mandatory = $false, ParameterSetName = "Private")]
- [Parameter(Mandatory = $false, ParameterSetName = "Shared")]
- [Switch]$UseCertStore
+ [Parameter(Mandatory = $false, ParameterSetName = 'Private')]
+ [Parameter(Mandatory = $false, ParameterSetName = 'Shared')]
+ [switch]$UseCertStore
)
begin {
# Lets get the current Date in a human readable format.
- $CurrentDate = Get-Date -UFormat "%Y-%m-%d %H:%M:%S"
-
- # Set latest Credential Store version
- # Set-Variable -Name "CSVersion" -Value "2.0.0" -Option Constant -Scope
+ $CurrentDate = Get-Date -Format 'u'
# test if the path input is a valid file path
if ($PSCmdlet.MyInvocation.BoundParameters.ContainsKey('Path')) {
@@ -108,7 +97,7 @@ function New-CredentialStore {
$ErrorParams = @{
ErrorAction = 'Stop'
Exception = [System.IO.InvalidDataException]::new(
- 'Your provided path does not contain the required file extension .json !'
+ 'Your provided path does not contain the required file extension .json!'
)
}
Write-Error @ErrorParams
@@ -119,17 +108,17 @@ function New-CredentialStore {
process {
# Set the CredentialStore for private, shared or custom mode.
Write-Debug ("ParameterSetName: {0}" -f $PSCmdlet.ParameterSetName)
- if ($PSCmdlet.ParameterSetName -eq "Private") {
+ if ($PSCmdlet.ParameterSetName -eq 'Private') {
$Path = Get-DefaultCredentialStorePath
}
- elseif ($PSCmdlet.ParameterSetName -eq "Shared") {
+ elseif ($PSCmdlet.ParameterSetName -eq 'Shared') {
if (!($PSBoundParameters.ContainsKey('Path'))) {
$Path = Get-DefaultCredentialStorePath -Shared
}
}
# Test if in the CredentialStore already exists.
- Write-Verbose "Test if there is already a credential store."
+ Write-Verbose 'Test if there is already a credential store.'
if ((Test-Path -Path $Path) -and ($Force -ne $true)) {
$ErrorParams = @{
ErrorAction = 'Stop'
@@ -211,11 +200,11 @@ function New-CredentialStore {
Type = $null
}
- if ($PSCmdlet.ParameterSetName -eq "Shared") {
- $ObjProperties.Type = "Shared"
+ if ($PSCmdlet.ParameterSetName -eq 'Shared') {
+ $ObjProperties.Type = 'Shared'
}
else {
- $ObjProperties.Type = "Private"
+ $ObjProperties.Type = 'Private'
}
if (! $SkipPFXCertCreation.IsPresent) {
@@ -253,6 +242,5 @@ function New-CredentialStore {
}
}
- end {
- }
+ end {}
}
diff --git a/tests/Store/02_Test-CredentialStore.Tests.ps1 b/src/Store/Test-CredentialStore.Tests.ps1
similarity index 58%
rename from tests/Store/02_Test-CredentialStore.Tests.ps1
rename to src/Store/Test-CredentialStore.Tests.ps1
index 6cdeca9..3ebb096 100644
--- a/tests/Store/02_Test-CredentialStore.Tests.ps1
+++ b/src/Store/Test-CredentialStore.Tests.ps1
@@ -1,24 +1,36 @@
-$RepoRoot = (Get-Item -Path (Get-GitDirectory) -Force).Parent | Select-Object -ExpandProperty 'FullName'
+BeforeAll {
+ $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName
+ Import-Module $ManifestFile -Force
+
+ $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object {
+ $_.BaseName -notmatch '.Tests'
+ }
+ ).FullName
+ foreach ( $func in $PrivateFunctions) {
+ . $func
+ }
+}
Describe "Test-CredentialStore" {
Context "Basic logic tests" {
- $TestCredentialStore = Join-Path -Path $RepoRoot -ChildPath '/resources/cs/CredentialStore.json'
- It "Test1: Should Not Throw" {
+ It "Should Not Throw" {
+ $TestCredentialStore = './resources/cs/CredentialStore.json'
{ Test-CredentialStore -Shared -Path $TestCredentialStore } | Should -Not -Throw
}
- It "Test2: Read valid CredentialStore" {
+ It "Read valid CredentialStore" {
+ $TestCredentialStore = './resources/cs/CredentialStore.json'
$res = Test-CredentialStore -Shared -Path $TestCredentialStore
$res | Should -Be $true
}
- It "Test3: Read a broken CredentialStore" {
- $BrokenCS = Join-Path -Path $RepoRoot -ChildPath '{0}/resources/cs/Broken_CS.json'
+ It "Read a broken CredentialStore" -Skip {
+ $BrokenCS = './resources/cs/Broken_CS.json'
$oWarningPreference = $WarningPreference
$WarningPreference = 'SilentlyContinue'
$res = Test-CredentialStore -Shared -Path $BrokenCS
$res | Should -Be $false
$WarningPreference = $oWarningPreference
}
- It "Test4: Not existing path should return false" {
+ It "Not existing path should return false" {
if ($isWindows -or ($PSVersionTable.PSVersion.Major -eq 5)) {
Test-CredentialStore -Shared -Path 'C:\foobar\CredentialStore.json' | Should -Be $false
}
@@ -26,7 +38,7 @@ Describe "Test-CredentialStore" {
Test-CredentialStore -Shared -Path '/var/opt/foo.json' | Should -Be $false
}
}
- It "Test5: testing private CredentialStore path" {
+ It "testing private CredentialStore path" {
if (Test-Path -Path (Get-DefaultCredentialStorePath)) {
Remove-Item -Path (Get-DefaultCredentialStorePath)
}
diff --git a/src/Store/Test-CredentialStore.ps1 b/src/Store/Test-CredentialStore.ps1
index afbc429..e535b06 100644
--- a/src/Store/Test-CredentialStore.ps1
+++ b/src/Store/Test-CredentialStore.ps1
@@ -16,36 +16,27 @@ function Test-CredentialStore {
.EXAMPLE
Test-CredentialStore -eq $true
-
- .NOTES
- - File Name : Test-CredentialStore.ps1
- - Author : Marco Blessing - marco.blessing@googlemail.com
- - Requires :
-
- .LINK
- https://github.com/OCram85/PSCredentialStore
#>
- [CmdletBinding(DefaultParameterSetName = "Private")]
- param(
- [Parameter(Mandatory = $false, ParameterSetName = "Shared")]
+
+ [CmdletBinding(DefaultParameterSetName = 'Private')]
+ [OutputType([bool])]
+ param (
+ [Parameter(Mandatory = $false, ParameterSetName = 'Shared')]
[string]$Path,
- [Parameter(Mandatory = $true, ParameterSetName = "Shared")]
+ [Parameter(Mandatory = $true, ParameterSetName = 'Shared')]
[switch]$Shared
)
- begin {
- # Set latest Credential Store version
- #Set-Variable -Name "CSVersion" -Value "2.0.0" -Option Constant
- }
+ begin {}
process {
# Set the CredentialStore for private, shared or custom mode.
Write-Debug ("ParameterSetName: {0}" -f $PSCmdlet.ParameterSetName)
- if ($PSCmdlet.ParameterSetName -eq "Private") {
+ if ($PSCmdlet.ParameterSetName -eq 'Private') {
$Path = Get-DefaultCredentialStorePath
}
- elseif ($PSCmdlet.ParameterSetName -eq "Shared") {
+ elseif ($PSCmdlet.ParameterSetName -eq 'Shared') {
if (!($PSBoundParameters.ContainsKey('Path'))) {
$Path = Get-DefaultCredentialStorePath -Shared
}
@@ -53,15 +44,15 @@ function Test-CredentialStore {
Write-Verbose -Message ("Path is: {0}" -f $Path)
if (Test-Path $Path) {
- Write-Verbose "CredentialStore in given path found."
- return $true
+ Write-Verbose 'CredentialStore in given path found.'
+ Write-Output $true
}
else {
- Write-Verbose "The given CredentialStore does not exist!"
- return $false
+ Write-Verbose 'The given CredentialStore does not exist!'
+ Write-Output $false
}
}
- end { }
+ end {}
}
diff --git a/tests/00_BasicModule.Tests.ps1 b/tests/00_BasicModule.Tests.ps1
deleted file mode 100644
index 6c846ad..0000000
--- a/tests/00_BasicModule.Tests.ps1
+++ /dev/null
@@ -1,17 +0,0 @@
-$RepoRoot = (Get-Item -Path (Get-GitDirectory) -Force).Parent | Select-Object -ExpandProperty 'FullName'
-Write-Verbose -Message ('RepoRoot: {0}' -f $RepoRoot) -Verbose
-
-$ManifestFilePath = Join-Path -Path $RepoRoot -ChildPath '/src/PSCredentialStore.psd1'
-Write-Verbose -Message ("ManifestFilePath: {0}" -f $ManifestFilePath) -Verbose
-Describe "Pre-Flight module tests" {
- Context "Manifest file related" {
- It "Test the parsed file itself" {
- { Test-ModuleManifest -Path $ManifestFilePath -Verbose } | Should -Not -Throw
- }
- }
- Context "Module consistency tests" {
- It "Importing should work" {
- { Import-Module -Name $ManifestFilePath -Global -Force -Verbose } | Should -Not -Throw
- }
- }
-}
diff --git a/tests/Certificate/50_New-CSCertAttribute.Tests.ps1 b/tests/Certificate/50_New-CSCertAttribute.Tests.ps1
deleted file mode 100644
index e6f5cb4..0000000
--- a/tests/Certificate/50_New-CSCertAttribute.Tests.ps1
+++ /dev/null
@@ -1,7 +0,0 @@
-Describe "New-CSCertAttribute" {
- Context "Basis Tests" {
- It "Test1: Should not throw " {
- { New-CSCertAttribute -Country 'DE' -State 'BW' -City 'KA' -Organization 'IT' -OrganizationalUnitName'' -CommonName 'Mycert' } | Should -Not -Throw
- }
- }
-}
diff --git a/tests/Certificate/51_New-CSCertificate.Tests.ps1 b/tests/Certificate/51_New-CSCertificate.Tests.ps1
deleted file mode 100644
index aac7f74..0000000
--- a/tests/Certificate/51_New-CSCertificate.Tests.ps1
+++ /dev/null
@@ -1,15 +0,0 @@
-Describe "New-CSCertificate" {
- Context "Basic Tests" {
- It "Test1: Should not throw" {
-
- $attribs = New-CSCertAttribute -Country 'DE' -State 'BW' -City 'KA' -Organization 'IT' -OrganizationalUnitName'' -CommonName 'Mycert'
-
- $CertAttribs = @{
- CRTAttribute = $attribs
- KeyName = Join-Path -Path (Get-TempDir) -ChildPath '/foo.key'
- CertName = Join-Path -Path (Get-TempDir) -ChildPath '/cert.pfx'
- }
- { New-CSCertificate @CertAttribs } | Should -Not -Throw
- }
- }
-}
diff --git a/tests/PfxCertificate/60_Test-CSPfxCertificate.Tests.ps1 b/tests/PfxCertificate/60_Test-CSPfxCertificate.Tests.ps1
deleted file mode 100644
index 9665cb6..0000000
--- a/tests/PfxCertificate/60_Test-CSPfxCertificate.Tests.ps1
+++ /dev/null
@@ -1,10 +0,0 @@
-Describe "Test-CSPfxCertificate" {
- Context "Basic Tests" {
- It "Should not Throw" {
- { Test-CSPfxCertificate -Thumbprint '12345' -StoreName My -StoreLocation CurrentUser } | Should -Not -Throw
- }
- It "Should return false" {
- Test-CSPfxCertificate -Thumbprint '12345' -StoreName My -StoreLocation CurrentUser | Should -Be $false
- }
- }
-}
diff --git a/tests/Private/01_Get-ModuleBase.Tests.ps1 b/tests/Private/01_Get-ModuleBase.Tests.ps1
deleted file mode 100644
index 0e5d972..0000000
--- a/tests/Private/01_Get-ModuleBase.Tests.ps1
+++ /dev/null
@@ -1,7 +0,0 @@
-Describe "Get-ModuleBase" {
- Context "Basic syntax check" {
- It "Test1: Should not throw" {
- { Get-ModuleBase } | Should -Not -Throw
- }
- }
-}
diff --git a/tests/Private/01_Get-RandomAESKey.Tests.ps1 b/tests/Private/01_Get-RandomAESKey.Tests.ps1
deleted file mode 100644
index 9a9c72f..0000000
--- a/tests/Private/01_Get-RandomAESKey.Tests.ps1
+++ /dev/null
@@ -1,13 +0,0 @@
-Describe "Get-RandomKey" {
- Context "Basic input tests" {
- It "Test1: Should not throw " {
- {Get-RandomAESKey} | Should -Not -Throw
- }
- }
- Context "Basic syntax check" {
- It "Test2: Should return a key with a length of 32 bytes" {
- $Key = Get-RandomAESKey
- $Key.length | Should -Be 32
- }
- }
-}
diff --git a/tests/Private/01_Resolve-Dependency.Tests.ps1 b/tests/Private/01_Resolve-Dependency.Tests.ps1
deleted file mode 100644
index 755ce9a..0000000
--- a/tests/Private/01_Resolve-Dependency.Tests.ps1
+++ /dev/null
@@ -1,35 +0,0 @@
-Describe "Resolve-Dependency" {
- Context "Basic syntax check" {
- Mock Get-ModuleBase {return (Join-Path -Path $PWD -ChildPath '/resources')}
- Mock Test-Module {return $true}
- It "Test1: Should not throw" {
- { Resolve-Dependency -Name 'foobar2000' } | Should -Not -Throw
- }
- It "Test2: Output type should be bool" {
- Resolve-Dependency -Name 'foobar2000' | Should -BeOfType bool
- }
- }
- Context "Enforce Error" {
- # Return incorrect module base to enforce there is no config file.
- Mock Get-ModuleBase {
- if ($IsWindows) {return "C:\"}
- elseif ($isLinux) {return "/"}
- }
- It "Missing dependency file should not cause an error" {
- { Resolve-Dependency -Name 'awesome'} | Should -Not -Throw
- }
-
- It "Missing dependency file should return true" {
- Resolve-Dependency -Name 'awesome' | Should -Be $true
- }
- }
- Context "Testing input variations" {
- Mock Get-ModuleBase {return (Join-Path -Path $PWD -ChildPath '/resources')}
- It "Should return true if all given dependencies exist" {
- Resolve-Dependency -Name 'Existing' | Should -Be $true
- }
- It "Mixed results should return false" {
- Resolve-Dependency -Name 'PSGetMixed' | Should -Be $false
- }
- }
-}
diff --git a/tests/Store/02_New-CredentialStore.Tests.ps1 b/tests/Store/02_New-CredentialStore.Tests.ps1
deleted file mode 100644
index ec58d99..0000000
--- a/tests/Store/02_New-CredentialStore.Tests.ps1
+++ /dev/null
@@ -1,117 +0,0 @@
-# Backup existing credential stores
-$VerbosePreference = "Continue"
-Write-Verbose "Backup private Credential Store..."
-$CSPath = Get-DefaultCredentialStorePath
-$BackupFile = "{0}.back" -f $CSPath
-If (Test-Path -Path $CSPath) {
- Move-Item -Path $CSPath -Destination $BackupFile
-}
-Write-Verbose "Backup shared CredentialStore..."
-$CSShared = Get-DefaultCredentialStorePath -Shared
-$BackupSharedFile = "{0}.back" -f $CSShared
-If (Test-Path -Path $CSShared) {
- Move-Item -Path $CSShared -Destination $BackupSharedFile
-}
-Write-Verbose "Remove old CredentialStore in Temp dir"
-$CSTemp = Join-Path -Path (Get-TempDir) -ChildPath '/CredentialStore.json'
-If (Test-Path -Path $CSTemp) {
- Remove-Item -Path $CSTemp
-}
-$VerbosePreference = "SilentlyContinue"
-
-Describe "New-CredentialStore" {
- Context "Private CS tests" {
- $pCS = Get-DefaultCredentialStorePath
- It "Test1: Create new private CredentialStore" {
- { New-CredentialStore -Confirm:$false } | Should -Not -Throw
- $result = Test-Path -Path $pCS
- $CS = Get-Content -Path $pCS -Raw | ConvertFrom-Json
- ($result -eq $true) -and ($CS.Type -eq "Private") | Should -Be $true
- }
- It "Test2: Try to override private Store" {
- { New-CredentialStore -Confirm:$false } | Should -Throw
- }
- It "Test3: Reset existing Credential Store" {
- $now = Get-Date
- $CS = Get-Content -Path $pCS -Raw | ConvertFrom-Json
- $CSCreation = [DateTime]$CS.Created
- New-CredentialStore -Confirm:$false -Force
- $now -gt $csCreation | Should -Be $true
- }
- }
- Context "Shared CS tests" {
- $sCS = Get-DefaultCredentialStorePath -Shared
- It "Test1: Create a new Shared Credential Store" {
- { New-CredentialStore -Confirm:$false -Shared } | Should -Not -Throw
- Test-Path -Path $sCS | Should -Be $true
- }
- It "Test2: Try to override existing shared CS" {
- { New-CredentialStore -Shared -Confirm:$false } | Should -Throw
- }
- It "Test3: Reset shared CredentialStore" {
- $now = Get-Date
- $CS = Get-Content -Path $sCS -Raw | ConvertFrom-Json
- $CSCreation = [DateTime]$CS.Created
- New-CredentialStore -Force -Shared -Confirm:$false
- $now -gt $csCreation | Should -Be $true
- }
- }
- Context "Custom Shared CS tests" {
- $cCS = Join-Path -Path (Get-TempDir) -ChildPath "CredentialStore.json"
- It "Test1: Create new custom shared" {
- { New-CredentialStore -Path $cCS -Shared -Confirm:$false } | Should -Not -Throw
- }
- It "Test2: Try to override exiting one" {
- { New-CredentialStore -Path $cCS -Shared -Confirm:$false } | Should -Throw
- }
- It "Test3: Reset existing custom CredentialStore" {
- { New-CredentialStore -Path $cCS -Shared -Force -Confirm:$false } | Should -Not -Throw
- }
- }
- Context "Test exception handling" {
- Mock Out-File { throw "foobar exception" }
- It "JSON Conversion should fail and throw" {
- { New-CredentialStore -Path (Join-Path -Path (Get-TempDir) -ChildPath '/dummy.json') -Shared -Confirm:$false } | Should -Throw
- }
- }
- Context "Tests for Windows certificate store" {
- It "Create new private store and skip certificate linking" {
- { New-CredentialStore -UseCertStore -Force } | Should -Not -Throw
- $CS = Get-CredentialStore
- $CS.PfxCertificate | Should -Be $null
- $CS.Thumbprint | Should -Not -Be $null
- $res = Test-CSCertificate -Type Private
- #Write-Verbose -Message ('res: {0}' -f $res) -Verbose
- $res | Should -Be $true
-
- }
- It "Create new shared store and skipt certificate linking" {
- { New-CredentialStore -Shared -UseCertStore -Force } | Should -Not -Throw
- $CS = Get-CredentialStore -Shared
- $CS.PfxCertificate | Should -Be $null
- $CS.Thumbprint | Should -Not -Be $null
- $res = Test-CSCertificate -Type Shared
- #Write-Verbose -Message ('res: {0}' -f $res) -Verbose
- $res | Should -Be $true
- }
- }
-}
-
-# Cleanup test stores and restore existing ones.
-$VerbosePreference = "Continue"
-Write-Verbose "Restoring private CredentialStore"
-If (Test-Path -Path $BackupFile) {
- If (Test-Path -Path $CSPath) {
- Remove-Item -Path $CSPath
- Move-Item -Path $BackupFile -Destination $CSPath
- }
-}
-
-Write-Verbose "Restoring shared CredentialStore"
-If (Test-Path -Path $BackupSharedFile) {
- If (Test-Path -Path $CSShared) {
- Remove-Item -Path $CSShared
- Move-Item -Path $BackupSharedFile -Destination $CSShared
- }
-}
-$VerbosePreference = "SilentlyContinue"
diff --git a/tests/Store/03_Get-CredentialStore.Tests.ps1 b/tests/Store/03_Get-CredentialStore.Tests.ps1
deleted file mode 100644
index 0bf63aa..0000000
--- a/tests/Store/03_Get-CredentialStore.Tests.ps1
+++ /dev/null
@@ -1,32 +0,0 @@
-$RepoRoot = (Get-Item -Path (Get-GitDirectory) -Force).Parent | Select-Object -ExpandProperty 'FullName'
-
-Describe "Get-CredentialStore" {
- Context "Basic logic tests" {
- $TestCredentialStore = Join-Path -Path $RepoRoot -ChildPath 'resources/cs/CredentialStore.json'
- $TestPfxCert = Join-Path -Path $RepoRoot -ChildPath 'resources/cs/PSCredentialStore.pfx'
- 'TestCredentialStore: {0}' -f $TestCredentialStore
- It "Test1: Read CS without params" {
- if (! (Test-Path -Path (Get-DefaultCredentialStorePath)) ) {
- { New-CredentialStore -Force } | Should -Not -Throw
-
- }
- { Get-CredentialStore } | Should -Not -Throw
- }
- It "Test2: Read Credential Store with testing data" {
- { Use-CSCertificate -Shared -CredentialStore $TestCredentialStore -Path $TestPfxCert } | Should -Not -Throw
- { Get-CredentialStore -Shared -Path $TestCredentialStore } | Should -Not -Throw
- }
- It "Test3: Not existing path should return false" {
- { Get-CredentialStore -Shared -Path './CredentialStore.json' } | Should -Throw "Could not find the CredentialStore."
- }
- }
- Context "Testing invalid json data" {
- #Mock Test-CredentialStore {return $true}
- #Mock Get-Content {return '"foo":"bar",'}
- $BrokenCS = Join-Path -Path $RepoRoot -ChildPath 'resources/cs/Broken_CS.json'
- Write-Verbose -Message ('BrokenCS Path: {0}' -f $BrokenCS) -Verbose
- It "Should throw with invalid CredentialStore" {
- { Get-CredentialStore -Path -Shared $BrokenCS } | Should -Throw
- }
- }
-}
diff --git a/tools/AppVeyor.psm1 b/tools/AppVeyor.psm1
deleted file mode 100644
index 3ea9c45..0000000
--- a/tools/AppVeyor.psm1
+++ /dev/null
@@ -1,249 +0,0 @@
-<#
- Define the callsign of you PowerShell Module.
- Callsign is used to identity:
- - Module Manifest file name
- - Artifact File
- - Git repository name
- - Module name
-#>
-$CALLSIGN = 'PSCredentialStore'
-Write-Host ("Callsign is: {0}" -f $CALLSIGN) -ForegroundColor Black -BackgroundColor Yellow
-
-
-Function Invoke-InstallDependencies() {
- [CmdletBinding()]
- Param()
-
- Process {
- Try {
- Write-Host 'Available PS modules are:' -ForegroundColor Green -BackgroundColor Black
- Get-Module -ListAvailable -Name Pester | Format-Table | Out-String
- Get-PackageProvider -ListAvailable
- Install-PackageProvider -Name NuGet -RequiredVersion '2.8.5.208' -Force -Verbose
- Import-PackageProvider -Name NuGet -RequiredVersion '2.8.5.208' -Force
- Write-Host 'Installing build deps...' -ForegroundColor Red -BackgroundColor Black
- Install-Module -Name 'Pester' -Scope CurrentUser -RequiredVersion '4.10.1' -Force -SkipPublisherCheck -AllowClobber -Verbose
- Install-Module -Name 'posh-git' -Scope CurrentUser -RequiredVersion '0.7.3' -Force -SkipPublisherCheck -AllowClobber
- Install-Module -Name 'PSCoverage' -Scope CurrentUser -Force -SkipPublisherCheck -AllowClobber -RequiredVersion '1.2.108' -Verbose
- Import-Module -Name 'posh-git'
- Remove-Module -Name 'Pester' -Force -ErrorAction SilentlyContinue
- Import-Module -Name 'Pester' -RequiredVersion '4.10.1' -Verbose -Force
- Import-Module -Name 'PSCoverage' -RequiredVersion '1.2.108' -Verbose -Force
- }
- Catch {
- $MsgParams = @{
- Message = 'Could not install the required dependencies!'
- Category = 'Error'
- Details = $_.Exception.Message
- }
- Add-AppveyorMessage @MsgParams
- Throw $MsgParams.Message
- }
- Write-Host 'Loaded PS modules are:' -ForegroundColor Green -BackgroundColor Black
- Get-Module -Name Pester | Format-Table | Out-String
- }
-}
-Function Invoke-AppVeyorBumpVersion() {
- [CmdletBinding()]
- Param()
-
- Write-Host "Listing Env Vars for debugging:" -ForegroundColor Black -BackgroundColor Yellow
- # Filter Results to prevent exposing secure vars.
- Get-ChildItem -Path "Env:*" | Where-Object { $_.name -notmatch "(NuGetToken|CoverallsToken|CodeCovToken)" } | Sort-Object -Property Name | Format-Table
-
- Try {
- $ModManifest = Get-Content -Path (".\src\{0}.psd1" -f $CALLSIGN)
- $BumpedManifest = $ModManifest -replace '0.0.9999', $Env:APPVEYOR_BUILD_VERSION
- Remove-Item -Path (".\src\{0}.psd1" -f $CALLSIGN)
- Out-File -FilePath (".\src\{0}.psd1" -f $CALLSIGN) -InputObject $BumpedManifest -NoClobber -Encoding utf8 -Force
- }
- Catch {
- $MsgParams = @{
- Message = 'Could not bump current version into module manifest.'
- Category = 'Error'
- Details = $_.Exception.Message
- }
- Add-AppveyorMessage @MsgParams
- Throw $MsgParams.Message
- }
-}
-
-Function Invoke-AppVeyorBuild() {
- [CmdletBinding()]
- [OutputType([PsCustomObject])]
- Param()
- $MsgParams = @{
- Message = 'Creating build artifacts'
- Category = 'Information'
- Details = 'Extracting source files and compressing them into zip file.'
- }
- Add-AppveyorMessage @MsgParams
- $CompParams = @{
- Path = "{0}\src\*" -f $env:APPVEYOR_BUILD_FOLDER
- DestinationPath = "{0}\bin\{1}.zip" -f $env:APPVEYOR_BUILD_FOLDER, $CALLSIGN
- Update = $True
- Verbose = $True
- }
- Compress-Archive @CompParams
- $MsgParams = @{
- Message = 'Pushing artifacts'
- Category = 'Information'
- Details = 'Pushing artifacts to AppVeyor store.'
- }
- Add-AppveyorMessage @MsgParams
- $ArtifactPath = Join-Path -Path '.' -ChildPath ('bin/{0}.zip' -f $CALLSIGN)
- Push-AppveyorArtifact $ArtifactPath
-}
-
-Function Invoke-AppVeyorTests() {
- [CmdletBinding()]
- Param()
-
- $MsgParams = @{
- Message = 'Starting Pester tests'
- Category = 'Information'
- Details = 'Now running all test found in .\tests\ dir.'
- }
- Add-AppveyorMessage @MsgParams
-
- try {
- Write-Host '===== Preload internal private functions =====' -ForegroundColor Black -BackgroundColor Yellow
-
- $Privates = Get-ChildItem -Path (Join-Path -Path $Env:APPVEYOR_BUILD_FOLDER -ChildPath '/src/Private/*') -Include "*.ps1" -Recurse
- foreach ($File in $Privates) {
- if (Test-Path -Path $File.FullName) {
- . $File.FullName
- Write-Verbose -Message ('Private function dot-sourced: {0}' -f $File.FullName) -Verbose
- }
- else {
- Write-Warning -Message ('Could not find file: {0} !' -f $File.FullName)
- }
- }
- Write-Host '===== Preload done. =====' -ForegroundColor Black -BackgroundColor Yellow
- }
- catch {
- $_.Exception.Message | Write-Error
- throw 'Could not load required private functions!'
- }
-
- #$testresults = Invoke-Pester -Path ( Get-ChildItem -Path ".\tests\*.Tests.ps1" -Recurse | Sort-Object -Property Name ) -ExcludeTag 'Disabled' -PassThru
- $srcFiles = Get-ChildItem -Path ".\src\*.ps1" -Recurse | Sort-Object -Property 'Name' | Select-Object -ExpandProperty 'FullName'
- $testFiles = Get-ChildItem -Path ".\tests\*.Tests.ps1" -Recurse | Sort-Object -Property 'Name' | Select-Object -ExpandProperty 'FullName'
- $TestResults = Invoke-Pester -Path $testFiles -CodeCoverage $srcFiles -PassThru -CodeCoverageOutputFile ".\coverage.xml" -CodeCoverageOutputFileEncoding ascii -CodeCoverageOutputFileFormat JaCoCo
- ForEach ($Item in $TestResults.TestResult) {
- Switch ($Item.Result) {
- "Passed" {
- $TestParams = @{
- Name = "{0}: {1}" -f $Item.Context, $Item.Name
- Framework = "NUnit"
- Filename = $Item.Describe
- Outcome = "Passed"
- Duration = $Item.Time.Milliseconds
- }
- Add-AppveyorTest @TestParams
- }
- "Failed" {
- $TestParams = @{
- Name = "{0}: {1}" -f $Item.Context, $Item.Name
- Framework = "NUnit"
- Filename = $Item.Describe
- Outcome = "Failed"
- Duration = $Item.Time.Milliseconds
- ErrorMessage = $Item.FailureMessage
- ErrorStackTrace = $Item.StackTrace
- }
- Add-AppveyorTest @TestParams
- }
- Default {
- $TestParams = @{
- Name = "{0}: {1}" -f $Item.Context, $Item.Name
- Framework = "NUnit"
- Filename = $Item.Describe
- Outcome = "None"
- Duration = $Item.Time.Milliseconds
- ErrorMessage = $Item.FailureMessage
- ErrorStackTrace = $Item.StackTrace
- }
- Add-AppveyorTest @TestParams
- }
- }
- }
- If ($TestResults.FailedCount -gt 0) {
- $MsgParams = @{
- Message = 'Pester Tests failed.'
- Category = 'Error'
- Details = "$($TestResults.FailedCount) tests failed."
- }
- Add-AppveyorMessage @MsgParams
- Throw $MsgParams.Message
- }
-
- return $TestResults.CodeCoverage
-
-}
-
-Function Invoke-CoverageReport() {
- [CmdletBinding()]
- Param(
- [Parameter(Mandatory = $False)]
- [ValidateNotNullOrEmpty()]
- [String]$RepoToken = $Env:CoverallsToken,
-
- [Parameter(Mandatory = $True)]
- [ValidateNotNullOrEmpty()]
- [PSCustomObject]$PesterCoverageReport
- )
-
- #$CoverageReport | Format-Custom -Depth 5 | Out-String | Write-Verbose
- $CoverageReport = New-CoverageReport -CodeCoverage $PesterCoverageReport -RepoToken $RepoToken
- Write-Host "CoverageReport JSON:" -ForegroundColor Yellow
- #$CoverageReport | ConvertTo-Json -Depth 5 | Out-String | Write-Verbose
- Publish-CoverageReport -CoverageReport $CoverageReport
-}
-
-
-Function Invoke-AppVeyorPSGallery() {
- [CmdletBinding()]
- Param(
- [Parameter(Mandatory = $true)]
- [ValidateNotNullOrEmpty()]
- [String]$OnBranch
- )
- Expand-Archive -Path (".\bin\{0}.zip" -f $CALLSIGN) -DestinationPath ("C:\Users\appveyor\Documents\WindowsPowerShell\Modules\{0}\" -f $CALLSIGN) -Verbose
- Import-Module -Name $CALLSIGN -Verbose -Force
- Write-Host "Available Package Provider:" -ForegroundColor Black -BackgroundColor Yellow
- Get-PackageProvider -ListAvailable
- Write-Host "Available Package Sources:" -ForegroundColor Black -BackgroundColor Yellow
- Get-PackageSource
- Try {
- Write-Host "Try to get NuGet Provider:" -ForegroundColor Black -BackgroundColor Yellow
- Get-PackageProvider -Name NuGet -ErrorAction Stop
- }
- Catch {
- Write-Host "Installing NuGet..." -ForegroundColor Black -BackgroundColor Yellow
- Install-PackageProvider -Name NuGet -MinimumVersion '2.8.5.201' -Force -Verbose
- Import-PackageProvider NuGet -MinimumVersion '2.8.5.201' -Force
- }
- Try {
- If ($env:APPVEYOR_REPO_BRANCH -eq 'master') {
- Write-Host "try to publish module" -ForegroundColor Black -BackgroundColor Yellow
- Write-Host ("Callsign is: {0}" -f $CALLSIGN) -ForegroundColor Black -BackgroundColor Yellow
- Publish-Module -Name $CALLSIGN -NuGetApiKey $env:NuGetToken -Verbose -Force -AllowPrerelease
- }
- Else {
- Write-Host "Skip publishing to PS Gallery because we are on $($env:APPVEYOR_REPO_BRANCH) branch." -ForegroundColor Black -BackgroundColor Yellow
- # had to remove the publish-Module statement because it would publish although the -WhatIf is given.
- # Publish-Module -Name $CALLSIGN -NuGetApiKey $env:NuGetToken -Verbose -WhatIf
- }
- }
- Catch {
- $MsgParams = @{
- Message = 'Could not deploy module to PSGallery.'
- Category = 'Error'
- Details = $_.Exception.Message
- }
- $_.Exception.Message | Write-Error
- Add-AppveyorMessage @MsgParams
- Throw $MsgParams.Message
- }
-}
diff --git a/tools/DroneIO.psm1 b/tools/DroneIO.psm1
index f696923..6f333d6 100644
--- a/tools/DroneIO.psm1
+++ b/tools/DroneIO.psm1
@@ -1,25 +1,70 @@
$Global:ProgressPreference = 'SilentlyContinue'
+$ErrorActionPreference = 'Stop'
-function Invoke-ShowEnv() {
+function Invoke-ShowEnv {
[CmdletBinding()]
- param()
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
+ 'PSProvideCommentHelp',
+ '',
+ Justification = 'internal function'
+ )]
+ param ()
process {
Get-ChildItem -Path 'Env:' | Format-Table | Out-String
}
}
-function Invoke-InstallDependencies() {
+function Invoke-InstallDependencies {
[CmdletBinding()]
- [OutputType()]
- param()
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
+ 'PSProvideCommentHelp',
+ '',
+ Justification = 'internal function'
+ )]
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
+ 'PSUseSingularNouns',
+ '',
+ Justification = 'internal function'
+ )]
+ param ()
process {
+ $ErrorActionPreference = 'Stop'
try {
- Install-Module -Name 'PSScriptAnalyzer' -Scope CurrentUser -RequiredVersion '1.19.1' -Force -SkipPublisherCheck -AllowClobber -Verbose:$VerbosePreference -ErrorAction 'Stop'
- Install-Module -Name 'Pester' -Scope CurrentUser -RequiredVersion '4.10.1' -Force -SkipPublisherCheck -AllowClobber -Verbose:$VerbosePreference -ErrorAction 'Stop'
- Install-Module -Name 'posh-git' -Scope CurrentUser -RequiredVersion '0.7.3' -Force -SkipPublisherCheck -AllowClobber -Verbose:$VerbosePreference -ErrorAction 'Stop'
- Install-Module -Name 'PSCoverage' -Scope CurrentUser -Force -SkipPublisherCheck -AllowClobber -RequiredVersion '1.2.108' -Verbose:$VerbosePreference -ErrorAction 'Stop'
+ $ParamsPSScript = @{
+ Name = 'PSScriptAnalyzer'
+ Scope = 'CurrentUser'
+ RequiredVersion = '1.20.0'
+ Force = $true
+ SkipPublisherCheck = $true
+ AllowClobber = $true
+ Verbose = $VerbosePreference
+ }
+ Install-Module @ParamsPSScript
+
+ $ParamsPester = @{
+ Name = 'Pester'
+ Scope = 'CurrentUser'
+ RequiredVersion = '5.3.3'
+ Force = $true
+ SkipPublisherCheck = $true
+ AllowClobber = $true
+ Verbose = $VerbosePreference
+ }
+ Install-Module @ParamsPester
+
+ $ParamsPosh = @{
+ Name = 'posh-git'
+ Scope = 'CurrentUser'
+ RequiredVersion = '1.1.0'
+ Force = $true
+ SkipPublisherCheck = $true
+ AllowClobber = $true
+ Verbose = $VerbosePreference
+ #ErrorAction = 'Stop'
+ }
+ Install-Module @ParamsPosh
}
catch {
$ExceParams = @{
@@ -35,47 +80,171 @@ function Invoke-InstallDependencies() {
}
}
-function Invoke-Linter () {
+
+function Start-PSScriptAnalyzer {
[CmdletBinding()]
- param()
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
+ 'PSUseShouldProcessForStateChangingFunctions',
+ '',
+ Justification = 'justification'
+ )]
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
+ 'PSProvideCommentHelp',
+ '',
+ Justification = 'internal function'
+ )]
+ param ()
process {
- Invoke-ScriptAnalyzer -Path './src/' -Recurse
+ $AnalyzerSettings = @{
+ Path = './src/'
+ Recurse = $true
+ Settings = './tools/PSScriptAnalyzerSettings.psd1'
+ ReportSummary = $true
+ ErrorAction = 'Stop'
+ }
+ $AnalyzerResults = Invoke-ScriptAnalyzer @AnalyzerSettings
+ if ( $AnalyzerResults ) {
+ Write-Output -InputObject $AnalyzerResults
+ }
}
}
-
-function Invoke-UnitTests {
+function Invoke-Linter {
[CmdletBinding()]
- Param()
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
+ 'PSProvideCommentHelp',
+ '',
+ Justification = 'internal function'
+ )]
+ param ()
process {
-
try {
- Write-Host '===== Preload internal private functions =====' -ForegroundColor Black -BackgroundColor Yellow
-
- $Privates = Get-ChildItem -Path (Join-Path -Path $Env:DRONE_WORKSPACE -ChildPath '/src/Private/*') -Include "*.ps1" -Recurse -ErrorAction Stop
- foreach ($File in $Privates) {
- if (Test-Path -Path $File.FullName) {
- . $File.FullName
- Write-Verbose -Message ('Private function dot-sourced: {0}' -f $File.FullName) -Verbose
- }
- else {
- Write-Warning -Message ('Could not find file: {0} !' -f $File.FullName)
- }
- }
+ $AnalyzerResults = Start-PSScriptAnalyzer
}
catch {
- $_.Exception.Message | Write-Error
- throw 'Could not load required private functions!'
+ Write-Debug -Message $_.Exception.Message -Debug
+ if ($_.Exception.Message -match 'Object reference not set') {
+ Write-Debug -Message 'ReRun PSScriptAnalyzer' -Debug
+ $AnalyzerResults = Start-PSScriptAnalyzer
+ }
+ else {
+ Write-Error -Message 'PSScriptAnalyzer failer'
+ }
+ }
+ finally {
+ if ( $AnalyzerResults ) {
+ $AnalyzerResults | Sort-Object -Property @(
+ "ScriptName",
+ "Line"
+ ) | Format-Table @(
+ "Severity",
+ "ScriptName",
+ "Line",
+ "RuleName",
+ "Message"
+ ) -AutoSize | Out-String | Write-Verbose -Verbose
+ Update-BuildStateFile
+ throw 'PS Script Analyzer failed!'
+ }
}
+ }
+}
+
+function Invoke-UnitTest {
+ [CmdletBinding()]
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
+ 'PSProvideCommentHelp',
+ '',
+ Justification = 'internal function'
+ )]
+
+ param (
+ [Parameter( Mandatory = $false )]
+ [ValidateSet('JaCoCo', 'CoverageGutters')]
+ [string]$CoverageFormat = 'JaCoCo',
+
+ [Parameter(Mandatory = $false)]
+ [ValidateSet('None', 'Normal', 'Detailed', 'Diagnostic')]
+ [string]$Verbosity = 'Normal',
+
+ [Parameter(Mandatory = $false)]
+ [switch]$PassThru,
+
+ [Parameter(Mandatory = $false)]
+ [ValidateNotNullOrEmpty()]
+ [string[]]$Tag,
- Write-Host '===== Running Pester =====' -ForegroundColor Black -BackgroundColor Yellow
- $srcFiles = Get-ChildItem -Path "./src/*.ps1" -Recurse | Sort-Object -Property 'Name' | Select-Object -ExpandProperty 'FullName'
- $TestFiles = Get-ChildItem -Path (Join-Path -Path '.' -ChildPath './tests/*.Tests.ps1') -Recurse | Sort-Object -Property Name
- $TestResults = Invoke-Pester -Path $testFiles -CodeCoverage $srcFiles -PassThru -CodeCoverageOutputFile "./coverage.xml" -CodeCoverageOutputFileEncoding ascii -CodeCoverageOutputFileFormat JaCoCo
+ [Parameter(Mandatory = $false)]
+ [ValidateNotNullOrEmpty()]
+ [string[]]$ExcludeTag
+ )
+
+ process {
+ Write-Verbose -Message '===== Running Pester =====' -Verbose:$VerbosePreference
+ $PesterConf = New-PesterConfiguration
+ $PesterConf.Run.Path = (Resolve-Path -Path './src').Path
+ $PesterConf.Run.Exit = $false
+ $PesterConf.Run.PassThru = $true
+ $PesterConf.CodeCoverage.Enabled = $true
+ $PesterConf.CodeCoverage.OutputFormat = $CoverageFormat
+ $PesterConf.TestResult.Enabled = $true
+ $CovFiles = Get-ChildItem -Path "./src/*.ps1" -Recurse | Where-Object {
+ $_.BaseName -notmatch '.Tests'
+ } | Select-Object -ExpandProperty 'FullName'
+ $PesterConf.CodeCoverage.Path = $CovFiles
+ $PesterConf.Output.Verbosity = $Verbosity
+ # Set Tags if given
+ if ($Tag) {
+ $PesterConf.Filter.Tag = $Tag
+ }
+ if ($ExcludeTag) {
+ $PesterConf.Filter.ExcludeTag = $ExcludeTag
+ }
+ $TestResults = Invoke-Pester -Configuration $PesterConf -ErrorAction 'Stop'
if ($TestResults.FailedCount -gt 0) {
+ Update-BuildStateFile
throw ('{0} tests failed!' -f $TestResults.FailedCount)
}
+
+ if ($PassThru.IsPresent) {
+ Write-Output -InputObject $TestResults
+ }
+ }
+}
+
+function Update-BuildStateFile {
+ [CmdletBinding()]
+ param (
+ [Parameter(Mandatory = $false)]
+ [ValidateNotNullOrEmpty()]
+ [string]$StepName = $Env:DRONE_FAILED_STEPS
+ )
+
+ process {
+ $StateFilePath = Join-Path -Path $PWD -ChildPath './STATE.xml'
+ if (Test-Path -Path $StateFilePath) {
+ $StateContent = Import-Clixml -Path $StateFilePath
+ $StateContent.Steps += $StepName
+ }
+ else {
+ $StateContent = [PSCustomObject]@{
+ Steps = @($StepName)
+ }
+ }
+ Export-Clixml -Path $StateFilePath -InputObject $StateContent -Force -Encoding utf8NoBOM
+ }
+}
+
+function Invoke-BuildState {
+ [CmdletBinding()]
+ param ()
+
+ process {
+ $StateFilePath = Join-Path -Path $PWD -ChildPath './STATE.xml'
+ if ( Test-Path -Path $StateFilePath ) {
+ throw 'One one more pipeline steps failed. Marking the pipeline as failed!'
+ }
}
}
diff --git a/tools/PSScriptAnalyzerSettings.psd1 b/tools/PSScriptAnalyzerSettings.psd1
new file mode 100644
index 0000000..8ba8ac8
--- /dev/null
+++ b/tools/PSScriptAnalyzerSettings.psd1
@@ -0,0 +1,141 @@
+@{
+ Severity = 'Error', 'Warning', 'Information'
+
+ IncludeRules = @(
+ 'PSAlignAssignmentStatement',
+ 'PSAvoidAssignmentToAutomaticVariable',
+ 'PSAvoidDefaultValueForMandatoryParameter',
+ 'PSAvoidDefaultValueSwitchParameter',
+ 'PSAvoidGlobalAliases',
+ 'PSAvoidGlobalFunctions',
+ 'PSAvoidGlobalVars',
+ 'PSAvoidInvokingEmptyMembers',
+ 'PSAvoidLongLines',
+ 'PSAvoidNullOrEmptyHelpMessageAttribute',
+ 'PSAvoidOverwritingBuiltInCmdlets',
+ 'PSAvoidShouldContinueWithoutForce',
+ 'PSAvoidTrailingWhitespace',
+ 'PSAvoidUsingCmdletAliases',
+ 'PSAvoidUsingComputerNameHardcoded',
+ 'PSAvoidUsingConvertToSecureStringWithPlainText',
+ 'PSAvoidUsingDeprecatedManifestFields',
+ 'PSAvoidUsingDoubleQuotesForConstantString',
+ 'PSAvoidUsingEmptyCatchBlock',
+ 'PSAvoidUsingInvokeExpression',
+ 'PSAvoidUsingPlainTextForPassword',
+ 'PSAvoidUsingPositionalParameters',
+ 'PSAvoidUsingUsernameAndPasswordParams',
+ 'PSAvoidUsingWMICmdlet',
+ 'PSAvoidUsingWriteHost',
+ 'PSMisleadingBacktick',
+ 'PSMissingModuleManifestField',
+ 'PSPlaceCloseBrace',
+ 'PSPlaceOpenBrace',
+ 'PSPossibleIncorrectComparisonWithNull',
+ 'PSPossibleIncorrectUsageOfAssignmentOperator',
+ 'PSPossibleIncorrectUsageOfRedirectionOperator',
+ 'PSProvideCommentHelp',
+ 'PSReservedCmdletChar',
+ 'PSReservedParams',
+ 'PSReviewUnusedParameter',
+ 'PSShouldProcess',
+ 'PSUseApprovedVerbs',
+ 'PSUseBOMForUnicodeEncodedFile',
+ 'PSUseCmdletCorrectly',
+ # There is no predefined set for Pwsh7 Cmdlets
+ 'PSUseCompatibleCmdlets',
+ #'PSUseCompatibleCommands',
+ 'PSUseCompatibleSyntax',
+ #'PSUseCompatibleTypes',
+ 'PSUseConsistentIndentation',
+ # Disable if bug in 1.19.1 version occurs.
+ 'PSUseConsistentWhitespace',
+ 'PSUseCorrectCasing',
+ 'PSUseDeclaredVarsMoreThanAssignments',
+ 'PSUseLiteralInitializerForHashtable',
+ 'PSUseOutputTypeCorrectly',
+ 'PSUsePSCredentialType',
+ 'PSUseProcessBlockForPipelineCommand',
+ 'PSUseShouldProcessForStateChangingFunctions',
+ 'PSUseSingularNouns',
+ 'PSUseSupportsShouldProcess',
+ 'PSUseToExportFieldsInManifest',
+ 'PSUseUTF8EncodingForHelpFile',
+ 'PSUseUsingScopeModifierInNewRunspaces'
+ )
+
+ Rules = @{
+
+ PSAvoidLongLines = @{
+ Enable = $true
+ MaximumLineLength = 116
+ }
+
+ PSPlaceOpenBrace = @{
+ Enable = $true
+ OnSameLine = $true
+ NewLineAfter = $true
+ IgnoreOneLineBlock = $true
+ }
+
+ PSPlaceCloseBrace = @{
+ Enable = $true
+ NewLineAfter = $true
+ IgnoreOneLineBlock = $true
+ NoEmptyLineBefore = $false
+ }
+
+ PSProvideCommentHelp = @{
+ Enable = $true
+ ExportedOnly = $false
+ BlockComment = $true
+ VSCodeSnippetCorrection = $false
+ Placement = "begin"
+ }
+
+ PSUseCompatibleCmdlets = @{
+ compatibility = @(
+ "desktop-5.1.14393.206-windows",
+ "core-6.1.0-windows"
+ )
+ }
+
+ PSUseCompatibleSyntax = @{
+ Enable = $true
+ TargetVersions = @(
+ "7.0",
+ "5.1"
+ )
+ }
+
+ PSUseConsistentIndentation = @{
+ Enable = $true
+ Kind = 'space'
+ PipelineIndentation = 'IncreaseIndentationForFirstPipeline'
+ IndentationSize = 4
+ }
+
+ PSUseConsistentWhitespace = @{
+ Enable = $true
+ CheckInnerBrace = $true
+ CheckOpenBrace = $true
+ CheckOpenParen = $true
+ CheckOperator = $true
+ CheckPipe = $true
+ CheckPipeForRedundantWhitespace = $false
+ CheckSeparator = $true
+ CheckParameter = $false
+ IgnoreAssignmentOperatorInsideHashTable = $true
+ }
+
+ PSAlignAssignmentStatement = @{
+ Enable = $true
+ CheckHashtable = $false
+ }
+
+ PSUseCorrectCasing = @{
+ Enable = $true
+ }
+ }
+
+}
diff --git a/tools/Travis.psm1 b/tools/Travis.psm1
deleted file mode 100644
index d4a37f6..0000000
--- a/tools/Travis.psm1
+++ /dev/null
@@ -1,66 +0,0 @@
-$Global:ProgressPreference = 'SilentlyContinue'
-
-$CALLSIGN = 'PSCredentialStore'
-Write-Host ("Callsign is: {0}" -f $CALLSIGN) -ForegroundColor Black -BackgroundColor Yellow
-
-function Invoke-InstallDependencies {
- [CmdletBinding()]
- Param()
-
- process {
- try {
- Write-Host '===== Environment Vars: =====' -ForegroundColor Black -BackgroundColor Yellow
- Get-ChildItem -Path Env:
-
- Write-Host -Message '===== Existing Variables: =====' -ForegroundColor Black -BackgroundColor Yellow
- Get-Variable -Name * | Format-Table -AutoSize
-
- Get-PackageProvider -ListAvailable
- Import-PackageProvider -Name 'NuGet' -MinimumVersion '2.8.5.208' -Verbose -Force
-
- Install-Module -Name 'Pester' -Scope CurrentUser -RequiredVersion '4.4.2' -Force -SkipPublisherCheck -AllowClobber -Verbose
- Install-Module -Name 'posh-git' -Scope CurrentUser -RequiredVersion '1.0.0-beta2' -Force -SkipPublisherCheck -AllowClobber -AllowPrerelease -Verbose
-
- Import-Module -Name 'Pester', 'posh-git' -Verbose
- }
- catch {
- $_.Exception.Message | Write-Error
- throw 'Could not install the required dependencies!'
- }
- }
-}
-
-function Invoke-UnitTests {
- [CmdletBinding()]
- Param()
-
- process {
-
- try {
- Write-Host '===== Preload internal private functions =====' -ForegroundColor Black -BackgroundColor Yellow
-
- $Privates = Get-ChildItem -Path (Join-Path -Path $Env:TRAVIS_BUILD_DIR -ChildPath '/src/Private/*') -Include "*.ps1" -Recurse -ErrorAction Stop
- foreach ($File in $Privates) {
- if (Test-Path -Path $File.FullName) {
- . $File.FullName
- Write-Verbose -Message ('Private function dot-sourced: {0}' -f $File.FullName) -Verbose
- }
- else {
- Write-Warning -Message ('Could not find file: {0} !' -f $File.FullName)
- }
- }
- }
- catch {
- $_.Exception.Message | Write-Error
- throw 'Could not load required private functions!'
- }
-
- Write-Host '===== Running Pester =====' -ForegroundColor Black -BackgroundColor Yellow
- $TestFiles = Get-ChildItem -Path (Join-Path -Path '.' -ChildPath './tests/*.Tests.ps1') -Recurse| Sort-Object -Property Name
- $TestResults = Invoke-Pester -Script $TestFiles -ExcludeTag 'Disabled' -PassThru
-
- if ($TestResults.FailedCount -gt 0) {
- throw ('{0} tests failed!' -f $TestResults.FailedCount)
- }
- }
-}
diff --git a/tools/travis.sh b/tools/travis.sh
deleted file mode 100644
index 029896a..0000000
--- a/tools/travis.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-set -x
-ulimit -n 4096
-
-echo "TRAVIS_EVENT_TYPE value $TRAVIS_EVENT_TYPE"
-
-if [ $TRAVIS_EVENT_TYPE = cron ] || [ $TRAVIS_EVENT_TYPE = api ]; then
- sudo pwsh -NoProfile -NonInteractive -c "Import-Module ./tools/Travis.psm1;
- Invoke-InstallDependencies;
- Invoke-UnitTests;"
-else
- sudo pwsh -NoProfile -NonInteractive -c "Import-Module ./tools/Travis.psm1;
- Invoke-InstallDependencies;
- Invoke-UnitTests;"
-fi