diff --git a/.azure-pipelines-ci/ci.yaml b/.azure-pipelines-ci/ci.yaml deleted file mode 100644 index 956139389..000000000 --- a/.azure-pipelines-ci/ci.yaml +++ /dev/null @@ -1,51 +0,0 @@ -variables: - # Avoid expensive initialization of dotnet cli, see: https://donovanbrown.com/post/Stop-wasting-time-during-NET-Core-builds - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 - -stages: - - stage: Build - jobs: - - job: 'Full_Build' - pool: - vmImage: windows-latest - steps: - - pwsh: | - Import-Module .\tools\appveyor.psm1 - Invoke-AppveyorInstall -SkipPesterInstallation - ./build.ps1 -Configuration 'Release' -All - ./PSCompatibilityCollector/build.ps1 -Configuration 'Release' - displayName: 'Full Build' - - pwsh: | - Write-Host "##vso[artifact.upload containerfolder=out;artifactname=out;]${env:Build_SourcesDirectory}/out" - - stage: Test - jobs: - - job: - strategy: - matrix: - Ubuntu_20_04: - vmImage: ubuntu-20.04 - Ubuntu_22_04: - vmImage: ubuntu-22.04 - mac_Latest: - vmImage: macOS-latest - Windows_Server2019_PowerShell_Core: - vmImage: windows-2019 - Windows_Server2022_PowerShell_Core: - vmImage: windows-2022 - pool: - vmImage: $[ variables['vmImage'] ] - steps: - - template: templates/test-pwsh.yaml - - job: - strategy: - matrix: - Windows_Server2019_PowerShell_5_1: - vmImage: windows-2019 - pwsh: false - Windows_Server2022_PowerShell_5_1: - vmImage: windows-2022 - pwsh: false - pool: - vmImage: $[ variables['vmImage'] ] - steps: - - template: templates/test-powershell.yaml diff --git a/.azure-pipelines-ci/templates/test-powershell.yaml b/.azure-pipelines-ci/templates/test-powershell.yaml deleted file mode 100644 index de3f30b68..000000000 --- a/.azure-pipelines-ci/templates/test-powershell.yaml +++ /dev/null @@ -1,20 +0,0 @@ -steps: -- task: DownloadPipelineArtifact@2 - displayName: 'Download Pipeline Artifact: out Folder' - inputs: - artifactName: out - targetPath: '$(Build.SourcesDirectory)/out' -- task: PowerShell@2 - displayName: 'Test' - retryCountOnTaskFailure: 2 - inputs: - targetType: inline - pwsh: false - script: | - Import-Module .\tools\appveyor.psm1 - Invoke-AppveyorTest -CheckoutPath $env:BUILD_SOURCESDIRECTORY -- task: PublishTestResults@2 - inputs: - testRunner: NUnit - testResultsFiles: 'testResults.xml' - condition: succeededOrFailed() diff --git a/.azure-pipelines-ci/templates/test-pwsh.yaml b/.azure-pipelines-ci/templates/test-pwsh.yaml deleted file mode 100644 index 152458d6c..000000000 --- a/.azure-pipelines-ci/templates/test-pwsh.yaml +++ /dev/null @@ -1,20 +0,0 @@ -steps: -- task: DownloadPipelineArtifact@2 - displayName: 'Download Pipeline Artifact: out Folder' - inputs: - artifactName: out - targetPath: '$(Build.SourcesDirectory)/out' -- task: PowerShell@2 - displayName: 'Test' - retryCountOnTaskFailure: 2 - inputs: - targetType: inline - pwsh: true - script: | - Import-Module .\tools\appveyor.psm1 - Invoke-AppveyorTest -CheckoutPath $env:BUILD_SOURCESDIRECTORY -- task: PublishTestResults@2 - inputs: - testRunner: NUnit - testResultsFiles: 'TestResults.xml' - condition: succeededOrFailed() diff --git a/.ci/releaseBuild.yml b/.ci/releaseBuild.yml deleted file mode 100644 index 57042b77c..000000000 --- a/.ci/releaseBuild.yml +++ /dev/null @@ -1,214 +0,0 @@ -# The name of the build that will be seen in mscodehub -name: PSSA-Release-$(Build.BuildId) -# how is the build triggered -# since this is a release build, no trigger as it's a manual release -trigger: none - -pr: - branches: - include: - - master - - release* - -# variables to set in the build environment -variables: - DOTNET_CLI_TELEMETRY_OPTOUT: 1 - POWERSHELL_TELEMETRY_OPTOUT: 1 - -# since this build relies on templates, we need access to those -# This needs a service connection in the build to work -# the *name* of the service connection must be the same as the endpoint -resources: - repositories: - - repository: ComplianceRepo - type: github - endpoint: ComplianceGHRepo - name: PowerShell/compliance - # this can be any branch of your choosing - ref: master - -# the stages in this build. There are 2 -# the assumption for script analyzer is that test is done as part of -# CI so we needn't do it here -stages: -- stage: Build - displayName: Build - pool: - name: PowerShell1ES # was Package ES CodeHub Lab E - demands: - - ImageOverride -equals PSMMS2019-Secure - jobs: - - job: Build_Job - displayName: Build Microsoft.PowerShell.ScriptAnalyzer - # note the variable reference to ESRP. - # this must be created in Project -> Pipelines -> Library -> VariableGroups - # where it describes the link to the SigningServer - variables: - - group: ESRP - steps: - - checkout: self - - # the steps for building the module go here - - pwsh: | - Set-Location "$(Build.SourcesDirectory)/OSS_Microsoft_PSSA" - try { ./build.ps1 -Configuration Release -All } catch { throw $_ } - displayName: Execute build - - # these are setting vso variables which will be persisted between stages - - pwsh: | - $signSrcPath = "$(Build.SourcesDirectory)/OSS_Microsoft_PSSA/out" - # Set signing src path variable - $vstsCommandString = "vso[task.setvariable variable=signSrcPath]${signSrcPath}" - Write-Host "sending $vstsCommandString" - Write-Host "##$vstsCommandString" - - $signOutStep1 = "$(Build.SourcesDirectory)/OSS_Microsoft_PSSA/Step1" - $null = New-Item -ItemType Directory -Path $signOutStep1 - # Set signing out path variable - $vstsCommandString = "vso[task.setvariable variable=signOutStep1]${signOutStep1}" - Write-Host "sending $vstsCommandString" - Write-Host "##$vstsCommandString" - - $signOutPath = "$(Build.SourcesDirectory)/OSS_Microsoft_PSSA/signed" - $null = New-Item -ItemType Directory -Path $signOutPath - # Set signing out path variable - $vstsCommandString = "vso[task.setvariable variable=signOutPath]${signOutPath}" - Write-Host "sending $vstsCommandString" - Write-Host "##$vstsCommandString" - - # Set path variable for guardian codesign validation - $vstsCommandString = "vso[task.setvariable variable=GDN_CODESIGN_TARGETDIRECTORY]${signOutPath}" - Write-Host "sending $vstsCommandString" - Write-Host "##$vstsCommandString" - - # Get version and create a variable - $moduleData = Import-PowerShellDataFile "$(Build.SourcesDirectory)/OSS_Microsoft_PSSA/Engine/PSScriptAnalyzer.psd1" - $moduleVersion = $moduleData.ModuleVersion - $vstsCommandString = "vso[task.setvariable variable=moduleVersion]${moduleVersion}" - Write-Host "sending $vstsCommandString" - Write-Host "##$vstsCommandString" - - - displayName: Setup variables for signing - - # checkout the Compliance repository so it can be used to do the actual signing - - checkout: ComplianceRepo - - # in script analyzer, we must sign with 2 different certs - # the normal cert for MS created items and the 3rd party cert - # this the MS authored step - # Because this needs 2 certs, we do it in 2 steps. - # the first step signs the binaries and puts them in a staging directory which - # will then be used for the second step. - - template: EsrpSign.yml@ComplianceRepo - parameters: - # the folder which contains the binaries to sign - buildOutputPath: $(signSrcPath) - # the location to put the signed output - signOutputPath: $(signOutStep1) - # the certificate ID to use - certificateId: "CP-230012" - # use minimatch because we need to exclude the NewtonSoft assembly - useMinimatch: true - # the file pattern to use - newtonSoft is excluded - pattern: | - **\*.psd1 - **\*.psm1 - **\*.ps1xml - **\Microsoft*.dll - - # this is the second step of the signing. - # note that the buildOutputPath (where we get the files to sign) - # is the same as the signOutputPath in the previous step - # at the end of this step we will have all the files signed that should be - # signOutPath is the location which contains the files we will use to make the module - - template: EsrpSign.yml@ComplianceRepo - parameters: - # the folder which contains the binaries to sign - buildOutputPath: $(signOutStep1) - # the location to put the signed output - signOutputPath: $(signOutPath) - # the certificate ID to use - # we'll need to change this to the 3rd party cert id - certificateId: "CP-231522" - # use minimatch because we need to exclude the NewtonSoft assembly - useMinimatch: true - # the file pattern to use - only sign newtonsoft and pluralize - pattern: | - **/Pluralize*.dll - **/Newtonsoft*.dll - - # Create the manifest for the module - - template: Sbom.yml@ComplianceRepo - parameters: - BuildDropPath: $(signOutPath) - Build_Repository_Uri: 'https://github.com/powershell/PSScriptAnalyzer' - - # now create the nupkg which we will use to publish the module - # to the powershell gallery (not part of this yaml) - - pwsh: | - Set-Location "$(Build.SourcesDirectory)/OSS_Microsoft_PSSA" - ./build -BuildNupkg -CopyManifest -signed - displayName: Create nupkg for publishing - - # finally publish the parts of the build which will be used in the next stages - # if it's not published, the subsequent stages will not be able to access it. - # This is the build directory (it contains all of the dll/pdb files) - - publish: "$(Build.SourcesDirectory)/OSS_Microsoft_PSSA" - artifact: build - displayName: publish build directory - - # export the nupkg only which will be used in the release pipeline - - publish: "$(signOutPath)/PSScriptAnalyzer.$(moduleVersion).nupkg" - artifact: nupkg - displayName: Publish module nupkg - -# Now on to the compliance stage -- stage: compliance - displayName: Compliance - dependsOn: Build - jobs: - - job: Compliance_Job - pool: - name: PowerShell1ES # was Package ES CodeHub Lab E - demands: - - ImageOverride -equals PSMMS2019-Secure - - steps: - - checkout: self - - checkout: ComplianceRepo - - download: current - artifact: build - - # use the templates in the compliance repo - # since script analyzer has modules, we're using the assembly-module-compliance template - # if you don't have assemblies, you should use script-module-compliance template - - template: assembly-module-compliance.yml@ComplianceRepo - parameters: - # component-governance - the path to sources - sourceScanPath: '$(Build.SourcesDirectory)/OSS_Microsoft_PSSA' - # binskim - this isn't recursive, so you need the path to the assemblies - AnalyzeTarget: '$(Pipeline.Workspace)\build\bin\PSV7Release\netcoreapp3.1\Microsoft.Windows.PowerShell.ScriptAnalyzer*.dll' - # credscan - scan the repo for credentials - # you can suppress some files with this. - suppressionsFile: '$(Build.SourcesDirectory)/OSS_Microsoft_PSSA/tools/ReleaseBuild/CredScan.Suppressions.json' - # TermCheck - optionsRulesDBPath: '' - optionsFTPath: '' - # tsa-upload - # the compliance scanning must be uploaded, which you need to request - codeBaseName: 'PSSA_202004' - # selections - APIScan: false # set to false when not using Windows APIs. - -#- template: template/publish.yml -# parameters: -# stageName: AzArtifactsFeed -# environmentName: -# feedCredential: - -#- template: template/publish.yml -# parameters: -# stageName: NuGet -# environmentName: PSMarkdownRenderNuGetApproval -# feedCredential: NugetOrgPush diff --git a/.config/tsaoptions.json b/.config/tsaoptions.json new file mode 100644 index 000000000..a0887d850 --- /dev/null +++ b/.config/tsaoptions.json @@ -0,0 +1,10 @@ +{ + "instanceUrl": "https://msazure.visualstudio.com/", + "projectName": "One", + "areaPath": "One\\MGMT\\Compute\\Powershell\\Powershell\\PowerShell Core", + "notificationAliases": [ + "andschwa@microsoft.com", + "slee@microsoft.com" + ], + "codebaseName": "PSSA_202403" +} diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index b731d046f..000000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. - -FROM mcr.microsoft.com/dotnet/sdk:6.0 - -RUN pwsh --command Install-Module platyPS,Pester -Force diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index d48d48c38..000000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,16 +0,0 @@ -// For format details, see https://aka.ms/vscode-remote/devcontainer.json -{ - "name": "C# (.NET 6.0)", - "dockerFile": "Dockerfile", - "customizations": { - "vscode": { - "settings": { - "terminal.integrated.defaultProfile.linux": "pwsh" - }, - "extensions": [ - "ms-dotnettools.csharp", - "ms-vscode.powershell" - ] - } - } -} diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..983234361 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,6 @@ +# Default owners +* @andyleejordan @bergmeister + +# Version bumps and documentation updates +Directory.Build.props @sdwheeler @michaeltlombardi +/docs/ @sdwheeler @michaeltlombardi diff --git a/.github/workflows/ci-test.yml b/.github/workflows/ci-test.yml new file mode 100644 index 000000000..d681191c8 --- /dev/null +++ b/.github/workflows/ci-test.yml @@ -0,0 +1,64 @@ +name: CI Tests + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + ci: + name: pester + strategy: + matrix: + os: [ windows-latest, macos-latest, ubuntu-latest ] + runs-on: ${{ matrix.os }} + env: + DOTNET_NOLOGO: true + DOTNET_GENERATE_ASPNET_CERTIFICATE: false + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install dotnet + uses: actions/setup-dotnet@v4 + with: + cache: true + cache-dependency-path: '**/*.csproj' + + - name: Install PSResources + run: ./tools/installPSResources.ps1 + shell: pwsh + + - name: Build + run: ./build.ps1 -Configuration Release -All + shell: pwsh + + - name: Package + run: ./build.ps1 -BuildNupkg + shell: pwsh + + - name: Test + run: ./build.ps1 -Test + shell: pwsh + + - name: Test Windows PowerShell + run: | + Install-Module Pester -Scope CurrentUser -Force -SkipPublisherCheck + ./build.ps1 -Test + if: matrix.os == 'windows-latest' + shell: powershell + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + if: always() + with: + name: PSScriptAnalyzer-package-${{ matrix.os }} + path: out/**/*.nupkg + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: PSScriptAnalyzer-tests-${{ matrix.os }} + path: testResults.xml diff --git a/.gitignore b/.gitignore index 92c1621bd..fdf91a4bf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,226 +1,5 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. - -# User-specific files -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -build/ -bld/ -[Bb]in/ -[Oo]bj/ - -# Visual Studo 2015 cache/options directory -.vs/ - -# VSCode configuration directory -.vscode/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# .Net Core CLI -project.lock.json -artifacts/ - -*_i.c -*_p.c -*_i.h -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opensdf -*.sdf -*.cachefile - -# Visual Studio profiler -*.psess -*.vsp -*.vspx - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding addin-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# NCrunch -_NCrunch_* -.*crunch*.local.xml - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/packages/* -# except build/, which is used as an MSBuild target. -!**/packages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config - -# Windows Azure Build Output -csx/ -*.build.csdef - -# Windows Store app package directory -AppPackages/ - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ - -# Others -ClientBin/ -[Ss]tyle[Cc]op.* -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.pfx -*.publishsettings -node_modules/ -bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm - -# SQL Server files -*.mdf -*.ldf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings - -# Microsoft Fakes -FakesAssemblies/ - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -##Our project binplace location -PSScriptAnalyzer/ - -# Vim swap files -*.swp - -# Test result file -TestResults.xml - -# PSCompatibilityCollector module -PSCompatibilityCollector/out/ - -# Folder of build module -out - -# Explicitely Include test dir -!/Tests/** +bin/ +obj/ +/module/ +/out/ +testResults.xml diff --git a/.pipelines/PSScriptAnalyzer-Official.yml b/.pipelines/PSScriptAnalyzer-Official.yml new file mode 100644 index 000000000..971cdc351 --- /dev/null +++ b/.pipelines/PSScriptAnalyzer-Official.yml @@ -0,0 +1,177 @@ +################################################################################# +# OneBranch Pipelines # +# This pipeline was created by EasyStart from a sample located at: # +# https://aka.ms/obpipelines/easystart/samples # +# Documentation: https://aka.ms/obpipelines # +# Yaml Schema: https://aka.ms/obpipelines/yaml/schema # +# Retail Tasks: https://aka.ms/obpipelines/tasks # +# Support: https://aka.ms/onebranchsup # +################################################################################# + +trigger: +- main + +schedules: +- cron: '20 16 * * 4' + displayName: Weekly CodeQL + branches: + include: + - main + always: true + +parameters: +- name: debug + displayName: Enable debug output + type: boolean + default: false + +variables: + system.debug: ${{ parameters.debug }} + BuildConfiguration: Release + WindowsContainerImage: onebranch.azurecr.io/windows/ltsc2022/vse2022:latest + DOTNET_NOLOGO: true + DOTNET_GENERATE_ASPNET_CERTIFICATE: false + +resources: + repositories: + - repository: templates + type: git + name: OneBranch.Pipelines/GovernedTemplates + ref: refs/heads/main + +extends: + # https://aka.ms/obpipelines/templates + template: v2/OneBranch.Official.CrossPlat.yml@templates + parameters: + globalSdl: # https://aka.ms/obpipelines/sdl + asyncSdl: + enabled: true + forStages: [build] + featureFlags: + EnableCDPxPAT: false + WindowsHostVersion: + Version: 2022 + Network: KS3 + release: + category: NonAzure + stages: + - stage: build + jobs: + - job: main + displayName: Build package + pool: + type: windows + variables: + ob_outputDirectory: $(Build.SourcesDirectory)/out + steps: + - pwsh: | + [xml]$xml = Get-Content ./Directory.Build.props + $version = $xml.Project.PropertyGroup.ModuleVersion + Write-Output "##vso[task.setvariable variable=version;isOutput=true]$version" + name: package + displayName: Get version from project properties + - task: onebranch.pipeline.version@1 + displayName: Set OneBranch version + inputs: + system: Custom + customVersion: $(package.version) + - task: UseDotNet@2 + displayName: Use .NET SDK + inputs: + packageType: sdk + useGlobalJson: true + - pwsh: | + Register-PSRepository -Name CFS -SourceLocation "https://pkgs.dev.azure.com/powershell/PowerShell/_packaging/powershell/nuget/v2" -InstallationPolicy Trusted + Install-Module -Repository CFS -Name Microsoft.PowerShell.PSResourceGet + ./tools/installPSResources.ps1 -PSRepository CFS + displayName: Install PSResources + - pwsh: ./build.ps1 -Configuration Release -All + displayName: Build + - task: onebranch.pipeline.signing@1 + displayName: Sign 1st-party files + inputs: + command: sign + signing_profile: external_distribution + search_root: $(Build.SourcesDirectory)/out + files_to_sign: | + **/Microsoft.*.dll; + **/*.psd1; + **/*.psm1; + **/*.ps1xml; + - task: onebranch.pipeline.signing@1 + displayName: Sign 3rd-party files + inputs: + command: sign + signing_profile: 135020002 + search_root: $(Build.SourcesDirectory)/out + files_to_sign: | + **/Newtonsoft.Json.dll; + **/Pluralize.NET.dll; + - pwsh: ./build.ps1 -BuildNupkg + displayName: Package module + - task: onebranch.pipeline.signing@1 + displayName: Sign NuGet package + inputs: + command: sign + signing_profile: external_distribution + search_root: $(Build.SourcesDirectory)/out + files_to_sign: | + *.nupkg + - stage: release + dependsOn: build + condition: eq(variables['Build.Reason'], 'Manual') + variables: + ob_release_environment: Production + version: $[ stageDependencies.build.main.outputs['package.version'] ] + jobs: + - job: github + displayName: Publish draft to GitHub + pool: + type: release + templateContext: + inputs: + - input: pipelineArtifact + artifactName: drop_build_main + steps: + - task: GitHubRelease@1 + displayName: Create GitHub release + inputs: + gitHubConnection: GitHub + repositoryName: PowerShell/PSScriptAnalyzer + target: main + assets: $(Pipeline.Workspace)/PSScriptAnalyzer.$(version).nupkg + tagSource: userSpecifiedTag + tag: v$(version) + isDraft: true + addChangeLog: false + releaseNotesSource: inline + releaseNotesInline: "" + - job: validation + displayName: Manual validation + pool: + type: server + timeoutInMinutes: 1440 + steps: + - task: ManualValidation@0 + displayName: Wait 24 hours for validation + inputs: + notifyUsers: $(Build.RequestedForEmail) + instructions: Please validate the release and then publish it! + timeoutInMinutes: 1440 + - job: publish + dependsOn: validation + displayName: Publish to PowerShell Gallery + pool: + type: release + templateContext: + inputs: + - input: pipelineArtifact + artifactName: drop_build_main + steps: + - task: NuGetCommand@2 + displayName: Publish module to PowerShell Gallery + inputs: + command: push + packagesToPush: $(Pipeline.Workspace)/PSScriptAnalyzer.$(version).nupkg + nuGetFeedType: external + publishFeedCredentials: PowerShellGallery diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 098ed86e6..bf1b08715 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -3,7 +3,6 @@ // for the documentation about the extensions.json format "recommendations": [ "ms-vscode.PowerShell", - "ms-dotnettools.csharp", - "ms-vscode-remote.remote-containers" + "ms-dotnettools.csharp" ] -} \ No newline at end of file +} diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 19ff33a1f..6afc5be8e 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,11 +1,95 @@ # CHANGELOG +## [1.22.0](https://github.com/PowerShell/PSScriptAnalyzer/tree/1.22.0) - 2024-03-05 + +Minimum required version when using PowerShell 7 is now `7.2.11`. + +## New Rule + +- Add AvoidUsingAllowUnencryptedAuthentication by @MJVL in (#1857) +- Add the AvoidExclaimOperator rule to warn about the use of the ! negation operator. Fixes (#1826) by + @liamjpeters in (#1922) + +## Enhancements + +- Enable suppression of PSAvoidAssignmentToAutomaticVariable for specific variable or parameter by + @fflaten in (#1896) +- Upgrade to use .NET 6 since PowerShell 7.0 is now out out of support by @bergmeister in (#1873) +- Convert UseSingularNouns to configurable rule and add Windows to allowlist by @MJVL in (#1858) +- Add ErrorView to SpecialVars.cs by @ewisniew0 in (#1865) +- Allow suppression of PSUseSingularNouns for specific function by @fflaten in (#1903) +- Adding ToString() methods to [CorrectionExtent] and [DiagnosticRecord] by @StartAutomating in (#1946) +- Add PSNativeCommandUseErrorActionPreference preference variable by @aelij in (#1954) +- AvoidUsingPositionalParameter: Check if command has parameters to avoid having az in default + CommandAllowList by @bergmeister in (#1850) +- PSReviewUnusedParameter: Add CommandsToTraverse option by @FriedrichWeinmann in (#1921) + +## Fixes + +- Prevent NullReferenceException for null analysis type. by @hubuk in (#1949) + +## Build & Test, Documentation and Maintenance + +- UseApprovedVerbs.md: Backport minor change of PR 104 in PowerShell-Docs-Modules by @bergmeister in + (#1849) +- Improve Pester bootstrap logic for CI by @bergmeister in (#1853) +- Bump .NET SDK from 3.1.419 to 3.1.424 by @bergmeister in (#1852) +- AvoidLongLines: Make internal function DiagnosticSeverity private by @bergmeister in (#1851) +- SupportsShouldProcess.md: Fix Typo - MicrosoftDocs backport of PR 121 there by @sdwheeler in (#1869) +- Minor test fix for UseCorrectCasing rule by @kilasuit in (#1885) +- Make Invoke-Formatter test case assertion fail in case of incorrect casing by @alexandear in (#1888) +- Fix `AvoidUsingDoubleQuotesForConstantString` information in overview README by @michaeltlombardi + in (#1883) +- Update dependabot reviewers to remove Rob by @fflaten in (#1897) +- Fix typo in AvoidUsingPlainTextForPassword error message: 'to' being repeated two times by + @ALiwoto in (#1902) +- CI: Use new Ubuntu 22.04 image and remove deprecated Ubuntu 18.04 by @bergmeister in (#1847) +- Change double quotes to single where possible by @sdwheeler in (#1911) +- Backport MicrosoftDocs PR 143 by @sdwheeler in (#1910) +- Fix typos in rules documentation by @sdwheeler in (#1913) +- add demand for compliance job by @TravisEz13 in (#1920) +- FabricBot: Onboarding to GitOps.ResourceManagement because of FabricBot decommissioning by + @microsoft-github-policy-service in (#1925) +- Sync changes from Docs repository by @sdwheeler in (#1929) +- Developer documentation fix and message fix of + PossibleIncorrectUsageOfRedirectionOperatorDescription by @JoelTipke in (#1928) +- Documentation corrections for AvoidUsingPositionalParameters by @ImportTaste in (#1917) +- Update minimum PowerShell Core version to 7.2.11 as 7.0 is now EOL by @bergmeister in (#1872) +- Remove dead code and simplify by @bergmeister in (#1856) +- PSReservedParams - link about_CommonParameters by @petervandivier in (#1908) +- Generate strongly typed resources as part of build by @bergmeister in (#1855) +- Bump Newtonsoft.Json to 13.0.3 by @dependabot in (#1866) +- Use latest .NET 6.0 SDK patch version and update devcontainer to use .NET 6 as well by + @bergmeister in (#1955) +- Bump Microsoft.Management.Infrastructure from 1.0.0 to 3.0.0 for PowerShell 7 only by @dependabot + in (#1947) +- Bump version from 1.21.0 to 1.22.0 by @bergmeister in (#1965) +- Remove Appveyor badge from main README by @bergmeister in (#1962) +- Do not hard code common parameters in module help test any more by @bergmeister in (#1963) + +## New Contributors + +- @fflaten made their first contribution in (#1897) +- @ALiwoto made their first contribution in (#1902) +- @microsoft-github-policy-service made their first contribution in (#1925) +- @JoelTipke made their first contribution in (#1928) +- @ImportTaste made their first contribution in (#1917) +- @liamjpeters made their first contribution in (#1922) +- @petervandivier made their first contribution in (#1908) +- @ewisniew0 made their first contribution in (#1865) +- @StartAutomating made their first contribution in (#1946) +- @aelij made their first contribution in (#1954) +- @FriedrichWeinmann made their first contribution in (#1921) + +**Full Changelog**: + ## [1.21.0](https://github.com/PowerShell/PSScriptAnalyzer/tree/1.21.0) - 2022-09-27 ### New Rule - Add AvoidMultipleTypeAttributes rule (#1705) (thanks @hankyi95) -- Add the AvoidSemicolonsAsLineTerminators rule to warn about lines ending with a semicolon. Fix (#824) (#1806) (thanks @tempora-mutantur) +- Add the AvoidSemicolonsAsLineTerminators rule to warn about lines ending with a semicolon. Fix + (#824) (#1806) (thanks @tempora-mutantur) - Add AvoidUsingBrokenHashAlgorithms (#1787) (thanks @MJVL) ### Enhancements @@ -13,7 +97,8 @@ - Also return suggestion to use PSCredential for AvoidUsingPlainTextForPassword rule (#1782) (by @bergmeister) - Invoke-Formatter: Accept input from pipeline (#1763) (by @bergmeister) - Make messages of UseCorrectCasing more detailed (#1843) -- Exclude automatic variable FormatEnumerationLimit from analysis by PSAvoidGlobalVars and PSUseDeclaredVarsMoreThanAssignments (#1836) (by @bergmeister) +- Exclude automatic variable FormatEnumerationLimit from analysis by PSAvoidGlobalVars and + PSUseDeclaredVarsMoreThanAssignments (#1836) (by @bergmeister) - PSAvoidUsingPositionalParameters: Do not warn on AZ CLI (#1846) (by @bergmeister) ### Fixes @@ -59,7 +144,7 @@ - Remove Ubuntu 16.04 from test matrix (#1733) (by @rjmholt) - Use PowerShell1ES pool for official build (#1719) (by @JamesWTruher) - Update cmdlet docs for 1.20.0 (#1726) (by @sdwheeler) -- Fixes #1720 - move rule docs and update tests (#1724) (by @sdwheeler) +- Fixes (#1720) - move rule docs and update tests (#1724) (by @sdwheeler) - Update rule docs (#1711) (by @sdwheeler) ## [1.20.0](https://github.com/PowerShell/PSScriptAnalyzer/tree/1.20.0) - 2021-08-20 @@ -170,7 +255,7 @@ ### Compatibility Rules -- Make CompatibilityCollector able to parse a single version String #1446 (by @bergmeister) +- Make CompatibilityCollector able to parse a single version String (#1446) (by @bergmeister) - Update compatibility profiles for PowerShell 7 (#1429) (by @rjmholt) - Ps7 syntax (#1426) (by @rjmholt) - Fix ps3 syntax check (#1395) (by @rjmholt) @@ -728,10 +813,10 @@ Here are some improvements since the last release. - Add build script to automate building and testing the solution A big **Thank You!** to the following folks for making PSScriptAnalyzer even better: -- [Kieran Jacobsen (@kjacobsen)](https://github.com/PowerShell/PSScriptAnalyzer/commits/development?author=kjacobsen): Fix rule documentation of `PSDSCExamplesPresent` [PR #591](https://github.com/PowerShell/PSScriptAnalyzer/pull/591) -- [Charlie Schmidt (@charlieschmidt)](https://github.com/PowerShell/PSScriptAnalyzer/commits/development?author=charlieschmidt): Suppress External Rules [PR #585](https://github.com/PowerShell/PSScriptAnalyzer/pull/585) +- [Kieran Jacobsen (@kjacobsen)](https://github.com/PowerShell/PSScriptAnalyzer/commits/development?author=kjacobsen): Fix rule documentation of `PSDSCExamplesPresent` [PR #591](#591) +- [Charlie Schmidt (@charlieschmidt)](https://github.com/PowerShell/PSScriptAnalyzer/commits/development?author=charlieschmidt): Suppress External Rules [PR #585](#585) - [June Blender (@juneb)](https://github.com/PowerShell/PSScriptAnalyzer/commits/development?author=juneb): Add tests for module help [058f65e1](https://github.com/PowerShell/PSScriptAnalyzer/commit/058f65e1f6278222378fedf444eecb2e32865b1e) -- [Shayde Nofziger (@Blackbaud-ShaydeNofziger)](https://github.com/PowerShell/PSScriptAnalyzer/commits/development?author=Blackbaud-ShaydeNofziger): Fix rule name typo and comment [PR #560](https://github.com/PowerShell/PSScriptAnalyzer/pull/560) +- [Shayde Nofziger (@Blackbaud-ShaydeNofziger)](https://github.com/PowerShell/PSScriptAnalyzer/commits/development?author=Blackbaud-ShaydeNofziger): Fix rule name typo and comment [PR #560](#560) ## [1.6.0](https://github.com/PowerShell/PSScriptAnalyzer/tree/1.6.0) - 2016-06-07 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..686e5e7a0 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,10 @@ +# Microsoft Open Source Code of Conduct + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). + +Resources: + +- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) +- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) +- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns +- Employees can reach out at [aka.ms/opensource/moderation-support](https://aka.ms/opensource/moderation-support) diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 000000000..d2db04cd1 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,7 @@ + + + + 1.23.0 + true + + diff --git a/Directory.Packages.props b/Directory.Packages.props new file mode 100644 index 000000000..e43bd7dfd --- /dev/null +++ b/Directory.Packages.props @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/Engine/Engine.csproj b/Engine/Engine.csproj index 860700b0b..3025c9a08 100644 --- a/Engine/Engine.csproj +++ b/Engine/Engine.csproj @@ -1,10 +1,10 @@  - 1.22.0 + $(ModuleVersion) net6;net462 Microsoft.Windows.PowerShell.ScriptAnalyzer - 1.22.0 + $(ModuleVersion) Engine Microsoft.Windows.PowerShell.ScriptAnalyzer 9.0 @@ -45,7 +45,7 @@ - + - - - - + + + + - - - + + + - + diff --git a/README.md b/README.md index c61522134..716224c7c 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ - [Contributions are welcome](#contributions-are-welcome) - [Creating a Release](#creating-a-release) - [Code of Conduct](#code-of-conduct) +- [Security Policy](#security-policy) @@ -227,10 +228,12 @@ New-Release ## Code of Conduct -This project has adopted the -[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more -information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or -contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or -comments. +Please see our [Code of Conduct](CODE_OF_CONDUCT.md) before participating in this project. + +[Back to ToC](#table-of-contents) + +## Security Policy + +For any security issues, please see our [Security Policy](SECURITY.md). [Back to ToC](#table-of-contents) diff --git a/Rules/Rules.csproj b/Rules/Rules.csproj index a9497824d..8fef9e969 100644 --- a/Rules/Rules.csproj +++ b/Rules/Rules.csproj @@ -1,10 +1,10 @@ - 1.22.0 + $(ModuleVersion) net6;net462 Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules - 1.22.0 + $(ModuleVersion) Rules Microsoft.Windows.PowerShell.ScriptAnalyzer true @@ -17,15 +17,14 @@ - - - - - + + + + - + diff --git a/Rules/UseConsistentWhitespace.cs b/Rules/UseConsistentWhitespace.cs index 13613ae74..a062e5d3f 100644 --- a/Rules/UseConsistentWhitespace.cs +++ b/Rules/UseConsistentWhitespace.cs @@ -396,8 +396,17 @@ private IEnumerable FindParameterViolations(Ast ast) testAst => testAst is CommandAst, true); foreach (CommandAst commandAst in commandAsts) { + /// When finding all the command parameter elements, there is no guarantee that + /// we will read them from the AST in the order they appear in the script (in token + /// order). So we first sort the tokens by their starting line number, followed by + /// their starting column number. List commandParameterAstElements = commandAst.FindAll( - testAst => testAst.Parent == commandAst, searchNestedScriptBlocks: false).ToList(); + testAst => testAst.Parent == commandAst, searchNestedScriptBlocks: false + ).OrderBy( + e => e.Extent.StartLineNumber + ).ThenBy( + e => e.Extent.StartColumnNumber + ).ToList(); for (int i = 0; i < commandParameterAstElements.Count - 1; i++) { IScriptExtent leftExtent = commandParameterAstElements[i].Extent; diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..f941d308b --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,41 @@ + + +## Security + +Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin) and [PowerShell](https://github.com/PowerShell). + +If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/security.md/definition), please report it to us as described below. + +## Reporting Security Issues + +**Please do not report security vulnerabilities through public GitHub issues.** + +Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/security.md/msrc/create-report). + +If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/security.md/msrc/pgp). + +You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). + +Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: + + * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) + * Full paths of source file(s) related to the manifestation of the issue + * The location of the affected source code (tag/branch/commit or direct URL) + * Any special configuration required to reproduce the issue + * Step-by-step instructions to reproduce the issue + * Proof-of-concept or exploit code (if possible) + * Impact of the issue, including how an attacker might exploit the issue + +This information will help us triage your report more quickly. + +If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/security.md/msrc/bounty) page for more details about our active programs. + +## Preferred Languages + +We prefer all communications to be in English. + +## Policy + +Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/security.md/cvd). + + diff --git a/Tests/Build/BuildModule.tests.ps1 b/Tests/Build/BuildModule.tests.ps1 index 542ac2a52..ebc4e2a6a 100644 --- a/Tests/Build/BuildModule.tests.ps1 +++ b/Tests/Build/BuildModule.tests.ps1 @@ -48,60 +48,6 @@ Describe "Build Module Tests" { } } - Context "Test-DotnetInstallation" { - BeforeAll { - $availableVersions = ConvertTo-PortableVersion -strVersion "2.2.400","2.2.401","2.2.405" - $foundVersion = ConvertTo-PortableVersion -strVersion 2.2.402 - $missingVersion = ConvertTo-PortableVersion -strVersion 2.2.410 - } - - It "Test-DotnetInstallation finds a good version" { - Mock Get-InstalledCLIVersion { return $availableVersions } - Mock Get-GlobalJSonSdkVersion { return $foundVersion } - $result = Test-DotnetInstallation -requestedVersion (Get-GlobalJsonSdkVersion) -installedVersions (Get-InstalledCLIVersion) - Assert-MockCalled "Get-InstalledCLIVersion" -Times 1 - Assert-MockCalled "Get-GlobalJsonSdkVersion" -Times 1 - $result | Should -Be $true - } - - It "Test-DotnetInstallation cannot find a good version should return false" { - Mock Get-InstalledCLIVersion { return $availableVersions } - Mock Get-GlobalJSonSdkVersion { return $missingVersion } - $result = Test-DotnetInstallation -requestedVersion (Get-GlobalJsonSdkVersion) -installedVersions (Get-InstalledCLIVersion) - Assert-MockCalled "Get-InstalledCLIVersion" -Times 1 - Assert-MockCalled "Get-GlobalJsonSdkVersion" -Times 1 - $result | Should -Be $false - } - } - - Context "Receive-DotnetInstallScript" { - - Mock -ModuleName Build Receive-File { new-item -type file TestDrive:/dotnet-install.sh } - It "Downloads the proper non-Windows file" { - try { - push-location TestDrive: - Receive-DotnetInstallScript -platform NonWindows - "TestDrive:/dotnet-install.sh" | Should -Exist - } - finally { - Pop-Location - } - } - - Mock -ModuleName Build Receive-File { new-item -type file TestDrive:/dotnet-install.ps1 } - It "Downloads the proper file Windows file" { - try { - push-location TestDrive: - Receive-DotnetInstallScript -platform "Windows" - "TestDrive:/dotnet-install.ps1" | Should -Exist - } - finally { - Pop-Location - } - } - - } - Context "Test result functions" { BeforeAll { $xmlFile = @' diff --git a/Tests/Rules/UseCompatibleCommands.Tests.ps1 b/Tests/Rules/UseCompatibleCommands.Tests.ps1 index d2a8c5b8e..cb49f3c1f 100644 --- a/Tests/Rules/UseCompatibleCommands.Tests.ps1 +++ b/Tests/Rules/UseCompatibleCommands.Tests.ps1 @@ -401,6 +401,9 @@ Describe 'UseCompatibleCommands' { ) IgnoreCommands = @( 'Install-Module' + 'Publish-Module' + 'Register-PSRepository' + 'Unregister-PSRepository' # Some PowerShell profiles have Pester installed by default # So Pester is legitimately flagged 'Describe' diff --git a/Tests/Rules/UseConsistentWhitespace.tests.ps1 b/Tests/Rules/UseConsistentWhitespace.tests.ps1 index 31442ad77..30d8cce57 100644 --- a/Tests/Rules/UseConsistentWhitespace.tests.ps1 +++ b/Tests/Rules/UseConsistentWhitespace.tests.ps1 @@ -540,6 +540,12 @@ bar -h i ` Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null } + It "Should not find a violation when redirect operators, spearated by 1 space, are used and not in stream order" { + # Related to Issue #2000 + $def = 'foo 3>&1 1>$null 2>&1' + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + } + It "Should find 1 violation if there is 1 space too much before a parameter" { $def = 'foo -bar' $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings @@ -578,5 +584,13 @@ bar -h i ` Invoke-Formatter -ScriptDefinition "$def" -Settings $settings | Should -Be "$expected" } + + It "Should fix script when redirects are involved and whitespace is not consistent" { + # Related to Issue #2000 + $def = 'foo 3>&1 1>$null 2>&1' + $expected = 'foo 3>&1 1>$null 2>&1' + Invoke-Formatter -ScriptDefinition $def -Settings $settings | + Should -Be $expected + } } } diff --git a/Utils/ReleaseMaker.psm1 b/Utils/ReleaseMaker.psm1 deleted file mode 100644 index ac59dbb32..000000000 --- a/Utils/ReleaseMaker.psm1 +++ /dev/null @@ -1,198 +0,0 @@ -Function Get-SolutionPath -{ - Split-Path $PSScriptRoot -Parent -} - -Function Get-ChangeLogPath -{ - Join-Path (Get-SolutionPath) 'CHANGELOG.MD' -} - -Function Get-EngineProjectPath -{ - Join-Path (Get-SolutionPath) 'Engine' -} - -Function Get-ModuleManifestPath -{ - Join-Path (Get-EngineProjectPath) 'PSScriptAnalyzer.psd1' -} - -Function New-Release -{ - [CmdletBinding()] - param($newVer, $oldVer) - - $isVersionGiven = $true - if ($null -eq $newVer -or $null -eq $oldVer) - { - Write-Warning "Parameters are null. Checking changelog for version..." - $isVersionGiven = $false - } - - $solutionRoot = Get-SolutionPath - $enginePath = Get-EngineProjectPath - $versions = Get-VersionsFromChangeLog - if ($versions.Count -le 2) - { - throw "This edge condition for the number versions less that 2 is not implemented." - } - - if ($isVersionGiven) - { - Function Test-IfNotPresentInChangelog - { - param($extractedVersion, $inputVersion) - if ($extractedVersion -ne $inputVersion) - { - throw ("Version {0} does not exist in changelog. Please update changelog." -f $inputVersion) - } - } - - Test-IfNotPresentInChangelog $versions[0] $newVer - Test-IfNotPresentInChangelog $versions[1] $oldVer - } - else - { - $newVer = $versions[0] - $oldVer = $versions[1] - $caption = "Version Check" - $query = "Is version {0} the next release and version {1} the previous release ?" -f $newVer,$oldVer - [bool] $yesToAll = $false - [bool] $noToAll = $false - - if (!$PSCmdlet.ShouldContinue($query, $caption, $false, [ref] $yesToAll, [ref] $noToAll)) - { - return "Aborting..." - } - } - - # update version - Update-Version $newVer $oldVer $solutionRoot - - # copy release notes from changelog to module manifest - Update-ReleaseNotesInModuleManifest $newVer $oldVer - - # build the module - New-ReleaseBuild -} - -function Get-VersionsFromChangeLog -{ - $moduleManifestPath = Get-ModuleManifestPath - $changelogPath = Get-ChangeLogPath - $matches = [regex]::new("\[(\d+\.\d+\.\d+)\]").Matches((get-content $changelogPath -raw)) - $versions = $matches | ForEach-Object {$_.Groups[1].Value} - $versions -} - -function New-ReleaseBuild -{ - $solutionPath = Get-SolutionPath - Push-Location $solutionPath - try - { - if ( test-path out ) { remove-item out/ -recurse -force } - .\build.ps1 -All -Configuration Release - .\PSCompatibilityCollector\build.ps1 -Clean -Configuration Release - Copy-Item -Recurse .\PSCompatibilityCollector\out\* .\out\ - } - finally - { - Pop-Location - } -} - -function Update-ReleaseNotesInModuleManifest -{ - [CmdletBinding()] - param($newVer, $oldVer) - - $moduleManifestPath = Get-ModuleManifestPath - Write-Verbose ("Module manifest: {0}" -f $moduleManifestPath) - $changelogPath = Get-ChangeLogPath - Write-Verbose ("CHANGELOG: {0}" -f $changelogPath) - $changelogRegexPattern = "##\s\[{0}\].*\n((?:.*\n)+)##\s\[{1}\].*" ` - -f [regex]::Escape($newVer),[regex]::Escape($oldVer) - $changelogRegex = [regex]::new($changelogRegexPattern) - $matches = $changelogRegex.Match((get-content $changelogPath -raw)) - $changelogWithHyperlinks = $matches.Groups[1].Value.Trim() - - Write-Verbose 'CHANGELOG:' - Write-Verbose $changelogWithHyperlinks - - # Remove hyperlinks from changelog to make is suitable for publishing on powershellgallery.com - Write-Verbose "Removing hyperlinks from changelog" - $changelog = Remove-MarkdownHyperlink $changelogWithHyperlinks - Write-Verbose "CHANGELOG without hyperlinks:" - Write-Verbose $changelog - - $releaseNotesPattern = ` - "(?ReleaseNotes\s*=\s*@')(?(?:.*\n)*)(?'@)" - $replacement = "`${releaseNotesBegin}" ` - + [environment]::NewLine ` - + $changelog ` - + [environment]::NewLine ` - + "`${releaseNotesEnd}" - $r = [regex]::new($releaseNotesPattern) - $updatedManifestContent = $r.Replace([System.IO.File]::ReadAllText($moduleManifestPath), $replacement) - Set-ContentUtf8NoBom $moduleManifestPath $updatedManifestContent -} - -function Remove-MarkdownHyperlink -{ - param($markdownContent) - $markdownContent -replace "\[(.*?)\]\(.*?\)",'$1' -} - -function Combine-Path -{ - if ($args.Count -lt 2) - { - throw "give more 1 argument" - } - - $path = Join-Path $args[0] $args[1] - for ($k = 2; $k -lt $args.Count; $k++) - { - $path = Join-Path $path $args[$k] - } - - $path -} - -function Update-Version -{ - param( - [string] $newVer, - [string] $oldVer, - [string] $solutionPath - ) - - $ruleJson = Combine-Path $solutionPath 'Rules' 'Rules.csproj' - $engineJson = Combine-Path $solutionPath 'Engine' 'Engine.csproj' - $pssaManifest = Combine-Path $solutionPath 'Engine' 'PSScriptAnalyzer.psd1' - - Update-PatternInFile $ruleJson '"version": "{0}"' $oldVer $newVer - Update-PatternInFile $ruleJson '"Engine": "{0}"' $oldVer $newVer - Update-PatternInFile $engineJson '"version": "{0}"' $oldVer $newVer - Update-PatternInFile $pssaManifest "ModuleVersion = '{0}'" $oldVer $newVer -} - -function Update-PatternInFile -{ - param ($path, $unformattedPattern, $oldVal, $newVal) - - $content = Get-Content $path - $newcontent = $content -replace ($unformattedPattern -f $oldVal),($unformattedPattern -f $newVal) - Set-ContentUtf8NoBom $path $newcontent -} - -function Set-ContentUtf8NoBom { - param($path, $content) - $utfNoBom = [System.Text.UTF8Encoding]::new($false) - [System.IO.File]::WriteAllLines($path, $content, $utfNoBom) -} - -Export-ModuleMember -Function New-Release -Export-ModuleMember -Function New-ReleaseBuild diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 4ba8d02c8..000000000 --- a/appveyor.yml +++ /dev/null @@ -1,55 +0,0 @@ -environment: - PSVersion: 5 - BuildConfiguration: Release - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true # For faster CI builds - matrix: - - APPVEYOR_BUILD_WORKER_IMAGE: WMF 4 - PowerShellEdition: WindowsPowerShell - PSVersion: 4 - ## Only the tests for WMF4 remain active in AppVeyor due to Azure DevOps not offering such images ## - # - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - # PowerShellEdition: PowerShellCore - # - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - # PowerShellEdition: WindowsPowerShell - # - APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu - # PowerShellEdition: PowerShellCore - -# cache Nuget packages and dotnet CLI cache -cache: - - '%USERPROFILE%\.nuget\packages -> appveyor.yml' - -install: - - ps: if ($env:PowerShellEdition -eq 'WindowsPowerShell') { Import-Module .\tools\appveyor.psm1; Invoke-AppveyorInstall } - - pwsh: if ($env:PowerShellEdition -eq 'PowerShellCore') { Import-Module .\tools\appveyor.psm1; Invoke-AppveyorInstall } - -build_script: - - ps: | - if ( $env:PowerShellEdition -eq 'WindowsPowerShell' ) { - Set-Location $env:APPVEYOR_BUILD_FOLDER - if ( $env:PSVersion -eq "4" ) { # On WMF4: Also build for v3 to check it builds at least since we do not have a WMF3 image - ./build.ps1 -Configuration "$env:BuildConfiguration" -PSVersion 3 - } - ./build.ps1 -Configuration "$env:BuildConfiguration" -PSVersion "$env:PSVersion" - ./PSCompatibilityCollector/build.ps1 -Configuration "$env:BuildConfiguration" -Framework 'net462' - } - - pwsh: | - if ($env:PowerShellEdition -eq 'PowerShellCore') { - Set-Location $env:APPVEYOR_BUILD_FOLDER - ./build.ps1 -Configuration "$env:BuildConfiguration" -PSVersion 7 - ./PSCompatibilityCollector/build.ps1 -Configuration "$env:BuildConfiguration" -Framework 'net6' - } - -test_script: - - ps: | - if ($env:PowerShellEdition -eq 'WindowsPowerShell') { - Invoke-AppveyorTest -CheckoutPath $env:APPVEYOR_BUILD_FOLDER - } - - pwsh: | - if ($env:PowerShellEdition -eq 'PowerShellCore') { - Import-Module .\tools\appveyor.psm1 # Appveyor does not persist pwsh sessions like it does for ps - Invoke-AppveyorTest -CheckoutPath $env:APPVEYOR_BUILD_FOLDER - } - -# Upload the project along with test results as a zip archive -on_finish: - - ps: Import-Module "${env:APPVEYOR_BUILD_FOLDER}\tools\appveyor.psm1"; Invoke-AppveyorFinish diff --git a/build.ps1 b/build.ps1 index a0e27e798..bbc6c505a 100644 --- a/build.ps1 +++ b/build.ps1 @@ -33,20 +33,11 @@ param( [Parameter(ParameterSetName='Test')] [switch] $InProcess, - [Parameter(ParameterSetName='Bootstrap')] - [switch] $Bootstrap, - [Parameter(ParameterSetName='BuildAll')] [switch] $Catalog, [Parameter(ParameterSetName='Package')] - [switch] $BuildNupkg, - - [Parameter(ParameterSetName='Package')] - [switch] $CopyManifest, - - [Parameter(ParameterSetName='Package')] - [switch] $Signed + [switch] $BuildNupkg ) @@ -90,15 +81,8 @@ END { } Start-ScriptAnalyzerBuild @buildArgs } - "Bootstrap" { - Install-DotNet - return - } "Package" { - if($CopyManifest) { - Copy-Manifest -signed:$Signed - } - Start-CreatePackage -signed:$Signed + Start-CreatePackage } "Test" { Test-ScriptAnalyzer -InProcess:$InProcess diff --git a/build.psm1 b/build.psm1 index 86dfbd763..604c5d17e 100644 --- a/build.psm1 +++ b/build.psm1 @@ -7,9 +7,8 @@ $analyzerName = "PSScriptAnalyzer" function Get-AnalyzerVersion { - $csprojPath = [io.path]::Combine($projectRoot,"Engine","Engine.csproj") - $xml = [xml](Get-Content "${csprojPath}") - $xml.SelectSingleNode(".//VersionPrefix")."#text" + [xml]$xml = Get-Content $([io.path]::Combine($projectRoot, "Directory.Build.props")) + $xml.Project.PropertyGroup.ModuleVersion } $analyzerVersion = Get-AnalyzerVersion @@ -29,61 +28,6 @@ function Publish-File } } -# attempt to get the users module directory -function Get-UserModulePath -{ - if ( $IsCoreCLR -and -not $IsWindows ) - { - $platformType = "System.Management.Automation.Platform" -as [Type] - if ( $platformType ) { - ${platformType}::SelectProductNameForDirectory("USER_MODULES") - } - else { - throw "Could not determine users module path" - } - } - else { - "${HOME}/Documents/WindowsPowerShell/Modules" - } -} - - -function Uninstall-ScriptAnalyzer -{ - [CmdletBinding(SupportsShouldProcess)] - param ( $ModulePath = $(Join-Path -Path (Get-UserModulePath) -ChildPath ${analyzerName}) ) - END { - if ( $PSCmdlet.ShouldProcess("$modulePath") ) { - Remove-Item -Recurse -Path "$ModulePath" -Force - } - } -} - -# install script analyzer, by default into the users module path -function Install-ScriptAnalyzer -{ - [CmdletBinding(SupportsShouldProcess)] - param ( $ModulePath = $(Join-Path -Path (Get-UserModulePath) -ChildPath ${analyzerName}) ) - END { - if ( $PSCmdlet.ShouldProcess("$modulePath") ) { - Copy-Item -Recurse -Path "$script:destinationDir" -Destination "$ModulePath\." -Force - } - } -} - -# if script analyzer is installed, remove it -function Uninstall-ScriptAnalyzer -{ - [CmdletBinding(SupportsShouldProcess)] - param ( $ModulePath = $(Join-Path -Path (Get-UserModulePath) -ChildPath ${analyzerName}) ) - END { - if ((Test-Path $ModulePath) -and (Get-Item $ModulePath).PSIsContainer ) - { - Remove-Item -Force -Recurse $ModulePath - } - } -} - # Clean up the build location function Remove-Build { @@ -157,9 +101,6 @@ function Start-ScriptAnalyzerBuild BEGIN { # don't allow the build to be started unless we have the proper Cli version - # this will not actually install dotnet if it's already present, but it will - # install the proper version - Install-Dotnet if ( -not (Test-SuitableDotnet) ) { $requiredVersion = $script:wantedVersion $foundVersion = Get-InstalledCLIVersion @@ -218,9 +159,15 @@ function Start-ScriptAnalyzerBuild throw "Not in solution root" } + # "Copy" the module file with the version placeholder replaced + $manifestContent = Get-Content -LiteralPath "$projectRoot\Engine\PSScriptAnalyzer.psd1" -Raw + $newManifestContent = $manifestContent -replace '{{ModuleVersion}}', $analyzerVersion + Set-Content -LiteralPath "$script:destinationDir\PSScriptAnalyzer.psd1" -Encoding utf8 -Value $newManifestContent + $itemsToCopyCommon = @( - "$projectRoot\Engine\PSScriptAnalyzer.psd1", "$projectRoot\Engine\PSScriptAnalyzer.psm1", - "$projectRoot\Engine\ScriptAnalyzer.format.ps1xml", "$projectRoot\Engine\ScriptAnalyzer.types.ps1xml" + "$projectRoot\Engine\PSScriptAnalyzer.psm1", + "$projectRoot\Engine\ScriptAnalyzer.format.ps1xml", + "$projectRoot\Engine\ScriptAnalyzer.types.ps1xml" ) switch ($PSVersion) @@ -386,7 +333,6 @@ function Test-ScriptAnalyzer else { $testModulePath = Join-Path "${projectRoot}" -ChildPath out } - $testResultsFile = "'$(Join-Path ${projectRoot} -childPath TestResults.xml)'" $testScripts = "'${projectRoot}\Tests\Build','${projectRoot}\Tests\Engine','${projectRoot}\Tests\Rules','${projectRoot}\Tests\Documentation'" try { if ( $major -lt 5 ) { @@ -395,7 +341,7 @@ function Test-ScriptAnalyzer $savedModulePath = $env:PSModulePath $env:PSModulePath = "${testModulePath}{0}${env:PSModulePath}" -f [System.IO.Path]::PathSeparator $analyzerPsd1Path = Join-Path -Path $script:destinationDir -ChildPath "$analyzerName.psd1" - $scriptBlock = [scriptblock]::Create("Import-Module '$analyzerPsd1Path'; Invoke-Pester -Path $testScripts") + $scriptBlock = [scriptblock]::Create("Import-Module '$analyzerPsd1Path'; Invoke-Pester -Path $testScripts -CI") if ( $InProcess ) { & $scriptBlock } @@ -432,49 +378,6 @@ function Get-TestFailures $results.SelectNodes(".//test-case[@result='Failure']") } -# BOOTSTRAPPING CODE FOR INSTALLING DOTNET -# install dotnet cli tools based on the version mentioned in global.json -function Install-Dotnet -{ - [CmdletBinding(SupportsShouldProcess=$true)] - param ( - [Parameter()][Switch]$Force, - [Parameter()]$version = $( Get-GlobalJsonSdkVersion -Raw ) - ) - - if ( Test-DotnetInstallation -requestedversion $version ) { - if ( $Force ) { - Write-Verbose -Verbose "Installing again" - } - else { - return - } - } - - try { - Push-Location $PSScriptRoot - $installScriptPath = Receive-DotnetInstallScript - $installScriptName = [System.IO.Path]::GetFileName($installScriptPath) - If ( $PSCmdlet.ShouldProcess("$installScriptName for $version")) { - & "${installScriptPath}" -c release -version $version -SkipNonVersionedFiles - } - # this may be the first time that dotnet has been installed, - # set up the executable variable - if ( -not $script:DotnetExe ) { - $script:DotnetExe = Get-DotnetExe - } - } - catch { - throw $_ - } - finally { - if ( Test-Path $installScriptPath ) { - Remove-Item $installScriptPath - } - Pop-Location - } -} - function Get-GlobalJsonSdkVersion { param ( [switch]$Raw ) $json = Get-Content -raw (Join-Path $PSScriptRoot global.json) | ConvertFrom-Json @@ -613,68 +516,6 @@ function Get-InstalledCLIVersion { return (ConvertTo-PortableVersion $installedVersions) } -function Test-DotnetInstallation -{ - param ( - $requestedVersion = $script:wantedVersion, - $installedVersions = $( Get-InstalledCLIVersion ) - ) - return (Test-SuitableDotnet -availableVersions $installedVersions -requiredVersion $requestedVersion ) -} - -function Receive-File { - param ( [Parameter(Mandatory,Position=0)]$uri ) - - # enable Tls12 for the request - # -SslProtocol parameter for Invoke-WebRequest wasn't in PSv3 - $securityProtocol = [System.Net.ServicePointManager]::SecurityProtocol - $tls12 = [System.Net.SecurityProtocolType]::Tls12 - try { - if ( ([System.Net.ServicePointManager]::SecurityProtocol -band $tls12) -eq 0 ) { - [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor $tls12 - } - $null = Invoke-WebRequest -Uri ${uri} -OutFile "${installScriptName}" - } - finally { - [System.Net.ServicePointManager]::SecurityProtocol = $securityProtocol - } - if ( (Test-Path Variable:IsWindows) -and -not $IsWindows ) { - chmod +x $installScriptName - } - $installScript = Get-Item $installScriptName -ErrorAction Stop - if ( -not $installScript ) { - throw "Download failure of ${uri}" - } - return $installScript -} - -function Receive-DotnetInstallScript -{ - # param '$platform' is a hook to enable forcing download of a specific - # install script, generally it should not be used except in testing. - param ( $platform = "" ) - - # if $platform has been set, it has priority - # if it's not set to Windows or NonWindows, it will be ignored - if ( $platform -eq "Windows" ) { - $installScriptName = "dotnet-install.ps1" - } - elseif ( $platform -eq "NonWindows" ) { - $installScriptName = "dotnet-install.sh" - } - elseif ( ((Test-Path Variable:IsWindows) -and -not $IsWindows) ) { - # if the variable IsWindows exists and it is set to false - $installScriptName = "dotnet-install.sh" - } - else { # the default case - we're running on a Windows system - $installScriptName = "dotnet-install.ps1" - } - $uri = "https://dot.net/v1/$%7BinstallScriptName%7D" - - $installScript = Receive-File -Uri $uri - return $installScript.FullName -} - function Get-DotnetExe { param ( $version = $script:wantedVersion ) @@ -731,7 +572,7 @@ try { $script:DotnetExe = Get-DotnetExe } catch { - Write-Warning "Could not find dotnet executable" + Write-Warning "The dotnet CLI was not found, please install it: https://aka.ms/dotnet-cli" } # Copies the built PSCompatibilityCollector module to the output destination for PSSA @@ -781,44 +622,11 @@ function Copy-CrossCompatibilityModule } } -# copy the manifest into the module if is present -function Copy-Manifest -{ - param ( [switch]$signed ) - if ( $signed ) { - $buildRoot = "signed" - } - else { - $buildRoot = "out" - } - $analyzerVersion = Get-AnalyzerVersion - # location where analyzer goes - # debugging - (Get-ChildItem -File -Recurse)|ForEach-Object {Write-Verbose -Verbose -Message $_} - $modBaseDir = [io.path]::Combine($projectRoot,${buildRoot},"${analyzerName}", $analyzerVersion) - # copy the manifest files - Push-Location $buildRoot - if ( Test-Path _manifest ) { - Copy-Item -Recurse -Path _manifest -Destination $modBaseDir -Verbose - } - else { - Write-Warning -Message "_manifest not found in $PWD" - } - Pop-Location -} - # creates the nuget package which can be used for publishing to the gallery function Start-CreatePackage { - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCompatibleCommands', '')] - param ( [switch]$signed ) try { - if ( $signed ) { - $buildRoot = "signed" - } - else { - $buildRoot = "out" - } + $buildRoot = "out" $repoName = [guid]::NewGuid().ToString() $nupkgDir = Join-Path $PSScriptRoot $buildRoot $null = Register-PSRepository -Name $repoName -InstallationPolicy Trusted -SourceLocation $nupkgDir diff --git a/docs/Cmdlets/Get-ScriptAnalyzerRule.md b/docs/Cmdlets/Get-ScriptAnalyzerRule.md index 90366c5b0..a86d7d301 100644 --- a/docs/Cmdlets/Get-ScriptAnalyzerRule.md +++ b/docs/Cmdlets/Get-ScriptAnalyzerRule.md @@ -1,7 +1,6 @@ --- external help file: Microsoft.Windows.PowerShell.ScriptAnalyzer.dll-Help.xml Module Name: PSScriptAnalyzer -ms.custom: PSSA v1.22.0 ms.date: 10/07/2021 online version: https://learn.microsoft.com/powershell/module/psscriptanalyzer/get-scriptanalyzerrule?view=ps-modules&wt.mc_id=ps-gethelp schema: 2.0.0 diff --git a/docs/Cmdlets/Invoke-Formatter.md b/docs/Cmdlets/Invoke-Formatter.md index 88dd320ae..1ffb766ce 100644 --- a/docs/Cmdlets/Invoke-Formatter.md +++ b/docs/Cmdlets/Invoke-Formatter.md @@ -1,7 +1,6 @@ --- external help file: Microsoft.Windows.PowerShell.ScriptAnalyzer.dll-Help.xml Module Name: PSScriptAnalyzer -ms.custom: PSSA v1.22.0 ms.date: 10/07/2021 online version: https://learn.microsoft.com/powershell/module/psscriptanalyzer/invoke-formatter?view=ps-modules&wt.mc_id=ps-gethelp schema: 2.0.0 diff --git a/docs/Cmdlets/Invoke-ScriptAnalyzer.md b/docs/Cmdlets/Invoke-ScriptAnalyzer.md index 9d0195c86..4eb1bff5f 100644 --- a/docs/Cmdlets/Invoke-ScriptAnalyzer.md +++ b/docs/Cmdlets/Invoke-ScriptAnalyzer.md @@ -1,7 +1,6 @@ --- external help file: Microsoft.Windows.PowerShell.ScriptAnalyzer.dll-Help.xml Module Name: PSScriptAnalyzer -ms.custom: PSSA v1.22.0 ms.date: 10/07/2021 online version: https://learn.microsoft.com/powershell/module/psscriptanalyzer/invoke-scriptanalyzer?view=ps-modules&wt.mc_id=ps-gethelp schema: 2.0.0 diff --git a/docs/Cmdlets/PSScriptAnalyzer.md b/docs/Cmdlets/PSScriptAnalyzer.md index b7267e8b5..df190238e 100644 --- a/docs/Cmdlets/PSScriptAnalyzer.md +++ b/docs/Cmdlets/PSScriptAnalyzer.md @@ -1,10 +1,9 @@ --- Download Help Link: https://aka.ms/ps-modules-help -Help Version: 1.22.0 +Help Version: 1.23.0 Locale: en-US Module Guid: d6245802-193d-4068-a631-8863a4342a18 Module Name: PSScriptAnalyzer -ms.custom: PSSA v1.22.0 ms.date: 10/07/2021 --- diff --git a/docs/Rules/AlignAssignmentStatement.md b/docs/Rules/AlignAssignmentStatement.md index e41bff7a1..c2709ac1a 100644 --- a/docs/Rules/AlignAssignmentStatement.md +++ b/docs/Rules/AlignAssignmentStatement.md @@ -1,6 +1,5 @@ --- description: Align assignment statement -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AlignAssignmentStatement diff --git a/docs/Rules/AvoidAssignmentToAutomaticVariable.md b/docs/Rules/AvoidAssignmentToAutomaticVariable.md index 572e9eb3a..f8203dc8e 100644 --- a/docs/Rules/AvoidAssignmentToAutomaticVariable.md +++ b/docs/Rules/AvoidAssignmentToAutomaticVariable.md @@ -1,6 +1,5 @@ --- description: Changing automatic variables might have undesired side effects -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidAssignmentToAutomaticVariable diff --git a/docs/Rules/AvoidDefaultValueForMandatoryParameter.md b/docs/Rules/AvoidDefaultValueForMandatoryParameter.md index ac5fdfc9c..19c9aa732 100644 --- a/docs/Rules/AvoidDefaultValueForMandatoryParameter.md +++ b/docs/Rules/AvoidDefaultValueForMandatoryParameter.md @@ -1,6 +1,5 @@ --- description: Avoid Default Value For Mandatory Parameter -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidDefaultValueForMandatoryParameter diff --git a/docs/Rules/AvoidDefaultValueSwitchParameter.md b/docs/Rules/AvoidDefaultValueSwitchParameter.md index 74e76bdc6..7cfbbc212 100644 --- a/docs/Rules/AvoidDefaultValueSwitchParameter.md +++ b/docs/Rules/AvoidDefaultValueSwitchParameter.md @@ -1,6 +1,5 @@ --- description: Switch Parameters Should Not Default To True -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidDefaultValueSwitchParameter diff --git a/docs/Rules/AvoidExclaimOperator.md b/docs/Rules/AvoidExclaimOperator.md index 5ef833fc0..11d078d6b 100644 --- a/docs/Rules/AvoidExclaimOperator.md +++ b/docs/Rules/AvoidExclaimOperator.md @@ -1,29 +1,33 @@ --- description: Avoid exclaim operator -ms.custom: PSSA v1.22.0 -ms.date: 06/14/2023 +ms.date: 03/26/2024 ms.topic: reference title: AvoidExclaimOperator --- # AvoidExclaimOperator + **Severity Level: Warning** ## Description -The negation operator `!` should not be used for readability purposes. Use `-not` instead. +Avoid using the negation operator (`!`). Use `-not` for improved readability. -**Note**: This rule is not enabled by default. The user needs to enable it through settings. +> [!NOTE] +> This rule is not enabled by default. The user needs to enable it through settings. ## How to Fix ## Example -### Wrong: -```PowerShell + +### Wrong + +```powershell $MyVar = !$true ``` -### Correct: -```PowerShell +### Correct + +```powershell $MyVar = -not $true ``` @@ -39,6 +43,6 @@ Rules = @{ ### Parameters -#### Enable: bool (Default value is `$false`) +- `Enable`: **bool** (Default value is `$false`) -Enable or disable the rule during ScriptAnalyzer invocation. \ No newline at end of file + Enable or disable the rule during ScriptAnalyzer invocation. diff --git a/docs/Rules/AvoidGlobalAliases.md b/docs/Rules/AvoidGlobalAliases.md index 36c581ca6..5157ec6f1 100644 --- a/docs/Rules/AvoidGlobalAliases.md +++ b/docs/Rules/AvoidGlobalAliases.md @@ -1,6 +1,5 @@ --- description: Avoid global aliases. -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidGlobalAliases diff --git a/docs/Rules/AvoidGlobalFunctions.md b/docs/Rules/AvoidGlobalFunctions.md index ef267ef8b..f74b094cb 100644 --- a/docs/Rules/AvoidGlobalFunctions.md +++ b/docs/Rules/AvoidGlobalFunctions.md @@ -1,6 +1,5 @@ --- description: Avoid global functions and aliases -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidGlobalFunctions diff --git a/docs/Rules/AvoidGlobalVars.md b/docs/Rules/AvoidGlobalVars.md index 0edcd4753..7fa0f6d2f 100644 --- a/docs/Rules/AvoidGlobalVars.md +++ b/docs/Rules/AvoidGlobalVars.md @@ -1,6 +1,5 @@ --- description: No Global Variables -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidGlobalVars diff --git a/docs/Rules/AvoidInvokingEmptyMembers.md b/docs/Rules/AvoidInvokingEmptyMembers.md index d512601ad..6049e869b 100644 --- a/docs/Rules/AvoidInvokingEmptyMembers.md +++ b/docs/Rules/AvoidInvokingEmptyMembers.md @@ -1,6 +1,5 @@ --- description: Avoid Invoking Empty Members -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidInvokingEmptyMembers diff --git a/docs/Rules/AvoidLongLines.md b/docs/Rules/AvoidLongLines.md index 2dd94369a..cc2603c51 100644 --- a/docs/Rules/AvoidLongLines.md +++ b/docs/Rules/AvoidLongLines.md @@ -1,6 +1,5 @@ --- description: Avoid long lines -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidLongLines diff --git a/docs/Rules/AvoidMultipleTypeAttributes.md b/docs/Rules/AvoidMultipleTypeAttributes.md index f97d183c0..9ccd478c5 100644 --- a/docs/Rules/AvoidMultipleTypeAttributes.md +++ b/docs/Rules/AvoidMultipleTypeAttributes.md @@ -1,6 +1,5 @@ --- description: Avoid multiple type specifiers on parameters. -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidMultipleTypeAttributes diff --git a/docs/Rules/AvoidNullOrEmptyHelpMessageAttribute.md b/docs/Rules/AvoidNullOrEmptyHelpMessageAttribute.md index cee57e0e2..386c96050 100644 --- a/docs/Rules/AvoidNullOrEmptyHelpMessageAttribute.md +++ b/docs/Rules/AvoidNullOrEmptyHelpMessageAttribute.md @@ -1,6 +1,5 @@ --- description: Avoid using null or empty HelpMessage parameter attribute. -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidNullOrEmptyHelpMessageAttribute diff --git a/docs/Rules/AvoidOverwritingBuiltInCmdlets.md b/docs/Rules/AvoidOverwritingBuiltInCmdlets.md index cd7f9c3a6..1d94a618a 100644 --- a/docs/Rules/AvoidOverwritingBuiltInCmdlets.md +++ b/docs/Rules/AvoidOverwritingBuiltInCmdlets.md @@ -1,6 +1,5 @@ --- description: Avoid overwriting built in cmdlets -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidOverwritingBuiltInCmdlets diff --git a/docs/Rules/AvoidSemicolonsAsLineTerminators.md b/docs/Rules/AvoidSemicolonsAsLineTerminators.md index f6d0d69b7..4716238ce 100644 --- a/docs/Rules/AvoidSemicolonsAsLineTerminators.md +++ b/docs/Rules/AvoidSemicolonsAsLineTerminators.md @@ -1,6 +1,5 @@ --- description: Avoid semicolons as line terminators -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidSemicolonsAsLineTerminators diff --git a/docs/Rules/AvoidShouldContinueWithoutForce.md b/docs/Rules/AvoidShouldContinueWithoutForce.md index dba5e6857..189989a89 100644 --- a/docs/Rules/AvoidShouldContinueWithoutForce.md +++ b/docs/Rules/AvoidShouldContinueWithoutForce.md @@ -1,6 +1,5 @@ --- description: Avoid Using ShouldContinue Without Boolean Force Parameter -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidShouldContinueWithoutForce diff --git a/docs/Rules/AvoidTrailingWhitespace.md b/docs/Rules/AvoidTrailingWhitespace.md index 9740d429c..416948c3b 100644 --- a/docs/Rules/AvoidTrailingWhitespace.md +++ b/docs/Rules/AvoidTrailingWhitespace.md @@ -1,6 +1,5 @@ --- description: Avoid trailing whitespace -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidTrailingWhitespace diff --git a/docs/Rules/AvoidUsingAllowUnencryptedAuthentication.md b/docs/Rules/AvoidUsingAllowUnencryptedAuthentication.md index c30b69844..20451e66f 100644 --- a/docs/Rules/AvoidUsingAllowUnencryptedAuthentication.md +++ b/docs/Rules/AvoidUsingAllowUnencryptedAuthentication.md @@ -1,7 +1,6 @@ --- description: Avoid sending credentials and secrets over unencrypted connections -ms.custom: PSSA v1.22.0 -ms.date: 11/06/2022 +ms.date: 02/28/2024 ms.topic: reference title: AvoidUsingAllowUnencryptedAuthentication --- @@ -11,14 +10,15 @@ title: AvoidUsingAllowUnencryptedAuthentication ## Description -Avoid using the `AllowUnencryptedAuthentication` switch on `Invoke-WebRequest`, `Invoke-RestMethod`, and other webrequest cmdlets, which sends credentials and secrets over unencrypted connections. -This should be avoided except for compatability with legacy systems. +Avoid using the **AllowUnencryptedAuthentication** parameter of `Invoke-WebRequest` and +`Invoke-RestMethod`. When using this parameter, the cmdlets send credentials and secrets over +unencrypted connections. This should be avoided except for compatibility with legacy systems. -For more details, see the documentation warning [here](https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/invoke-webrequest#-allowunencryptedauthentication). +For more details, see [Invoke-RestMethod](xref:Microsoft.PowerShell.Utility.Invoke-RestMethod). ## How -Avoid using the `AllowUnencryptedAuthentication` switch. +Avoid using the **AllowUnencryptedAuthentication** parameter. ## Example 1 @@ -32,4 +32,4 @@ Invoke-WebRequest foo -AllowUnencryptedAuthentication ```powershell Invoke-WebRequest foo -``` \ No newline at end of file +``` diff --git a/docs/Rules/AvoidUsingBrokenHashAlgorithms.md b/docs/Rules/AvoidUsingBrokenHashAlgorithms.md index a8fc60dc1..32bb464af 100644 --- a/docs/Rules/AvoidUsingBrokenHashAlgorithms.md +++ b/docs/Rules/AvoidUsingBrokenHashAlgorithms.md @@ -1,6 +1,5 @@ --- description: Avoid using broken hash algorithms -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidUsingBrokenHashAlgorithms diff --git a/docs/Rules/AvoidUsingCmdletAliases.md b/docs/Rules/AvoidUsingCmdletAliases.md index 25adb3767..48c914eec 100644 --- a/docs/Rules/AvoidUsingCmdletAliases.md +++ b/docs/Rules/AvoidUsingCmdletAliases.md @@ -1,6 +1,5 @@ --- description: Avoid Using Cmdlet Aliases or omitting the 'Get-' prefix. -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidUsingCmdletAliases diff --git a/docs/Rules/AvoidUsingComputerNameHardcoded.md b/docs/Rules/AvoidUsingComputerNameHardcoded.md index f15b69c06..83a60c950 100644 --- a/docs/Rules/AvoidUsingComputerNameHardcoded.md +++ b/docs/Rules/AvoidUsingComputerNameHardcoded.md @@ -1,6 +1,5 @@ --- description: Avoid Using ComputerName Hardcoded -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidUsingComputerNameHardcoded diff --git a/docs/Rules/AvoidUsingConvertToSecureStringWithPlainText.md b/docs/Rules/AvoidUsingConvertToSecureStringWithPlainText.md index fa6a0df0e..5a94d89a3 100644 --- a/docs/Rules/AvoidUsingConvertToSecureStringWithPlainText.md +++ b/docs/Rules/AvoidUsingConvertToSecureStringWithPlainText.md @@ -1,6 +1,5 @@ --- description: Avoid Using SecureString With Plain Text -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidUsingConvertToSecureStringWithPlainText diff --git a/docs/Rules/AvoidUsingDeprecatedManifestFields.md b/docs/Rules/AvoidUsingDeprecatedManifestFields.md index 32bc4d5b5..802304dfc 100644 --- a/docs/Rules/AvoidUsingDeprecatedManifestFields.md +++ b/docs/Rules/AvoidUsingDeprecatedManifestFields.md @@ -1,6 +1,5 @@ --- description: Avoid Using Deprecated Manifest Fields -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidUsingDeprecatedManifestFields diff --git a/docs/Rules/AvoidUsingDoubleQuotesForConstantString.md b/docs/Rules/AvoidUsingDoubleQuotesForConstantString.md index 002a72aca..19c83fad7 100644 --- a/docs/Rules/AvoidUsingDoubleQuotesForConstantString.md +++ b/docs/Rules/AvoidUsingDoubleQuotesForConstantString.md @@ -1,6 +1,5 @@ --- description: Avoid using double quotes if the string is constant. -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidUsingDoubleQuotesForConstantString diff --git a/docs/Rules/AvoidUsingEmptyCatchBlock.md b/docs/Rules/AvoidUsingEmptyCatchBlock.md index 8c944563f..198341758 100644 --- a/docs/Rules/AvoidUsingEmptyCatchBlock.md +++ b/docs/Rules/AvoidUsingEmptyCatchBlock.md @@ -1,6 +1,5 @@ --- description: Avoid Using Empty Catch Block -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidUsingEmptyCatchBlock diff --git a/docs/Rules/AvoidUsingInvokeExpression.md b/docs/Rules/AvoidUsingInvokeExpression.md index 570b51ac4..7779008ec 100644 --- a/docs/Rules/AvoidUsingInvokeExpression.md +++ b/docs/Rules/AvoidUsingInvokeExpression.md @@ -1,6 +1,5 @@ --- description: Avoid Using Invoke-Expression -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidUsingInvokeExpression diff --git a/docs/Rules/AvoidUsingPlainTextForPassword.md b/docs/Rules/AvoidUsingPlainTextForPassword.md index 3d2b9f6e0..c25123ec1 100644 --- a/docs/Rules/AvoidUsingPlainTextForPassword.md +++ b/docs/Rules/AvoidUsingPlainTextForPassword.md @@ -1,6 +1,5 @@ --- description: Avoid Using Plain Text For Password Parameter -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidUsingPlainTextForPassword diff --git a/docs/Rules/AvoidUsingPositionalParameters.md b/docs/Rules/AvoidUsingPositionalParameters.md index 0078ffd70..1a1b77d01 100644 --- a/docs/Rules/AvoidUsingPositionalParameters.md +++ b/docs/Rules/AvoidUsingPositionalParameters.md @@ -1,7 +1,6 @@ --- description: Avoid Using Positional Parameters -ms.custom: PSSA v1.22.0 -ms.date: 06/28/2023 +ms.date: 02/13/2024 ms.topic: reference title: AvoidUsingPositionalParameters --- diff --git a/docs/Rules/AvoidUsingUsernameAndPasswordParams.md b/docs/Rules/AvoidUsingUsernameAndPasswordParams.md index b37bbfd42..32fbac3c7 100644 --- a/docs/Rules/AvoidUsingUsernameAndPasswordParams.md +++ b/docs/Rules/AvoidUsingUsernameAndPasswordParams.md @@ -1,6 +1,5 @@ --- description: Avoid Using Username and Password Parameters -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidUsingUsernameAndPasswordParams diff --git a/docs/Rules/AvoidUsingWMICmdlet.md b/docs/Rules/AvoidUsingWMICmdlet.md index 47888b361..96e716718 100644 --- a/docs/Rules/AvoidUsingWMICmdlet.md +++ b/docs/Rules/AvoidUsingWMICmdlet.md @@ -1,6 +1,5 @@ --- description: Avoid Using Get-WMIObject, Remove-WMIObject, Invoke-WmiMethod, Register-WmiEvent, Set-WmiInstance -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidUsingWMICmdlet diff --git a/docs/Rules/AvoidUsingWriteHost.md b/docs/Rules/AvoidUsingWriteHost.md index 930202d4f..561914168 100644 --- a/docs/Rules/AvoidUsingWriteHost.md +++ b/docs/Rules/AvoidUsingWriteHost.md @@ -1,6 +1,5 @@ --- description: Avoid Using Write-Host -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: AvoidUsingWriteHost diff --git a/docs/Rules/DSCDscExamplesPresent.md b/docs/Rules/DSCDscExamplesPresent.md index aaf84d185..b2b1cf608 100644 --- a/docs/Rules/DSCDscExamplesPresent.md +++ b/docs/Rules/DSCDscExamplesPresent.md @@ -1,6 +1,5 @@ --- description: DSC examples are present -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: DSCDscExamplesPresent diff --git a/docs/Rules/DSCDscTestsPresent.md b/docs/Rules/DSCDscTestsPresent.md index 22eca027f..f8fe31983 100644 --- a/docs/Rules/DSCDscTestsPresent.md +++ b/docs/Rules/DSCDscTestsPresent.md @@ -1,6 +1,5 @@ --- description: Dsc tests are present -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: DSCDscTestsPresent diff --git a/docs/Rules/DSCReturnCorrectTypesForDSCFunctions.md b/docs/Rules/DSCReturnCorrectTypesForDSCFunctions.md index 882a492ca..168185280 100644 --- a/docs/Rules/DSCReturnCorrectTypesForDSCFunctions.md +++ b/docs/Rules/DSCReturnCorrectTypesForDSCFunctions.md @@ -1,6 +1,5 @@ --- description: Return Correct Types For DSC Functions -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: DSCReturnCorrectTypesForDSCFunctions diff --git a/docs/Rules/DSCStandardDSCFunctionsInResource.md b/docs/Rules/DSCStandardDSCFunctionsInResource.md index 6280e412c..f455d7437 100644 --- a/docs/Rules/DSCStandardDSCFunctionsInResource.md +++ b/docs/Rules/DSCStandardDSCFunctionsInResource.md @@ -1,6 +1,5 @@ --- description: Use Standard Get/Set/Test TargetResource functions in DSC Resource -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: DSCStandardDSCFunctionsInResource diff --git a/docs/Rules/DSCUseIdenticalMandatoryParametersForDSC.md b/docs/Rules/DSCUseIdenticalMandatoryParametersForDSC.md index 2c6f04709..dc8e9e918 100644 --- a/docs/Rules/DSCUseIdenticalMandatoryParametersForDSC.md +++ b/docs/Rules/DSCUseIdenticalMandatoryParametersForDSC.md @@ -1,6 +1,5 @@ --- description: Use identical mandatory parameters for DSC Get/Test/Set TargetResource functions -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: DSCUseIdenticalMandatoryParametersForDSC diff --git a/docs/Rules/DSCUseIdenticalParametersForDSC.md b/docs/Rules/DSCUseIdenticalParametersForDSC.md index 2497f41ad..8f8e98e55 100644 --- a/docs/Rules/DSCUseIdenticalParametersForDSC.md +++ b/docs/Rules/DSCUseIdenticalParametersForDSC.md @@ -1,6 +1,5 @@ --- description: Use Identical Parameters For DSC Test and Set Functions -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: DSCUseIdenticalParametersForDSC diff --git a/docs/Rules/DSCUseVerboseMessageInDSCResource.md b/docs/Rules/DSCUseVerboseMessageInDSCResource.md index 49ef63ed4..bb5abacef 100644 --- a/docs/Rules/DSCUseVerboseMessageInDSCResource.md +++ b/docs/Rules/DSCUseVerboseMessageInDSCResource.md @@ -1,6 +1,5 @@ --- description: Use verbose message in DSC resource -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: DSCUseVerboseMessageInDSCResource diff --git a/docs/Rules/MisleadingBacktick.md b/docs/Rules/MisleadingBacktick.md index 3194e706f..e140b8e9d 100644 --- a/docs/Rules/MisleadingBacktick.md +++ b/docs/Rules/MisleadingBacktick.md @@ -1,6 +1,5 @@ --- description: Misleading Backtick -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: MisleadingBacktick diff --git a/docs/Rules/MissingModuleManifestField.md b/docs/Rules/MissingModuleManifestField.md index efcf70af1..c19d53454 100644 --- a/docs/Rules/MissingModuleManifestField.md +++ b/docs/Rules/MissingModuleManifestField.md @@ -1,6 +1,5 @@ --- description: Module Manifest Fields -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: MissingModuleManifestField diff --git a/docs/Rules/PlaceCloseBrace.md b/docs/Rules/PlaceCloseBrace.md index d181eebd9..6e14acc74 100644 --- a/docs/Rules/PlaceCloseBrace.md +++ b/docs/Rules/PlaceCloseBrace.md @@ -1,6 +1,5 @@ --- description: Place close braces -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: PlaceCloseBrace diff --git a/docs/Rules/PlaceOpenBrace.md b/docs/Rules/PlaceOpenBrace.md index bc3e4b5e2..faa6d4c5d 100644 --- a/docs/Rules/PlaceOpenBrace.md +++ b/docs/Rules/PlaceOpenBrace.md @@ -1,6 +1,5 @@ --- description: Place open braces consistently -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: PlaceOpenBrace diff --git a/docs/Rules/PossibleIncorrectComparisonWithNull.md b/docs/Rules/PossibleIncorrectComparisonWithNull.md index d3c62321b..28c9c7075 100644 --- a/docs/Rules/PossibleIncorrectComparisonWithNull.md +++ b/docs/Rules/PossibleIncorrectComparisonWithNull.md @@ -1,6 +1,5 @@ --- description: Null Comparison -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: PossibleIncorrectComparisonWithNull diff --git a/docs/Rules/PossibleIncorrectUsageOfAssignmentOperator.md b/docs/Rules/PossibleIncorrectUsageOfAssignmentOperator.md index 8d046e302..bbaf437b8 100644 --- a/docs/Rules/PossibleIncorrectUsageOfAssignmentOperator.md +++ b/docs/Rules/PossibleIncorrectUsageOfAssignmentOperator.md @@ -1,6 +1,5 @@ --- description: Equal sign is not an assignment operator. Did you mean the equality operator \'-eq\'? -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: PossibleIncorrectUsageOfAssignmentOperator diff --git a/docs/Rules/PossibleIncorrectUsageOfRedirectionOperator.md b/docs/Rules/PossibleIncorrectUsageOfRedirectionOperator.md index cfd00c05b..871d1340f 100644 --- a/docs/Rules/PossibleIncorrectUsageOfRedirectionOperator.md +++ b/docs/Rules/PossibleIncorrectUsageOfRedirectionOperator.md @@ -1,6 +1,5 @@ --- description: \'>\' is not a comparison operator. Use \'-gt\' (greater than) or \'-ge\' (greater or equal). -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: PossibleIncorrectUsageOfRedirectionOperator diff --git a/docs/Rules/ProvideCommentHelp.md b/docs/Rules/ProvideCommentHelp.md index c6e373f36..8c642419f 100644 --- a/docs/Rules/ProvideCommentHelp.md +++ b/docs/Rules/ProvideCommentHelp.md @@ -1,6 +1,5 @@ --- description: Basic Comment Help -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: ProvideCommentHelp @@ -17,9 +16,9 @@ presence of comment based help and not on the validity or format. For assistance on comment based help, use the command `Get-Help about_comment_based_help` or the following articles: -- [Writing Comment-based Help](https://learn.microsoft.com/powershell/scripting/developer/help/writing-comment-based-help-topics) -- [Writing Help for PowerShell Cmdlets](https://learn.microsoft.com/powershell/scripting/developer/help/writing-help-for-windows-powershell-cmdlets) -- [Create XML-based help using PlatyPS](https://learn.microsoft.com/powershell/utility-modules/platyps/create-help-using-platyps) +- [Writing Comment-based Help][01] +- [Writing Help for PowerShell Cmdlets][02] +- [Create XML-based help using PlatyPS][03] ## Configuration @@ -37,34 +36,35 @@ Rules = @{ ### Parameters -#### Enable: bool (Default valus is `$true`) +- `Enable`: **bool** (Default valus is `$true`) -Enable or disable the rule during ScriptAnalyzer invocation. + Enable or disable the rule during ScriptAnalyzer invocation. -#### ExportedOnly: bool (Default value is `$true`) +- `ExportedOnly`: **bool** (Default value is `$true`) -If enabled, throw violation only on functions/cmdlets that are exported using the -`Export-ModuleMember` cmdlet. + If enabled, throw violation only on functions/cmdlets that are exported using the + `Export-ModuleMember` cmdlet. -#### BlockComment: bool (Default value is `$true`) +- `BlockComment`: **bool** (Default value is `$true`) -If enabled, returns comment help in block comment style, i.e., `<#...#>`. Otherwise returns comment -help in line comment style, i.e., each comment line starts with `#`. + If enabled, returns comment help in block comment style (`<#...#>`). Otherwise returns + comment help in line comment style where each comment line starts with `#`. -#### VSCodeSnippetCorrection: bool (Default value is `$false`) +- `VSCodeSnippetCorrection`: **bool** (Default value is `$false`) -If enabled, returns comment help in vscode snippet format. + If enabled, returns comment help in vscode snippet format. -#### Placement: string (Default value is `before`) +- `Placement`: **string** (Default value is `before`) -Represents the position of comment help with respect to the function definition. + Represents the position of comment help with respect to the function definition. -Possible values are: `before`, `begin` and `end`. If any invalid value is given, the property -defaults to `before`. + Possible values are: -`before` means the help is placed before the function definition. `begin` means the help is placed -at the beginning of the function definition body. `end` means the help is places the end of the -function definition body. + - `before`: means the help is placed before the function definition + - `begin` means the help is placed at the beginning of the function definition body + - `end` means the help is places the end of the function definition body + + If any invalid value is given, the property defaults to `before`. ## Example @@ -118,3 +118,7 @@ function Get-File } ``` + +[01]: https://learn.microsoft.com/powershell/scripting/developer/help/writing-comment-based-help-topics +[02]: https://learn.microsoft.com/powershell/scripting/developer/help/writing-help-for-windows-powershell-cmdlets +[03]: https://learn.microsoft.com/powershell/utility-modules/platyps/create-help-using-platyps diff --git a/docs/Rules/README.md b/docs/Rules/README.md index ded305e89..06f27d2da 100644 --- a/docs/Rules/README.md +++ b/docs/Rules/README.md @@ -1,7 +1,6 @@ --- description: List of PSScriptAnalyzer rules -ms.custom: PSSA v1.22.0 -ms.date: 06/28/2023 +ms.date: 03/27/2024 ms.topic: reference title: List of PSScriptAnalyzer rules --- @@ -58,7 +57,7 @@ The PSScriptAnalyzer contains the following rule definitions. | [ProvideCommentHelp](./ProvideCommentHelp.md) | Information | Yes | Yes | | [ReservedCmdletChar](./ReservedCmdletChar.md) | Error | Yes | | | [ReservedParams](./ReservedParams.md) | Error | Yes | | -| [ReviewUnusedParameter](./ReviewUnusedParameter.md) | Warning | Yes | | +| [ReviewUnusedParameter](./ReviewUnusedParameter.md) | Warning | Yes | Yes2 | | [ShouldProcess](./ShouldProcess.md) | Warning | Yes | | | [UseApprovedVerbs](./UseApprovedVerbs.md) | Warning | Yes | | | [UseBOMForUnicodeEncodedFile](./UseBOMForUnicodeEncodedFile.md) | Warning | Yes | | @@ -84,5 +83,5 @@ The PSScriptAnalyzer contains the following rule definitions. - 1 Rule is not available on all PowerShell versions, editions, or OS platforms. See the rule's documentation for details. -- 2 The rule a configurable property, but the rule can't be disabled like other +- 2 The rule has a configurable property, but the rule can't be disabled like other configurable rules. diff --git a/docs/Rules/ReservedCmdletChar.md b/docs/Rules/ReservedCmdletChar.md index e4195d42b..55acfc707 100644 --- a/docs/Rules/ReservedCmdletChar.md +++ b/docs/Rules/ReservedCmdletChar.md @@ -1,6 +1,5 @@ --- description: Reserved Cmdlet Chars -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: ReservedCmdletChar diff --git a/docs/Rules/ReservedParams.md b/docs/Rules/ReservedParams.md index 2d38c1af2..0e433e0e4 100644 --- a/docs/Rules/ReservedParams.md +++ b/docs/Rules/ReservedParams.md @@ -1,7 +1,6 @@ --- description: Reserved Parameters -ms.custom: PSSA v1.22.0 -ms.date: 06/28/2023 +ms.date: 03/06/2024 ms.topic: reference title: ReservedParams --- @@ -11,9 +10,9 @@ title: ReservedParams ## Description -You cannot use [reserved common parameters][01] in an advanced function. - -[01]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_commonparameters +You can't redefine [common parameters][01] in an advanced function. Using the `CmdletBinding` or +`Parameter` attributes creates an advanced function. The common parameters are are automatically +available in advanced functions, so you can't redefine them. ## How @@ -48,3 +47,5 @@ function Test ) } ``` + +[01]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_commonparameters diff --git a/docs/Rules/ReviewUnusedParameter.md b/docs/Rules/ReviewUnusedParameter.md index 1673bb5a3..4732b8aba 100644 --- a/docs/Rules/ReviewUnusedParameter.md +++ b/docs/Rules/ReviewUnusedParameter.md @@ -1,7 +1,6 @@ --- description: ReviewUnusedParameter -ms.custom: PSSA v1.22.0 -ms.date: 06/28/2023 +ms.date: 03/26/2024 ms.topic: reference title: ReviewUnusedParameter --- @@ -16,14 +15,14 @@ been used in that scope. ## Configuration settings -|Configuration key|Meaning|Accepted values|Mandatory|Example| -|---|---|---|---|---| -|CommandsToTraverse|By default, this command will not consider child scopes other than scriptblocks provided to Where-Object or ForEach-Object. This setting allows you to add additional commands that accept scriptblocks that this rule should traverse into.|string[]: list of commands whose scriptblock to traverse.|`@('Invoke-PSFProtectedCommand')`| +By default, this rule doesn't consider child scopes other than scriptblocks provided to +`Where-Object` or `ForEach-Object`. The `CommandsToTraverse` setting is an string array allows you +to add additional commands that accept scriptblocks that this rule should examine. ```powershell @{ Rules = @{ - ReviewUnusedParameter = @{ + PSReviewUnusedParameter = @{ CommandsToTraverse = @( 'Invoke-PSFProtectedCommand' ) diff --git a/docs/Rules/ShouldProcess.md b/docs/Rules/ShouldProcess.md index 6746c3621..40dcedec4 100644 --- a/docs/Rules/ShouldProcess.md +++ b/docs/Rules/ShouldProcess.md @@ -1,6 +1,5 @@ --- description: Should Process -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: ShouldProcess @@ -18,9 +17,9 @@ but makes no calls to `ShouldProcess` or it calls `ShouldProcess` but does not d For more information, see the following articles: -- [about_Functions_Advanced_Methods](https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_functions_advanced_methods) -- [about_Functions_CmdletBindingAttribute](https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_Functions_CmdletBindingAttribute) -- [Everything you wanted to know about ShouldProcess](https://learn.microsoft.com/powershell/scripting/learn/deep-dives/everything-about-shouldprocess) +- [about_Functions_Advanced_Methods][01] +- [about_Functions_CmdletBindingAttribute][02] +- [Everything you wanted to know about ShouldProcess][03] ## How @@ -73,3 +72,7 @@ function Set-File } } ``` + +[01]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_functions_advanced_methods +[02]: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_Functions_CmdletBindingAttribute +[03]: https://learn.microsoft.com/powershell/scripting/learn/deep-dives/everything-about-shouldprocess diff --git a/docs/Rules/UseApprovedVerbs.md b/docs/Rules/UseApprovedVerbs.md index f4d685585..c1bcaa0c7 100644 --- a/docs/Rules/UseApprovedVerbs.md +++ b/docs/Rules/UseApprovedVerbs.md @@ -1,7 +1,6 @@ --- description: Cmdlet Verbs -ms.custom: PSSA v1.22.0 -ms.date: 06/28/2023 +ms.date: 03/26/2024 ms.topic: reference title: UseApprovedVerbs --- @@ -15,10 +14,9 @@ All cmdlets must used approved verbs. Approved verbs can be found by running the command `Get-Verb`. -Additional documentation on approved verbs can be found at -[Approved Verbs for PowerShell Commands](https://learn.microsoft.com/powershell/scripting/developer/cmdlet/approved-verbs-for-windows-powershell-commands). -Some unapproved verbs are documented on the approved verbs page and point to approved alternatives. -Try searching for the verb you used to find its approved form. For example, searching for `Read`, +For a more information about approved verbs, see [Approved Verbs for PowerShell Commands][01]. Some +unapproved verbs are documented on the approved verbs page and point to approved alternatives. Try +searching for the verb you used to find its approved form. For example, searching for `Read`, `Open`, or `Search` leads you to `Get`. ## How @@ -44,3 +42,6 @@ function Update-Item ... } ``` + + +[01]: /powershell/scripting/developer/cmdlet/approved-verbs-for-windows-powershell-commands diff --git a/docs/Rules/UseBOMForUnicodeEncodedFile.md b/docs/Rules/UseBOMForUnicodeEncodedFile.md index 2d174f99e..6fffaa7fe 100644 --- a/docs/Rules/UseBOMForUnicodeEncodedFile.md +++ b/docs/Rules/UseBOMForUnicodeEncodedFile.md @@ -1,6 +1,5 @@ --- description: Use BOM encoding for non-ASCII files -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: UseBOMForUnicodeEncodedFile diff --git a/docs/Rules/UseCmdletCorrectly.md b/docs/Rules/UseCmdletCorrectly.md index 39de79c5c..81ec42e4e 100644 --- a/docs/Rules/UseCmdletCorrectly.md +++ b/docs/Rules/UseCmdletCorrectly.md @@ -1,6 +1,5 @@ --- description: Use Cmdlet Correctly -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: UseCmdletCorrectly diff --git a/docs/Rules/UseCompatibleCmdlets.md b/docs/Rules/UseCompatibleCmdlets.md index a340a6869..1fc9520d4 100644 --- a/docs/Rules/UseCompatibleCmdlets.md +++ b/docs/Rules/UseCompatibleCmdlets.md @@ -1,6 +1,5 @@ --- description: Use compatible cmdlets -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: UseCompatibleCmdlets diff --git a/docs/Rules/UseCompatibleCommands.md b/docs/Rules/UseCompatibleCommands.md index 6e0714f2f..00b768ba3 100644 --- a/docs/Rules/UseCompatibleCommands.md +++ b/docs/Rules/UseCompatibleCommands.md @@ -1,6 +1,5 @@ --- description: Use compatible commands -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: UseCompatibleCommands @@ -102,7 +101,7 @@ An example configuration might look like: ```powershell @{ Rules = @{ - PSUseCompatibleCommmands = @{ + PSUseCompatibleCommands = @{ Enable = $true TargetProfiles = @( 'ubuntu_x64_18.04_6.1.3_x64_4.0.30319.42000_core' diff --git a/docs/Rules/UseCompatibleSyntax.md b/docs/Rules/UseCompatibleSyntax.md index ebea10c22..a2adbbbb6 100644 --- a/docs/Rules/UseCompatibleSyntax.md +++ b/docs/Rules/UseCompatibleSyntax.md @@ -1,6 +1,5 @@ --- description: Use compatible syntax -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: UseCompatibleSyntax diff --git a/docs/Rules/UseCompatibleTypes.md b/docs/Rules/UseCompatibleTypes.md index 72927d140..355f35bed 100644 --- a/docs/Rules/UseCompatibleTypes.md +++ b/docs/Rules/UseCompatibleTypes.md @@ -1,6 +1,5 @@ --- description: Use compatible types -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: UseCompatibleTypes diff --git a/docs/Rules/UseConsistentIndentation.md b/docs/Rules/UseConsistentIndentation.md index fa331a74f..f084d5ac4 100644 --- a/docs/Rules/UseConsistentIndentation.md +++ b/docs/Rules/UseConsistentIndentation.md @@ -1,6 +1,5 @@ --- description: Use consistent indentation -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: UseConsistentIndentation diff --git a/docs/Rules/UseConsistentWhitespace.md b/docs/Rules/UseConsistentWhitespace.md index 1841ed0f5..e36c42783 100644 --- a/docs/Rules/UseConsistentWhitespace.md +++ b/docs/Rules/UseConsistentWhitespace.md @@ -1,6 +1,5 @@ --- description: Use whitespaces -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: UseConsistentWhitespace diff --git a/docs/Rules/UseCorrectCasing.md b/docs/Rules/UseCorrectCasing.md index c39c08875..f64a7888d 100644 --- a/docs/Rules/UseCorrectCasing.md +++ b/docs/Rules/UseCorrectCasing.md @@ -1,6 +1,5 @@ --- description: Use exact casing of cmdlet/function/parameter name. -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: UseCorrectCasing diff --git a/docs/Rules/UseDeclaredVarsMoreThanAssignments.md b/docs/Rules/UseDeclaredVarsMoreThanAssignments.md index 482105db4..e316dbf85 100644 --- a/docs/Rules/UseDeclaredVarsMoreThanAssignments.md +++ b/docs/Rules/UseDeclaredVarsMoreThanAssignments.md @@ -1,7 +1,6 @@ --- description: Extra Variables -ms.custom: PSSA v1.22.0 -ms.date: 06/28/2023 +ms.date: 03/06/2024 ms.topic: reference title: UseDeclaredVarsMoreThanAssignments --- @@ -44,10 +43,13 @@ function Test } ``` -### Special case +### Special cases -The following example triggers the **PSUseDeclaredVarsMoreThanAssignments** warning because `$bar` -is not used within the scriptblock where it was defined. +The following examples trigger the **PSUseDeclaredVarsMoreThanAssignments** warning. This behavior +is a limitation of the rule. There is no way to avoid these false positive warnings. + +In this case, the warning is triggered because `$bar` is not used within the scriptblock where it +was defined. ```powershell $foo | ForEach-Object { @@ -60,3 +62,11 @@ if($bar){ Write-Host 'Collection contained a false case.' } ``` + +In the next example, the warning is triggered because `$errResult` isn't recognized as being used in +the `Write-Host` command. + +```powershell +$errResult = $null +Write-Host 'Ugh:' -ErrorVariable errResult +``` diff --git a/docs/Rules/UseLiteralInitializerForHashtable.md b/docs/Rules/UseLiteralInitializerForHashtable.md index bb180d832..16f9a2f9b 100644 --- a/docs/Rules/UseLiteralInitializerForHashtable.md +++ b/docs/Rules/UseLiteralInitializerForHashtable.md @@ -1,6 +1,5 @@ --- description: Create hashtables with literal initializers -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: UseLiteralInitializerForHashtable diff --git a/docs/Rules/UseOutputTypeCorrectly.md b/docs/Rules/UseOutputTypeCorrectly.md index 01895c17d..733425fdd 100644 --- a/docs/Rules/UseOutputTypeCorrectly.md +++ b/docs/Rules/UseOutputTypeCorrectly.md @@ -1,6 +1,5 @@ --- description: Use OutputType Correctly -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: UseOutputTypeCorrectly diff --git a/docs/Rules/UsePSCredentialType.md b/docs/Rules/UsePSCredentialType.md index c3c2dc7f1..c962762ed 100644 --- a/docs/Rules/UsePSCredentialType.md +++ b/docs/Rules/UsePSCredentialType.md @@ -1,6 +1,5 @@ --- description: Use PSCredential type. -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: UsePSCredentialType diff --git a/docs/Rules/UseProcessBlockForPipelineCommand.md b/docs/Rules/UseProcessBlockForPipelineCommand.md index d74da5a71..2e5630880 100644 --- a/docs/Rules/UseProcessBlockForPipelineCommand.md +++ b/docs/Rules/UseProcessBlockForPipelineCommand.md @@ -1,6 +1,5 @@ --- description: Use process block for command that accepts input from pipeline. -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: UseProcessBlockForPipelineCommand diff --git a/docs/Rules/UseShouldProcessForStateChangingFunctions.md b/docs/Rules/UseShouldProcessForStateChangingFunctions.md index 5c63d150d..f0e102da3 100644 --- a/docs/Rules/UseShouldProcessForStateChangingFunctions.md +++ b/docs/Rules/UseShouldProcessForStateChangingFunctions.md @@ -1,6 +1,5 @@ --- description: Use ShouldProcess For State Changing Functions -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: UseShouldProcessForStateChangingFunctions diff --git a/docs/Rules/UseSingularNouns.md b/docs/Rules/UseSingularNouns.md index 6d1379664..3997c069a 100644 --- a/docs/Rules/UseSingularNouns.md +++ b/docs/Rules/UseSingularNouns.md @@ -1,7 +1,6 @@ --- description: Cmdlet Singular Noun -ms.custom: PSSA v1.22.0 -ms.date: 06/28/2023 +ms.date: 03/27/2024 ms.topic: reference title: UseSingularNouns --- @@ -11,9 +10,8 @@ title: UseSingularNouns ## Description -PowerShell team best practices state cmdlets should use singular nouns and not plurals. - -Suppression allows to suppress just specific function names, for example +PowerShell team best practices state cmdlets should use singular nouns and not plurals. Suppression +allows you to suppress the rule for specific function names. For example: ``` function Get-Elements { @@ -26,22 +24,23 @@ function Get-Elements { ```powershell Rules = @{ - UseSingularNouns = @{ - NounAllowList = 'Data', 'Windows', 'Foos' + PSUseSingularNouns = @{ Enable = $true + NounAllowList = 'Data', 'Windows', 'Foos' } } ``` ### Parameters -#### `UseSingularNouns: string[]` (Default value is `{'Data', 'Windows'}`) +- `Enable`: `bool` (Default value is `$true`) -Commands to be excluded from this rule. `Data` and `Windows` are common false positives and are excluded by default + Enable or disable the rule during ScriptAnalyzer invocation. -#### Enable: `bool` (Default value is `$true`) +- `NounAllowList`: `string[]` (Default value is `{'Data', 'Windows'}`) -Enable or disable the rule during ScriptAnalyzer invocation. + Commands to be excluded from this rule. `Data` and `Windows` are common false positives and are + excluded by default. ## How diff --git a/docs/Rules/UseSupportsShouldProcess.md b/docs/Rules/UseSupportsShouldProcess.md index 40767e060..04ca2bfe7 100644 --- a/docs/Rules/UseSupportsShouldProcess.md +++ b/docs/Rules/UseSupportsShouldProcess.md @@ -1,6 +1,5 @@ --- description: Use SupportsShouldProcess -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: UseSupportsShouldProcess diff --git a/docs/Rules/UseToExportFieldsInManifest.md b/docs/Rules/UseToExportFieldsInManifest.md index 5a4c87c73..5faaf9d1b 100644 --- a/docs/Rules/UseToExportFieldsInManifest.md +++ b/docs/Rules/UseToExportFieldsInManifest.md @@ -1,6 +1,5 @@ --- description: Use the *ToExport module manifest fields. -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: UseToExportFieldsInManifest diff --git a/docs/Rules/UseUTF8EncodingForHelpFile.md b/docs/Rules/UseUTF8EncodingForHelpFile.md index 8f7ab429c..31c525db6 100644 --- a/docs/Rules/UseUTF8EncodingForHelpFile.md +++ b/docs/Rules/UseUTF8EncodingForHelpFile.md @@ -1,6 +1,5 @@ --- description: Use UTF8 Encoding For Help File -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: UseUTF8EncodingForHelpFile diff --git a/docs/Rules/UseUsingScopeModifierInNewRunspaces.md b/docs/Rules/UseUsingScopeModifierInNewRunspaces.md index 86a76561c..bde0f667d 100644 --- a/docs/Rules/UseUsingScopeModifierInNewRunspaces.md +++ b/docs/Rules/UseUsingScopeModifierInNewRunspaces.md @@ -1,6 +1,5 @@ --- description: Use 'Using:' scope modifier in RunSpace ScriptBlocks -ms.custom: PSSA v1.22.0 ms.date: 06/28/2023 ms.topic: reference title: UseUsingScopeModifierInNewRunspaces diff --git a/global.json b/global.json index 1cec616b3..6e6e5445c 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "6.0.418" + "version": "6.0.427" } } diff --git a/tools/appveyor.psm1 b/tools/appveyor.psm1 deleted file mode 100644 index 294e8d096..000000000 --- a/tools/appveyor.psm1 +++ /dev/null @@ -1,174 +0,0 @@ -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. - -$ErrorActionPreference = 'Stop' - -function Install-Pester { - $requiredPesterVersion = '5.3' - $pester = Get-Module Pester -ListAvailable | Where-Object { $_.Version -ge $requiredPesterVersion } - if ($null -eq $pester) { - if ($null -eq (Get-Module -ListAvailable PowershellGet)) { - # WMF 4 image build - Write-Verbose -Verbose "Installing Pester via nuget" - nuget install Pester -Version $requiredPesterVersion -source https://www.powershellgallery.com/api/v2 -outputDirectory "$env:ProgramFiles\WindowsPowerShell\Modules\." -ExcludeVersion - } - else { - # Visual Studio 2017 build (has already Pester v3, therefore a different installation mechanism is needed to make it also use the new version 4) - Write-Verbose -Verbose "Installing Pester via Install-Module" - $installedPester = Install-Module -Name Pester -Force -SkipPublisherCheck -Scope CurrentUser -Repository PSGallery -Verbose -PassThru - } - - $pesterVersion = if ($installedPester) { $installedPester.Version } else { $requiredPesterVersion } - - Write-Verbose -Verbose "Installed Pester version $pesterVersion" - } -} - -# Implements the AppVeyor 'install' step and installs the required versions of Pester, platyPS and the .Net Core SDK if needed. -function Invoke-AppVeyorInstall { - param( - # For the multi-stage build in Azure DevOps, Pester is not needed for bootstrapping the build environment - [switch] $SkipPesterInstallation - ) - - $installPowerShellModulesjobs = @() - if (-not $SkipPesterInstallation.IsPresent) { $installPowerShellModulesjobs += Start-Job ${Function:Install-Pester} } - - $installPowerShellModulesjobs += Start-Job { - if ($null -eq (Get-Module -ListAvailable PowershellGet)) { - # WMF 4 image build - Write-Verbose -Verbose "Installing platyPS via nuget" - nuget install platyPS -source https://www.powershellgallery.com/api/v2 -outputDirectory "$Env:ProgramFiles\WindowsPowerShell\Modules\." -ExcludeVersion - } - else { - Write-Verbose -Verbose "Installing platyPS via Install-Module" - Install-Module -Name platyPS -Force -Scope CurrentUser -Repository PSGallery - } - Write-Verbose -Verbose 'Installed platyPS' - } - - # Do not use 'build.ps1 -bootstrap' option for bootstraping the .Net SDK as it does not work well in CI with the AppVeyor Ubuntu image - Write-Verbose -Verbose "Installing required .Net CORE SDK" - # the legacy WMF4 image only has the old preview SDKs of dotnet - $globalDotJson = Get-Content (Join-Path $PSScriptRoot '..\global.json') -Raw | ConvertFrom-Json - $requiredDotNetCoreSDKVersion = $globalDotJson.sdk.version - if ($PSVersionTable.PSVersion.Major -gt 4) { - $requiredDotNetCoreSDKVersionPresent = (dotnet --list-sdks) -match $requiredDotNetCoreSDKVersion - } - else { - # WMF 4 image has old SDK that does not have --list-sdks parameter - $requiredDotNetCoreSDKVersionPresent = (dotnet --version).StartsWith($requiredDotNetCoreSDKVersion) - } - if (-not $requiredDotNetCoreSDKVersionPresent) { - Write-Verbose -Verbose "Installing required .Net CORE SDK $requiredDotNetCoreSDKVersion" - $originalSecurityProtocol = [Net.ServicePointManager]::SecurityProtocol - try { - [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 - if ($IsLinux -or $isMacOS) { - Invoke-WebRequest 'https://dot.net/v1/dotnet-install.sh' -OutFile dotnet-install.sh - bash dotnet-install.sh --version $requiredDotNetCoreSDKVersion - [System.Environment]::SetEnvironmentVariable('PATH', "/home/appveyor/.dotnet$([System.IO.Path]::PathSeparator)$PATH") - } - else { - Invoke-WebRequest 'https://dot.net/v1/dotnet-install.ps1' -OutFile dotnet-install.ps1 - .\dotnet-install.ps1 -Version $requiredDotNetCoreSDKVersion - } - } - finally { - [Net.ServicePointManager]::SecurityProtocol = $originalSecurityProtocol - Remove-Item .\dotnet-install.* - } - Write-Verbose -Verbose 'Installed required .Net CORE SDK' - } - - Wait-Job $installPowerShellModulesjobs | Receive-Job - $installPowerShellModulesjobs | ForEach-Object { - if ($_.State -eq 'Failed') { - throw 'Installing PowerShell modules failed, see job logs above' - } - } -} - -# Implements AppVeyor 'test_script' step -function Invoke-AppveyorTest { - Param( - [Parameter(Mandatory)] - [ValidateScript( {Test-Path $_})] - $CheckoutPath - ) - - Install-Pester - - # enforce the language to utf-8 to avoid issues - $env:LANG = "en_US.UTF-8" - Write-Verbose -Verbose ("Running tests on PowerShell version " + $PSVersionTable.PSVersion) - Write-Verbose -Verbose "Language set to '${env:LANG}'" - - # set up env:PSModulePath to the build location, don't copy it to the "normal place" - $analyzerVersion = ([xml](Get-Content "${CheckoutPath}\Engine\Engine.csproj")).SelectSingleNode(".//VersionPrefix")."#text".Trim() - $majorVersion = ([System.Version]$analyzerVersion).Major - $psMajorVersion = $PSVersionTable.PSVersion.Major - - if ( $psMajorVersion -lt 5 ) { - $versionModuleDir = "${CheckoutPath}\out\PSScriptAnalyzer\${analyzerVersion}" - $renameTarget = "${CheckoutPath}\out\PSScriptAnalyzer\PSScriptAnalyzer" - Rename-Item "${versionModuleDir}" "${renameTarget}" - $moduleDir = "${CheckoutPath}\out\PSScriptAnalyzer" - } - else{ - $moduleDir = "${CheckoutPath}\out" - } - - $env:PSModulePath = "${moduleDir}","${env:PSModulePath}" -join [System.IO.Path]::PathSeparator - Write-Verbose -Verbose "module path: ${env:PSModulePath}" - - # Set up testing assets - [string[]] $testScripts = @( - Join-Path $CheckoutPath 'Tests\Engine' - Join-Path $CheckoutPath 'Tests\Rules' - Join-Path $CheckoutPath 'Tests\Documentation' - Join-Path $CheckoutPath 'PSCompatibilityCollector\Tests' - ) - - # Change culture to Turkish to test that PSSA works well with different locales - [System.Threading.Thread]::CurrentThread.CurrentCulture = [cultureinfo]::CreateSpecificCulture('tr-TR') - [System.Threading.Thread]::CurrentThread.CurrentUICulture = [cultureinfo]::CreateSpecificCulture('tr-TR') - - # Run all tests - Import-Module PSScriptAnalyzer - Import-Module Pester - - Write-Verbose -Verbose "Module versions:" - Get-Module PSScriptAnalyzer,Pester,PowershellGet -ErrorAction SilentlyContinue | - ForEach-Object { - Write-Verbose -Verbose "$($_.Name): $($_.Version) [$($_.Path)]" - } - - $configuration = [PesterConfiguration]::Default - $configuration.CodeCoverage.Enabled = $false - $configuration.Output.Verbosity = 'Normal' - $configuration.Run.Exit = $true - $configuration.Run.PassThru = $true - $configuration.Run.Path = $testScripts - $configuration.TestResult.Enabled = $true - Invoke-Pester -Configuration $configuration -} - -# Implements AppVeyor 'on_finish' step -function Invoke-AppveyorFinish { - $uploadUrl = "https://ci.appveyor.com/api/testresults/nunit/$%7Benv:APPVEYOR_JOB_ID%7D" - $testResultsPath = Join-Path $pwd TestResults.xml # default when using the -CI switch in Invoke-Pester - Write-Verbose -Verbose "Uploading test results '$testResultsPath' to '${uploadUrl}'" - $null = (New-Object 'System.Net.WebClient').UploadFile("$uploadUrl" , $testResultsPath) - - $stagingDirectory = (Resolve-Path ..).Path - $zipFile = Join-Path $stagingDirectory "$(Split-Path $pwd -Leaf).zip" - Add-Type -AssemblyName 'System.IO.Compression.FileSystem' - [System.IO.Compression.ZipFile]::CreateFromDirectory((Join-Path $pwd 'out'), $zipFile) - @( - # add test results as an artifact - (Get-ChildItem testResults.xml) - # You can add other artifacts here - (Get-ChildItem $zipFile) - ) | ForEach-Object { Push-AppveyorArtifact $_.FullName } -} diff --git a/tools/docker/ubuntu/Dockerfile b/tools/docker/ubuntu/Dockerfile deleted file mode 100644 index b3ea385fd..000000000 --- a/tools/docker/ubuntu/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM mcr.microsoft.com/powershell:ubuntu-20.04 - -ENV __InContainer 1 - -RUN apt update -qq && apt install -q -y wget git apt-transport-https -RUN wget -q https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb && dpkg -i packages-microsoft-prod.deb - -RUN apt update -qq && \ - cd / && \ - git clone https://github.com/PowerShell/PSScriptAnalyzer - -RUN pwsh -c 'save-module -name platyps,pester -path $PSHOME/Modules' diff --git a/tools/installPSResources.ps1 b/tools/installPSResources.ps1 new file mode 100644 index 000000000..506d93a35 --- /dev/null +++ b/tools/installPSResources.ps1 @@ -0,0 +1,13 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +param( + [ValidateSet("PSGallery", "CFS")] + [string]$PSRepository = "PSGallery" +) + +if ($PSRepository -eq "CFS" -and -not (Get-PSResourceRepository -Name CFS -ErrorAction SilentlyContinue)) { + Register-PSResourceRepository -Name CFS -Uri "https://pkgs.dev.azure.com/powershell/PowerShell/_packaging/powershell/nuget/v3/index.json" +} + +Install-PSResource -Repository $PSRepository -TrustRepository -Name platyPS +Install-PSResource -Repository $PSRepository -TrustRepository -Name Pester diff --git a/tools/releaseBuild/AssemblySignConfig.xml b/tools/releaseBuild/AssemblySignConfig.xml deleted file mode 100644 index a3f2e3f1c..000000000 --- a/tools/releaseBuild/AssemblySignConfig.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tools/releaseBuild/CatalogSignConfig.xml b/tools/releaseBuild/CatalogSignConfig.xml deleted file mode 100644 index a0f7da038..000000000 --- a/tools/releaseBuild/CatalogSignConfig.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/tools/releaseBuild/CredScan.Suppressions.json b/tools/releaseBuild/CredScan.Suppressions.json deleted file mode 100644 index 0a0e5db11..000000000 --- a/tools/releaseBuild/CredScan.Suppressions.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "tool": "Credential Scanner", - "suppressions": [ - { "file": "\\README.md", - "_justification": "The file refers to passwords but has no actual passwords" }, - { "file": "\\Engine\\Settings\\desktop-4.0-windows.json", - "_justification": "The file contains the list of all parameters of a cmdlet but no passwords are actually present." }, - { "file": "\\Engine\\Settings\\desktop-3.0-windows.json", - "_justification": "The file contains the list of all parameters of a cmdlet but no passwords are actually present." }, - { "file": "\\Engine\\Settings\\desktop-5.1.14393.206-windows.json", - "_justification": "The file contains the list of all parameters of a cmdlet but no passwords are actually present." }, - { "file": "\\Tests\\Engine\\RuleSuppression.tests.ps1", - "_justification": "The parameter password is used in function declaration for test but is not called and no password is present." } - ] -} - - diff --git a/tools/releaseBuild/FileCatalogSigning.xml b/tools/releaseBuild/FileCatalogSigning.xml deleted file mode 100644 index e2e2a6323..000000000 --- a/tools/releaseBuild/FileCatalogSigning.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - diff --git a/tools/releaseBuild/Image/DockerFile b/tools/releaseBuild/Image/DockerFile deleted file mode 100644 index 682f7248e..000000000 --- a/tools/releaseBuild/Image/DockerFile +++ /dev/null @@ -1,28 +0,0 @@ -# escape=` -#0.3.6 (no powershell 6) -# FROM microsoft/windowsservercore -FROM mcr.microsoft.com/dotnet/framework/sdk:4.8 -LABEL maintainer='PowerShell Team ' -LABEL description="This Dockerfile for Windows Server Core with git installed via chocolatey." - -SHELL ["C:\\windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", "-command"] -# Install Git, and platyPS -# Git installs to C:\Program Files\Git -# nuget installs to C:\ProgramData\chocolatey\bin\NuGet.exe -COPY dockerInstall.psm1 containerFiles/dockerInstall.psm1 - -RUN Import-Module PackageManagement; ` - Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force; ` - Import-Module ./containerFiles/dockerInstall.psm1; ` - [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor [System.Net.SecurityProtocolType]::Tls12; ` - Install-ChocolateyPackage -PackageName git -Executable git.exe; ` - Install-ChocolateyPackage -PackageName nuget.commandline -Executable nuget.exe -Cleanup; ` - Install-Module -Force -Name platyPS -Repository PSGallery; ` - Invoke-WebRequest -Uri https://dot.net/v1/dotnet-install.ps1 -OutFile C:/dotnet-install.ps1; ` - C:/dotnet-install.ps1 -Version 3.1.419; ` - Add-Path C:/Users/ContainerAdministrator/AppData/Local/Microsoft/dotnet; - -COPY buildPSSA.ps1 containerFiles/buildPSSA.ps1 - -ENTRYPOINT ["C:\\windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", "-command"] - diff --git a/tools/releaseBuild/Image/buildPSSA.ps1 b/tools/releaseBuild/Image/buildPSSA.ps1 deleted file mode 100644 index bb60eb2b5..000000000 --- a/tools/releaseBuild/Image/buildPSSA.ps1 +++ /dev/null @@ -1,4 +0,0 @@ -push-location C:/PSScriptAnalyzer -import-module C:/PSScriptAnalyzer/Utils/ReleaseMaker.psm1 -New-ReleaseBuild -Copy-Item -Recurse C:/PSScriptAnalyzer/out C:/ diff --git a/tools/releaseBuild/Image/dockerInstall.psm1 b/tools/releaseBuild/Image/dockerInstall.psm1 deleted file mode 100644 index 24d1235d6..000000000 --- a/tools/releaseBuild/Image/dockerInstall.psm1 +++ /dev/null @@ -1,114 +0,0 @@ -function Install-ChocolateyPackage -{ - param( - [Parameter(Mandatory=$true)] - [string] - $PackageName, - - [Parameter(Mandatory=$false)] - [string] - $Executable, - - [string[]] - $ArgumentList, - - [switch] - $Cleanup, - - [int] - $ExecutionTimeout = 2700, - - [string] - $Version - ) - - if(-not(Get-Command -name Choco -ErrorAction SilentlyContinue)) - { - Write-Verbose "Installing Chocolatey provider..." -Verbose - Invoke-WebRequest https://chocolatey.org/install.ps1 -UseBasicParsing | Invoke-Expression - } - - Write-Verbose "Installing $PackageName..." -Verbose - $extraCommand = @() - if($Version) - { - $extraCommand += '--version', $version - } - choco install -y $PackageName --no-progress --execution-timeout=$ExecutionTimeout $ArgumentList $extraCommands - - if($executable) - { - Write-Verbose "Verifing $Executable is in path..." -Verbose - $exeSource = $null - $exeSource = Get-ChildItem -path "$env:ProgramFiles\$Executable" -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName - if(!$exeSource) - { - Write-Verbose "Falling back to x86 program files..." -Verbose - $exeSource = Get-ChildItem -path "${env:ProgramFiles(x86)}\$Executable" -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName - } - - # Don't search the chocolatey program data until more official locations have been searched - if(!$exeSource) - { - Write-Verbose "Falling back to chocolatey..." -Verbose - $exeSource = Get-ChildItem -path "$env:ProgramData\chocolatey\$Executable" -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName - } - - # all obvious locations are exhausted, use brute force and search from the root of the filesystem - if(!$exeSource) - { - Write-Verbose "Falling back to the root of the drive..." -Verbose - $exeSource = Get-ChildItem -path "/$Executable" -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName - } - - if(!$exeSource) - { - throw "$Executable not found" - } - - $exePath = Split-Path -Path $exeSource - Add-Path -path $exePath - } - - if($Cleanup.IsPresent) - { - Remove-Folder -Folder "$env:temp\chocolatey" - } -} - -function Add-Path -{ - param - ( - $path - ) - $machinePathString = [System.Environment]::GetEnvironmentVariable('path',[System.EnvironmentVariableTarget]::Machine) - $machinePath = $machinePathString -split ';' - - if($machinePath -inotcontains $path) - { - $newPath = "$machinePathString;$path" - Write-Verbose "Adding $path to path..." -Verbose - [System.Environment]::SetEnvironmentVariable('path',$newPath,[System.EnvironmentVariableTarget]::Machine) - Write-Verbose "Added $path to path." -Verbose - $env:Path += ";$newPath" - } - else - { - Write-Verbose "$path already in path." -Verbose - } -} - -function Remove-Folder -{ - param( - [string] - $Folder - ) - - Write-Verbose "Cleaning up $Folder..." -Verbose - $filter = Join-Path -Path $Folder -ChildPath * - [int]$measuredCleanupMB = (Get-ChildItem $filter -Recurse | Measure-Object -Property Length -Sum).Sum / 1MB - Remove-Item -recurse -force $filter -ErrorAction SilentlyContinue - Write-Verbose "Cleaned up $measuredCleanupMB MB from $Folder" -Verbose -} diff --git a/tools/releaseBuild/build.json b/tools/releaseBuild/build.json deleted file mode 100644 index 8d46f2e33..000000000 --- a/tools/releaseBuild/build.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "Windows": { - "Name": "win7-x64", - "RepoDestinationPath": "C:\\PSScriptAnalyzer", - "BuildCommand": "C:\\containerFiles\\buildPSSA.ps1", - "DockerFile": ".\\tools\\releaseBuild\\Image\\DockerFile", - "DockerImageName": "pssa", - "BinaryBucket": "release", - "PublishAsFolder": true, - "AdditionalContextFiles" : [ - ".\\tools\\releaseBuild\\Image\\buildPSSA.ps1", - ".\\tools\\releaseBuild\\Image\\dockerInstall.psm1" - ] - } -} diff --git a/tools/releaseBuild/signing.xml b/tools/releaseBuild/signing.xml deleted file mode 100644 index f2fc1c3ee..000000000 --- a/tools/releaseBuild/signing.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tools/releaseBuild/updateSigning.ps1 b/tools/releaseBuild/updateSigning.ps1 deleted file mode 100644 index d3973fb44..000000000 --- a/tools/releaseBuild/updateSigning.ps1 +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. -param( - [string] $SigningXmlPath = (Join-Path -Path $PSScriptRoot -ChildPath 'signing.xml') -) -# Script for use in VSTS to update signing.xml - -$ErrorActionPreference = 'Stop' - -# Parse the signing xml -$signingXml = [xml](Get-Content $signingXmlPath) - -# Get any variables to updating 'signType' in the XML -# Define a varabile named `SignType' in VSTS to updating that signing type -# Example: $env:AuthenticodeSignType='newvalue' -# will cause all files with the 'Authenticode' signtype to be updated with the 'newvalue' signtype -$signTypes = @{} -Get-ChildItem -Path env:/*SignType | ForEach-Object -Process { - $signType = $_.Name.ToUpperInvariant().Replace('SIGNTYPE','') - Write-Host "Found SigningType $signType with value $($_.value)" - $signTypes[$signType] = $_.Value -} - -# examine each job in the xml -$signingXml.SignConfigXML.job | ForEach-Object -Process { - # examine each file in the job - $_.file | ForEach-Object -Process { - # if the sign type is one of the variables we found, update it to the new value - $signType = $_.SignType.ToUpperInvariant() - if($signTypes.ContainsKey($signType)) - { - $newSignType = $signTypes[$signType] - Write-Host "Updating $($_.src) to $newSignType" - $_.signType = $newSignType - } - } -} - -$signingXml.Save($signingXmlPath) diff --git a/tools/releaseBuild/vstsbuild.ps1 b/tools/releaseBuild/vstsbuild.ps1 deleted file mode 100644 index 9faeedfa0..000000000 --- a/tools/releaseBuild/vstsbuild.ps1 +++ /dev/null @@ -1,70 +0,0 @@ -[cmdletbinding()] -param ( ) - -Begin -{ - $ErrorActionPreference = 'Stop' - - $gitBinFullPath = (Get-Command -Name git -CommandType Application).Path | Select-Object -First 1 - if ( ! $gitBinFullPath ) - { - throw "Git is missing! Install from 'https://git-scm.com/download/win'" - } - - # clone the release tools - $releaseToolsDirName = "PSRelease" - $releaseToolsLocation = Join-Path -Path $PSScriptRoot -ChildPath PSRelease - if ( Test-Path $releaseToolsLocation ) - { - Remove-Item -Force -Recurse -Path $releaseToolsLocation - } - & $gitBinFullPath clone -b master --quiet https://github.com/PowerShell/${releaseToolsDirName}.git $releaseToolsLocation - Import-Module "$releaseToolsLocation/vstsBuild" -Force - Import-Module "$releaseToolsLocation/dockerBasedBuild" -Force -} - -End { - - $AdditionalFiles = .{ - Join-Path $PSScriptRoot -child "Image/buildPSSA.ps1" - Join-Path $PSScriptRoot -child "Image/dockerInstall.psm1" - } - $buildPackageName = $null - - # defined if building in VSTS - if($env:BUILD_STAGINGDIRECTORY) - { - # Use artifact staging if running in VSTS - $destFolder = $env:BUILD_STAGINGDIRECTORY - } - else - { - # Use temp as destination if not running in VSTS - $destFolder = $env:temp - } - - $resolvedRepoRoot = (Resolve-Path (Join-Path -Path $PSScriptRoot -ChildPath "../../")).Path - - try - { - Write-Verbose "Starting build at $resolvedRepoRoot ..." -Verbose - Clear-VstsTaskState - - $buildArgs = @{ - RepoPath = $resolvedRepoRoot - BuildJsonPath = './tools/releaseBuild/build.json' - Parameters = @{ ReleaseTag = "unused" } # not needed for PSSA - AdditionalFiles = $AdditionalFiles - Name = "win7-x64" - } - Invoke-Build @buildArgs - } - catch - { - Write-VstsError -Error $_ - } - finally{ - Write-VstsTaskState - exit 0 - } -} diff --git a/tools/updateVersion.ps1 b/tools/updateVersion.ps1 new file mode 100644 index 000000000..7e9d1a47d --- /dev/null +++ b/tools/updateVersion.ps1 @@ -0,0 +1,29 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +param( + [Parameter(Mandatory)] + [semver]$Version, + + [Parameter(Mandatory)] + [string]$Changes +) + +git diff --staged --quiet --exit-code +if ($LASTEXITCODE -ne 0) { + throw "There are staged changes in the repository. Please commit or reset them before running this script." +} + +$Path = "Directory.Build.props" +$f = Get-Content -Path $Path +$f = $f -replace '^(?\s+)(.+)(?)$', "`${prefix}${Version}`${suffix}" +$f | Set-Content -Path $Path +git add $Path + +$Path = "docs/Cmdlets/PSScriptAnalyzer.md" +$f = Get-Content -Path $Path +$f = $f -replace '^(?Help Version: )(.+)$', "`${prefix}${Version}" +$f | Set-Content -Path $Path +git add $Path + +git commit --edit --message "v${Version}: $Changes"