From b3342d4ebbf614bf3f984ee7ebffa0cf2bf89391 Mon Sep 17 00:00:00 2001 From: OCram85 Date: Wed, 15 Jun 2022 10:50:22 +0200 Subject: [PATCH] wip --- .editorconfig | 31 ++++++ .gitattributes | 26 ++++- .gitignore | 21 +++- .vscode/cSpell.json | 62 ++++------- .vscode/dictionaries/default.txt | 0 .vscode/extensions.json | 13 +++ .vscode/launch.json | 2 +- .vscode/pwsh.code-snippets | 31 ++++++ .vscode/settings.json | 103 +++++++++--------- .vscode/tasks.json | 151 ++++++++++++++++++-------- src/Certificate/Get-CSCertificate.ps1 | 2 +- src/PSModule.Tests.ps1 | 14 +++ tools/DroneIO.psm1 | 104 +++++++++++++----- tools/PSScriptAnalyzerSettings.psd1 | 141 ++++++++++++++++++++++++ 14 files changed, 533 insertions(+), 168 deletions(-) create mode 100644 .editorconfig create mode 100644 .vscode/dictionaries/default.txt create mode 100644 .vscode/extensions.json create mode 100644 .vscode/pwsh.code-snippets create mode 100644 src/PSModule.Tests.ps1 create mode 100644 tools/PSScriptAnalyzerSettings.psd1 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/.gitignore b/.gitignore index 45b36c1..18af3f7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,18 @@ -# 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 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/.vscode/dictionaries/default.txt b/.vscode/dictionaries/default.txt new file mode 100644 index 0000000..e69de29 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..e781fe6 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 'Debug'" ], - "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/src/Certificate/Get-CSCertificate.ps1 b/src/Certificate/Get-CSCertificate.ps1 index 1898234..7db89f1 100644 --- a/src/Certificate/Get-CSCertificate.ps1 +++ b/src/Certificate/Get-CSCertificate.ps1 @@ -21,7 +21,7 @@ function Get-CSCertificate { .EXAMPLE Get-CSCertificate -Type 'Shared' -Thumbprint '12334456' #> - + [CmdletBinding()] [OutputType([System.Security.Cryptography.X509Certificates.X509Certificate2])] param ( diff --git a/src/PSModule.Tests.ps1 b/src/PSModule.Tests.ps1 new file mode 100644 index 0000000..2338087 --- /dev/null +++ b/src/PSModule.Tests.ps1 @@ -0,0 +1,14 @@ +Describe 'Test module meta' { + 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 + } + # Dummy test to force pester error + #It 'Force Pester Error' { + # $true | Should -BeFalse + #} +} diff --git a/tools/DroneIO.psm1 b/tools/DroneIO.psm1 index 799a23d..1428b12 100644 --- a/tools/DroneIO.psm1 +++ b/tools/DroneIO.psm1 @@ -1,7 +1,13 @@ $Global:ProgressPreference = 'SilentlyContinue' +$ErrorActionPreference = 'Stop' function Invoke-ShowEnv { [CmdletBinding()] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSProvideCommentHelp', + '', + Justification = 'internal function' + )] param () process { @@ -11,6 +17,16 @@ function Invoke-ShowEnv { function Invoke-InstallDependencies { [CmdletBinding()] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSProvideCommentHelp', + '', + Justification = 'internal function' + )] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSUseSingularNouns', + '', + Justification = 'internal function' + )] param () process { @@ -36,44 +52,78 @@ function Invoke-InstallDependencies { function Invoke-Linter { [CmdletBinding()] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSProvideCommentHelp', + '', + Justification = 'internal function' + )] param () process { - Invoke-ScriptAnalyzer -Path './src/' -Recurse + Import-Module -Name PSScriptAnalyzer + $AnalyzerSettings = @{ + Path = './src/' + Recurse = $true + Settings = './tools/PSScriptAnalyzerSettings.psd1' + ReportSummary = $true + } + Invoke-ScriptAnalyzer @AnalyzerSettings } } -function Invoke-UnitTests { +function Invoke-UnitTest { [CmdletBinding()] - param () + [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, + + [Parameter(Mandatory = $false)] + [ValidateNotNullOrEmpty()] + [string[]]$ExcludeTag + ) 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) - } - } + 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 } - catch { - $_.Exception.Message | Write-Error - throw 'Could not load required private functions!' + if ($ExcludeTag) { + $PesterConf.Filter.ExcludeTag = $ExcludeTag } - - 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 - - if ($TestResults.FailedCount -gt 0) { - throw ('{0} tests failed!' -f $TestResults.FailedCount) + $TestResults = Invoke-Pester -Configuration $PesterConf -ErrorAction 'Stop' + if ($PassThru.IsPresent) { + Write-Output -InputObject $TestResults } } } 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 + } + } + +}