├── .github ├── FUNDING.yml └── workflows │ └── BuildModule.yml ├── .gitignore ├── Assets └── Images │ ├── NewPrepareModule.png │ └── NewPrepareModule1.png ├── Build ├── Build-Module.ps1 ├── Build-ModuleLegacy.ps1 ├── Build-ModuleSimplified.ps1 └── Update-Version.ps1 ├── CHANGELOG.MD ├── Data ├── Example-CHANGELOG.MD ├── Example-Gitignore.txt ├── Example-LicenseMIT.txt ├── Example-ModuleBuilder.txt ├── Example-ModulePSD1.txt ├── Example-ModulePSM1.txt └── Example-README.MD ├── Docs ├── Convert-CommandsToList.md ├── Get-MissingFunctions.md ├── Get-PowerShellAssemblyMetadata.md ├── Get-ProjectVersion.md ├── Initialize-PortableModule.md ├── Initialize-PortableScript.md ├── Initialize-ProjectManager.md ├── Invoke-ModuleBuild.md ├── New-ConfigurationArtefact.md ├── New-ConfigurationBuild.md ├── New-ConfigurationCommand.md ├── New-ConfigurationDocumentation.md ├── New-ConfigurationExecute.md ├── New-ConfigurationFormat.md ├── New-ConfigurationImportModule.md ├── New-ConfigurationInformation.md ├── New-ConfigurationManifest.md ├── New-ConfigurationModule.md ├── New-ConfigurationModuleSkip.md ├── New-ConfigurationPlaceHolder.md ├── New-ConfigurationPublish.md ├── New-ConfigurationTest.md ├── Readme.md ├── Register-Certificate.md ├── Remove-Comments.md ├── Send-GitHubRelease.md ├── Set-ProjectVersion.md ├── Test-BasicModule.md ├── Test-ScriptFile.md └── Test-ScriptModule.md ├── Examples ├── Example.CmdletAliasDetection.ps1 ├── Example.DetectUsedLibraries.ps1 ├── Example.FindMicrosoftClientIdentity.ps1 ├── Example.RegisterCertificate.ps1 ├── Example.RemoveComments.ps1.ps1 ├── Example.SignMultipleFiles.ps1 ├── Step01.CreateModuleProject.ps1 ├── Step02.BuildModuleOver.ps1 └── Step03.PrepareVariablesForGitHubActions.ps1 ├── LICENSE ├── PSPublishModule.Tests.ps1 ├── PSPublishModule.psd1 ├── PSPublishModule.psm1 ├── Private ├── Add-Artefact.ps1 ├── Add-BinaryImportModule.ps1 ├── Add-Directory.ps1 ├── Approve-RequiredModules.ps1 ├── Compress-Artefact.ps1 ├── Convert-HashTableToNicelyFormattedString.ps1 ├── Convert-RequiredModules.ps1 ├── Copy-ArtefactMainModule.ps1 ├── Copy-ArtefactRequiredFiles.ps1 ├── Copy-ArtefactRequiredFolders.ps1 ├── Copy-ArtefactRequiredModule.ps1 ├── Copy-ArtefactToScript.ps1.ps1 ├── Copy-DictionaryManual.ps1 ├── Copy-InternalDictionary.ps1 ├── Copy-InternalFiles.ps1 ├── Export-PSData.ps1 ├── Find-NetFramework.ps1 ├── Find-RequiredModules.ps1 ├── Format-Code.ps1 ├── Format-UsingNamespace.ps1 ├── Get-AstTokens.ps1 ├── Get-CurrentVersionFromBuildScript.ps1 ├── Get-CurrentVersionFromCsProj.ps1 ├── Get-CurrentVersionFromPsd1.ps1 ├── Get-Encoding.ps1 ├── Get-FilteredScriptCommands.ps1 ├── Get-FunctionAliases.ps1 ├── Get-FunctionAliasesFromFolder.ps1 ├── Get-FunctionNames.ps1 ├── Get-GitLog.ps1 ├── Get-RequiredModule.ps1 ├── Get-RestMethodExceptionDetailsOrNull.ps1 ├── Get-ScriptCommands.ps1 ├── Get-ScriptsContentAndTryReplace.ps1 ├── Import-ValidCertificate.ps1 ├── Initialize-InternalTests.ps1 ├── Initialize-ReplacePath.ps1 ├── Invoke-RestMethodAndThrowDescriptiveErrorOnFailure.ps1 ├── Merge-Module.ps1 ├── New-CreateModule.ps1 ├── New-DLLCodeOutput.ps1 ├── New-DLLResolveConflict.ps1 ├── New-LibraryContent.ps1 ├── New-PSMFile.ps1 ├── New-PersonalManifest.ps1 ├── New-PrepareManifest.ps1 ├── New-PrepareStructure.ps1 ├── Out-FileUft8NoBom.ps1 ├── Register-DataForInitialModule.ps1 ├── Remove-Directory.ps1 ├── Remove-EmptyLines.ps1 ├── Remove-EmptyValue.ps1 ├── Remove-ItemAlternative.ps1 ├── Repair-CustomPlaceHolders.ps1 ├── Script.FormatterSettings.ps1 ├── Send-FilesToGitHubRelease.ps1 ├── Start-ArtefactsBuilding.ps1 ├── Start-DocumentationBuilding.ps1 ├── Start-ImportingModules.ps1 ├── Start-LibraryBuilding.ps1 ├── Start-ModuleBuilding.ps1 ├── Start-ModuleMerging.ps1 ├── Start-ModuleSigning.ps1 ├── Start-PreparingFunctionsAndAliases.ps1 ├── Start-PreparingStructure.ps1 ├── Start-PreparingVariables.ps1 ├── Start-PublishingGallery.ps1 ├── Start-PublishingGitHub.ps1 ├── Step-Version.ps1 ├── Test-AllFilePathsAndThrowErrorIfOneIsNotValid.ps1 ├── Test-ReparsePoint.ps1 ├── Update-VersionInBuildScript.ps1 ├── Update-VersionInCsProj.ps1 ├── Update-VersionInPsd1.ps1 ├── Update-VersionNumber.ps1 ├── Write-PowerShellHashTable.ps1 ├── Write-Text.ps1 └── Write-TextWithTime.ps1 ├── Public ├── Convert-CommandsToList.ps1 ├── Get-MissingFunctions.ps1 ├── Get-PowerShellAssemblyMetaData.ps1 ├── Get-ProjectVersion.ps1 ├── Initialize-PortableModule.ps1 ├── Initialize-PortableScript.ps1 ├── Initialize-ProjectManager.ps1 ├── Invoke-ModuleBuild.ps1 ├── New-ConfigurationArtefact.ps1 ├── New-ConfigurationBuild.ps1 ├── New-ConfigurationCommand.ps1 ├── New-ConfigurationDocumentation.ps1 ├── New-ConfigurationExecute.ps1 ├── New-ConfigurationFormat.ps1 ├── New-ConfigurationImportModule.ps1 ├── New-ConfigurationInformation.ps1 ├── New-ConfigurationManifest.ps1 ├── New-ConfigurationModule.ps1 ├── New-ConfigurationModuleSkip.ps1 ├── New-ConfigurationPlaceHolder.ps1 ├── New-ConfigurationPublish.ps1 ├── New-ConfigurationTest.ps1 ├── Register-Certificate.ps1 ├── Remove-Comments.ps1 ├── Send-GitHubRelease.ps1 ├── Set-ProjectVersion.ps1 ├── Test-Basic.ps1 ├── Test-ScriptFile.ps1 └── Test-ScriptModule.ps1 ├── README.MD ├── Sources └── PSPublishModule │ ├── PSPublishModule.sln │ └── PSPublishModule │ ├── Initialize.cs │ ├── OnImportAndRemove.cs │ └── PSPublishModule.csproj └── Tests ├── Build-Module.Tests.ps1 ├── Input └── RemoveCommentsTests.ps1 ├── Remove-Comments.Tests.ps1 └── Step-Version.Tests.ps1 /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: PrzemyslawKlys 2 | custom: https://paypal.me/PrzemyslawKlys -------------------------------------------------------------------------------- /.github/workflows/BuildModule.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: Test & Build Module 4 | 5 | # Controls when the workflow will run 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the "master" branch 8 | push: 9 | branches: [ "master" ] 10 | pull_request: 11 | branches: [ "master" ] 12 | 13 | # Allows you to run this workflow manually from the Actions tab 14 | workflow_dispatch: 15 | 16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 17 | jobs: 18 | # This workflow contains a single job called "build" 19 | WindowsBuild: 20 | # The type of runner that the job will run on 21 | runs-on: windows-latest 22 | 23 | # Steps represent a sequence of tasks that will be executed as part of the job 24 | steps: 25 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 26 | - uses: actions/checkout@v4 27 | 28 | - name: Test with Pester 29 | shell: pwsh 30 | run: .\PSPublishModule.Tests.ps1 31 | 32 | - name: Build Module 33 | shell: pwsh 34 | run: .\Build\Build-Module.ps1 35 | LinuxBuild: 36 | # The type of runner that the job will run on 37 | runs-on: ubuntu-latest 38 | 39 | # Steps represent a sequence of tasks that will be executed as part of the job 40 | steps: 41 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 42 | - uses: actions/checkout@v4 43 | 44 | - name: Test with Pester 45 | shell: pwsh 46 | run: .\PSPublishModule.Tests.ps1 47 | 48 | - name: Build Module 49 | shell: pwsh 50 | run: .\Build\Build-Module.ps1 51 | MacOsBuild: 52 | # The type of runner that the job will run on 53 | runs-on: macos-latest 54 | 55 | # Steps represent a sequence of tasks that will be executed as part of the job 56 | steps: 57 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 58 | - uses: actions/checkout@v4 59 | 60 | - name: Test with Pester 61 | shell: pwsh 62 | run: .\PSPublishModule.Tests.ps1 63 | 64 | - name: Build Module 65 | shell: pwsh 66 | run: .\Build\Build-Module.ps1 67 | -------------------------------------------------------------------------------- /Assets/Images/NewPrepareModule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvotecIT/PSPublishModule/7aa6c64b67b9426527f6a5ce10137be81281c87e/Assets/Images/NewPrepareModule.png -------------------------------------------------------------------------------- /Assets/Images/NewPrepareModule1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvotecIT/PSPublishModule/7aa6c64b67b9426527f6a5ce10137be81281c87e/Assets/Images/NewPrepareModule1.png -------------------------------------------------------------------------------- /Build/Update-Version.ps1: -------------------------------------------------------------------------------- 1 | #Import-Module C:\Support\GitHub\PSPublishModule\PSPublishModule.psd1 -Force 2 | 3 | Get-ProjectVersion -Path "C:\Support\GitHub\DnsClientX" -ExcludeFolders @('C:\Support\GitHub\DnsClientX\Module\Artefacts') 4 | 5 | #Set-ProjectVersion -Path "C:\Support\GitHub\DnsClientX" -NewVersion "0.4.0" 6 | #Set-ProjectVersion -Path "C:\Support\GitHub\DnsClientX" -VersionType Build 7 | -------------------------------------------------------------------------------- /Data/Example-CHANGELOG.MD: -------------------------------------------------------------------------------- 1 | ### 1.0.0 2 | - Initial release -------------------------------------------------------------------------------- /Data/Example-Gitignore.txt: -------------------------------------------------------------------------------- 1 | Ignore/* 2 | .vs/* 3 | .vscode/* 4 | Examples/Output/* 5 | Releases/* 6 | Artefacts/* 7 | ReleasedUnpacked/* 8 | Sources/.vs 9 | Sources/*/.vs 10 | Sources/*/obj 11 | Sources/*/bin 12 | Sources/*/*/obj 13 | Sources/*/*/bin 14 | Sources/packages/* 15 | Lib/Default/* 16 | Lib/Standard/* 17 | Lib/Core/* -------------------------------------------------------------------------------- /Data/Example-LicenseMIT.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 CompanyName 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Data/Example-ModulePSD1.txt: -------------------------------------------------------------------------------- 1 | @{ 2 | AliasesToExport = @() 3 | Author = 'Author' 4 | CmdletsToExport = @() 5 | CompanyName = 'CompanyName' 6 | CompatiblePSEditions = @('Desktop', 'Core') 7 | Copyright = '(c) 2011 - 2023 Author @ CompanyName. All rights reserved.' 8 | Description = 'Simple project $ModuleName' 9 | FunctionsToExport = @() 10 | GUID = '$Guid' 11 | ModuleVersion = '1.0.0' 12 | PowerShellVersion = '5.1' 13 | PrivateData = @{ 14 | PSData = @{ 15 | Tags = @('Windows', 'MacOS', 'Linux') 16 | } 17 | } 18 | RootModule = '$ModuleName.psm1' 19 | } -------------------------------------------------------------------------------- /Data/Example-ModulePSM1.txt: -------------------------------------------------------------------------------- 1 | # Get public and private function definition files. 2 | $Public = @( Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -ErrorAction SilentlyContinue -Recurse ) 3 | $Private = @( Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -ErrorAction SilentlyContinue -Recurse ) 4 | $Classes = @( Get-ChildItem -Path $PSScriptRoot\Classes\*.ps1 -ErrorAction SilentlyContinue -Recurse ) 5 | $Enums = @( Get-ChildItem -Path $PSScriptRoot\Enums\*.ps1 -ErrorAction SilentlyContinue -Recurse ) 6 | # Get all assemblies 7 | $AssemblyFolders = Get-ChildItem -Path $PSScriptRoot\Lib -Directory -ErrorAction SilentlyContinue 8 | 9 | # Lets find which libraries we need to load 10 | $Default = $false 11 | $Core = $false 12 | $Standard = $false 13 | foreach ($A in $AssemblyFolders.Name) { 14 | if ($A -eq 'Default') { 15 | $Default = $true 16 | } elseif ($A -eq 'Core') { 17 | $Core = $true 18 | } elseif ($A -eq 'Standard') { 19 | $Standard = $true 20 | } 21 | } 22 | if ($Standard -and $Core -and $Default) { 23 | $FrameworkNet = 'Default' 24 | $Framework = 'Standard' 25 | } elseif ($Standard -and $Core) { 26 | $Framework = 'Standard' 27 | $FrameworkNet = 'Standard' 28 | } elseif ($Core -and $Default) { 29 | $Framework = 'Core' 30 | $FrameworkNet = 'Default' 31 | } elseif ($Standard -and $Default) { 32 | $Framework = 'Standard' 33 | $FrameworkNet = 'Default' 34 | } elseif ($Standard) { 35 | $Framework = 'Standard' 36 | $FrameworkNet = 'Standard' 37 | } elseif ($Core) { 38 | $Framework = 'Core' 39 | $FrameworkNet = '' 40 | } elseif ($Default) { 41 | $Framework = '' 42 | $FrameworkNet = 'Default' 43 | } else { 44 | #Write-Error -Message 'No assemblies found' 45 | } 46 | 47 | $Assembly = @( 48 | if ($Framework -and $PSEdition -eq 'Core') { 49 | Get-ChildItem -Path $PSScriptRoot\Lib\$Framework\*.dll -ErrorAction SilentlyContinue -Recurse 50 | } 51 | if ($FrameworkNet -and $PSEdition -ne 'Core') { 52 | Get-ChildItem -Path $PSScriptRoot\Lib\$FrameworkNet\*.dll -ErrorAction SilentlyContinue -Recurse 53 | } 54 | ) 55 | $FoundErrors = @( 56 | Foreach ($Import in @($Assembly)) { 57 | try { 58 | Write-Verbose -Message $Import.FullName 59 | Add-Type -Path $Import.Fullname -ErrorAction Stop 60 | # } 61 | } catch [System.Reflection.ReflectionTypeLoadException] { 62 | Write-Warning "Processing $($Import.Name) Exception: $($_.Exception.Message)" 63 | $LoaderExceptions = $($_.Exception.LoaderExceptions) | Sort-Object -Unique 64 | foreach ($E in $LoaderExceptions) { 65 | Write-Warning "Processing $($Import.Name) LoaderExceptions: $($E.Message)" 66 | } 67 | $true 68 | #Write-Error -Message "StackTrace: $($_.Exception.StackTrace)" 69 | } catch { 70 | Write-Warning "Processing $($Import.Name) Exception: $($_.Exception.Message)" 71 | $LoaderExceptions = $($_.Exception.LoaderExceptions) | Sort-Object -Unique 72 | foreach ($E in $LoaderExceptions) { 73 | Write-Warning "Processing $($Import.Name) LoaderExceptions: $($E.Message)" 74 | } 75 | $true 76 | #Write-Error -Message "StackTrace: $($_.Exception.StackTrace)" 77 | } 78 | } 79 | #Dot source the files 80 | Foreach ($Import in @($Classes + $Enums + $Private + $Public)) { 81 | Try { 82 | . $Import.Fullname 83 | } Catch { 84 | Write-Error -Message "Failed to import functions from $($import.Fullname): $_" 85 | $true 86 | } 87 | } 88 | ) 89 | 90 | if ($FoundErrors.Count -gt 0) { 91 | $ModuleName = (Get-ChildItem $PSScriptRoot\*.psd1).BaseName 92 | Write-Warning "Importing module $ModuleName failed. Fix errors before continuing." 93 | break 94 | } 95 | 96 | Export-ModuleMember -Function '*' -Alias '*' -Cmdlet '*' -------------------------------------------------------------------------------- /Data/Example-README.MD: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /Docs/Convert-CommandsToList.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSPublishModule-help.xml 3 | Module Name: PSPublishModule 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Convert-CommandsToList 9 | 10 | ## SYNOPSIS 11 | {{ Fill in the Synopsis }} 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Convert-CommandsToList [-ModuleName] [[-CommandTypes] ] [-ProgressAction ] 17 | [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | {{ Fill in the Description }} 22 | 23 | ## EXAMPLES 24 | 25 | ### Example 1 26 | ```powershell 27 | PS C:\> {{ Add example code here }} 28 | ``` 29 | 30 | {{ Add example description here }} 31 | 32 | ## PARAMETERS 33 | 34 | ### -CommandTypes 35 | {{ Fill CommandTypes Description }} 36 | 37 | ```yaml 38 | Type: String[] 39 | Parameter Sets: (All) 40 | Aliases: 41 | 42 | Required: False 43 | Position: 1 44 | Default value: None 45 | Accept pipeline input: False 46 | Accept wildcard characters: False 47 | ``` 48 | 49 | ### -ModuleName 50 | {{ Fill ModuleName Description }} 51 | 52 | ```yaml 53 | Type: String 54 | Parameter Sets: (All) 55 | Aliases: 56 | 57 | Required: True 58 | Position: 0 59 | Default value: None 60 | Accept pipeline input: False 61 | Accept wildcard characters: False 62 | ``` 63 | 64 | ### -ProgressAction 65 | {{ Fill ProgressAction Description }} 66 | 67 | ```yaml 68 | Type: ActionPreference 69 | Parameter Sets: (All) 70 | Aliases: proga 71 | 72 | Required: False 73 | Position: Named 74 | Default value: None 75 | Accept pipeline input: False 76 | Accept wildcard characters: False 77 | ``` 78 | 79 | ### CommonParameters 80 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 81 | 82 | ## INPUTS 83 | 84 | ### None 85 | 86 | ## OUTPUTS 87 | 88 | ### System.Object 89 | ## NOTES 90 | 91 | ## RELATED LINKS 92 | -------------------------------------------------------------------------------- /Docs/Get-MissingFunctions.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSPublishModule-help.xml 3 | Module Name: PSPublishModule 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-MissingFunctions 9 | 10 | ## SYNOPSIS 11 | {{ Fill in the Synopsis }} 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Get-MissingFunctions [[-FilePath] ] [[-Code] ] [[-Functions] ] [-Summary] 17 | [-SummaryWithCommands] [[-ApprovedModules] ] [[-IgnoreFunctions] ] 18 | [-ProgressAction ] [] 19 | ``` 20 | 21 | ## DESCRIPTION 22 | {{ Fill in the Description }} 23 | 24 | ## EXAMPLES 25 | 26 | ### Example 1 27 | ```powershell 28 | PS C:\> {{ Add example code here }} 29 | ``` 30 | 31 | {{ Add example description here }} 32 | 33 | ## PARAMETERS 34 | 35 | ### -ApprovedModules 36 | {{ Fill ApprovedModules Description }} 37 | 38 | ```yaml 39 | Type: Array 40 | Parameter Sets: (All) 41 | Aliases: 42 | 43 | Required: False 44 | Position: 3 45 | Default value: None 46 | Accept pipeline input: False 47 | Accept wildcard characters: False 48 | ``` 49 | 50 | ### -Code 51 | {{ Fill Code Description }} 52 | 53 | ```yaml 54 | Type: ScriptBlock 55 | Parameter Sets: (All) 56 | Aliases: ScriptBlock 57 | 58 | Required: False 59 | Position: 1 60 | Default value: None 61 | Accept pipeline input: False 62 | Accept wildcard characters: False 63 | ``` 64 | 65 | ### -FilePath 66 | {{ Fill FilePath Description }} 67 | 68 | ```yaml 69 | Type: String 70 | Parameter Sets: (All) 71 | Aliases: Path 72 | 73 | Required: False 74 | Position: 0 75 | Default value: None 76 | Accept pipeline input: False 77 | Accept wildcard characters: False 78 | ``` 79 | 80 | ### -Functions 81 | {{ Fill Functions Description }} 82 | 83 | ```yaml 84 | Type: String[] 85 | Parameter Sets: (All) 86 | Aliases: 87 | 88 | Required: False 89 | Position: 2 90 | Default value: None 91 | Accept pipeline input: False 92 | Accept wildcard characters: False 93 | ``` 94 | 95 | ### -IgnoreFunctions 96 | {{ Fill IgnoreFunctions Description }} 97 | 98 | ```yaml 99 | Type: Array 100 | Parameter Sets: (All) 101 | Aliases: 102 | 103 | Required: False 104 | Position: 4 105 | Default value: None 106 | Accept pipeline input: False 107 | Accept wildcard characters: False 108 | ``` 109 | 110 | ### -Summary 111 | {{ Fill Summary Description }} 112 | 113 | ```yaml 114 | Type: SwitchParameter 115 | Parameter Sets: (All) 116 | Aliases: 117 | 118 | Required: False 119 | Position: Named 120 | Default value: None 121 | Accept pipeline input: False 122 | Accept wildcard characters: False 123 | ``` 124 | 125 | ### -SummaryWithCommands 126 | {{ Fill SummaryWithCommands Description }} 127 | 128 | ```yaml 129 | Type: SwitchParameter 130 | Parameter Sets: (All) 131 | Aliases: 132 | 133 | Required: False 134 | Position: Named 135 | Default value: None 136 | Accept pipeline input: False 137 | Accept wildcard characters: False 138 | ``` 139 | 140 | ### -ProgressAction 141 | {{ Fill ProgressAction Description }} 142 | 143 | ```yaml 144 | Type: ActionPreference 145 | Parameter Sets: (All) 146 | Aliases: proga 147 | 148 | Required: False 149 | Position: Named 150 | Default value: None 151 | Accept pipeline input: False 152 | Accept wildcard characters: False 153 | ``` 154 | 155 | ### CommonParameters 156 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 157 | 158 | ## INPUTS 159 | 160 | ### None 161 | 162 | ## OUTPUTS 163 | 164 | ### System.Object 165 | ## NOTES 166 | 167 | ## RELATED LINKS 168 | -------------------------------------------------------------------------------- /Docs/Get-PowerShellAssemblyMetadata.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSPublishModule-help.xml 3 | Module Name: PSPublishModule 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-PowerShellAssemblyMetadata 9 | 10 | ## SYNOPSIS 11 | Gets the cmdlets and aliases in a dotnet assembly. 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Get-PowerShellAssemblyMetadata [-Path] [-ProgressAction ] [] 17 | ``` 18 | 19 | ## DESCRIPTION 20 | {{ Fill in the Description }} 21 | 22 | ## EXAMPLES 23 | 24 | ### EXAMPLE 1 25 | ``` 26 | Get-PowerShellAssemblyMetadata -Path MyModule.dll 27 | ``` 28 | 29 | ## PARAMETERS 30 | 31 | ### -Path 32 | The assembly to inspect. 33 | 34 | ```yaml 35 | Type: String 36 | Parameter Sets: (All) 37 | Aliases: 38 | 39 | Required: True 40 | Position: 1 41 | Default value: None 42 | Accept pipeline input: False 43 | Accept wildcard characters: False 44 | ``` 45 | 46 | ### -ProgressAction 47 | {{ Fill ProgressAction Description }} 48 | 49 | ```yaml 50 | Type: ActionPreference 51 | Parameter Sets: (All) 52 | Aliases: proga 53 | 54 | Required: False 55 | Position: Named 56 | Default value: None 57 | Accept pipeline input: False 58 | Accept wildcard characters: False 59 | ``` 60 | 61 | ### CommonParameters 62 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 63 | 64 | ## INPUTS 65 | 66 | ## OUTPUTS 67 | 68 | ## NOTES 69 | This requires the System.Reflection.MetadataLoadContext assembly to be 70 | loaded through Add-Type. 71 | WinPS (5.1) will also need to load its deps 72 | System.Memory 73 | System.Collections.Immutable 74 | System.Reflection.Metadata 75 | System.Runtime.CompilerServices.Unsafe 76 | 77 | https://www.nuget.org/packages/System.Reflection.MetadataLoadContext 78 | 79 | Copyright: (c) 2024, Jordan Borean (@jborean93) \ 80 | MIT License (see LICENSE or https://opensource.org/licenses/MIT) 81 | 82 | ## RELATED LINKS 83 | -------------------------------------------------------------------------------- /Docs/Get-ProjectVersion.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSPublishModule-help.xml 3 | Module Name: PSPublishModule 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-ProjectVersion 9 | 10 | ## SYNOPSIS 11 | {{ Fill in the Synopsis }} 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Get-ProjectVersion [[-ModuleName] ] [[-Path] ] [[-ExcludeFolders] ] 17 | [-ProgressAction ] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | {{ Fill in the Description }} 22 | 23 | ## EXAMPLES 24 | 25 | ### Example 1 26 | ```powershell 27 | PS C:\> {{ Add example code here }} 28 | ``` 29 | 30 | {{ Add example description here }} 31 | 32 | ## PARAMETERS 33 | 34 | ### -ExcludeFolders 35 | {{ Fill ExcludeFolders Description }} 36 | 37 | ```yaml 38 | Type: String[] 39 | Parameter Sets: (All) 40 | Aliases: 41 | 42 | Required: False 43 | Position: 2 44 | Default value: None 45 | Accept pipeline input: False 46 | Accept wildcard characters: False 47 | ``` 48 | 49 | ### -ModuleName 50 | {{ Fill ModuleName Description }} 51 | 52 | ```yaml 53 | Type: String 54 | Parameter Sets: (All) 55 | Aliases: 56 | 57 | Required: False 58 | Position: 0 59 | Default value: None 60 | Accept pipeline input: False 61 | Accept wildcard characters: False 62 | ``` 63 | 64 | ### -Path 65 | {{ Fill Path Description }} 66 | 67 | ```yaml 68 | Type: String 69 | Parameter Sets: (All) 70 | Aliases: 71 | 72 | Required: False 73 | Position: 1 74 | Default value: None 75 | Accept pipeline input: False 76 | Accept wildcard characters: False 77 | ``` 78 | 79 | ### -ProgressAction 80 | {{ Fill ProgressAction Description }} 81 | 82 | ```yaml 83 | Type: ActionPreference 84 | Parameter Sets: (All) 85 | Aliases: proga 86 | 87 | Required: False 88 | Position: Named 89 | Default value: None 90 | Accept pipeline input: False 91 | Accept wildcard characters: False 92 | ``` 93 | 94 | ### CommonParameters 95 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 96 | 97 | ## INPUTS 98 | 99 | ### None 100 | 101 | ## OUTPUTS 102 | 103 | ### System.Object 104 | ## NOTES 105 | 106 | ## RELATED LINKS 107 | -------------------------------------------------------------------------------- /Docs/Initialize-PortableModule.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSPublishModule-help.xml 3 | Module Name: PSPublishModule 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Initialize-PortableModule 9 | 10 | ## SYNOPSIS 11 | {{ Fill in the Synopsis }} 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Initialize-PortableModule [[-Name] ] [[-Path] ] [-Download] [-Import] 17 | [-ProgressAction ] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | {{ Fill in the Description }} 22 | 23 | ## EXAMPLES 24 | 25 | ### Example 1 26 | ```powershell 27 | PS C:\> {{ Add example code here }} 28 | ``` 29 | 30 | {{ Add example description here }} 31 | 32 | ## PARAMETERS 33 | 34 | ### -Download 35 | {{ Fill Download Description }} 36 | 37 | ```yaml 38 | Type: SwitchParameter 39 | Parameter Sets: (All) 40 | Aliases: 41 | 42 | Required: False 43 | Position: Named 44 | Default value: None 45 | Accept pipeline input: False 46 | Accept wildcard characters: False 47 | ``` 48 | 49 | ### -Import 50 | {{ Fill Import Description }} 51 | 52 | ```yaml 53 | Type: SwitchParameter 54 | Parameter Sets: (All) 55 | Aliases: 56 | 57 | Required: False 58 | Position: Named 59 | Default value: None 60 | Accept pipeline input: False 61 | Accept wildcard characters: False 62 | ``` 63 | 64 | ### -Name 65 | {{ Fill Name Description }} 66 | 67 | ```yaml 68 | Type: String 69 | Parameter Sets: (All) 70 | Aliases: ModuleName 71 | 72 | Required: False 73 | Position: 0 74 | Default value: None 75 | Accept pipeline input: False 76 | Accept wildcard characters: False 77 | ``` 78 | 79 | ### -Path 80 | {{ Fill Path Description }} 81 | 82 | ```yaml 83 | Type: String 84 | Parameter Sets: (All) 85 | Aliases: 86 | 87 | Required: False 88 | Position: 1 89 | Default value: None 90 | Accept pipeline input: False 91 | Accept wildcard characters: False 92 | ``` 93 | 94 | ### -ProgressAction 95 | {{ Fill ProgressAction Description }} 96 | 97 | ```yaml 98 | Type: ActionPreference 99 | Parameter Sets: (All) 100 | Aliases: proga 101 | 102 | Required: False 103 | Position: Named 104 | Default value: None 105 | Accept pipeline input: False 106 | Accept wildcard characters: False 107 | ``` 108 | 109 | ### CommonParameters 110 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 111 | 112 | ## INPUTS 113 | 114 | ### None 115 | 116 | ## OUTPUTS 117 | 118 | ### System.Object 119 | ## NOTES 120 | 121 | ## RELATED LINKS 122 | -------------------------------------------------------------------------------- /Docs/Initialize-PortableScript.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSPublishModule-help.xml 3 | Module Name: PSPublishModule 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Initialize-PortableScript 9 | 10 | ## SYNOPSIS 11 | {{ Fill in the Synopsis }} 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Initialize-PortableScript [[-FilePath] ] [[-OutputPath] ] [[-ApprovedModules] ] 17 | [-ProgressAction ] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | {{ Fill in the Description }} 22 | 23 | ## EXAMPLES 24 | 25 | ### Example 1 26 | ```powershell 27 | PS C:\> {{ Add example code here }} 28 | ``` 29 | 30 | {{ Add example description here }} 31 | 32 | ## PARAMETERS 33 | 34 | ### -ApprovedModules 35 | {{ Fill ApprovedModules Description }} 36 | 37 | ```yaml 38 | Type: Array 39 | Parameter Sets: (All) 40 | Aliases: 41 | 42 | Required: False 43 | Position: 2 44 | Default value: None 45 | Accept pipeline input: False 46 | Accept wildcard characters: False 47 | ``` 48 | 49 | ### -FilePath 50 | {{ Fill FilePath Description }} 51 | 52 | ```yaml 53 | Type: String 54 | Parameter Sets: (All) 55 | Aliases: 56 | 57 | Required: False 58 | Position: 0 59 | Default value: None 60 | Accept pipeline input: False 61 | Accept wildcard characters: False 62 | ``` 63 | 64 | ### -OutputPath 65 | {{ Fill OutputPath Description }} 66 | 67 | ```yaml 68 | Type: String 69 | Parameter Sets: (All) 70 | Aliases: 71 | 72 | Required: False 73 | Position: 1 74 | Default value: None 75 | Accept pipeline input: False 76 | Accept wildcard characters: False 77 | ``` 78 | 79 | ### -ProgressAction 80 | {{ Fill ProgressAction Description }} 81 | 82 | ```yaml 83 | Type: ActionPreference 84 | Parameter Sets: (All) 85 | Aliases: proga 86 | 87 | Required: False 88 | Position: Named 89 | Default value: None 90 | Accept pipeline input: False 91 | Accept wildcard characters: False 92 | ``` 93 | 94 | ### CommonParameters 95 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 96 | 97 | ## INPUTS 98 | 99 | ### None 100 | 101 | ## OUTPUTS 102 | 103 | ### System.Object 104 | ## NOTES 105 | 106 | ## RELATED LINKS 107 | -------------------------------------------------------------------------------- /Docs/Initialize-ProjectManager.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSPublishModule-help.xml 3 | Module Name: PSPublishModule 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Initialize-ProjectManager 9 | 10 | ## SYNOPSIS 11 | Builds VSCode Project manager config from filesystem 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Initialize-ProjectManager [-Path] [-DisableSorting] [-ProgressAction ] 17 | [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | Builds VSCode Project manager config from filesystem 22 | 23 | ## EXAMPLES 24 | 25 | ### EXAMPLE 1 26 | ``` 27 | Initialize-ProjectManager -Path "C:\Support\GitHub" 28 | ``` 29 | 30 | ### EXAMPLE 2 31 | ``` 32 | Initialize-ProjectManager -Path "C:\Support\GitHub" -DisableSorting 33 | ``` 34 | 35 | ## PARAMETERS 36 | 37 | ### -Path 38 | Path to where the projects are located 39 | 40 | ```yaml 41 | Type: String 42 | Parameter Sets: (All) 43 | Aliases: 44 | 45 | Required: True 46 | Position: 1 47 | Default value: None 48 | Accept pipeline input: False 49 | Accept wildcard characters: False 50 | ``` 51 | 52 | ### -DisableSorting 53 | Disables sorting of the projects by last modified date 54 | 55 | ```yaml 56 | Type: SwitchParameter 57 | Parameter Sets: (All) 58 | Aliases: 59 | 60 | Required: False 61 | Position: Named 62 | Default value: False 63 | Accept pipeline input: False 64 | Accept wildcard characters: False 65 | ``` 66 | 67 | ### -ProgressAction 68 | {{ Fill ProgressAction Description }} 69 | 70 | ```yaml 71 | Type: ActionPreference 72 | Parameter Sets: (All) 73 | Aliases: proga 74 | 75 | Required: False 76 | Position: Named 77 | Default value: None 78 | Accept pipeline input: False 79 | Accept wildcard characters: False 80 | ``` 81 | 82 | ### CommonParameters 83 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 84 | 85 | ## INPUTS 86 | 87 | ## OUTPUTS 88 | 89 | ## NOTES 90 | General notes 91 | 92 | ## RELATED LINKS 93 | -------------------------------------------------------------------------------- /Docs/New-ConfigurationCommand.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSPublishModule-help.xml 3 | Module Name: PSPublishModule 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # New-ConfigurationCommand 9 | 10 | ## SYNOPSIS 11 | {{ Fill in the Synopsis }} 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | New-ConfigurationCommand [[-ModuleName] ] [[-CommandName] ] 17 | [-ProgressAction ] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | {{ Fill in the Description }} 22 | 23 | ## EXAMPLES 24 | 25 | ### Example 1 26 | ```powershell 27 | PS C:\> {{ Add example code here }} 28 | ``` 29 | 30 | {{ Add example description here }} 31 | 32 | ## PARAMETERS 33 | 34 | ### -CommandName 35 | {{ Fill CommandName Description }} 36 | 37 | ```yaml 38 | Type: String[] 39 | Parameter Sets: (All) 40 | Aliases: 41 | 42 | Required: False 43 | Position: 1 44 | Default value: None 45 | Accept pipeline input: False 46 | Accept wildcard characters: False 47 | ``` 48 | 49 | ### -ModuleName 50 | {{ Fill ModuleName Description }} 51 | 52 | ```yaml 53 | Type: String 54 | Parameter Sets: (All) 55 | Aliases: 56 | 57 | Required: False 58 | Position: 0 59 | Default value: None 60 | Accept pipeline input: False 61 | Accept wildcard characters: False 62 | ``` 63 | 64 | ### -ProgressAction 65 | {{ Fill ProgressAction Description }} 66 | 67 | ```yaml 68 | Type: ActionPreference 69 | Parameter Sets: (All) 70 | Aliases: proga 71 | 72 | Required: False 73 | Position: Named 74 | Default value: None 75 | Accept pipeline input: False 76 | Accept wildcard characters: False 77 | ``` 78 | 79 | ### CommonParameters 80 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 81 | 82 | ## INPUTS 83 | 84 | ### None 85 | 86 | ## OUTPUTS 87 | 88 | ### System.Object 89 | ## NOTES 90 | 91 | ## RELATED LINKS 92 | -------------------------------------------------------------------------------- /Docs/New-ConfigurationDocumentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSPublishModule-help.xml 3 | Module Name: PSPublishModule 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # New-ConfigurationDocumentation 9 | 10 | ## SYNOPSIS 11 | Enables or disables creation of documentation from the module using PlatyPS 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | New-ConfigurationDocumentation [-Enable] [-StartClean] [-UpdateWhenNew] [-Path] [-PathReadme] 17 | [[-Tool] ] [-ProgressAction ] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | Enables or disables creation of documentation from the module using PlatyPS 22 | 23 | ## EXAMPLES 24 | 25 | ### EXAMPLE 1 26 | ``` 27 | New-ConfigurationDocumentation -Enable:$false -StartClean -UpdateWhenNew -PathReadme 'Docs\Readme.md' -Path 'Docs' 28 | ``` 29 | 30 | ### EXAMPLE 2 31 | ``` 32 | New-ConfigurationDocumentation -Enable -PathReadme 'Docs\Readme.md' -Path 'Docs' 33 | ``` 34 | 35 | ## PARAMETERS 36 | 37 | ### -Enable 38 | Enables creation of documentation from the module. 39 | If not specified, the documentation will not be created. 40 | 41 | ```yaml 42 | Type: SwitchParameter 43 | Parameter Sets: (All) 44 | Aliases: 45 | 46 | Required: False 47 | Position: Named 48 | Default value: False 49 | Accept pipeline input: False 50 | Accept wildcard characters: False 51 | ``` 52 | 53 | ### -StartClean 54 | Removes all files from the documentation folder before creating new documentation. 55 | Otherwise the \`Update-MarkdownHelpModule\` will be used to update the documentation. 56 | 57 | ```yaml 58 | Type: SwitchParameter 59 | Parameter Sets: (All) 60 | Aliases: 61 | 62 | Required: False 63 | Position: Named 64 | Default value: False 65 | Accept pipeline input: False 66 | Accept wildcard characters: False 67 | ``` 68 | 69 | ### -UpdateWhenNew 70 | Updates the documentation right after running \`New-MarkdownHelp\` due to platyPS bugs. 71 | 72 | ```yaml 73 | Type: SwitchParameter 74 | Parameter Sets: (All) 75 | Aliases: 76 | 77 | Required: False 78 | Position: Named 79 | Default value: False 80 | Accept pipeline input: False 81 | Accept wildcard characters: False 82 | ``` 83 | 84 | ### -Path 85 | Path to the folder where documentation will be created. 86 | 87 | ```yaml 88 | Type: String 89 | Parameter Sets: (All) 90 | Aliases: 91 | 92 | Required: True 93 | Position: 1 94 | Default value: None 95 | Accept pipeline input: False 96 | Accept wildcard characters: False 97 | ``` 98 | 99 | ### -PathReadme 100 | Path to the readme file that will be used for the documentation. 101 | 102 | ```yaml 103 | Type: String 104 | Parameter Sets: (All) 105 | Aliases: 106 | 107 | Required: True 108 | Position: 2 109 | Default value: None 110 | Accept pipeline input: False 111 | Accept wildcard characters: False 112 | ``` 113 | 114 | ### -Tool 115 | Tool to use for documentation generation. 116 | By default \`HelpOut\` is used. 117 | Available options are \`PlatyPS\` and \`HelpOut\`. 118 | 119 | ```yaml 120 | Type: String 121 | Parameter Sets: (All) 122 | Aliases: 123 | 124 | Required: False 125 | Position: 3 126 | Default value: PlatyPS 127 | Accept pipeline input: False 128 | Accept wildcard characters: False 129 | ``` 130 | 131 | ### -ProgressAction 132 | {{ Fill ProgressAction Description }} 133 | 134 | ```yaml 135 | Type: ActionPreference 136 | Parameter Sets: (All) 137 | Aliases: proga 138 | 139 | Required: False 140 | Position: Named 141 | Default value: None 142 | Accept pipeline input: False 143 | Accept wildcard characters: False 144 | ``` 145 | 146 | ### CommonParameters 147 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 148 | 149 | ## INPUTS 150 | 151 | ## OUTPUTS 152 | 153 | ## NOTES 154 | General notes 155 | 156 | ## RELATED LINKS 157 | -------------------------------------------------------------------------------- /Docs/New-ConfigurationExecute.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSPublishModule-help.xml 3 | Module Name: PSPublishModule 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # New-ConfigurationExecute 9 | 10 | ## SYNOPSIS 11 | {{ Fill in the Synopsis }} 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | New-ConfigurationExecute [-ProgressAction ] [] 17 | ``` 18 | 19 | ## DESCRIPTION 20 | {{ Fill in the Description }} 21 | 22 | ## EXAMPLES 23 | 24 | ### Example 1 25 | ```powershell 26 | PS C:\> {{ Add example code here }} 27 | ``` 28 | 29 | {{ Add example description here }} 30 | 31 | ## PARAMETERS 32 | 33 | ### -ProgressAction 34 | {{ Fill ProgressAction Description }} 35 | 36 | ```yaml 37 | Type: ActionPreference 38 | Parameter Sets: (All) 39 | Aliases: proga 40 | 41 | Required: False 42 | Position: Named 43 | Default value: None 44 | Accept pipeline input: False 45 | Accept wildcard characters: False 46 | ``` 47 | 48 | ### CommonParameters 49 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 50 | 51 | ## INPUTS 52 | 53 | ### None 54 | 55 | ## OUTPUTS 56 | 57 | ### System.Object 58 | ## NOTES 59 | 60 | ## RELATED LINKS 61 | -------------------------------------------------------------------------------- /Docs/New-ConfigurationImportModule.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSPublishModule-help.xml 3 | Module Name: PSPublishModule 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # New-ConfigurationImportModule 9 | 10 | ## SYNOPSIS 11 | Creates a configuration for importing PowerShell modules. 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | New-ConfigurationImportModule [-ImportSelf] [-ImportRequiredModules] [-ProgressAction ] 17 | [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | This function generates a configuration object for importing PowerShell modules. 22 | It allows specifying whether to import the current module itself and/or any required modules. 23 | 24 | ## EXAMPLES 25 | 26 | ### EXAMPLE 1 27 | ``` 28 | New-ConfigurationImportModule -ImportSelf -ImportRequiredModules 29 | ``` 30 | 31 | ## PARAMETERS 32 | 33 | ### -ImportSelf 34 | Indicates whether to import the current module itself. 35 | 36 | ```yaml 37 | Type: SwitchParameter 38 | Parameter Sets: (All) 39 | Aliases: 40 | 41 | Required: False 42 | Position: Named 43 | Default value: False 44 | Accept pipeline input: False 45 | Accept wildcard characters: False 46 | ``` 47 | 48 | ### -ImportRequiredModules 49 | Indicates whether to import any required modules specified in the module manifest. 50 | 51 | ```yaml 52 | Type: SwitchParameter 53 | Parameter Sets: (All) 54 | Aliases: 55 | 56 | Required: False 57 | Position: Named 58 | Default value: False 59 | Accept pipeline input: False 60 | Accept wildcard characters: False 61 | ``` 62 | 63 | ### -ProgressAction 64 | {{ Fill ProgressAction Description }} 65 | 66 | ```yaml 67 | Type: ActionPreference 68 | Parameter Sets: (All) 69 | Aliases: proga 70 | 71 | Required: False 72 | Position: Named 73 | Default value: None 74 | Accept pipeline input: False 75 | Accept wildcard characters: False 76 | ``` 77 | 78 | ### CommonParameters 79 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 80 | 81 | ## INPUTS 82 | 83 | ## OUTPUTS 84 | 85 | ## NOTES 86 | This function helps in creating a standardized import configuration for PowerShell modules. 87 | 88 | ## RELATED LINKS 89 | -------------------------------------------------------------------------------- /Docs/New-ConfigurationModuleSkip.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSPublishModule-help.xml 3 | Module Name: PSPublishModule 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # New-ConfigurationModuleSkip 9 | 10 | ## SYNOPSIS 11 | Provides a way to ignore certain commands or modules during build process and continue module building on errors. 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | New-ConfigurationModuleSkip [[-IgnoreModuleName] ] [[-IgnoreFunctionName] ] [-Force] 17 | [-ProgressAction ] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | Provides a way to ignore certain commands or modules during build process and continue module building on errors. 22 | During build if a build module can't find require module or command it will fail the build process to prevent incomplete module from being created. 23 | This option allows to skip certain modules or commands and continue building the module. 24 | This is useful for commands we know are not available on all systems, or we get them different way. 25 | 26 | ## EXAMPLES 27 | 28 | ### EXAMPLE 1 29 | ``` 30 | New-ConfigurationModuleSkip -IgnoreFunctionName 'Invoke-Formatter', 'Find-Module' -IgnoreModuleName 'platyPS' 31 | ``` 32 | 33 | ## PARAMETERS 34 | 35 | ### -IgnoreModuleName 36 | Ignore module name or names. 37 | If the module is not available on the system it will be ignored and build process will continue. 38 | 39 | ```yaml 40 | Type: String[] 41 | Parameter Sets: (All) 42 | Aliases: 43 | 44 | Required: False 45 | Position: 1 46 | Default value: None 47 | Accept pipeline input: False 48 | Accept wildcard characters: False 49 | ``` 50 | 51 | ### -IgnoreFunctionName 52 | Ignore function name or names. 53 | If the function is not available in the module it will be ignored and build process will continue. 54 | 55 | ```yaml 56 | Type: String[] 57 | Parameter Sets: (All) 58 | Aliases: 59 | 60 | Required: False 61 | Position: 2 62 | Default value: None 63 | Accept pipeline input: False 64 | Accept wildcard characters: False 65 | ``` 66 | 67 | ### -Force 68 | This switch will force build process to continue even if the module or command is not available (aka you know what you are doing) 69 | 70 | ```yaml 71 | Type: SwitchParameter 72 | Parameter Sets: (All) 73 | Aliases: 74 | 75 | Required: False 76 | Position: Named 77 | Default value: False 78 | Accept pipeline input: False 79 | Accept wildcard characters: False 80 | ``` 81 | 82 | ### -ProgressAction 83 | {{ Fill ProgressAction Description }} 84 | 85 | ```yaml 86 | Type: ActionPreference 87 | Parameter Sets: (All) 88 | Aliases: proga 89 | 90 | Required: False 91 | Position: Named 92 | Default value: None 93 | Accept pipeline input: False 94 | Accept wildcard characters: False 95 | ``` 96 | 97 | ### CommonParameters 98 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 99 | 100 | ## INPUTS 101 | 102 | ## OUTPUTS 103 | 104 | ## NOTES 105 | General notes 106 | 107 | ## RELATED LINKS 108 | -------------------------------------------------------------------------------- /Docs/New-ConfigurationPlaceHolder.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSPublishModule-help.xml 3 | Module Name: PSPublishModule 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # New-ConfigurationPlaceHolder 9 | 10 | ## SYNOPSIS 11 | Command helping define custom placeholders replacing content within a script or module during the build process. 12 | 13 | ## SYNTAX 14 | 15 | ### FindAndReplace (Default) 16 | ``` 17 | New-ConfigurationPlaceHolder -Find -Replace [-ProgressAction ] 18 | [] 19 | ``` 20 | 21 | ### CustomReplacement 22 | ``` 23 | New-ConfigurationPlaceHolder -CustomReplacement [-ProgressAction ] 24 | [] 25 | ``` 26 | 27 | ## DESCRIPTION 28 | Command helping define custom placeholders replacing content within a script or module during the build process. 29 | It modifies only the content of the script or module (PSM1) and does not modify the sources. 30 | 31 | ## EXAMPLES 32 | 33 | ### EXAMPLE 1 34 | ``` 35 | New-ConfigurationPlaceHolder -Find '{CustomName}' -Replace 'SpecialCase' 36 | ``` 37 | 38 | ### EXAMPLE 2 39 | ``` 40 | New-ConfigurationPlaceHolder -CustomReplacement @( 41 | @{ Find = '{CustomName}'; Replace = 'SpecialCase' } 42 | @{ Find = '{CustomVersion}'; Replace = '1.0.0' } 43 | ) 44 | ``` 45 | 46 | ## PARAMETERS 47 | 48 | ### -CustomReplacement 49 | Hashtable array with custom placeholders to replace. 50 | Each hashtable must contain two keys: Find and Replace. 51 | 52 | ```yaml 53 | Type: IDictionary[] 54 | Parameter Sets: CustomReplacement 55 | Aliases: 56 | 57 | Required: True 58 | Position: Named 59 | Default value: None 60 | Accept pipeline input: False 61 | Accept wildcard characters: False 62 | ``` 63 | 64 | ### -Find 65 | The string to find in the script or module content. 66 | 67 | ```yaml 68 | Type: String 69 | Parameter Sets: FindAndReplace 70 | Aliases: 71 | 72 | Required: True 73 | Position: Named 74 | Default value: None 75 | Accept pipeline input: False 76 | Accept wildcard characters: False 77 | ``` 78 | 79 | ### -Replace 80 | The string to replace the Find string in the script or module content. 81 | 82 | ```yaml 83 | Type: String 84 | Parameter Sets: FindAndReplace 85 | Aliases: 86 | 87 | Required: True 88 | Position: Named 89 | Default value: None 90 | Accept pipeline input: False 91 | Accept wildcard characters: False 92 | ``` 93 | 94 | ### -ProgressAction 95 | {{ Fill ProgressAction Description }} 96 | 97 | ```yaml 98 | Type: ActionPreference 99 | Parameter Sets: (All) 100 | Aliases: proga 101 | 102 | Required: False 103 | Position: Named 104 | Default value: None 105 | Accept pipeline input: False 106 | Accept wildcard characters: False 107 | ``` 108 | 109 | ### CommonParameters 110 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 111 | 112 | ## INPUTS 113 | 114 | ## OUTPUTS 115 | 116 | ## NOTES 117 | General notes 118 | 119 | ## RELATED LINKS 120 | -------------------------------------------------------------------------------- /Docs/New-ConfigurationTest.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSPublishModule-help.xml 3 | Module Name: PSPublishModule 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # New-ConfigurationTest 9 | 10 | ## SYNOPSIS 11 | {{ Fill in the Synopsis }} 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | New-ConfigurationTest [-TestsPath] [-Enable] [-Force] [-ProgressAction ] 17 | [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | {{ Fill in the Description }} 22 | 23 | ## EXAMPLES 24 | 25 | ### Example 1 26 | ```powershell 27 | PS C:\> {{ Add example code here }} 28 | ``` 29 | 30 | {{ Add example description here }} 31 | 32 | ## PARAMETERS 33 | 34 | ### -Enable 35 | {{ Fill Enable Description }} 36 | 37 | ```yaml 38 | Type: SwitchParameter 39 | Parameter Sets: (All) 40 | Aliases: 41 | 42 | Required: False 43 | Position: Named 44 | Default value: None 45 | Accept pipeline input: False 46 | Accept wildcard characters: False 47 | ``` 48 | 49 | ### -Force 50 | {{ Fill Force Description }} 51 | 52 | ```yaml 53 | Type: SwitchParameter 54 | Parameter Sets: (All) 55 | Aliases: 56 | 57 | Required: False 58 | Position: Named 59 | Default value: None 60 | Accept pipeline input: False 61 | Accept wildcard characters: False 62 | ``` 63 | 64 | ### -TestsPath 65 | {{ Fill TestsPath Description }} 66 | 67 | ```yaml 68 | Type: String 69 | Parameter Sets: (All) 70 | Aliases: 71 | 72 | Required: True 73 | Position: 0 74 | Default value: None 75 | Accept pipeline input: False 76 | Accept wildcard characters: False 77 | ``` 78 | 79 | ### -ProgressAction 80 | {{ Fill ProgressAction Description }} 81 | 82 | ```yaml 83 | Type: ActionPreference 84 | Parameter Sets: (All) 85 | Aliases: proga 86 | 87 | Required: False 88 | Position: Named 89 | Default value: None 90 | Accept pipeline input: False 91 | Accept wildcard characters: False 92 | ``` 93 | 94 | ### CommonParameters 95 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 96 | 97 | ## INPUTS 98 | 99 | ### None 100 | 101 | ## OUTPUTS 102 | 103 | ### System.Object 104 | ## NOTES 105 | 106 | ## RELATED LINKS 107 | -------------------------------------------------------------------------------- /Docs/Readme.md: -------------------------------------------------------------------------------- 1 | --- 2 | Module Name: PSPublishModule 3 | Module Guid: eb76426a-1992-40a5-82cd-6480f883ef4d 4 | Download Help Link: {{ Update Download Link }} 5 | Help Version: {{ Please enter version of help manually (X.X.X.X) format }} 6 | Locale: en-US 7 | --- 8 | 9 | # PSPublishModule Module 10 | ## Description 11 | {{ Fill in the Description }} 12 | 13 | ## PSPublishModule Cmdlets 14 | ### [Convert-CommandsToList](Convert-CommandsToList.md) 15 | {{ Fill in the Description }} 16 | 17 | ### [Get-MissingFunctions](Get-MissingFunctions.md) 18 | {{ Fill in the Description }} 19 | 20 | ### [Get-PowerShellAssemblyMetadata](Get-PowerShellAssemblyMetadata.md) 21 | {{ Fill in the Description }} 22 | 23 | ### [Get-ProjectVersion](Get-ProjectVersion.md) 24 | {{ Fill in the Description }} 25 | 26 | ### [Initialize-PortableModule](Initialize-PortableModule.md) 27 | {{ Fill in the Description }} 28 | 29 | ### [Initialize-PortableScript](Initialize-PortableScript.md) 30 | {{ Fill in the Description }} 31 | 32 | ### [Initialize-ProjectManager](Initialize-ProjectManager.md) 33 | {{ Fill in the Description }} 34 | 35 | ### [Invoke-ModuleBuild](Invoke-ModuleBuild.md) 36 | {{ Fill in the Description }} 37 | 38 | ### [New-ConfigurationArtefact](New-ConfigurationArtefact.md) 39 | {{ Fill in the Description }} 40 | 41 | ### [New-ConfigurationBuild](New-ConfigurationBuild.md) 42 | {{ Fill in the Description }} 43 | 44 | ### [New-ConfigurationCommand](New-ConfigurationCommand.md) 45 | {{ Fill in the Description }} 46 | 47 | ### [New-ConfigurationDocumentation](New-ConfigurationDocumentation.md) 48 | {{ Fill in the Description }} 49 | 50 | ### [New-ConfigurationExecute](New-ConfigurationExecute.md) 51 | {{ Fill in the Description }} 52 | 53 | ### [New-ConfigurationFormat](New-ConfigurationFormat.md) 54 | {{ Fill in the Description }} 55 | 56 | ### [New-ConfigurationImportModule](New-ConfigurationImportModule.md) 57 | {{ Fill in the Description }} 58 | 59 | ### [New-ConfigurationInformation](New-ConfigurationInformation.md) 60 | {{ Fill in the Description }} 61 | 62 | ### [New-ConfigurationManifest](New-ConfigurationManifest.md) 63 | {{ Fill in the Description }} 64 | 65 | ### [New-ConfigurationModule](New-ConfigurationModule.md) 66 | {{ Fill in the Description }} 67 | 68 | ### [New-ConfigurationModuleSkip](New-ConfigurationModuleSkip.md) 69 | {{ Fill in the Description }} 70 | 71 | ### [New-ConfigurationPlaceHolder](New-ConfigurationPlaceHolder.md) 72 | {{ Fill in the Description }} 73 | 74 | ### [New-ConfigurationPublish](New-ConfigurationPublish.md) 75 | {{ Fill in the Description }} 76 | 77 | ### [New-ConfigurationTest](New-ConfigurationTest.md) 78 | {{ Fill in the Description }} 79 | 80 | ### [Register-Certificate](Register-Certificate.md) 81 | {{ Fill in the Description }} 82 | 83 | ### [Remove-Comments](Remove-Comments.md) 84 | {{ Fill in the Description }} 85 | 86 | ### [Send-GitHubRelease](Send-GitHubRelease.md) 87 | {{ Fill in the Description }} 88 | 89 | ### [Set-ProjectVersion](Set-ProjectVersion.md) 90 | {{ Fill in the Description }} 91 | 92 | ### [Test-BasicModule](Test-BasicModule.md) 93 | {{ Fill in the Description }} 94 | 95 | ### [Test-ScriptFile](Test-ScriptFile.md) 96 | {{ Fill in the Description }} 97 | 98 | ### [Test-ScriptModule](Test-ScriptModule.md) 99 | {{ Fill in the Description }} 100 | 101 | -------------------------------------------------------------------------------- /Docs/Set-ProjectVersion.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSPublishModule-help.xml 3 | Module Name: PSPublishModule 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Set-ProjectVersion 9 | 10 | ## SYNOPSIS 11 | {{ Fill in the Synopsis }} 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Set-ProjectVersion [[-VersionType] ] [[-NewVersion] ] [[-ModuleName] ] 17 | [[-Path] ] [[-ExcludeFolders] ] [-PassThru] [-ProgressAction ] [-WhatIf] 18 | [-Confirm] [] 19 | ``` 20 | 21 | ## DESCRIPTION 22 | {{ Fill in the Description }} 23 | 24 | ## EXAMPLES 25 | 26 | ### Example 1 27 | ```powershell 28 | PS C:\> {{ Add example code here }} 29 | ``` 30 | 31 | {{ Add example description here }} 32 | 33 | ## PARAMETERS 34 | 35 | ### -Confirm 36 | Prompts you for confirmation before running the cmdlet. 37 | 38 | ```yaml 39 | Type: SwitchParameter 40 | Parameter Sets: (All) 41 | Aliases: cf 42 | 43 | Required: False 44 | Position: Named 45 | Default value: None 46 | Accept pipeline input: False 47 | Accept wildcard characters: False 48 | ``` 49 | 50 | ### -ExcludeFolders 51 | {{ Fill ExcludeFolders Description }} 52 | 53 | ```yaml 54 | Type: String[] 55 | Parameter Sets: (All) 56 | Aliases: 57 | 58 | Required: False 59 | Position: 4 60 | Default value: None 61 | Accept pipeline input: False 62 | Accept wildcard characters: False 63 | ``` 64 | 65 | ### -ModuleName 66 | {{ Fill ModuleName Description }} 67 | 68 | ```yaml 69 | Type: String 70 | Parameter Sets: (All) 71 | Aliases: 72 | 73 | Required: False 74 | Position: 2 75 | Default value: None 76 | Accept pipeline input: False 77 | Accept wildcard characters: False 78 | ``` 79 | 80 | ### -NewVersion 81 | {{ Fill NewVersion Description }} 82 | 83 | ```yaml 84 | Type: String 85 | Parameter Sets: (All) 86 | Aliases: 87 | 88 | Required: False 89 | Position: 1 90 | Default value: None 91 | Accept pipeline input: False 92 | Accept wildcard characters: False 93 | ``` 94 | 95 | ### -PassThru 96 | {{ Fill PassThru Description }} 97 | 98 | ```yaml 99 | Type: SwitchParameter 100 | Parameter Sets: (All) 101 | Aliases: 102 | 103 | Required: False 104 | Position: Named 105 | Default value: None 106 | Accept pipeline input: False 107 | Accept wildcard characters: False 108 | ``` 109 | 110 | ### -Path 111 | {{ Fill Path Description }} 112 | 113 | ```yaml 114 | Type: String 115 | Parameter Sets: (All) 116 | Aliases: 117 | 118 | Required: False 119 | Position: 3 120 | Default value: None 121 | Accept pipeline input: False 122 | Accept wildcard characters: False 123 | ``` 124 | 125 | ### -VersionType 126 | {{ Fill VersionType Description }} 127 | 128 | ```yaml 129 | Type: String 130 | Parameter Sets: (All) 131 | Aliases: 132 | Accepted values: Major, Minor, Build, Revision 133 | 134 | Required: False 135 | Position: 0 136 | Default value: None 137 | Accept pipeline input: False 138 | Accept wildcard characters: False 139 | ``` 140 | 141 | ### -WhatIf 142 | Shows what would happen if the cmdlet runs. 143 | The cmdlet is not run. 144 | 145 | ```yaml 146 | Type: SwitchParameter 147 | Parameter Sets: (All) 148 | Aliases: wi 149 | 150 | Required: False 151 | Position: Named 152 | Default value: None 153 | Accept pipeline input: False 154 | Accept wildcard characters: False 155 | ``` 156 | 157 | ### -ProgressAction 158 | {{ Fill ProgressAction Description }} 159 | 160 | ```yaml 161 | Type: ActionPreference 162 | Parameter Sets: (All) 163 | Aliases: proga 164 | 165 | Required: False 166 | Position: Named 167 | Default value: None 168 | Accept pipeline input: False 169 | Accept wildcard characters: False 170 | ``` 171 | 172 | ### CommonParameters 173 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 174 | 175 | ## INPUTS 176 | 177 | ### None 178 | 179 | ## OUTPUTS 180 | 181 | ### System.Object 182 | ## NOTES 183 | 184 | ## RELATED LINKS 185 | -------------------------------------------------------------------------------- /Docs/Test-BasicModule.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSPublishModule-help.xml 3 | Module Name: PSPublishModule 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Test-BasicModule 9 | 10 | ## SYNOPSIS 11 | {{ Fill in the Synopsis }} 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Test-BasicModule [[-Path] ] [[-Type] ] [-ProgressAction ] 17 | [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | {{ Fill in the Description }} 22 | 23 | ## EXAMPLES 24 | 25 | ### Example 1 26 | ```powershell 27 | PS C:\> {{ Add example code here }} 28 | ``` 29 | 30 | {{ Add example description here }} 31 | 32 | ## PARAMETERS 33 | 34 | ### -Path 35 | {{ Fill Path Description }} 36 | 37 | ```yaml 38 | Type: String 39 | Parameter Sets: (All) 40 | Aliases: 41 | 42 | Required: False 43 | Position: 0 44 | Default value: None 45 | Accept pipeline input: False 46 | Accept wildcard characters: False 47 | ``` 48 | 49 | ### -Type 50 | {{ Fill Type Description }} 51 | 52 | ```yaml 53 | Type: String 54 | Parameter Sets: (All) 55 | Aliases: 56 | 57 | Required: False 58 | Position: 1 59 | Default value: None 60 | Accept pipeline input: False 61 | Accept wildcard characters: False 62 | ``` 63 | 64 | ### -ProgressAction 65 | {{ Fill ProgressAction Description }} 66 | 67 | ```yaml 68 | Type: ActionPreference 69 | Parameter Sets: (All) 70 | Aliases: proga 71 | 72 | Required: False 73 | Position: Named 74 | Default value: None 75 | Accept pipeline input: False 76 | Accept wildcard characters: False 77 | ``` 78 | 79 | ### CommonParameters 80 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 81 | 82 | ## INPUTS 83 | 84 | ### None 85 | 86 | ## OUTPUTS 87 | 88 | ### System.Object 89 | ## NOTES 90 | 91 | ## RELATED LINKS 92 | -------------------------------------------------------------------------------- /Docs/Test-ScriptFile.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSPublishModule-help.xml 3 | Module Name: PSPublishModule 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Test-ScriptFile 9 | 10 | ## SYNOPSIS 11 | Test a PowerShell script for cmdlets 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Test-ScriptFile [-Path] [-ProgressAction ] [] 17 | ``` 18 | 19 | ## DESCRIPTION 20 | This command will analyze a PowerShell script file and display a list of detected commands such as PowerShell cmdlets and functions. 21 | Commands will be compared to what is installed locally. 22 | It is recommended you run this on a Windows 8.1 client with the latest version of RSAT installed. 23 | Unknown commands could also be internally defined functions. 24 | If in doubt view the contents of the script file in the PowerShell ISE or a script editor. 25 | You can test any .ps1, .psm1 or .txt file. 26 | 27 | ## EXAMPLES 28 | 29 | ### EXAMPLE 1 30 | ``` 31 | test-scriptfile C:\scripts\Remove-MyVM2.ps1 32 | ``` 33 | 34 | CommandType Name ModuleName 35 | ----------- ---- ---------- 36 | Cmdlet Disable-VMEventing Hyper-V 37 | Cmdlet ForEach-Object Microsoft.PowerShell.Core 38 | Cmdlet Get-VHD Hyper-V 39 | Cmdlet Get-VMSnapshot Hyper-V 40 | Cmdlet Invoke-Command Microsoft.PowerShell.Core 41 | Cmdlet New-PSSession Microsoft.PowerShell.Core 42 | Cmdlet Out-Null Microsoft.PowerShell.Core 43 | Cmdlet Out-String Microsoft.PowerShell.Utility 44 | Cmdlet Remove-Item Microsoft.PowerShell.Management 45 | Cmdlet Remove-PSSession Microsoft.PowerShell.Core 46 | Cmdlet Remove-VM Hyper-V 47 | Cmdlet Remove-VMSnapshot Hyper-V 48 | Cmdlet Write-Debug Microsoft.PowerShell.Utility 49 | Cmdlet Write-Verbose Microsoft.PowerShell.Utility 50 | Cmdlet Write-Warning Microsoft.PowerShell.Utility 51 | 52 | ### EXAMPLE 2 53 | ``` 54 | Test-ScriptFile -Path 'C:\Users\przemyslaw.klys\Documents\WindowsPowerShell\Modules\PSWinReportingV2\PSWinReportingV2.psm1' | Sort-Object -Property Source, Name | ft -AutoSize 55 | ``` 56 | 57 | ## PARAMETERS 58 | 59 | ### -Path 60 | The path to the PowerShell script file. 61 | You can test any .ps1, .psm1 or .txt file. 62 | 63 | ```yaml 64 | Type: String 65 | Parameter Sets: (All) 66 | Aliases: 67 | 68 | Required: True 69 | Position: 1 70 | Default value: None 71 | Accept pipeline input: True (ByPropertyName, ByValue) 72 | Accept wildcard characters: False 73 | ``` 74 | 75 | ### -ProgressAction 76 | {{ Fill ProgressAction Description }} 77 | 78 | ```yaml 79 | Type: ActionPreference 80 | Parameter Sets: (All) 81 | Aliases: proga 82 | 83 | Required: False 84 | Position: Named 85 | Default value: None 86 | Accept pipeline input: False 87 | Accept wildcard characters: False 88 | ``` 89 | 90 | ### CommonParameters 91 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 92 | 93 | ## INPUTS 94 | 95 | ## OUTPUTS 96 | 97 | ## NOTES 98 | Original script provided by Jeff Hicks at (https://www.petri.com/powershell-problem-solver-find-script-commands) and https://twitter.com/donnie_taylor/status/1160920407031058432 99 | 100 | ## RELATED LINKS 101 | -------------------------------------------------------------------------------- /Docs/Test-ScriptModule.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSPublishModule-help.xml 3 | Module Name: PSPublishModule 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Test-ScriptModule 9 | 10 | ## SYNOPSIS 11 | {{ Fill in the Synopsis }} 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Test-ScriptModule [[-ModuleName] ] [[-SortName] ] [-Unique] 17 | [-ProgressAction ] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | {{ Fill in the Description }} 22 | 23 | ## EXAMPLES 24 | 25 | ### Example 1 26 | ```powershell 27 | PS C:\> {{ Add example code here }} 28 | ``` 29 | 30 | {{ Add example description here }} 31 | 32 | ## PARAMETERS 33 | 34 | ### -ModuleName 35 | {{ Fill ModuleName Description }} 36 | 37 | ```yaml 38 | Type: String 39 | Parameter Sets: (All) 40 | Aliases: 41 | 42 | Required: False 43 | Position: 0 44 | Default value: None 45 | Accept pipeline input: False 46 | Accept wildcard characters: False 47 | ``` 48 | 49 | ### -SortName 50 | {{ Fill SortName Description }} 51 | 52 | ```yaml 53 | Type: Object 54 | Parameter Sets: (All) 55 | Aliases: 56 | Accepted values: Name, CommandType, ModuleName, Source 57 | 58 | Required: False 59 | Position: 1 60 | Default value: None 61 | Accept pipeline input: False 62 | Accept wildcard characters: False 63 | ``` 64 | 65 | ### -Unique 66 | {{ Fill Unique Description }} 67 | 68 | ```yaml 69 | Type: SwitchParameter 70 | Parameter Sets: (All) 71 | Aliases: 72 | 73 | Required: False 74 | Position: Named 75 | Default value: None 76 | Accept pipeline input: False 77 | Accept wildcard characters: False 78 | ``` 79 | 80 | ### -ProgressAction 81 | {{ Fill ProgressAction Description }} 82 | 83 | ```yaml 84 | Type: ActionPreference 85 | Parameter Sets: (All) 86 | Aliases: proga 87 | 88 | Required: False 89 | Position: Named 90 | Default value: None 91 | Accept pipeline input: False 92 | Accept wildcard characters: False 93 | ``` 94 | 95 | ### CommonParameters 96 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 97 | 98 | ## INPUTS 99 | 100 | ### None 101 | 102 | ## OUTPUTS 103 | 104 | ### System.Object 105 | ## NOTES 106 | 107 | ## RELATED LINKS 108 | -------------------------------------------------------------------------------- /Examples/Example.CmdletAliasDetection.ps1: -------------------------------------------------------------------------------- 1 | Import-Module .\PSPublishModule.psd1 -Force 2 | 3 | #Get-PowerShellAssemblyMetadata -Path "C:\Support\GitHub\Mailozaurr\Sources\Mailozaurr.PowerShell\bin\Release\net472\Mailozaurr.PowerShell.dll" | Format-Table 4 | #Get-PowerShellAssemblyMetadata -Path "C:\Support\GitHub\Mailozaurr\Sources\Mailozaurr.PowerShell\bin\Release\net7.0\Mailozaurr.PowerShell.dll" 5 | #Get-PowerShellAssemblyMetadata -Path "C:\Support\GitHub\PSEventViewer\Sources\PSEventViewer\bin\Debug\net6.0\PSEventViewer.dll" | Format-Table 6 | Get-PowerShellAssemblyMetadata -Path "C:\Support\GitHub\PSEventViewer\Sources\PSEventViewer\bin\Debug\net472\PSEventViewer.dll" -Verbose | Format-Table -------------------------------------------------------------------------------- /Examples/Example.DetectUsedLibraries.ps1: -------------------------------------------------------------------------------- 1 | [appdomain]::currentdomain.getassemblies() | Sort-Object -Property fullname | Format-Table Fullname, Name, Location -AutoSize 2 | [appdomain]::currentdomain.getassemblies() | Where-Object { $_.FullName -like "*identity*" } | Sort-Object -Property fullname | Format-Table Fullname, Name, Location -AutoSize -------------------------------------------------------------------------------- /Examples/Example.FindMicrosoftClientIdentity.ps1: -------------------------------------------------------------------------------- 1 | # $Folder = $Env:PSModulePath -split ";" 2 | # $Output = foreach ($F in $Folder) { 3 | # if (Test-Path -Path $F) { 4 | # Get-ChildItem -LiteralPath $F -Recurse -Filter "*.dll" | ForEach-Object { 5 | # if ($_.Name -like "Microsoft.Identity.Client.dll") { 6 | # [PSCustomObject] @{ 7 | # Name = $_.FullName 8 | # Version = $_.VersionInfo.FileVersion 9 | # } 10 | # } 11 | # } 12 | # } 13 | # } 14 | # $Output | Format-Table -AutoSize 15 | 16 | $Folder = $Env:PSModulePath -split ";" 17 | $Output1 = foreach ($F in $Folder) { 18 | if (Test-Path -Path $F) { 19 | Get-ChildItem -LiteralPath $F -Recurse -Filter "*.dll" | ForEach-Object { 20 | if ($_.Name -like "Microsoft.IdentityModel.Abstractions.dll") { 21 | [PSCustomObject] @{ 22 | Name = $_.Name 23 | Path = $_.FullName 24 | Version = $_.VersionInfo.FileVersion 25 | } 26 | } 27 | } 28 | } 29 | } 30 | $Output1 | Group-Object -Property Name | ForEach-Object { 31 | "DLL Name: $($_.Name)" 32 | $_.Group | Format-Table -AutoSize -Property Version, Path 33 | '' 34 | } 35 | 36 | $Output2 = foreach ($F in $Folder) { 37 | if (Test-Path -Path $F) { 38 | Get-ChildItem -LiteralPath $F -Recurse -Filter "*.dll" | ForEach-Object { 39 | if ($_.Name -like "Microsoft.Identity.Client.*") { 40 | [PSCustomObject] @{ 41 | Name = $_.Name 42 | Path = $_.FullName 43 | Version = $_.VersionInfo.FileVersion 44 | } 45 | } 46 | } 47 | } 48 | } 49 | $Output2 | Group-Object -Property Name | ForEach-Object { 50 | "DLL Name: $($_.Name)" 51 | $_.Group | Format-Table -AutoSize -Property Version, Path 52 | '' 53 | } -------------------------------------------------------------------------------- /Examples/Example.RegisterCertificate.ps1: -------------------------------------------------------------------------------- 1 | Import-Module "$PSSCriptRoot\..\PSPublishModule.psd1" -Force 2 | 3 | Import-ValidCertificate -CertificateAsBase64 $BasePfx -PfxPassword 'TemporaryPassword' 4 | 5 | #$pfxCertFilePath = Join-Path -Path $PSScriptRoot -ChildPath "CodeSigningCertificate.pfx" 6 | #Set-Content -Value $([System.Convert]::FromBase64String($env:BASE64_PFX)) -Path $pfxCertFilePath -Encoding Byte 7 | #$codeSigningCert = Import-PfxCertificate -FilePath $pfxCertFilePath -Password $($env:PFX_PASSWORD | ConvertTo-SecureString -AsPlainText -Force) -CertStoreLocation Cert:\CurrentUser\My 8 | 9 | #Register-Certificate -CertificatePFX -Path $PSSCriptRoot\Files 10 | -------------------------------------------------------------------------------- /Examples/Example.RemoveComments.ps1.ps1: -------------------------------------------------------------------------------- 1 | Import-Module .\PSPublishModule.psd1 -Force 2 | 3 | $removeCommentsSplat = @{ 4 | SourceFilePath = 'C:\Users\przemyslaw.klys\OneDrive - Evotec Services sp. z o.o\Documents\PowerShell\Modules\PSWriteHTML\PSWriteHTML.psm1' 5 | DestinationFilePath = 'C:\Support\GitHub\PSPublishModule\Examples\TestScript1.ps1' 6 | } 7 | 8 | #Remove-Comments @removeCommentsSplat -RemoveCommentsInParamBlock -RemoveAllEmptyLines -RemoveCommentsBeforeParamBlock 9 | 10 | $removeCommentsSplat = @{ 11 | SourceFilePath = 'C:\Support\GitHub\PSPublishModule\Examples\TestScript.ps1' 12 | DestinationFilePath = 'C:\Support\GitHub\PSPublishModule\Examples\TestScript1.ps1' 13 | # RemoveAllEmptyLines = $true 14 | RemoveEmptyLines = $true 15 | RemoveCommentsInParamBlock = $false 16 | RemoveCommentsBeforeParamBlock = $false 17 | } 18 | 19 | Remove-Comments @removeCommentsSplat -------------------------------------------------------------------------------- /Examples/Example.SignMultipleFiles.ps1: -------------------------------------------------------------------------------- 1 | Import-Module .\PSPublishModule.psd1 -Force 2 | 3 | $Folder = "C:\Users\przemyslaw.klys\Downloads\MDE\MDE\2016" 4 | 5 | $registerCertificateSplat = @{ 6 | LocalStore = 'CurrentUser' 7 | Path = $Folder 8 | Include = @('*.ps1', '*.psd1', '*.psm1', '*.dll', '*.cat') 9 | TimeStampServer = 'http://timestamp.digicert.com' 10 | Thumbprint = '483292C9E317AA13B07BB7A96AE9D1A5ED9E7703' 11 | } 12 | 13 | Register-Certificate @registerCertificateSplat -Verbose -------------------------------------------------------------------------------- /Examples/Step01.CreateModuleProject.ps1: -------------------------------------------------------------------------------- 1 | Import-Module "$PSSCriptRoot\..\PSPublishModule.psd1" -Force 2 | 3 | # Step 01 - An initial module structure, manifest, and configuration file will be created 4 | Build-Module -ModuleName 'MyGreatModule' -Path "C:\Support\GitHub" -------------------------------------------------------------------------------- /Examples/Step03.PrepareVariablesForGitHubActions.ps1: -------------------------------------------------------------------------------- 1 | # this command allows you to copy the certificate to clipboard, to be put as GitHub Action Secret Variable 2 | # keep in mind that this certificate needs to have private key included, and be password protected to be used for signing 3 | $pfxCertFilePath = "C:\Support\Important\EvotecSignGitHubCertificate.pfx" 4 | $pfxContent = [System.IO.File]::ReadAllBytes($pfxCertFilePath) 5 | $BasePfx = [System.Convert]::ToBase64String($pfxContent) 6 | $BasePfx | Set-Clipboard 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Evotec 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /PSPublishModule.Tests.ps1: -------------------------------------------------------------------------------- 1 | $ItemPath = [System.IO.Path]::Combine($PSScriptRoot, "*.psd1") 2 | $ModuleName = (Get-ChildItem -Path $ItemPath).BaseName 3 | $PrimaryModule = Get-ChildItem -Path $PSScriptRoot -Filter '*.psd1' -Recurse -ErrorAction SilentlyContinue -Depth 1 4 | if (-not $PrimaryModule) { 5 | throw "Path $PSScriptRoot doesn't contain PSD1 files. Failing tests." 6 | } 7 | if ($PrimaryModule.Count -ne 1) { 8 | throw 'More than one PSD1 files detected. Failing tests.' 9 | } 10 | $PSDInformation = Import-PowerShellDataFile -Path $PrimaryModule.FullName 11 | $RequiredModules = @( 12 | 'Pester' 13 | 'PSWriteColor' 14 | if ($PSDInformation.RequiredModules) { 15 | $PSDInformation.RequiredModules 16 | } 17 | ) 18 | foreach ($Module in $RequiredModules) { 19 | if ($Module -is [System.Collections.IDictionary]) { 20 | $Exists = Get-Module -ListAvailable -Name $Module.ModuleName 21 | if (-not $Exists) { 22 | Write-Warning "$ModuleName - Downloading $($Module.ModuleName) from PSGallery" 23 | Install-Module -Name $Module.ModuleName -Force -SkipPublisherCheck 24 | } 25 | } else { 26 | $Exists = Get-Module -ListAvailable $Module -ErrorAction SilentlyContinue 27 | if (-not $Exists) { 28 | Install-Module -Name $Module -Force -SkipPublisherCheck 29 | } 30 | } 31 | } 32 | 33 | Write-Color 'ModuleName: ', $ModuleName, ' Version: ', $PSDInformation.ModuleVersion -Color Yellow, Green, Yellow, Green -LinesBefore 2 34 | Write-Color 'PowerShell Version: ', $PSVersionTable.PSVersion -Color Yellow, Green 35 | Write-Color 'PowerShell Edition: ', $PSVersionTable.PSEdition -Color Yellow, Green 36 | Write-Color 'Required modules: ' -Color Yellow 37 | foreach ($Module in $PSDInformation.RequiredModules) { 38 | if ($Module -is [System.Collections.IDictionary]) { 39 | Write-Color ' [>] ', $Module.ModuleName, ' Version: ', $Module.ModuleVersion -Color Yellow, Green, Yellow, Green 40 | } else { 41 | Write-Color ' [>] ', $Module -Color Yellow, Green 42 | } 43 | } 44 | try { 45 | $Path = [System.IO.Path]::Combine($PSScriptRoot, "*.psd1") 46 | Import-Module -Name $Path -Force -ErrorAction Stop 47 | } catch { 48 | Write-Color 'Failed to import module', $_.Exception.Message -Color Red 49 | exit 1 50 | } 51 | 52 | Write-Color 'Running tests...' -Color Yellow 53 | Write-Color 54 | 55 | $result = Invoke-Pester -Script $PSScriptRoot\Tests -Verbose -PassThru 56 | 57 | if ($result.FailedCount -gt 0) { 58 | throw "$($result.FailedCount) tests failed." 59 | } -------------------------------------------------------------------------------- /PSPublishModule.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | AliasesToExport = @('New-PrepareModule', 'Build-Module', 'Invoke-ModuleBuilder') 3 | Author = 'Przemyslaw Klys' 4 | CmdletsToExport = @() 5 | CompanyName = 'Evotec' 6 | CompatiblePSEditions = @('Desktop', 'Core') 7 | Copyright = '(c) 2011 - 2025 Przemyslaw Klys @ Evotec. All rights reserved.' 8 | Description = 'Simple project allowing preparing, managing, building and publishing modules to PowerShellGallery' 9 | DotNetFrameworkVersion = '4.5.2' 10 | FunctionsToExport = @('Convert-CommandsToList', 'Get-MissingFunctions', 'Get-PowerShellAssemblyMetadata', 'Get-ProjectVersion', 'Initialize-PortableModule', 'Initialize-PortableScript', 'Initialize-ProjectManager', 'Invoke-ModuleBuild', 'New-ConfigurationArtefact', 'New-ConfigurationBuild', 'New-ConfigurationCommand', 'New-ConfigurationDocumentation', 'New-ConfigurationExecute', 'New-ConfigurationFormat', 'New-ConfigurationImportModule', 'New-ConfigurationInformation', 'New-ConfigurationManifest', 'New-ConfigurationModule', 'New-ConfigurationModuleSkip', 'New-ConfigurationPlaceHolder', 'New-ConfigurationPublish', 'New-ConfigurationTest', 'Register-Certificate', 'Remove-Comments', 'Send-GitHubRelease', 'Set-ProjectVersion', 'Test-BasicModule', 'Test-ScriptFile', 'Test-ScriptModule') 11 | GUID = 'eb76426a-1992-40a5-82cd-6480f883ef4d' 12 | ModuleVersion = '2.0.17' 13 | PowerShellVersion = '5.1' 14 | PrivateData = @{ 15 | PSData = @{ 16 | ExternalModuleDependencies = @('Microsoft.PowerShell.Utility', 'Microsoft.PowerShell.Archive', 'Microsoft.PowerShell.Management', 'Microsoft.PowerShell.Security') 17 | IconUri = 'https://evotec.xyz/wp-content/uploads/2019/02/PSPublishModule.png' 18 | ProjectUri = 'https://github.com/EvotecIT/PSPublishModule' 19 | Tags = @('Windows', 'MacOS', 'Linux', 'Build', 'Module') 20 | } 21 | } 22 | RequiredModules = @(@{ 23 | Guid = '1d73a601-4a6c-43c5-ba3f-619b18bbb404' 24 | ModuleName = 'powershellget' 25 | ModuleVersion = '2.2.5' 26 | }, @{ 27 | Guid = 'd6245802-193d-4068-a631-8863a4342a18' 28 | ModuleName = 'PSScriptAnalyzer' 29 | ModuleVersion = '1.24.0' 30 | }, @{ 31 | Guid = 'a699dea5-2c73-4616-a270-1f7abb777e71' 32 | ModuleName = 'Pester' 33 | ModuleVersion = '5.7.1' 34 | }, 'Microsoft.PowerShell.Utility', 'Microsoft.PowerShell.Archive', 'Microsoft.PowerShell.Management', 'Microsoft.PowerShell.Security') 35 | RootModule = 'PSPublishModule.psm1' 36 | } -------------------------------------------------------------------------------- /PSPublishModule.psm1: -------------------------------------------------------------------------------- 1 | #Get public and private function definition files. 2 | $Public = @( Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -ErrorAction SilentlyContinue -Recurse ) 3 | $Private = @( Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -ErrorAction SilentlyContinue -Recurse ) 4 | $Classes = @( Get-ChildItem -Path $PSScriptRoot\Classes\*.ps1 -ErrorAction SilentlyContinue -Recurse ) 5 | $Enums = @( Get-ChildItem -Path $PSScriptRoot\Enums\*.ps1 -ErrorAction SilentlyContinue -Recurse ) 6 | 7 | $AssemblyFolders = Get-ChildItem -Path $PSScriptRoot\Lib -Directory -ErrorAction SilentlyContinue 8 | $Assembly = @( 9 | if ($AssemblyFolders.BaseName -contains 'Standard') { 10 | @( Get-ChildItem -Path $PSScriptRoot\Lib\Standard\*.dll -ErrorAction SilentlyContinue -Recurse) 11 | } 12 | if ($PSEdition -eq 'Core') { 13 | @( Get-ChildItem -Path $PSScriptRoot\Lib\Core\*.dll -ErrorAction SilentlyContinue -Recurse ) 14 | } else { 15 | @( Get-ChildItem -Path $PSScriptRoot\Lib\Default\*.dll -ErrorAction SilentlyContinue -Recurse ) 16 | } 17 | ) 18 | $FoundErrors = @( 19 | foreach ($Import in @($Assembly)) { 20 | try { 21 | Add-Type -Path $Import.Fullname -ErrorAction Stop 22 | } catch [System.Reflection.ReflectionTypeLoadException] { 23 | Write-Warning "Processing $($Import.Name) Exception: $($_.Exception.Message)" 24 | $LoaderExceptions = $($_.Exception.LoaderExceptions) | Sort-Object -Unique 25 | foreach ($E in $LoaderExceptions) { 26 | Write-Warning "Processing $($Import.Name) LoaderExceptions: $($E.Message)" 27 | } 28 | $true 29 | #Write-Error -Message "StackTrace: $($_.Exception.StackTrace)" 30 | } catch { 31 | Write-Warning "Processing $($Import.Name) Exception: $($_.Exception.Message)" 32 | $LoaderExceptions = $($_.Exception.LoaderExceptions) | Sort-Object -Unique 33 | foreach ($E in $LoaderExceptions) { 34 | Write-Warning "Processing $($Import.Name) LoaderExceptions: $($E.Message)" 35 | } 36 | $true 37 | #Write-Error -Message "StackTrace: $($_.Exception.StackTrace)" 38 | } 39 | } 40 | #Dot source the files 41 | foreach ($Import in @($Private + $Public + $Classes + $Enums)) { 42 | try { 43 | . $Import.Fullname 44 | } catch { 45 | Write-Error -Message "Failed to import functions from $($import.Fullname): $_" 46 | $true 47 | } 48 | } 49 | ) 50 | 51 | if ($FoundErrors.Count -gt 0) { 52 | $ModuleName = (Get-ChildItem $PSScriptRoot\*.psd1).BaseName 53 | Write-Warning "Importing module $ModuleName failed. Fix errors before continuing." 54 | break 55 | } 56 | 57 | Export-ModuleMember -Function '*' -Alias '*' -------------------------------------------------------------------------------- /Private/Add-BinaryImportModule.ps1: -------------------------------------------------------------------------------- 1 | function Add-BinaryImportModule { 2 | <# 3 | .SYNOPSIS 4 | Add code into PSM1 that will import binary modules based on the edition 5 | 6 | .DESCRIPTION 7 | Add code into PSM1 that will import binary modules based on the edition 8 | 9 | .PARAMETER LibrariesStandard 10 | Parameter description 11 | 12 | .PARAMETER LibrariesCore 13 | Parameter description 14 | 15 | .PARAMETER LibrariesDefault 16 | Parameter description 17 | 18 | .PARAMETER Configuration 19 | Parameter description 20 | 21 | .EXAMPLE 22 | Add-BinaryImportModule -Configuration $Configuration -LibrariesStandard $LibrariesStandard -LibrariesCore $LibrariesCore -LibrariesDefault $LibrariesDefault 23 | 24 | .NOTES 25 | 26 | .OUTPUT 27 | # adds code into PSM1 file similar to this one 28 | if ($PSEdition -eq 'Core') { 29 | Import-Module -Name "$PSScriptRoot\Lib\Standard\PSEventViewer.PowerShell.dll" -Force -ErrorAction Stop 30 | } else { 31 | Import-Module -Name "$PSScriptRoot\Lib\Default\PSEventViewer.PowerShell.dll" -Force -ErrorAction Stop 32 | } 33 | 34 | #> 35 | [CmdletBinding()] 36 | param( 37 | [string[]] $LibrariesStandard, 38 | [string[]] $LibrariesCore, 39 | [string[]] $LibrariesDefault, 40 | [System.Collections.IDictionary] $Configuration 41 | ) 42 | 43 | if ($null -ne $Configuration.Steps.BuildLibraries.BinaryModule) { 44 | foreach ($BinaryModule in $Configuration.Steps.BuildLibraries.BinaryModule) { 45 | if ($LibrariesStandard.Count -gt 0) { 46 | foreach ($Library in $LibrariesStandard) { 47 | if ($Library -like "*\$BinaryModule") { 48 | "Import-Module -Name `"`$PSScriptRoot\$Library`" -Force -ErrorAction Stop" 49 | } 50 | } 51 | } elseif ($LibrariesCore.Count -gt 0 -and $LibrariesDefault.Count -gt 0) { 52 | 'if ($PSEdition -eq ''Core'') {' 53 | if ($LibrariesCore.Count -gt 0) { 54 | foreach ($Library in $LibrariesCore) { 55 | if ($Library -like "*\$BinaryModule") { 56 | "Import-Module -Name `"`$PSScriptRoot\$Library`" -Force -ErrorAction Stop" 57 | } 58 | } 59 | } 60 | '} else {' 61 | if ($LibrariesDefault.Count -gt 0) { 62 | foreach ($Library in $LibrariesDefault) { 63 | if ($Library -like "*\$BinaryModule") { 64 | "Import-Module -Name `"`$PSScriptRoot\$Library`" -Force -ErrorAction Stop" 65 | } 66 | } 67 | } 68 | '}' 69 | } else { 70 | if ($LibrariesCore.Count -gt 0) { 71 | if ($LibrariesCore.Count -gt 0) { 72 | foreach ($Library in $LibrariesCore) { 73 | if ($Library -like "*\$BinaryModule") { 74 | "Import-Module -Name `"`$PSScriptRoot\$Library`" -Force -ErrorAction Stop" 75 | } 76 | } 77 | } 78 | } 79 | if ($LibrariesDefault.Count -gt 0) { 80 | foreach ($Library in $LibrariesDefault) { 81 | if ($Library -like "*\$BinaryModule") { 82 | "Import-Module -Name `"`$PSScriptRoot\$Library`" -Force -ErrorAction Stop" 83 | } 84 | } 85 | } 86 | } 87 | } 88 | } 89 | } -------------------------------------------------------------------------------- /Private/Add-Directory.ps1: -------------------------------------------------------------------------------- 1 | function Add-Directory { 2 | [CmdletBinding()] 3 | param( 4 | [string] $Directory 5 | ) 6 | $exists = Test-Path -Path $Directory 7 | if ($exists -eq $false) { 8 | $null = New-Item -Path $Directory -ItemType Directory -Force 9 | } 10 | } -------------------------------------------------------------------------------- /Private/Convert-HashTableToNicelyFormattedString.ps1: -------------------------------------------------------------------------------- 1 | function Convert-HashTableToNicelyFormattedString { 2 | [CmdletBinding()] 3 | param( 4 | [System.Collections.IDictionary] $hashTable 5 | ) 6 | [string] $nicelyFormattedString = $hashTable.Keys | ForEach-Object ` 7 | { 8 | $key = $_ 9 | $value = $hashTable.$key 10 | " $key = $value$NewLine" 11 | } 12 | return $nicelyFormattedString 13 | } 14 | -------------------------------------------------------------------------------- /Private/Convert-RequiredModules.ps1: -------------------------------------------------------------------------------- 1 | function Convert-RequiredModules { 2 | <# 3 | .SYNOPSIS 4 | Converts the RequiredModules section of the manifest to the correct format 5 | 6 | .DESCRIPTION 7 | Converts the RequiredModules section of the manifest to the correct format 8 | Fixes the ModuleVersion and Guid if set to 'Latest' or 'Auto' 9 | 10 | .PARAMETER Configuration 11 | The configuration object of the module 12 | 13 | .EXAMPLE 14 | Convert-RequiredModules -Configuration $Configuration 15 | 16 | .NOTES 17 | General notes 18 | #> 19 | [CmdletBinding()] 20 | param( 21 | [System.Collections.IDictionary] $Configuration 22 | ) 23 | $Manifest = $Configuration.Information.Manifest 24 | 25 | $Failures = $false 26 | if ($Manifest.Contains('RequiredModules')) { 27 | foreach ($SubModule in $Manifest.RequiredModules) { 28 | if ($SubModule -is [string]) { 29 | #[Array] $AvailableModule = Get-Module -ListAvailable $SubModule -Verbose:$false 30 | } else { 31 | [Array] $AvailableModule = Get-Module -ListAvailable $SubModule.ModuleName -Verbose:$false 32 | if ($SubModule.ModuleVersion -in 'Latest', 'Auto') { 33 | if ($AvailableModule) { 34 | $SubModule.ModuleVersion = $AvailableModule[0].Version.ToString() 35 | } else { 36 | Write-Text -Text "[-] Module $($SubModule.ModuleName) is not available (Version), but defined as required with last version. Terminating." -Color Red 37 | $Failures = $true 38 | } 39 | } 40 | if ($SubModule.Guid -in 'Latest', 'Auto') { 41 | if ($AvailableModule) { 42 | $SubModule.Guid = $AvailableModule[0].Guid.ToString() 43 | } else { 44 | Write-Text -Text "[-] Module $($SubModule.ModuleName) is not available (GUID), but defined as required with last version. Terminating." -Color Red 45 | $Failures = $true 46 | } 47 | } 48 | } 49 | } 50 | } 51 | if ($Failures -eq $true) { 52 | $false 53 | } 54 | } -------------------------------------------------------------------------------- /Private/Copy-ArtefactMainModule.ps1: -------------------------------------------------------------------------------- 1 | function Copy-ArtefactMainModule { 2 | [CmdletBinding()] 3 | param( 4 | [switch] $Enabled, 5 | [nullable[bool]] $IncludeTagName, 6 | [string] $ModuleName, 7 | [string] $Destination 8 | ) 9 | if (-not $Enabled) { 10 | return 11 | } 12 | if ($IncludeTagName) { 13 | $NameOfDestination = [io.path]::Combine($Destination, $ModuleName, $TagName) 14 | } else { 15 | $NameOfDestination = [io.path]::Combine($Destination, $ModuleName) 16 | } 17 | $ResolvedDestination = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($NameOfDestination) 18 | Write-TextWithTime -PreAppend Addition -Text "Copying main module to $ResolvedDestination" -Color Yellow { 19 | if (Test-Path -Path $NameOfDestination) { 20 | Remove-ItemAlternative -LiteralPath $NameOfDestination -ErrorAction Stop 21 | } 22 | $null = New-Item -ItemType Directory -Path $Destination -Force 23 | 24 | if ($DestinationPaths.Desktop) { 25 | Copy-Item -LiteralPath $DestinationPaths.Desktop -Recurse -Destination $ResolvedDestination -Force 26 | } elseif ($DestinationPaths.Core) { 27 | Copy-Item -LiteralPath $DestinationPaths.Core -Recurse -Destination $ResolvedDestination -Force 28 | } 29 | } -SpacesBefore ' ' 30 | } -------------------------------------------------------------------------------- /Private/Copy-ArtefactRequiredFiles.ps1: -------------------------------------------------------------------------------- 1 | function Copy-ArtefactRequiredFiles { 2 | [CmdletBinding()] 3 | param( 4 | [System.Collections.IDictionary] $FilesInput, 5 | [string] $ProjectPath, 6 | [string] $Destination, 7 | [nullable[bool]] $DestinationRelative 8 | ) 9 | 10 | foreach ($File in $FilesInput.Keys) { 11 | if ($FilesInput[$File] -is [string]) { 12 | $FullFilePath = [System.IO.Path]::Combine($ProjectPath, $File) 13 | if (Test-Path -Path $FullFilePath) { 14 | if ($DestinationRelative) { 15 | $DestinationPath = [System.IO.Path]::Combine($Destination, $FilesInput[$File]) 16 | } else { 17 | $DestinationPath = $FilesInput[$File] 18 | } 19 | $ResolvedDestination = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($DestinationPath) 20 | Write-TextWithTime -Text "Copying file $FullFilePath to $ResolvedDestination" { 21 | $DirectoryPath = [Io.Path]::GetDirectoryName($ResolvedDestination) 22 | $null = New-Item -ItemType Directory -Force -ErrorAction Stop -Path $DirectoryPath 23 | Copy-Item -LiteralPath $FullFilePath -Destination $ResolvedDestination -Force -ErrorAction Stop 24 | } -PreAppend Addition -SpacesBefore ' ' -Color Yellow 25 | } else { 26 | Write-TextWithTime -Text "File $FullFilePath does not exist" -PreAppend Plus -SpacesBefore ' ' -Color Red -ColorTime Red -ColorBefore Red 27 | return $false 28 | } 29 | } elseif ($FilesInput[$File] -is [System.Collections.IDictionary]) { 30 | if ($FilesInput[$File].Enabled -eq $true) { 31 | if ($FilesInput[$File].Source) { 32 | $FullFilePath = [System.IO.Path]::Combine($ProjectPath, $FilesInput[$File].Source) 33 | if (Test-Path -Path $FullFilePath) { 34 | if ($FilesInput[$File].DestinationRelative) { 35 | $DestinationPath = [System.IO.Path]::Combine($Destination, $FilesInput[$File].Destination) 36 | } else { 37 | $DestinationPath = $FilesInput[$File].Destination 38 | } 39 | $ResolvedDestination = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($DestinationPath) 40 | Write-TextWithTime -Text "Copying file $FullFilePath to $ResolvedDestination" { 41 | $DirectoryPath = [Io.Path]::GetDirectoryName($ResolvedDestination) 42 | $null = New-Item -ItemType Directory -Force -ErrorAction Stop -Path $DirectoryPath 43 | Copy-Item -LiteralPath $FullFilePath -Destination $ResolvedDestination -Force -ErrorAction Stop 44 | } -PreAppend Addition -SpacesBefore ' ' -Color Yellow 45 | } else { 46 | Write-TextWithTime -Text "File $FullFilePath does not exist" -PreAppend Plus -SpacesBefore ' ' -Color Red -ColorTime Red -ColorBefore Red 47 | return $false 48 | } 49 | } 50 | } 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /Private/Copy-ArtefactRequiredFolders.ps1: -------------------------------------------------------------------------------- 1 | function Copy-ArtefactRequiredFolders { 2 | [CmdletBinding()] 3 | param( 4 | [System.Collections.IDictionary] $FoldersInput, 5 | [string] $ProjectPath, 6 | [string] $Destination, 7 | [nullable[bool]] $DestinationRelative 8 | ) 9 | } -------------------------------------------------------------------------------- /Private/Copy-ArtefactRequiredModule.ps1: -------------------------------------------------------------------------------- 1 | function Copy-ArtefactRequiredModule { 2 | [CmdletBinding()] 3 | param( 4 | [switch] $Enabled, 5 | [Array] $RequiredModules, 6 | [string] $Destination 7 | ) 8 | if (-not $Enabled) { 9 | return 10 | } 11 | if (-not (Test-Path -LiteralPath $Destination)) { 12 | New-Item -ItemType Directory -Path $Destination -Force 13 | } 14 | foreach ($Module in $RequiredModules) { 15 | if ($Module.ModuleName) { 16 | Write-TextWithTime -PreAppend Addition -Text "Copying required module $($Module.ModuleName)" -Color Yellow { 17 | $ModulesFound = Get-Module -ListAvailable -Name $Module.ModuleName 18 | if ($ModulesFound.Count -gt 0) { 19 | $PathToPSD1 = if ($Module.ModuleVersion -eq 'Latest') { 20 | $ModulesFound[0].Path 21 | } else { 22 | $FoundModule = foreach ($M in $ModulesFound) { 23 | if ($M.Version -eq $Module.ModuleVersion) { 24 | $M.Path 25 | break 26 | } 27 | } 28 | if (-not $FoundModule) { 29 | # we tried to find exact version, but it was not found 30 | # we use the latest version instead 31 | $ModulesFound[0].Path 32 | } else { 33 | $FoundModule 34 | } 35 | } 36 | $FolderToCopy = [System.IO.Path]::GetDirectoryName($PathToPSD1) 37 | $ItemInformation = Get-Item -LiteralPath $FolderToCopy 38 | 39 | if ($ItemInformation.Name -ne $Module.ModuleName) { 40 | $NewPath = [io.path]::Combine($Destination, $Module.ModuleName) 41 | if (Test-Path -LiteralPath $NewPath) { 42 | Remove-Item -LiteralPath $NewPath -Recurse -Force -ErrorAction Stop 43 | } 44 | Copy-Item -LiteralPath $FolderToCopy -Destination $NewPath -Recurse -Force -ErrorAction Stop 45 | } else { 46 | Copy-Item -LiteralPath $FolderToCopy -Destination $Destination -Recurse -Force 47 | } 48 | } 49 | } -SpacesBefore ' ' 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /Private/Copy-DictionaryManual.ps1: -------------------------------------------------------------------------------- 1 | function Copy-DictionaryManual { 2 | [CmdletBinding()] 3 | param( 4 | [System.Collections.IDictionary] $Dictionary 5 | ) 6 | 7 | $clone = @{} 8 | foreach ($Key in $Dictionary.Keys) { 9 | $value = $Dictionary.$Key 10 | 11 | $clonedValue = switch ($Dictionary.$Key) { 12 | { $null -eq $_ } { 13 | $null 14 | continue 15 | } 16 | { $_ -is [System.Collections.IDictionary] } { 17 | Copy-DictionaryManual -Dictionary $_ 18 | continue 19 | } 20 | { 21 | $type = $_.GetType() 22 | $type.IsPrimitive -or $type.IsValueType -or $_ -is [string] 23 | } { 24 | $_ 25 | continue 26 | } 27 | default { 28 | $_ | Select-Object -Property * 29 | } 30 | 31 | } 32 | 33 | if ($value -is [System.Collections.IList]) { 34 | $clone[$Key] = @($clonedValue) 35 | } else { 36 | $clone[$Key] = $clonedValue 37 | } 38 | } 39 | 40 | $clone 41 | } -------------------------------------------------------------------------------- /Private/Copy-InternalDictionary.ps1: -------------------------------------------------------------------------------- 1 | function Copy-InternalDictionary { 2 | [cmdletbinding()] 3 | param( 4 | [System.Collections.IDictionary] $Dictionary 5 | ) 6 | # create a deep-clone of an object 7 | $ms = [System.IO.MemoryStream]::new() 8 | $bf = [System.Runtime.Serialization.Formatters.Binary.BinaryFormatter]::new() 9 | $bf.Serialize($ms, $Dictionary) 10 | $ms.Position = 0 11 | $clone = $bf.Deserialize($ms) 12 | $ms.Close() 13 | $clone 14 | } -------------------------------------------------------------------------------- /Private/Copy-InternalFiles.ps1: -------------------------------------------------------------------------------- 1 | function Copy-InternalFiles { 2 | [CmdletBinding()] 3 | param( 4 | [string[]] $LinkFiles, 5 | [string] $FullModulePath, 6 | [string] $FullProjectPath, 7 | [switch] $Delete 8 | ) 9 | 10 | foreach ($File in $LinkFiles) { 11 | [string] $Path = [System.IO.Path]::Combine($FullModulePath, $File) 12 | [string] $Path2 = [System.IO.Path]::Combine($FullProjectPath, $File) 13 | 14 | if ($Delete) { 15 | if (Test-ReparsePoint -path $Path) { 16 | # Write-Color 'Removing symlink first ', $path -Color White, Yellow 17 | #Write-Verbose "Removing symlink first $path" 18 | Remove-Item $Path -Confirm:$false 19 | } 20 | } 21 | #Write-Verbose "Creating symlink from $path2 (source) to $path (target)" 22 | #Write-Color 'Creating symlink from ', $path2, ' (source) to ', $path, ' (target)' -Color White, Yellow, White, Yellow, White 23 | Copy-Item -Path $Path2 -Destination $Path -Force -Recurse -Confirm:$false 24 | #$null = cmd /c mklink $path $path2 25 | } 26 | } -------------------------------------------------------------------------------- /Private/Export-PSData.ps1: -------------------------------------------------------------------------------- 1 | function Export-PSData { 2 | <# 3 | .Synopsis 4 | Exports property bags into a data file 5 | .Description 6 | Exports property bags and the first level of any other object into a ps data file (.psd1) 7 | .Link 8 | https://github.com/StartAutomating/Pipeworks 9 | Import-PSData 10 | .Example 11 | Get-Web -Url http://www.youtube.com/watch?v=xPRC3EDR_GU -AsMicrodata -ItemType http://schema.org/VideoObject | 12 | Export-PSData .\PipeworksQuickstart.video.psd1 13 | #> 14 | [OutputType([IO.FileInfo])] 15 | [cmdletbinding()] 16 | param( 17 | # The data that will be exported 18 | [Parameter(Mandatory = $true, ValueFromPipeline = $true)][PSObject[]]$InputObject, 19 | # The path to the data file 20 | [Parameter(Mandatory = $true, Position = 0)][string] $DataFile, 21 | [switch] $Sort 22 | ) 23 | begin { 24 | $AllObjects = [System.Collections.Generic.List[object]]::new() 25 | } 26 | process { 27 | $AllObjects.AddRange($InputObject) 28 | } 29 | end { 30 | if ($PSVersionTable.PSVersion.Major -gt 5) { 31 | $Encoding = 'UTF8BOM' 32 | } else { 33 | $Encoding = 'UTF8' 34 | } 35 | 36 | #region Convert to Hashtables and export 37 | $Text = $AllObjects | Write-PowerShellHashtable -Sort:$Sort.IsPresent 38 | $Text | Out-File -FilePath $DataFile -Encoding $Encoding 39 | #endregion Convert to Hashtables and export 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /Private/Find-NetFramework.ps1: -------------------------------------------------------------------------------- 1 | function Find-NetFramework { 2 | <# 3 | .SYNOPSIS 4 | Short description 5 | 6 | .DESCRIPTION 7 | Long description 8 | 9 | .PARAMETER RequireVersion 10 | Parameter description 11 | 12 | .EXAMPLE 13 | Find-NetFramework -RequireVersion 4.8 14 | 15 | .NOTES 16 | General notes 17 | #> 18 | [cmdletBinding()] 19 | param( 20 | [string] $RequireVersion 21 | ) 22 | if ($RequireVersion) { 23 | $Framework = [ordered] @{ 24 | '4.5' = 378389 25 | '4.5.1' = 378675 26 | '4.5.2' = 379893 27 | '4.6' = 393295 28 | '4.6.1' = 394254 29 | '4.6.2' = 394802 30 | '4.7' = 460798 31 | '4.7.1' = 461308 32 | '4.7.2' = 461808 33 | '4.8' = 528040 34 | } 35 | $DetectVersion = $Framework[$RequireVersion] 36 | 37 | "if (`$PSVersionTable.PSEdition -eq 'Desktop' -and (Get-ItemProperty `"HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full`").Release -lt $DetectVersion) { Write-Warning `"This module requires .NET Framework $RequireVersion or later.`"; return } " 38 | } 39 | } -------------------------------------------------------------------------------- /Private/Find-RequiredModules.ps1: -------------------------------------------------------------------------------- 1 | function Find-RequiredModules { 2 | [cmdletbinding()] 3 | param( 4 | [string] $Name 5 | ) 6 | $Module = Get-Module -ListAvailable $Name -ErrorAction SilentlyContinue -Verbose:$false 7 | $AllModules = if ($Module) { 8 | [Array] $RequiredModules = $Module.RequiredModules.Name 9 | if ($null -ne $RequiredModules) { 10 | $null 11 | } 12 | $RequiredModules 13 | foreach ($_ in $RequiredModules) { 14 | Find-RequiredModules -Name $_ 15 | } 16 | } 17 | 18 | [Array] $ListModules = $AllModules | Where-Object { $null -ne $_ } 19 | if ($null -ne $ListModules) { 20 | [array]::Reverse($ListModules) 21 | } 22 | $CleanedModules = [System.Collections.Generic.List[string]]::new() 23 | foreach ($_ in $ListModules) { 24 | if ($CleanedModules -notcontains $_) { 25 | $CleanedModules.Add($_) 26 | } 27 | } 28 | $CleanedModules 29 | } -------------------------------------------------------------------------------- /Private/Format-Code.ps1: -------------------------------------------------------------------------------- 1 | function Format-Code { 2 | [cmdletbinding()] 3 | param( 4 | [string] $FilePath, 5 | [System.Collections.IDictionary] $FormatCode 6 | ) 7 | 8 | if ($PSVersionTable.PSVersion.Major -gt 5) { 9 | $Encoding = 'UTF8BOM' 10 | } else { 11 | $Encoding = 'UTF8' 12 | } 13 | 14 | if ($FormatCode.Enabled) { 15 | if ($FormatCode.RemoveComments -or $FormatCode.RemoveCommentsInParamBlock -or $FormatCode.RemoveCommentsBeforeParamBlock) { 16 | $Output = Write-TextWithTime -Text "[+] Removing Comments - $FilePath" { 17 | $removeCommentsSplat = @{ 18 | SourceFilePath = $FilePath 19 | RemoveCommentsInParamBlock = $FormatCode.RemoveCommentsInParamBlock 20 | RemoveCommentsBeforeParamBlock = $FormatCode.RemoveCommentsBeforeParamBlock 21 | RemoveAllEmptyLines = $FormatCode.RemoveAllEmptyLines 22 | RemoveEmptyLines = $FormatCode.RemoveEmptyLines 23 | } 24 | Remove-Comments @removeCommentsSplat 25 | } 26 | } elseif ($FormatCode.RemoveAllEmptyLines -or $FormatCode.RemoveEmptyLines) { 27 | $Output = Write-TextWithTime -Text "[+] Removing Empty Lines - $FilePath" { 28 | $removeEmptyLinesSplat = @{ 29 | SourceFilePath = $FilePath 30 | RemoveAllEmptyLines = $FormatCode.RemoveAllEmptyLines 31 | RemoveEmptyLines = $FormatCode.RemoveEmptyLines 32 | } 33 | Remove-EmptyLines @removeEmptyLinesSplat 34 | } 35 | } else { 36 | $Output = Write-TextWithTime -Text "Reading file content - $FilePath" { 37 | Get-Content -LiteralPath $FilePath -Raw -Encoding UTF8 -ErrorAction Stop 38 | } -PreAppend Plus -SpacesBefore ' ' 39 | } 40 | if ($Output -eq $false) { 41 | return $false 42 | } 43 | if ($null -eq $FormatCode.FormatterSettings) { 44 | $FormatCode.FormatterSettings = $Script:FormatterSettings 45 | } 46 | $Data = Write-TextWithTime -Text "Formatting file - $FilePath" { 47 | try { 48 | Invoke-Formatter -ScriptDefinition $Output -Settings $FormatCode.FormatterSettings -ErrorAction Stop 49 | } catch { 50 | $ErrorMessage = $_.Exception.Message 51 | #Write-Warning "Merge module on file $FilePath failed. Error: $ErrorMessage" 52 | Write-Host # This is to add new line, because the first line was opened up. 53 | Write-Text " [-] Format-Code - Formatting on file $FilePath failed." -Color Red 54 | Write-Text " [-] Format-Code - Error: $ErrorMessage" -Color Red 55 | Write-Text " [-] Format-Code - This is most likely related to a bug in PSScriptAnalyzer running inside VSCode. Please try running outside of VSCode when using formatting." -Color Red 56 | return $false 57 | } 58 | } -PreAppend Plus -SpacesBefore ' ' 59 | if ($Data -eq $false) { 60 | return $false 61 | } 62 | Write-TextWithTime -Text "Saving file - $FilePath" { 63 | # Resave 64 | $Final = foreach ($O in $Data) { 65 | if ($O.Trim() -ne '') { 66 | $O.Trim() 67 | } 68 | } 69 | try { 70 | $Final | Out-File -LiteralPath $FilePath -NoNewline -Encoding $Encoding -ErrorAction Stop 71 | } catch { 72 | $ErrorMessage = $_.Exception.Message 73 | #Write-Warning "Merge module on file $FilePath failed. Error: $ErrorMessage" 74 | Write-Host # This is to add new line, because the first line was opened up. 75 | Write-Text "[-] Format-Code - Resaving file $FilePath failed. Error: $ErrorMessage" -Color Red 76 | return $false 77 | } 78 | } -PreAppend Plus -SpacesBefore ' ' 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Private/Format-UsingNamespace.ps1: -------------------------------------------------------------------------------- 1 | function Format-UsingNamespace { 2 | [CmdletBinding()] 3 | param( 4 | [string] $FilePath, 5 | [string] $FilePathSave, 6 | [string] $FilePathUsing 7 | ) 8 | 9 | if ($PSVersionTable.PSVersion.Major -gt 5) { 10 | $Encoding = 'UTF8BOM' 11 | } else { 12 | $Encoding = 'UTF8' 13 | } 14 | 15 | if ($FilePathSave -eq '') { 16 | $FilePathSave = $FilePath 17 | } 18 | if ($FilePath -ne '' -and (Test-Path -Path $FilePath) -and (Get-Item -LiteralPath $FilePath).Length -gt 0kb) { 19 | $FileStream = New-Object -TypeName IO.FileStream -ArgumentList ($FilePath), ([System.IO.FileMode]::Open), ([System.IO.FileAccess]::Read), ([System.IO.FileShare]::ReadWrite); 20 | $ReadFile = New-Object -TypeName System.IO.StreamReader -ArgumentList ($FileStream, [System.Text.Encoding]::UTF8, $true); 21 | # Read Lines 22 | $UsingNamespaces = [System.Collections.Generic.List[string]]::new() 23 | #$AddTypes = [System.Collections.Generic.List[string]]::new() 24 | 25 | $Content = while (!$ReadFile.EndOfStream) { 26 | $Line = $ReadFile.ReadLine() 27 | if ($Line -like 'using namespace*') { 28 | $UsingNamespaces.Add($Line) 29 | #} elseif ($Line -like '*Add-Type*') { 30 | #$AddTypes.Add($Line) 31 | } else { 32 | $Line 33 | } 34 | } 35 | $ReadFile.Close() 36 | 37 | $null = New-Item -Path $FilePathSave -ItemType file -Force 38 | if ($UsingNamespaces) { 39 | # Repeat using namespaces 40 | $null = New-Item -Path $FilePathUsing -ItemType file -Force 41 | $UsingNamespaces = $UsingNamespaces.Trim() | Sort-Object -Unique 42 | $UsingNamespaces | Out-File -Append -LiteralPath $FilePathUsing -Encoding $Encoding 43 | 44 | $Content | Out-File -Append -LiteralPath $FilePathSave -Encoding $Encoding 45 | return $true 46 | } else { 47 | $Content | Out-File -Append -LiteralPath $FilePathSave -Encoding $Encoding 48 | return $False 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /Private/Get-AstTokens.ps1: -------------------------------------------------------------------------------- 1 | function Get-AstTokens { 2 | [cmdletBinding()] 3 | param( 4 | [System.Management.Automation.Language.Token[]] $ASTTokens, 5 | [System.Collections.Generic.List[Object]] $Commands, 6 | [System.Management.Automation.Language.Ast] $FileAst 7 | ) 8 | 9 | $ListOfFuncionsAst = $FileAst.FindAll( { 10 | param([System.Management.Automation.Language.Ast] $ast) 11 | end { 12 | if ($ast -isnot [System.Management.Automation.Language.CommandAst]) { 13 | return $false 14 | } 15 | 16 | for ($node = $ast.Parent; $null -ne $node; $node = $node.Parent) { 17 | if ($node -isnot [System.Management.Automation.Language.CommandAst]) { 18 | continue 19 | } 20 | 21 | # This is to prevent filters from AD based cmdlets from being included in the list 22 | # Since sometimes scriptblock is used in the filter, instead of a string it causes filter variables to be included in the list 23 | if ($node.GetCommandName() -in 'Get-ADComputer', 'Get-ADUser', 'Get-ADObject', 'Get-ADDomainController', 'Get-ADReplicationSubnet') { 24 | return $false 25 | } 26 | } 27 | 28 | return $true 29 | } 30 | }, $true 31 | ) 32 | 33 | $List = foreach ($Function in $ListOfFuncionsAst) { 34 | $Line = $Function.CommandElements[0] 35 | if ($Line.Value) { 36 | $Line.Value 37 | } 38 | } 39 | $List 40 | } -------------------------------------------------------------------------------- /Private/Get-CurrentVersionFromBuildScript.ps1: -------------------------------------------------------------------------------- 1 | function Get-CurrentVersionFromBuildScript { 2 | [CmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory = $true)] 5 | [string]$ScriptFile 6 | ) 7 | 8 | if (!(Test-Path -Path $ScriptFile)) { 9 | Write-Warning "Build script file not found: $ScriptFile" 10 | return $null 11 | } 12 | 13 | try { 14 | $content = Get-Content -Path $ScriptFile -Raw 15 | if ($content -match 'ModuleVersion\s*=\s*[''"\"]?([\d\.]+)[''"\"]?') { 16 | return $matches[1] 17 | } 18 | return $null 19 | } catch { 20 | Write-Warning "Error reading build script $ScriptFile`: $_" 21 | return $null 22 | } 23 | } -------------------------------------------------------------------------------- /Private/Get-CurrentVersionFromCsProj.ps1: -------------------------------------------------------------------------------- 1 | function Get-CurrentVersionFromCsProj { 2 | [CmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory = $true)] 5 | [string]$ProjectFile 6 | ) 7 | 8 | if (!(Test-Path -Path $ProjectFile)) { 9 | Write-Warning "Project file not found: $ProjectFile" 10 | return $null 11 | } 12 | 13 | try { 14 | $content = Get-Content -Path $ProjectFile -Raw 15 | if ($content -match '([\d\.]+)<\/VersionPrefix>') { 16 | return $matches[1] 17 | } 18 | return $null 19 | } catch { 20 | Write-Warning "Error reading project file $ProjectFile`: $_" 21 | return $null 22 | } 23 | } -------------------------------------------------------------------------------- /Private/Get-CurrentVersionFromPsd1.ps1: -------------------------------------------------------------------------------- 1 | function Get-CurrentVersionFromPsd1 { 2 | [CmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory = $true)] 5 | [string]$ManifestFile 6 | ) 7 | 8 | if (!(Test-Path -Path $ManifestFile)) { 9 | Write-Warning "Module manifest file not found: $ManifestFile" 10 | return $null 11 | } 12 | 13 | try { 14 | $manifest = Import-PowerShellDataFile -Path $ManifestFile 15 | return $manifest.ModuleVersion 16 | } catch { 17 | Write-Warning "Error reading module manifest $ManifestFile`: $_" 18 | return $null 19 | } 20 | } -------------------------------------------------------------------------------- /Private/Get-Encoding.ps1: -------------------------------------------------------------------------------- 1 | function Get-Encoding { 2 | [cmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)][Alias('FullName')][string] $Path 5 | ) 6 | process { 7 | $bom = New-Object -TypeName System.Byte[](4) 8 | 9 | $file = New-Object System.IO.FileStream($Path, 'Open', 'Read') 10 | 11 | $null = $file.Read($bom, 0, 4) 12 | $file.Close() 13 | $file.Dispose() 14 | 15 | $enc = [Text.Encoding]::ASCII 16 | if ($bom[0] -eq 0x2b -and $bom[1] -eq 0x2f -and $bom[2] -eq 0x76) 17 | { $enc = [Text.Encoding]::UTF7 } 18 | if ($bom[0] -eq 0xff -and $bom[1] -eq 0xfe) 19 | { $enc = [Text.Encoding]::Unicode } 20 | if ($bom[0] -eq 0xfe -and $bom[1] -eq 0xff) 21 | { $enc = [Text.Encoding]::BigEndianUnicode } 22 | if ($bom[0] -eq 0x00 -and $bom[1] -eq 0x00 -and $bom[2] -eq 0xfe -and $bom[3] -eq 0xff) 23 | { $enc = [Text.Encoding]::UTF32 } 24 | if ($bom[0] -eq 0xef -and $bom[1] -eq 0xbb -and $bom[2] -eq 0xbf) 25 | { $enc = [Text.Encoding]::UTF8 } 26 | 27 | [PSCustomObject]@{ 28 | Encoding = $enc 29 | Path = $Path 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Private/Get-FunctionAliasesFromFolder.ps1: -------------------------------------------------------------------------------- 1 | function Get-FunctionAliasesFromFolder { 2 | [cmdletbinding()] 3 | param( 4 | [string] $FullProjectPath, 5 | [string[]] $Folder, 6 | [Array] $Files, 7 | [string] $FunctionsToExport, 8 | [string] $AliasesToExport 9 | ) 10 | [Array] $FilesPS1 = foreach ($File in $Files) { 11 | if ($FunctionsToExport) { 12 | $PathFunctions = [io.path]::Combine($FullProjectPath, $FunctionsToExport, '*') 13 | if ($File.FullName -like $PathFunctions) { 14 | if ($File.Extension -eq '.ps1' -or $File.Extension -eq '*.psm1') { 15 | $File 16 | } 17 | } 18 | } 19 | if ($AliasesToExport -and $AliasesToExport -ne $FunctionsToExport) { 20 | $PathAliases = [io.path]::Combine($FullProjectPath, $AliasesToExport, '*') 21 | if ($File.FullName -like $PathAliases) { 22 | if ($File.Extension -eq '.ps1' -or $File.Extension -eq '*.psm1') { 23 | $File 24 | } 25 | } 26 | } 27 | } 28 | [Array] $Content = foreach ($File in $FilesPS1 | Sort-Object -Unique) { 29 | '' 30 | Get-Content -LiteralPath $File.FullName -Raw -Encoding UTF8 31 | } 32 | $Code = $Content -join [System.Environment]::NewLine 33 | 34 | $OutputAliasesToExport = Get-FunctionAliases -Content $Code -AsHashtable 35 | $OutputAliasesToExport 36 | } -------------------------------------------------------------------------------- /Private/Get-FunctionNames.ps1: -------------------------------------------------------------------------------- 1 | function Get-FunctionNames { 2 | [cmdletbinding()] 3 | param( 4 | [string] $Path, 5 | [switch] $Recurse 6 | ) 7 | if ($Path -ne '' -and (Test-Path -LiteralPath $Path)) { 8 | $FilePath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path) 9 | [System.Management.Automation.Language.Parser]::ParseFile(($FilePath), 10 | [ref]$null, 11 | [ref]$null).FindAll( 12 | { param($c)$c -is [Management.Automation.Language.FunctionDefinitionAst] }, $Recurse).Name 13 | } 14 | } -------------------------------------------------------------------------------- /Private/Get-GitLog.ps1: -------------------------------------------------------------------------------- 1 | function Get-GitLog { 2 | # Source https://gist.github.com/thedavecarroll/3245449f5ff893e51907f7aa13e33ebe 3 | # Author: thedavecarroll/Get-GitLog.ps1 4 | [CmdLetBinding(DefaultParameterSetName='Default')] 5 | param ( 6 | 7 | [Parameter(ParameterSetName='Default',Mandatory)] 8 | [Parameter(ParameterSetName='SourceTarget',Mandatory)] 9 | [ValidateScript({Resolve-Path -Path $_ | Test-Path})] 10 | [string]$GitFolder, 11 | 12 | [Parameter(ParameterSetName='SourceTarget',Mandatory)] 13 | [string]$StartCommitId, 14 | [Parameter(ParameterSetName='SourceTarget')] 15 | [string]$EndCommitId='HEAD' 16 | ) 17 | 18 | Push-Location 19 | try { 20 | Set-Location -Path $GitFolder 21 | $GitCommand = Get-Command -Name git -ErrorAction Stop 22 | } 23 | catch { 24 | $PSCmdlet.ThrowTerminatingError($_) 25 | } 26 | 27 | if ($StartCommitId) { 28 | $GitLogCommand = '"{0}" log --oneline --format="%H`t%h`t%ai`t%an`t%ae`t%ci`t%cn`t%ce`t%s`t%f" {1}...{2} 2>&1' -f $GitCommand.Source,$StartCommitId,$EndCommitId 29 | } else { 30 | $GitLogCommand = '"{0}" log --oneline --format="%H`t%h`t%ai`t%an`t%ae`t%ci`t%cn`t%ce`t%s`t%f" 2>&1' -f $GitCommand.Source 31 | } 32 | 33 | Write-Verbose -Message $GitLogCommand 34 | $GitLog = Invoke-Expression -Command "& $GitLogCommand" -ErrorAction SilentlyContinue 35 | Pop-Location 36 | 37 | if ($GitLog[0] -notmatch 'fatal:') { 38 | $GitLog | ConvertFrom-Csv -Delimiter "`t" -Header 'CommitId','ShortCommitId','AuthorDate','AuthorName','AuthorEmail','CommitterDate','CommitterName','ComitterEmail','CommitMessage','SafeCommitMessage' 39 | } else { 40 | if ($GitLog[0] -like "fatal: ambiguous argument '*...*'*") { 41 | Write-Warning -Message 'Unknown revision. Please check the values for StartCommitId or EndCommitId; omit the parameters to retrieve the entire log.' 42 | } else { 43 | Write-Error -Category InvalidArgument -Message ($GitLog -join "`n") 44 | } 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /Private/Get-RequiredModule.ps1: -------------------------------------------------------------------------------- 1 | function Get-RequiredModule { 2 | [cmdletbinding()] 3 | param( 4 | [string] $Path, 5 | [string] $Name 6 | ) 7 | $LiteralPath = [System.IO.Path]::Combine($Path, $Name) 8 | $PrimaryModule = Get-ChildItem -LiteralPath $LiteralPath -Filter '*.psd1' -Recurse -ErrorAction SilentlyContinue -Depth 1 9 | if ($PrimaryModule) { 10 | $Module = Get-Module -ListAvailable $PrimaryModule.FullName -ErrorAction SilentlyContinue -Verbose:$false 11 | if ($Module) { 12 | [Array] $RequiredModules = $Module.RequiredModules.Name 13 | if ($null -ne $RequiredModules) { 14 | $null 15 | } 16 | $RequiredModules 17 | foreach ($_ in $RequiredModules) { 18 | Get-RequiredModule -Path $Path -Name $_ 19 | } 20 | } 21 | } else { 22 | Write-Warning "Initialize-ModulePortable - Modules to load not found in $Path" 23 | } 24 | } -------------------------------------------------------------------------------- /Private/Get-RestMethodExceptionDetailsOrNull.ps1: -------------------------------------------------------------------------------- 1 | function Get-RestMethodExceptionDetailsOrNull { 2 | [CmdletBinding()] 3 | param( 4 | [Exception] $restMethodException 5 | ) 6 | try { 7 | $responseDetails = @{ 8 | ResponseUri = $exception.Response.ResponseUri 9 | StatusCode = $exception.Response.StatusCode 10 | StatusDescription = $exception.Response.StatusDescription 11 | ErrorMessage = $exception.Message 12 | } 13 | [string] $responseDetailsAsNicelyFormattedString = Convert-HashTableToNicelyFormattedString $responseDetails 14 | 15 | [string] $errorInfo = "Request Details:" + $NewLine + $requestDetailsAsNicelyFormattedString 16 | $errorInfo += $NewLine 17 | $errorInfo += "Response Details:" + $NewLine + $responseDetailsAsNicelyFormattedString 18 | return $errorInfo 19 | } catch { 20 | return $null 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Private/Get-ScriptCommands.ps1: -------------------------------------------------------------------------------- 1 | function Get-ScriptCommands { 2 | [CmdletBinding()] 3 | param( 4 | [string] $FilePath, 5 | [alias('ScriptBlock')][scriptblock] $Code, 6 | [switch] $CommandsOnly 7 | ) 8 | $astTokens = $null 9 | $astErr = $null 10 | 11 | if ($FilePath) { 12 | $FileAst = [System.Management.Automation.Language.Parser]::ParseFile($FilePath, [ref]$astTokens, [ref]$astErr) 13 | } else { 14 | $FileAst = [System.Management.Automation.Language.Parser]::ParseInput($Code, [ref]$astTokens, [ref]$astErr) 15 | } 16 | #$Commands = [System.Collections.Generic.List[Object]]::new() 17 | 18 | $Commands = Get-AstTokens -ASTTokens $astTokens -Commands $Commands -FileAst $FileAst 19 | #if ($CommandsOnly) { 20 | $Commands | Sort-Object -Unique 21 | # } else { 22 | # $Commands 23 | # } 24 | # $astTokens | Group-Object tokenflags -AsHashTable -AsString 25 | #$Commands = $astTokens | Where-Object { $_.TokenFlags -eq 'Command' } | Sort-Object -Property Value -Unique 26 | } -------------------------------------------------------------------------------- /Private/Import-ValidCertificate.ps1: -------------------------------------------------------------------------------- 1 | function Import-ValidCertificate { 2 | [CmdletBinding()] 3 | [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")] 4 | param( 5 | [parameter(Mandatory, ParameterSetName = 'FilePath')][string] $FilePath, 6 | [parameter(Mandatory, ParameterSetName = 'Base64')][string] $CertificateAsBase64, 7 | [parameter(Mandatory)][string] $PfxPassword 8 | ) 9 | if ($FilePath -and (Test-Path -LiteralPath $FilePath)) { 10 | $TemporaryFile = $FilePath 11 | } elseif ($CertificateAsBase64) { 12 | $TemporaryFile = [io.path]::GetTempFileName() 13 | if ($PSVersionTable.PSEdition -eq 'Core') { 14 | Set-Content -AsByteStream -Value $([System.Convert]::FromBase64String($CertificateAsBase64)) -Path $TemporaryFile -ErrorAction Stop 15 | } else { 16 | Set-Content -Value $([System.Convert]::FromBase64String($CertificateAsBase64)) -Path $TemporaryFile -Encoding Byte -ErrorAction Stop 17 | } 18 | } else { 19 | return $false 20 | } 21 | # if ($TemporaryFile) { 22 | # $CodeSigningCert = Import-PfxCertificate -FilePath $pfxCertFilePath -Password $($PfxPassword | ConvertTo-SecureString -AsPlainText -Force) -CertStoreLocation Cert:\CurrentUser\My -ErrorAction Stop 23 | # if ($CodeSigningCert) { 24 | # return $CodeSigningCert 25 | # } else { 26 | # return $false 27 | # } 28 | # } else { 29 | # return $false 30 | # } 31 | } -------------------------------------------------------------------------------- /Private/Initialize-InternalTests.ps1: -------------------------------------------------------------------------------- 1 | function Initialize-InternalTests { 2 | [CmdletBinding()] 3 | param( 4 | [System.Collections.IDictionary] $Configuration, 5 | [string] $Type 6 | ) 7 | 8 | if ($Configuration.Options.$Type.TestsPath -and (Test-Path -LiteralPath $Configuration.Options.$Type.TestsPath)) { 9 | Write-TextWithTime -PreAppend Plus -Text "Running tests ($Type)" { 10 | $TestsResult = Invoke-Pester -Script $Configuration.Options.$Type.TestsPath -Verbose -PassThru 11 | Write-Host 12 | if (-not $TestsResult) { 13 | if ($Configuration.Options.$Type.Force) { 14 | Write-Text "[e] Tests ($Type) failed, but Force was used to skip failed tests. Continuing" -Color Red 15 | } else { 16 | Write-Text "[e] Tests ($Type) failed. Terminating." -Color Red 17 | return $false 18 | } 19 | } elseif ($TestsResult.FailedCount -gt 0) { 20 | if ($Configuration.Options.$Type.Force) { 21 | Write-Text "[e] Tests ($Type) failed, but Force was used to skip failed tests. Continuing" -Color Red 22 | } else { 23 | Write-Text "[e] Tests ($Type) failed (failedCount $($TestsResult.FailedCount)). Terminating." -Color Red 24 | return $false 25 | } 26 | } 27 | } -Color Blue 28 | } else { 29 | Write-Text "[e] Tests ($Type) are enabled, but the path to tests doesn't exits. Terminating." -Color Red 30 | return $false 31 | } 32 | } -------------------------------------------------------------------------------- /Private/Initialize-ReplacePath.ps1: -------------------------------------------------------------------------------- 1 | function Initialize-ReplacePath { 2 | [CmdletBinding()] 3 | param( 4 | [string] $ReplacementPath, 5 | [string] $ModuleName, 6 | [string] $ModuleVersion, 7 | [System.Collections.IDictionary] $Configuration 8 | ) 9 | 10 | $TagName = "v$($ModuleVersion)" 11 | if ($Configuration.CurrentSettings.PreRelease) { 12 | $ModuleVersionWithPreRelease = "$($ModuleVersion)-$($Configuration.CurrentSettings.PreRelease)" 13 | $TagModuleVersionWithPreRelease = "v$($ModuleVersionWithPreRelease)" 14 | } else { 15 | $ModuleVersionWithPreRelease = $ModuleVersion 16 | $TagModuleVersionWithPreRelease = "v$($ModuleVersion)" 17 | } 18 | 19 | $ReplacementPath = $ReplacementPath.Replace('', $TagName) 20 | $ReplacementPath = $ReplacementPath.Replace('{TagName}', $TagName) 21 | $ReplacementPath = $ReplacementPath.Replace('', $ModuleVersion) 22 | $ReplacementPath = $ReplacementPath.Replace('{ModuleVersion}', $ModuleVersion) 23 | $ReplacementPath = $ReplacementPath.Replace('', $ModuleVersionWithPreRelease) 24 | $ReplacementPath = $ReplacementPath.Replace('{ModuleVersionWithPreRelease}', $ModuleVersionWithPreRelease) 25 | $ReplacementPath = $ReplacementPath.Replace('', $TagModuleVersionWithPreRelease) 26 | $ReplacementPath = $ReplacementPath.Replace('{TagModuleVersionWithPreRelease}', $TagModuleVersionWithPreRelease) 27 | $ReplacementPath = $ReplacementPath.Replace('', $ModuleName) 28 | $ReplacementPath = $ReplacementPath.Replace('{ModuleName}', $ModuleName) 29 | $ReplacementPath 30 | } -------------------------------------------------------------------------------- /Private/Invoke-RestMethodAndThrowDescriptiveErrorOnFailure.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-RestMethodAndThrowDescriptiveErrorOnFailure { 2 | [cmdletbinding()] 3 | param( 4 | [System.Collections.IDictionary] $requestParametersHashTable 5 | ) 6 | $requestDetailsAsNicelyFormattedString = Convert-HashTableToNicelyFormattedString $requestParametersHashTable 7 | Write-Verbose "Making web request with the following parameters:$NewLine$requestDetailsAsNicelyFormattedString" 8 | 9 | try { 10 | $webRequestResult = Invoke-RestMethod @requestParametersHashTable 11 | } catch { 12 | [Exception] $exception = $_.Exception 13 | 14 | [string] $errorMessage = Get-RestMethodExceptionDetailsOrNull -restMethodException $exception 15 | if ([string]::IsNullOrWhiteSpace($errorMessage)) { 16 | $errorMessage = $exception.ToString() 17 | } 18 | 19 | throw "An unexpected error occurred while making web request:$NewLine$errorMessage" 20 | } 21 | 22 | Write-Verbose "Web request returned the following result:$NewLine$webRequestResult" 23 | return $webRequestResult 24 | } 25 | -------------------------------------------------------------------------------- /Private/New-CreateModule.ps1: -------------------------------------------------------------------------------- 1 | function New-CreateModule { 2 | [CmdletBinding()] 3 | param ( 4 | [string] $ProjectName, 5 | [string] $ModulePath, 6 | [string] $ProjectPath 7 | ) 8 | $FullProjectPath = [io.path]::Combine($ProjectPath, $ProjectName) 9 | $Folders = 'Private', 'Public', 'Examples', 'Ignore', 'Publish', 'Enums', 'Data' 10 | Add-Directory -Directory $FullProjectPath 11 | foreach ($Folder in $Folders) { 12 | $PathToCreate = [io.path]::Combine($FullProjectPath, $Folder) 13 | Add-Directory -Directory $PathToCreate 14 | } 15 | $Source = [io.path]::Combine($PSScriptRoot, "..", 'Data', 'Example-Gitignore.txt') 16 | $Destination = [io.path]::Combine($FullProjectPath, '.gitignore') 17 | Copy-Item -Path $Source -Destination $Destination -ErrorAction Stop 18 | $Source = [io.path]::Combine($PSScriptRoot, "..", 'Data', 'Example-LicenseMIT.txt') 19 | $Destination = [io.path]::Combine($FullProjectPath, 'License') 20 | Copy-Item -Path $Source -Destination $Destination -ErrorAction Stop 21 | $Source = [io.path]::Combine($PSScriptRoot, "..", 'Data', 'Example-ModuleStarter.txt') 22 | $Destination = [io.path]::Combine($FullProjectPath, "$ProjectName.psm1") 23 | Copy-Item -Path $Source -Destination $Destination -ErrorAction Stop 24 | } -------------------------------------------------------------------------------- /Private/New-DLLResolveConflict.ps1: -------------------------------------------------------------------------------- 1 | function New-DLLResolveConflict { 2 | [CmdletBinding()] 3 | param( 4 | [string] $ProjectName, 5 | [System.Collections.IDictionary] $LibraryConfiguration 6 | ) 7 | 8 | if ($LibraryConfiguration.SearchClass) { 9 | $SearchClass = $LibraryConfiguration.SearchClass 10 | } else { 11 | $SearchClass = "`$LibraryName.Initialize" 12 | } 13 | 14 | if ($ProjectName) { 15 | $StandardName = "'$ProjectName'" 16 | } else { 17 | $StandardName = '$myInvocation.MyCommand.Name.Replace(".psm1", "")' 18 | } 19 | $Output = @" 20 | 21 | # Get library name, from the PSM1 file name 22 | `$LibraryName = $StandardName 23 | `$Library = "`$LibraryName.dll" 24 | `$Class = "$SearchClass" 25 | 26 | `$AssemblyFolders = Get-ChildItem -Path `$PSScriptRoot\Lib -Directory -ErrorAction SilentlyContinue 27 | 28 | # Lets find which libraries we need to load 29 | `$Default = `$false 30 | `$Core = `$false 31 | `$Standard = `$false 32 | foreach (`$A in `$AssemblyFolders.Name) { 33 | if (`$A -eq 'Default') { 34 | `$Default = `$true 35 | } elseif (`$A -eq 'Core') { 36 | `$Core = `$true 37 | } elseif (`$A -eq 'Standard') { 38 | `$Standard = `$true 39 | } 40 | } 41 | if (`$Standard -and `$Core -and `$Default) { 42 | `$FrameworkNet = 'Default' 43 | `$Framework = 'Standard' 44 | } elseif (`$Standard -and `$Core) { 45 | `$Framework = 'Standard' 46 | `$FrameworkNet = 'Standard' 47 | } elseif (`$Core -and `$Default) { 48 | `$Framework = 'Core' 49 | `$FrameworkNet = 'Default' 50 | } elseif (`$Standard -and `$Default) { 51 | `$Framework = 'Standard' 52 | `$FrameworkNet = 'Default' 53 | } elseif (`$Standard) { 54 | `$Framework = 'Standard' 55 | `$FrameworkNet = 'Standard' 56 | } elseif (`$Core) { 57 | `$Framework = 'Core' 58 | `$FrameworkNet = '' 59 | } elseif (`$Default) { 60 | `$Framework = '' 61 | `$FrameworkNet = 'Default' 62 | } else { 63 | Write-Error -Message 'No assemblies found' 64 | } 65 | if (`$PSEdition -eq 'Core') { 66 | `$LibFolder = `$Framework 67 | } else { 68 | `$LibFolder = `$FrameworkNet 69 | } 70 | 71 | try { 72 | `$ImportModule = Get-Command -Name Import-Module -Module Microsoft.PowerShell.Core 73 | 74 | if (-not (`$Class -as [type])) { 75 | & `$ImportModule ([IO.Path]::Combine(`$PSScriptRoot, 'Lib', `$LibFolder, `$Library)) -ErrorAction Stop 76 | } else { 77 | `$Type = "`$Class" -as [Type] 78 | & `$importModule -Force -Assembly (`$Type.Assembly) 79 | } 80 | } catch { 81 | if (`$ErrorActionPreference -eq 'Stop') { 82 | throw 83 | } else { 84 | Write-Warning -Message "Importing module `$Library failed. Fix errors before continuing. Error: `$(`$_.Exception.Message)" 85 | # we will continue, but it's not a good idea to do so 86 | # return 87 | } 88 | } 89 | "@ 90 | $Output 91 | 92 | } -------------------------------------------------------------------------------- /Private/New-PrepareManifest.ps1: -------------------------------------------------------------------------------- 1 | function New-PrepareManifest { 2 | [CmdletBinding()] 3 | param( 4 | [string] $ProjectName, 5 | [string] $ModulePath, 6 | [string] $ProjectPath, 7 | $FunctionToExport, 8 | [string] $ProjectUrl 9 | ) 10 | $Location = [System.IO.Path]::Combine($projectPath, $ProjectName) 11 | Set-Location -Path $Location 12 | $manifest = @{ 13 | Path = ".\$ProjectName.psd1" 14 | RootModule = "$ProjectName.psm1" 15 | Author = 'Przemyslaw Klys' 16 | CompanyName = 'Evotec' 17 | Copyright = 'Evotec (c) 2011-2022. All rights reserved.' 18 | Description = "Simple project" 19 | FunctionsToExport = $functionToExport 20 | CmdletsToExport = '' 21 | VariablesToExport = '' 22 | AliasesToExport = '' 23 | FileList = "$ProjectName.psm1", "$ProjectName.psd1" 24 | HelpInfoURI = $projectUrl 25 | ProjectUri = $projectUrl 26 | } 27 | New-ModuleManifest @manifest 28 | } -------------------------------------------------------------------------------- /Private/Out-FileUft8NoBom.ps1: -------------------------------------------------------------------------------- 1 | function Out-FileUtf8NoBom { 2 | <# 3 | .SYNOPSIS 4 | Outputs to a UTF-8-encoded file *without a BOM* (byte-order mark). 5 | 6 | .DESCRIPTION 7 | Mimics the most important aspects of Out-File: 8 | * Input objects are sent to Out-String first. 9 | * -Append allows you to append to an existing file, -NoClobber prevents 10 | overwriting of an existing file. 11 | * -Width allows you to specify the line width for the text representations 12 | of input objects that aren't strings. 13 | However, it is not a complete implementation of all Out-String parameters: 14 | * Only a literal output path is supported, and only as a parameter. 15 | * -Force is not supported. 16 | 17 | Caveat: *All* pipeline input is buffered before writing output starts, 18 | but the string representations are generated and written to the target 19 | file one by one. 20 | 21 | .NOTES 22 | The raison d'être for this advanced function is that, as of PowerShell v5, 23 | Out-File still lacks the ability to write UTF-8 files without a BOM: 24 | using -Encoding UTF8 invariably prepends a BOM. 25 | 26 | #> 27 | [CmdletBinding()] 28 | param( 29 | [Parameter(Mandatory, Position = 0)] [string] $LiteralPath, 30 | [switch] $Append, 31 | [switch] $NoClobber, 32 | [AllowNull()] [int] $Width, 33 | [Parameter(ValueFromPipeline)] $InputObject 34 | ) 35 | # Make sure that the .NET framework sees the same working dir. as PS 36 | # and resolve the input path to a full path. 37 | [System.IO.Directory]::SetCurrentDirectory($PWD) # Caveat: .NET Core doesn't support [Environment]::CurrentDirectory 38 | $LiteralPath = [IO.Path]::GetFullPath($LiteralPath) 39 | 40 | # If -NoClobber was specified, throw an exception if the target file already 41 | # exists. 42 | if ($NoClobber -and (Test-Path $LiteralPath)) { 43 | Throw [IO.IOException] "The file '$LiteralPath' already exists." 44 | } 45 | 46 | # Create a StreamWriter object. 47 | # Note that we take advantage of the fact that the StreamWriter class by default: 48 | # - uses UTF-8 encoding 49 | # - without a BOM. 50 | $sw = New-Object IO.StreamWriter $LiteralPath, $Append 51 | 52 | $htOutStringArgs = @{} 53 | if ($Width) { 54 | $htOutStringArgs += @{ Width = $Width } 55 | } 56 | 57 | # Note: By not using begin / process / end blocks, we're effectively running 58 | # in the end block, which means that all pipeline input has already 59 | # been collected in automatic variable $Input. 60 | # We must use this approach, because using | Out-String individually 61 | # in each iteration of a process block would format each input object 62 | # with an indvidual header. 63 | try { 64 | $Input | Out-String -Stream @htOutStringArgs | ForEach-Object { $sw.WriteLine($_) } 65 | } finally { 66 | $sw.Dispose() 67 | } 68 | } -------------------------------------------------------------------------------- /Private/Register-DataForInitialModule.ps1: -------------------------------------------------------------------------------- 1 | function Register-DataForInitialModule { 2 | [CmdletBinding()] 3 | param( 4 | [Parameter(Mandatory)][string] $FilePath, 5 | [Parameter(Mandatory)][string] $ModuleName, 6 | [Parameter(Mandatory)][string] $Guid 7 | ) 8 | 9 | if ($PSVersionTable.PSVersion.Major -gt 5) { 10 | $Encoding = 'UTF8BOM' 11 | } else { 12 | $Encoding = 'UTF8' 13 | } 14 | try { 15 | $BuildModule = Get-Content -Path $FilePath -Raw -ErrorAction Stop 16 | } catch { 17 | Write-Text -Text "[-] Couldn't read $FilePath, error: $($_.Exception.Message)" -Color Red 18 | return $false 19 | } 20 | $BuildModule = $BuildModule -replace "\`$GUID", $Guid 21 | $BuildModule = $BuildModule -replace "\`$ModuleName", $ModuleName 22 | try { 23 | Set-Content -Path $FilePath -Value $BuildModule -Encoding $Encoding -ErrorAction Stop 24 | } catch { 25 | Write-Text -Text "[-] Couldn't save $FilePath, error: $($_.Exception.Message)" -Color Red 26 | return $false 27 | } 28 | } -------------------------------------------------------------------------------- /Private/Remove-Directory.ps1: -------------------------------------------------------------------------------- 1 | function Remove-Directory { 2 | [CmdletBinding()] 3 | param ( 4 | [string] $Directory, 5 | [string] $SpacesBefore 6 | ) 7 | if ($Directory) { 8 | $Exists = Test-Path -LiteralPath $Directory 9 | if ($Exists) { 10 | try { 11 | Remove-Item -Path $Directory -ErrorAction Stop -Force -Recurse -Confirm:$false 12 | } catch { 13 | $ErrorMessage = $_.Exception.Message 14 | Write-Text "Can't delete folder $Directory. Fix error before continuing: $ErrorMessage" -PreAppend Error -SpacesBefore $SpacesBefore 15 | return $false 16 | } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Private/Remove-EmptyLines.ps1: -------------------------------------------------------------------------------- 1 | function Remove-EmptyLines { 2 | [CmdletBinding(DefaultParameterSetName = 'FilePath')] 3 | param( 4 | [Parameter(Mandatory, ParameterSetName = 'FilePath')] 5 | [alias('FilePath', 'Path', 'LiteralPath')][string] $SourceFilePath, 6 | 7 | [Parameter(Mandatory, ParameterSetName = 'Content')][string] $Content, 8 | 9 | [Parameter(ParameterSetName = 'Content')] 10 | [Parameter(ParameterSetName = 'FilePath')] 11 | [alias('Destination')][string] $DestinationFilePath, 12 | 13 | [Parameter(ParameterSetName = 'Content')] 14 | [Parameter(ParameterSetName = 'FilePath')] 15 | [switch] $RemoveAllEmptyLines, 16 | 17 | [Parameter(ParameterSetName = 'Content')] 18 | [Parameter(ParameterSetName = 'FilePath')] 19 | [switch] $RemoveEmptyLines 20 | ) 21 | 22 | if ($PSVersionTable.PSVersion.Major -gt 5) { 23 | $Encoding = 'UTF8BOM' 24 | } else { 25 | $Encoding = 'UTF8' 26 | } 27 | 28 | if ($SourceFilePath) { 29 | $Fullpath = Resolve-Path -LiteralPath $SourceFilePath 30 | $Content = [IO.File]::ReadAllText($FullPath) 31 | } 32 | if ($RemoveEmptyLines) { 33 | # Remove empty lines if more than one empty line is found. If it's just one line, leave it as is 34 | $Content = $Content -replace '(?m)^\s*$', '' 35 | } 36 | if ($RemoveAllEmptyLines) { 37 | # Remove all empty lines from the content 38 | $Content = $Content -replace '(?m)^\s*$(\r?\n)?', '' 39 | } 40 | if ($Content) { 41 | $Content = $Content.Trim() 42 | } 43 | if ($DestinationFilePath) { 44 | $Content | Set-Content -Path $DestinationFilePath -Encoding $Encoding 45 | } else { 46 | $Content 47 | } 48 | } -------------------------------------------------------------------------------- /Private/Remove-EmptyValue.ps1: -------------------------------------------------------------------------------- 1 | function Remove-EmptyValue { 2 | [alias('Remove-EmptyValues')] 3 | [CmdletBinding()] 4 | param( 5 | [alias('Splat', 'IDictionary')][Parameter(Mandatory)][System.Collections.IDictionary] $Hashtable, 6 | [string[]] $ExcludeParameter, 7 | [switch] $Recursive, 8 | [int] $Rerun, 9 | [switch] $DoNotRemoveNull, 10 | [switch] $DoNotRemoveEmpty, 11 | [switch] $DoNotRemoveEmptyArray, 12 | [switch] $DoNotRemoveEmptyDictionary 13 | ) 14 | foreach ($Key in [string[]] $Hashtable.Keys) { 15 | if ($Key -notin $ExcludeParameter) { 16 | if ($Recursive) { 17 | if ($Hashtable[$Key] -is [System.Collections.IDictionary]) { 18 | if ($Hashtable[$Key].Count -eq 0) { 19 | if (-not $DoNotRemoveEmptyDictionary) { 20 | $Hashtable.Remove($Key) 21 | } 22 | } else { 23 | Remove-EmptyValue -Hashtable $Hashtable[$Key] -Recursive:$Recursive 24 | } 25 | } else { 26 | if (-not $DoNotRemoveNull -and $null -eq $Hashtable[$Key]) { 27 | $Hashtable.Remove($Key) 28 | } elseif (-not $DoNotRemoveEmpty -and $Hashtable[$Key] -is [string] -and $Hashtable[$Key] -eq '') { 29 | $Hashtable.Remove($Key) 30 | } elseif (-not $DoNotRemoveEmptyArray -and $Hashtable[$Key] -is [System.Collections.IList] -and $Hashtable[$Key].Count -eq 0) { 31 | $Hashtable.Remove($Key) 32 | } 33 | } 34 | } else { 35 | if (-not $DoNotRemoveNull -and $null -eq $Hashtable[$Key]) { 36 | $Hashtable.Remove($Key) 37 | } elseif (-not $DoNotRemoveEmpty -and $Hashtable[$Key] -is [string] -and $Hashtable[$Key] -eq '') { 38 | $Hashtable.Remove($Key) 39 | } elseif (-not $DoNotRemoveEmptyArray -and $Hashtable[$Key] -is [System.Collections.IList] -and $Hashtable[$Key].Count -eq 0) { 40 | $Hashtable.Remove($Key) 41 | } 42 | } 43 | } 44 | } 45 | if ($Rerun) { 46 | for ($i = 0; $i -lt $Rerun; $i++) { 47 | Remove-EmptyValue -Hashtable $Hashtable -Recursive:$Recursive 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /Private/Remove-ItemAlternative.ps1: -------------------------------------------------------------------------------- 1 | function Remove-ItemAlternative { 2 | <# 3 | .SYNOPSIS 4 | Removes all files and folders within given path 5 | 6 | .DESCRIPTION 7 | Removes all files and folders within given path. Workaround for Access to the cloud file is denied issue 8 | 9 | .PARAMETER Path 10 | Path to file/folder 11 | 12 | .PARAMETER SkipFolder 13 | Do not delete top level folder 14 | 15 | .PARAMETER Exclude 16 | Skip files/folders matching given pattern 17 | 18 | .EXAMPLE 19 | Remove-ItemAlternative -Path "C:\Support\GitHub\GpoZaurr\Docs" 20 | 21 | .EXAMPLE 22 | Remove-ItemAlternative -Path "C:\Support\GitHub\GpoZaurr\Docs" 23 | 24 | .NOTES 25 | General notes 26 | #> 27 | [cmdletbinding()] 28 | param( 29 | [alias('LiteralPath')][string] $Path, 30 | [switch] $SkipFolder, 31 | [string[]] $Exclude 32 | ) 33 | if ($Path -and (Test-Path -LiteralPath $Path)) { 34 | $getChildItemSplat = @{ 35 | Path = $Path 36 | Recurse = $true 37 | Force = $true 38 | File = $true 39 | Exclude = $Exclude 40 | } 41 | Remove-EmptyValue -Hashtable $getChildItemSplat 42 | $Items = Get-ChildItem @getChildItemSplat 43 | foreach ($Item in $Items) { 44 | try { 45 | $Item.Delete() 46 | } catch { 47 | if ($ErrorActionPreference -eq 'Stop') { 48 | throw "Couldn't delete $($Item.FullName), error: $($_.Exception.Message)" 49 | } else { 50 | Write-Warning "Remove-ItemAlternative - Couldn't delete $($Item.FullName), error: $($_.Exception.Message)" 51 | } 52 | } 53 | } 54 | $getChildItemSplat = @{ 55 | Path = $Path 56 | Recurse = $true 57 | Force = $true 58 | Exclude = $Exclude 59 | } 60 | Remove-EmptyValue -Hashtable $getChildItemSplat 61 | $Items = Get-ChildItem @getChildItemSplat | Sort-Object -Descending -Property 'FullName' 62 | foreach ($Item in $Items) { 63 | try { 64 | $Item.Delete() 65 | } catch { 66 | if ($ErrorActionPreference -eq 'Stop') { 67 | throw "Couldn't delete $($Item.FullName), error: $($_.Exception.Message)" 68 | } else { 69 | Write-Warning "Remove-ItemAlternative - Couldn't delete $($Item.FullName), error: $($_.Exception.Message)" 70 | } 71 | } 72 | } 73 | if (-not $SkipFolder.IsPresent) { 74 | $Item = Get-Item -LiteralPath $Path 75 | try { 76 | $Item.Delete($true) 77 | } catch { 78 | if ($ErrorActionPreference -eq 'Stop') { 79 | throw "Couldn't delete $($Item.FullName), error: $($_.Exception.Message)" 80 | } else { 81 | Write-Warning "Remove-ItemAlternative - Couldn't delete $($Item.FullName), error: $($_.Exception.Message)" 82 | } 83 | } 84 | } 85 | } else { 86 | if ($ErrorActionPreference -eq 'Stop') { 87 | throw "Remove-ItemAlternative - Path $Path doesn't exists. Skipping." 88 | } else { 89 | Write-Warning "Remove-ItemAlternative - Path $Path doesn't exists. Skipping." 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /Private/Repair-CustomPlaceHolders.ps1: -------------------------------------------------------------------------------- 1 | function Repair-CustomPlaceHolders { 2 | [CmdletBinding()] 3 | param( 4 | [Parameter(Mandatory)][string] $Path, 5 | [System.Collections.IDictionary] $Configuration 6 | ) 7 | 8 | $ModuleName = $Configuration.Information.ModuleName 9 | $ModuleVersion = $Configuration.Information.Manifest.ModuleVersion 10 | $TagName = "v$($ModuleVersion)" 11 | if ($Configuration.CurrentSettings.PreRelease) { 12 | $ModuleVersionWithPreRelease = "$($ModuleVersion)-$($Configuration.CurrentSettings.PreRelease)" 13 | $TagModuleVersionWithPreRelease = "v$($ModuleVersionWithPreRelease)" 14 | } else { 15 | $ModuleVersionWithPreRelease = $ModuleVersion 16 | $TagModuleVersionWithPreRelease = "v$($ModuleVersion)" 17 | } 18 | 19 | $BuiltinPlaceHolders = @( 20 | @{ Find = '{ModuleName}'; Replace = $ModuleName } 21 | @{ Find = ''; Replace = $ModuleName } 22 | @{ Find = '{ModuleVersion}'; Replace = $ModuleVersion } 23 | @{ Find = ''; Replace = $ModuleVersion } 24 | @{ Find = '{ModuleVersionWithPreRelease}'; Replace = $ModuleVersionWithPreRelease } 25 | @{ Find = ''; Replace = $ModuleVersionWithPreRelease } 26 | @{ Find = '{TagModuleVersionWithPreRelease}'; Replace = $TagModuleVersionWithPreRelease } 27 | @{ Find = ''; Replace = $TagModuleVersionWithPreRelease } 28 | @{ Find = '{TagName}'; Replace = $TagName } 29 | @{ Find = ''; Replace = $TagName } 30 | ) 31 | 32 | Write-TextWithTime -Text "Replacing built-in and custom placeholders" -Color Yellow { 33 | $PSM1Content = Get-Content -LiteralPath $Path -Raw -Encoding UTF8 -ErrorAction Stop 34 | 35 | # Replace built-in placeholders 36 | if ($Configuration.PlaceHolderOption.SkipBuiltinReplacements -ne $true) { 37 | foreach ($PlaceHolder in $BuiltinPlaceHolders) { 38 | $PSM1Content = $PSM1Content.Replace($PlaceHolder.Find, $PlaceHolder.Replace) 39 | } 40 | } 41 | # Replace custom placeholders provided by the user 42 | foreach ($PlaceHolder in $Configuration.PlaceHolders) { 43 | $PSM1Content = $PSM1Content.Replace($PlaceHolder.Find, $PlaceHolder.Replace) 44 | } 45 | 46 | Set-Content -LiteralPath $Path -Value $PSM1Content -Encoding UTF8 -ErrorAction Stop -Force 47 | } -PreAppend Plus -SpacesBefore ' ' 48 | } -------------------------------------------------------------------------------- /Private/Script.FormatterSettings.ps1: -------------------------------------------------------------------------------- 1 | $Script:FormatterSettings = @{ 2 | IncludeRules = @( 3 | 'PSPlaceOpenBrace', 4 | 'PSPlaceCloseBrace', 5 | 'PSUseConsistentWhitespace', 6 | 'PSUseConsistentIndentation', 7 | 'PSAlignAssignmentStatement', 8 | 'PSUseCorrectCasing' 9 | ) 10 | 11 | Rules = @{ 12 | PSPlaceOpenBrace = @{ 13 | Enable = $true 14 | OnSameLine = $true 15 | NewLineAfter = $true 16 | IgnoreOneLineBlock = $true 17 | } 18 | 19 | PSPlaceCloseBrace = @{ 20 | Enable = $true 21 | NewLineAfter = $false 22 | IgnoreOneLineBlock = $true 23 | NoEmptyLineBefore = $false 24 | } 25 | 26 | PSUseConsistentIndentation = @{ 27 | Enable = $true 28 | Kind = 'space' 29 | PipelineIndentation = 'IncreaseIndentationAfterEveryPipeline' 30 | IndentationSize = 4 31 | } 32 | 33 | PSUseConsistentWhitespace = @{ 34 | Enable = $true 35 | CheckInnerBrace = $true 36 | CheckOpenBrace = $true 37 | CheckOpenParen = $true 38 | CheckOperator = $true 39 | CheckPipe = $true 40 | CheckSeparator = $true 41 | } 42 | 43 | PSAlignAssignmentStatement = @{ 44 | Enable = $true 45 | CheckHashtable = $true 46 | } 47 | 48 | PSUseCorrectCasing = @{ 49 | Enable = $true 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /Private/Send-FilesToGitHubRelease.ps1: -------------------------------------------------------------------------------- 1 | function Send-FilesToGitHubRelease { 2 | [cmdletbinding()] 3 | param( 4 | [string[]] $filePathsToUpload, 5 | [string] $urlToUploadFilesTo, 6 | $authHeader 7 | ) 8 | [int] $numberOfFilesToUpload = $filePathsToUpload.Count 9 | [int] $numberOfFilesUploaded = 0 10 | 11 | $filePathsToUpload | ForEach-Object { 12 | $filePath = $_ 13 | $fileName = Get-Item $filePath | Select-Object -ExpandProperty Name 14 | 15 | $uploadAssetWebRequestParameters = 16 | @{ 17 | # Append the name of the file to the upload url. 18 | Uri = $urlToUploadFilesTo + "?name=$fileName" 19 | Method = 'POST' 20 | Headers = $authHeader 21 | ContentType = 'application/zip' 22 | InFile = $filePath 23 | } 24 | 25 | $numberOfFilesUploaded = $numberOfFilesUploaded + 1 26 | Write-Verbose "Uploading asset $numberOfFilesUploaded of $numberOfFilesToUpload, '$filePath'." 27 | Invoke-RestMethodAndThrowDescriptiveErrorOnFailure $uploadAssetWebRequestParameters > $null 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Private/Start-DocumentationBuilding.ps1: -------------------------------------------------------------------------------- 1 | function Start-DocumentationBuilding { 2 | [CmdletBinding()] 3 | param( 4 | [System.Collections.IDictionary] $Configuration, 5 | [string] $FullProjectPath, 6 | [string] $ProjectName 7 | ) 8 | # Support for old way of building documentation -> converts to new one 9 | if ($Configuration.Steps.BuildDocumentation -is [bool]) { 10 | $TemporaryBuildDocumentation = $Configuration.Steps.BuildDocumentation 11 | $Configuration.Steps.BuildDocumentation = @{ 12 | Enable = $TemporaryBuildDocumentation 13 | } 14 | } 15 | # Real documentation process 16 | if ($Configuration.Steps.BuildDocumentation -is [System.Collections.IDictionary]) { 17 | if ($Configuration.Steps.BuildDocumentation.Enable -eq $true) { 18 | $WarningVariablesMarkdown = @() 19 | $DocumentationPath = "$FullProjectPath\$($Configuration.Options.Documentation.Path)" 20 | $ReadMePath = "$FullProjectPath\$($Configuration.Options.Documentation.PathReadme)" 21 | Write-Text "[+] Generating documentation to $DocumentationPath with $ReadMePath" -Color Yellow 22 | 23 | if (-not (Test-Path -Path $DocumentationPath)) { 24 | $null = New-Item -Path "$FullProjectPath\Docs" -ItemType Directory -Force 25 | } 26 | if ($Configuration.Steps.BuildDocumentation.Tool -eq 'HelpOut') { 27 | try { 28 | Save-MarkdownHelp -Module $ProjectName -OutputPath $DocumentationPath -ErrorAction Stop -WarningVariable +WarningVariablesMarkdown -WarningAction SilentlyContinue -SkipCommandType Alias -ExcludeFile "*.svg" 29 | } catch { 30 | Write-Text "[-] Documentation warning: $($_.Exception.Message)" -Color Yellow 31 | } 32 | } else { 33 | [Array] $Files = Get-ChildItem -Path $DocumentationPath 34 | if ($Files.Count -gt 0) { 35 | if ($Configuration.Steps.BuildDocumentation.StartClean -ne $true) { 36 | try { 37 | $null = Update-MarkdownHelpModule $DocumentationPath -RefreshModulePage -ModulePagePath $ReadMePath -ErrorAction Stop -WarningVariable +WarningVariablesMarkdown -WarningAction SilentlyContinue -ExcludeDontShow 38 | } catch { 39 | Write-Text "[-] Documentation warning: $($_.Exception.Message)" -Color Yellow 40 | } 41 | } else { 42 | Remove-ItemAlternative -Path $DocumentationPath -SkipFolder 43 | [Array] $Files = Get-ChildItem -Path $DocumentationPath 44 | } 45 | } 46 | if ($Files.Count -eq 0) { 47 | try { 48 | $null = New-MarkdownHelp -Module $ProjectName -WithModulePage -OutputFolder $DocumentationPath -ErrorAction Stop -WarningVariable +WarningVariablesMarkdown -WarningAction SilentlyContinue -ExcludeDontShow 49 | } catch { 50 | Write-Text "[-] Documentation warning: $($_.Exception.Message)" -Color Yellow 51 | } 52 | $null = Move-Item -Path "$DocumentationPath\$ProjectName.md" -Destination $ReadMePath -ErrorAction SilentlyContinue 53 | #Start-Sleep -Seconds 1 54 | # this is temporary workaround - due to diff output on update 55 | if ($Configuration.Steps.BuildDocumentation.UpdateWhenNew) { 56 | try { 57 | $null = Update-MarkdownHelpModule $DocumentationPath -RefreshModulePage -ModulePagePath $ReadMePath -ErrorAction Stop -WarningVariable +WarningVariablesMarkdown -WarningAction SilentlyContinue -ExcludeDontShow 58 | } catch { 59 | Write-Text "[-] Documentation warning: $($_.Exception.Message)" -Color Yellow 60 | } 61 | } 62 | } 63 | } 64 | foreach ($_ in $WarningVariablesMarkdown) { 65 | Write-Text "[-] Documentation warning: $_" -Color Yellow 66 | } 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /Private/Start-ImportingModules.ps1: -------------------------------------------------------------------------------- 1 | function Start-ImportingModules { 2 | [CmdletBinding()] 3 | param( 4 | [string] $ProjectName, 5 | [System.Collections.IDictionary] $Configuration 6 | ) 7 | $TemporaryVerbosePreference = $VerbosePreference 8 | $TemporaryErrorPreference = $global:ErrorActionPreference 9 | $global:ErrorActionPreference = 'Stop' 10 | 11 | if ($null -ne $ImportModules.Verbose) { 12 | $VerbosePreference = $true 13 | } else { 14 | $VerbosePreference = $false 15 | } 16 | if ($Configuration.Steps.ImportModules.RequiredModules) { 17 | Write-TextWithTime -Text 'Importing modules (as defined in dependencies)' { 18 | foreach ($Module in $Configuration.Information.Manifest.RequiredModules) { 19 | if ($Module -is [System.Collections.IDictionary]) { 20 | Write-Text " [>] Importing required module - $($Module.ModuleName)" -Color Yellow 21 | if ($Module.ModuleVersion) { 22 | Import-Module -Name $Module.ModuleName -MinimumVersion $Module.ModuleVersion -Force -ErrorAction Stop -Verbose:$VerbosePreference 23 | } elseif ($Module.ModuleName) { 24 | Import-Module -Name $Module.ModuleName -Force -ErrorAction Stop -Verbose:$VerbosePreference 25 | } 26 | } elseif ($Module -is [string]) { 27 | Write-Text " [>] Importing required module - $($Module)" -Color Yellow 28 | Import-Module -Name $Module -Force -ErrorAction Stop -Verbose:$VerbosePreference 29 | } 30 | } 31 | } -PreAppend 'Information' 32 | } 33 | if ($Configuration.Steps.ImportModules.Self) { 34 | Write-TextWithTime -Text 'Importing module - SELF' { 35 | # global:Write-Warning ($Message) { throw 'Import warnings raised: $Message' } 36 | Import-Module -Name $ProjectName -Force -ErrorAction Stop -Verbose:$VerbosePreference 37 | #Remove-Item function:Write-Warning 38 | } -PreAppend 'Information' 39 | } 40 | $global:ErrorActionPreference = $TemporaryErrorPreference 41 | $VerbosePreference = $TemporaryVerbosePreference 42 | } -------------------------------------------------------------------------------- /Private/Start-ModuleSigning.ps1: -------------------------------------------------------------------------------- 1 | function Start-ModuleSigning { 2 | [CmdletBinding()] 3 | param( 4 | $Configuration, 5 | $FullModuleTemporaryPath 6 | ) 7 | if ($Configuration.Steps.BuildModule.SignMerged) { 8 | Write-TextWithTime -Text 'Applying signature to files' { 9 | $registerCertificateSplat = @{ 10 | WarningAction = 'SilentlyContinue' 11 | WarningVariable = 'Warnings' 12 | LocalStore = 'CurrentUser' 13 | Path = $FullModuleTemporaryPath 14 | Include = @('*.ps1', '*.psd1', '*.psm1', '*.dll', '*.cat') 15 | TimeStampServer = 'http://timestamp.digicert.com' 16 | } 17 | 18 | if ($Configuration.Options.Signing) { 19 | if ($Configuration.Options.Signing.CertificatePFXBase64) { 20 | $Success = Import-ValidCertificate -CertificateAsBase64 $Configuration.Options.Signing.CertificatePFXBase64 -PfxPassword $Configuration.Options.Signing.CertificatePFXPassword 21 | if (-not $Success) { 22 | return $false 23 | } 24 | $registerCertificateSplat.Thumbprint = $Success.Thumbprint 25 | # Write-Host $Success.Thumbprint 26 | } elseif ($Configuration.Options.Signing.CertificatePFXPath) { 27 | $Success = Import-ValidCertificate -FilePath $Configuration.Options.Signing.CertificatePFXPath -PfxPassword $Configuration.Options.Signing.CertificatePFXPassword 28 | if (-not $Success) { 29 | return $false 30 | } 31 | #Write-Host $Success.Thumbprint 32 | $registerCertificateSplat.Thumbprint = $Success.Thumbprint 33 | } else { 34 | if ($Configuration.Options.Signing -and $Configuration.Options.Signing.Thumbprint) { 35 | $registerCertificateSplat.Thumbprint = $Configuration.Options.Signing.Thumbprint 36 | } elseif ($Configuration.Options.Signing -and $Configuration.Options.Signing.CertificateThumbprint) { 37 | $registerCertificateSplat.Thumbprint = $Configuration.Options.Signing.CertificateThumbprint 38 | } 39 | } 40 | [Array] $SignedFiles = Register-Certificate @registerCertificateSplat 41 | if ($Warnings) { 42 | foreach ($W in $Warnings) { 43 | Write-Text -Text " [!] $($W.Message)" -Color Red 44 | } 45 | } 46 | if ($SignedFiles.Count -eq 0) { 47 | throw "Please configure certificate for use, or disable signing." 48 | return $false 49 | } else { 50 | if ($SignedFiles[0].Thumbprint) { 51 | Write-Text -Text " [i] Multiple certificates found for signing:" 52 | foreach ($Certificate in $SignedFiles) { 53 | Write-Text " [>] Certificate $($Certificate.Thumbprint) with subject: $($Certificate.Subject)" -Color Yellow 54 | } 55 | throw "Please configure single certificate for use or disable signing." 56 | return $false 57 | } else { 58 | foreach ($File in $SignedFiles) { 59 | Write-Text " [>] File $($File.Path) with status: $($File.StatusMessage)" -Color Yellow 60 | } 61 | } 62 | } 63 | } 64 | } -PreAppend Plus 65 | } 66 | } -------------------------------------------------------------------------------- /Private/Start-PreparingStructure.ps1: -------------------------------------------------------------------------------- 1 | function Start-PreparingStructure { 2 | [CmdletBinding()] 3 | param( 4 | [System.Collections.IDictionary] $Configuration, 5 | [System.Collections.IDictionary] $DestinationPaths, 6 | [string] $FullProjectPath, 7 | [string] $FullModuleTemporaryPath, 8 | [string] $FullTemporaryPath 9 | ) 10 | Write-TextWithTime -Text "Preparing structure" -PreAppend Information { 11 | if ($Configuration.Steps.BuildModule.DeleteBefore -eq $true) { 12 | Write-TextWithTime -Text "Deleting old module (Desktop destination) $($DestinationPaths.Desktop)" { 13 | $Success = Remove-Directory -Directory $($DestinationPaths.Desktop) -ErrorAction Stop -SpacesBefore " " 14 | if ($Success -eq $false) { 15 | return $false 16 | } 17 | } -PreAppend Minus -SpacesBefore " " -Color Blue -ColorError Red -ColorTime Green -ColorBefore Yellow 18 | 19 | Write-TextWithTime -Text "Deleting old module (Core destination) $($DestinationPaths.Core)" { 20 | $Success = Remove-Directory -Directory $($DestinationPaths.Core) -SpacesBefore " " 21 | if ($Success -eq $false) { 22 | return $false 23 | } 24 | } -PreAppend Minus -SpacesBefore " " -Color Blue -ColorError Red -ColorTime Green -ColorBefore Yellow 25 | } 26 | 27 | Set-Location -Path $FullProjectPath 28 | 29 | Write-TextWithTime -Text "Cleaning up temporary path $($FullModuleTemporaryPath)" { 30 | $Success = Remove-Directory -Directory $FullModuleTemporaryPath -SpacesBefore " " 31 | if ($Success -eq $false) { 32 | return $false 33 | } 34 | Add-Directory -Directory $FullModuleTemporaryPath 35 | } -PreAppend Minus -SpacesBefore " " -Color Blue -ColorError Red -ColorTime Green -ColorBefore Yellow 36 | Write-TextWithTime -Text "Cleaning up temporary path $($FullTemporaryPath)" { 37 | $Success = Remove-Directory -Directory $FullTemporaryPath -SpacesBefore " " 38 | if ($Success -eq $false) { 39 | return $false 40 | } 41 | Add-Directory -Directory $FullTemporaryPath 42 | } -PreAppend Minus -SpacesBefore " " -Color Blue -ColorError Red -ColorTime Green -ColorBefore Yellow 43 | } 44 | } -------------------------------------------------------------------------------- /Private/Start-PublishingGallery.ps1: -------------------------------------------------------------------------------- 1 | function Start-PublishingGallery { 2 | [CmdletBinding()] 3 | param( 4 | [System.Collections.IDictionary] $Configuration, 5 | [System.Collections.IDictionary] $ChosenNuget 6 | ) 7 | 8 | if ($ChosenNuget) { 9 | $Repository = if ($ChosenNuget.RepositoryName) { $ChosenNuget.RepositoryName } else { 'PSGallery' } 10 | Write-TextWithTime -Text "Publishing Module to Gallery ($Repository)" { 11 | if ($ChosenNuget.ApiKey) { 12 | $publishModuleSplat = @{ 13 | Name = $Configuration.Information.ModuleName 14 | Repository = $Repository 15 | NuGetApiKey = $ChosenNuget.ApiKey 16 | Force = $ChosenNuget.Force 17 | Verbose = $ChosenNuget.Verbose 18 | ErrorAction = 'Stop' 19 | } 20 | Publish-Module @publishModuleSplat 21 | } else { 22 | return $false 23 | } 24 | } -PreAppend Plus 25 | } elseif ($Configuration.Steps.PublishModule.Enabled) { 26 | # old way 27 | Write-TextWithTime -Text "Publishing Module to PowerShellGallery" { 28 | if ($Configuration.Options.PowerShellGallery.FromFile) { 29 | $ApiKey = Get-Content -Path $Configuration.Options.PowerShellGallery.ApiKey -ErrorAction Stop -Encoding UTF8 30 | } else { 31 | $ApiKey = $Configuration.Options.PowerShellGallery.ApiKey 32 | } 33 | $publishModuleSplat = @{ 34 | Name = $Configuration.Information.ModuleName 35 | Repository = 'PSGallery' 36 | NuGetApiKey = $ApiKey 37 | Force = $Configuration.Steps.PublishModule.RequireForce 38 | Verbose = if ($Configuration.Steps.PublishModule.PSGalleryVerbose) { $Configuration.Steps.PublishModule.PSGalleryVerbose } else { $false } 39 | ErrorAction = 'Stop' 40 | } 41 | Publish-Module @publishModuleSplat 42 | } -PreAppend Plus 43 | } 44 | } -------------------------------------------------------------------------------- /Private/Test-AllFilePathsAndThrowErrorIfOneIsNotValid.ps1: -------------------------------------------------------------------------------- 1 | function Test-AllFilePathsAndThrowErrorIfOneIsNotValid { 2 | [CmdletBinding()] 3 | param( 4 | [string[]] $filePaths 5 | ) 6 | foreach ($filePath in $filePaths) { 7 | [bool] $fileWasNotFoundAtPath = [string]::IsNullOrEmpty($filePath) -or !(Test-Path -Path $filePath -PathType Leaf) 8 | if ($fileWasNotFoundAtPath) { 9 | throw "There is no file at the specified path, '$filePath'." 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Private/Test-ReparsePoint.ps1: -------------------------------------------------------------------------------- 1 | function Test-ReparsePoint { 2 | [CmdletBinding()] 3 | param ( 4 | [string]$path 5 | ) 6 | $file = Get-Item $path -Force -ea SilentlyContinue 7 | return [bool]($file.Attributes -band [IO.FileAttributes]::ReparsePoint) 8 | } -------------------------------------------------------------------------------- /Private/Update-VersionInBuildScript.ps1: -------------------------------------------------------------------------------- 1 | function Update-VersionInBuildScript { 2 | <# 3 | .SYNOPSIS 4 | Updates the version in the Build-Module.ps1 script. 5 | 6 | .DESCRIPTION 7 | Modifies the ModuleVersion entry in the Build-Module.ps1 script with the new version. 8 | 9 | .PARAMETER ScriptFile 10 | Path to the Build-Module.ps1 file. 11 | 12 | .PARAMETER Version 13 | The new version string to set. 14 | #> 15 | [CmdletBinding(SupportsShouldProcess)] 16 | param ( 17 | [Parameter(Mandatory = $true)] 18 | [string]$ScriptFile, 19 | 20 | [Parameter(Mandatory = $true)] 21 | [string]$Version, 22 | 23 | [System.Collections.IDictionary] $CurrentVersionHash 24 | ) 25 | 26 | if (!(Test-Path -Path $ScriptFile)) { 27 | Write-Warning "Build script file not found: $ScriptFile" 28 | return $false 29 | } 30 | 31 | $CurrentFileVersion = $CurrentVersionHash[$ScriptFile] 32 | 33 | try { 34 | $content = Get-Content -Path $ScriptFile -Raw 35 | $newContent = $content -replace "ModuleVersion\s*=\s*['""][\d\.]+['""]", "ModuleVersion = '$Version'" 36 | 37 | if ($content -eq $newContent) { 38 | Write-Verbose "No version change needed for $ScriptFile," 39 | return $true 40 | } 41 | Write-Verbose -Message "Updating version in $ScriptFile from '$CurrentFileVersion' to '$Version'" 42 | 43 | if ($PSCmdlet.ShouldProcess("Build script $ScriptFile", "Update version from '$CurrentFileVersion' to '$Version'")) { 44 | $newContent | Set-Content -Path $ScriptFile -NoNewline 45 | Write-Host "Updated version in $ScriptFile to $Version" -ForegroundColor Green 46 | } 47 | return $true 48 | } catch { 49 | Write-Error "Error updating build script $ScriptFile`: $_" 50 | return $false 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Private/Update-VersionInCsProj.ps1: -------------------------------------------------------------------------------- 1 | function Update-VersionInCsProj { 2 | <# 3 | .SYNOPSIS 4 | Updates the version in a .csproj file. 5 | 6 | .DESCRIPTION 7 | Modifies the VersionPrefix element in a .csproj file with the new version. 8 | 9 | .PARAMETER ProjectFile 10 | Path to the .csproj file. 11 | 12 | .PARAMETER Version 13 | The new version string to set. 14 | #> 15 | [CmdletBinding(SupportsShouldProcess)] 16 | param ( 17 | [Parameter(Mandatory = $true)] 18 | [string]$ProjectFile, 19 | 20 | [Parameter(Mandatory = $true)] 21 | [string]$Version, 22 | 23 | [System.Collections.IDictionary] $CurrentVersionHash 24 | ) 25 | 26 | if (!(Test-Path -Path $ProjectFile)) { 27 | Write-Warning "Project file not found: $ProjectFile" 28 | return $false 29 | } 30 | 31 | $CurrentFileVersion = $CurrentVersionHash[$ProjectFile] 32 | 33 | try { 34 | $content = Get-Content -Path $ProjectFile -Raw 35 | $newContent = $content -replace '[\d\.]+<\/VersionPrefix>', "$Version" 36 | 37 | if ($content -eq $newContent) { 38 | Write-Verbose "No version change needed for $ProjectFile" 39 | return $true 40 | } 41 | Write-Verbose -Message "Updating version in $ProjectFile from '$CurrentFileVersion' to '$Version'" 42 | if ($PSCmdlet.ShouldProcess("Project file $ProjectFile", "Update version from '$CurrentFileVersion' to '$Version'")) { 43 | $newContent | Set-Content -Path $ProjectFile -NoNewline 44 | Write-Host "Updated version in $ProjectFile to $Version" -ForegroundColor Green 45 | } 46 | return $true 47 | } catch { 48 | Write-Error "Error updating project file $ProjectFile`: $_" 49 | return $false 50 | } 51 | } -------------------------------------------------------------------------------- /Private/Update-VersionInPsd1.ps1: -------------------------------------------------------------------------------- 1 | function Update-VersionInPsd1 { 2 | <# 3 | .SYNOPSIS 4 | Updates the version in a PowerShell module manifest (.psd1) file. 5 | 6 | .DESCRIPTION 7 | Modifies the ModuleVersion entry in a module manifest with the new version. 8 | 9 | .PARAMETER ManifestFile 10 | Path to the .psd1 file. 11 | 12 | .PARAMETER Version 13 | The new version string to set. 14 | #> 15 | [CmdletBinding(SupportsShouldProcess)] 16 | param ( 17 | [Parameter(Mandatory = $true)] 18 | [string]$ManifestFile, 19 | 20 | [Parameter(Mandatory = $true)] 21 | [string]$Version, 22 | 23 | [System.Collections.IDictionary] $CurrentVersionHash 24 | ) 25 | 26 | if (!(Test-Path -Path $ManifestFile)) { 27 | Write-Warning "Module manifest file not found: $ManifestFile" 28 | return $false 29 | } 30 | 31 | $CurrentFileVersion = $CurrentVersionHash[$ManifestFile] 32 | 33 | try { 34 | # Read the content first to avoid Update-ModuleManifest mangling the format 35 | $content = Get-Content -Path $ManifestFile -Raw 36 | $newContent = $content -replace "ModuleVersion\s*=\s*['""][\d\.]+['""]", "ModuleVersion = '$Version'" 37 | 38 | 39 | if ($content -eq $newContent) { 40 | Write-Verbose "No version change needed for $ManifestFile" 41 | return $true 42 | } 43 | Write-Verbose -Message "Updating version in $ManifestFile from '$CurrentFileVersion' to '$Version'" 44 | 45 | if ($PSCmdlet.ShouldProcess("Module manifest $ManifestFile", "Update version from '$CurrentFileVersion' to '$Version'")) { 46 | $newContent | Set-Content -Path $ManifestFile -NoNewline 47 | Write-Host "Updated version in $ManifestFile to $Version" -ForegroundColor Green 48 | } 49 | return $true 50 | } catch { 51 | Write-Error "Error updating module manifest $ManifestFile`: $_" 52 | return $false 53 | } 54 | } -------------------------------------------------------------------------------- /Private/Update-VersionNumber.ps1: -------------------------------------------------------------------------------- 1 | function Update-VersionNumber { 2 | [CmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory = $true)] 5 | [string]$Version, 6 | [Parameter(Mandatory = $true)] 7 | [ValidateSet('Major', 'Minor', 'Build', 'Revision')] 8 | [string]$Type 9 | ) 10 | 11 | $versionParts = $Version -split '\.' 12 | 13 | while ($versionParts.Count -lt 3) { 14 | $versionParts += "0" 15 | } 16 | 17 | if ($Type -eq 'Revision' -and $versionParts.Count -lt 4) { 18 | $versionParts += "0" 19 | } 20 | 21 | switch ($Type) { 22 | 'Major' { 23 | $versionParts[0] = [string]([int]$versionParts[0] + 1) 24 | $versionParts[1] = "0" 25 | $versionParts[2] = "0" 26 | if ($versionParts.Count -gt 3) { 27 | $versionParts[3] = "0" 28 | } 29 | } 30 | 'Minor' { 31 | $versionParts[1] = [string]([int]$versionParts[1] + 1) 32 | $versionParts[2] = "0" 33 | if ($versionParts.Count -gt 3) { 34 | $versionParts[3] = "0" 35 | } 36 | } 37 | 'Build' { 38 | $versionParts[2] = [string]([int]$versionParts[2] + 1) 39 | if ($versionParts.Count -gt 3) { 40 | $versionParts[3] = "0" 41 | } 42 | } 43 | 'Revision' { 44 | if ($versionParts.Count -lt 4) { 45 | $versionParts += "1" 46 | } else { 47 | $versionParts[3] = [string]([int]$versionParts[3] + 1) 48 | } 49 | } 50 | } 51 | 52 | $newVersion = $versionParts -join '.' 53 | $versionPartCount = ($Version -split '\.' | Measure-Object).Count 54 | if ($versionPartCount -eq 3 -and $Type -ne 'Revision') { 55 | $newVersion = ($versionParts | Select-Object -First 3) -join '.' 56 | } 57 | 58 | return $newVersion 59 | } -------------------------------------------------------------------------------- /Private/Write-Text.ps1: -------------------------------------------------------------------------------- 1 | function Write-Text { 2 | [CmdletBinding()] 3 | param( 4 | [Parameter(Position = 0)][string] $Text, 5 | [System.ConsoleColor] $Color, 6 | [System.ConsoleColor] $ColorBefore, 7 | [System.ConsoleColor] $ColorTime, 8 | [switch] $Start, 9 | [switch] $End, 10 | [System.Diagnostics.Stopwatch] $Time, 11 | [ValidateSet('Plus', 'Minus', 'Information', 'Addition', 'Error')][string] $PreAppend, 12 | [string] $SpacesBefore 13 | ) 14 | if ($PreAppend) { 15 | if ($PreAppend -eq "Information") { 16 | $TextBefore = "$SpacesBefore[i] " 17 | if (-not $ColorBefore) { 18 | $ColorBefore = [System.ConsoleColor]::Yellow 19 | } 20 | } elseif ($PreAppend -eq 'Minus') { 21 | $TextBefore = "$SpacesBefore[-] " 22 | if (-not $ColorBefore) { 23 | $ColorBefore = [System.ConsoleColor]::Red 24 | } 25 | } elseif ($PreAppend -eq 'Plus') { 26 | $TextBefore = "$SpacesBefore[+] " 27 | if (-not $ColorBefore) { 28 | $ColorBefore = [System.ConsoleColor]::Cyan 29 | } 30 | } elseif ($PreAppend -eq 'Addition') { 31 | $TextBefore = "$SpacesBefore[>] " 32 | if (-not $ColorBefore) { 33 | $ColorBefore = [System.ConsoleColor]::Yellow 34 | } 35 | } elseif ($PreAppend -eq 'Error') { 36 | $TextBefore = "$SpacesBefore[e] " 37 | if (-not $ColorBefore) { 38 | $ColorBefore = [System.ConsoleColor]::Red 39 | } 40 | if (-not $Color) { 41 | $Color = [System.ConsoleColor]::Red 42 | } 43 | } 44 | Write-Host -Object "$TextBefore" -NoNewline -ForegroundColor $ColorBefore 45 | } 46 | if (-not $Color) { 47 | $Color = [System.ConsoleColor]::Cyan 48 | } 49 | if (-not $ColorTime) { 50 | $ColorTime = [System.ConsoleColor]::Green 51 | } 52 | if (-not $Start -and -not $End) { 53 | Write-Host "$Text" -ForegroundColor $Color 54 | } 55 | if ($Start) { 56 | Write-Host "$Text" -NoNewline -ForegroundColor $Color 57 | $Time = [System.Diagnostics.Stopwatch]::StartNew() 58 | } 59 | if ($End) { 60 | $TimeToExecute = $Time.Elapsed.ToString() 61 | Write-Host " [Time: $TimeToExecute]" -ForegroundColor $ColorTime 62 | $Time.Stop() 63 | } else { 64 | if ($Time) { 65 | return $Time 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /Private/Write-TextWithTime.ps1: -------------------------------------------------------------------------------- 1 | function Write-TextWithTime { 2 | [CmdletBinding()] 3 | param( 4 | [ScriptBlock] $Content, 5 | [ValidateSet('Plus', 'Minus', 'Information', 'Addition')][string] $PreAppend, 6 | [string] $Text, 7 | [switch] $Continue, 8 | [System.ConsoleColor] $Color = [System.ConsoleColor]::Cyan, 9 | [System.ConsoleColor] $ColorTime = [System.ConsoleColor]::Green, 10 | [System.ConsoleColor] $ColorError = [System.ConsoleColor]::Red, 11 | [System.ConsoleColor] $ColorBefore, 12 | [string] $SpacesBefore 13 | ) 14 | if ($PreAppend) { 15 | if ($PreAppend -eq "Information") { 16 | $TextBefore = "$SpacesBefore[i] " 17 | if (-not $ColorBefore) { 18 | $ColorBefore = [System.ConsoleColor]::Yellow 19 | } 20 | } elseif ($PreAppend -eq 'Minus') { 21 | $TextBefore = "$SpacesBefore[-] " 22 | if (-not $ColorBefore) { 23 | $ColorBefore = [System.ConsoleColor]::Red 24 | } 25 | } elseif ($PreAppend -eq 'Plus') { 26 | $TextBefore = "$SpacesBefore[+] " 27 | if (-not $ColorBefore) { 28 | $ColorBefore = [System.ConsoleColor]::Cyan 29 | } 30 | } elseif ($PreAppend -eq 'Addition') { 31 | $TextBefore = "$SpacesBefore[>] " 32 | if (-not $ColorBefore) { 33 | $ColorBefore = [System.ConsoleColor]::Yellow 34 | } 35 | } 36 | Write-Host -Object "$TextBefore" -NoNewline -ForegroundColor $ColorBefore 37 | Write-Host -Object "$Text" -ForegroundColor $Color 38 | } else { 39 | Write-Host -Object "$Text" -ForegroundColor $Color 40 | } 41 | $Time = [System.Diagnostics.Stopwatch]::StartNew() 42 | if ($null -ne $Content) { 43 | try { 44 | $InputData = & $Content 45 | if ($InputData -contains $false) { 46 | $ErrorMessage = "Failure in action above. Check output above." 47 | } else { 48 | $InputData 49 | } 50 | } catch { 51 | $ErrorMessage = $_.Exception.Message + " (File: $($_.InvocationInfo.ScriptName), Line: " + $_.InvocationInfo.ScriptLineNumber + ")" 52 | } 53 | } 54 | $TimeToExecute = $Time.Elapsed.ToString() 55 | if ($ErrorMessage) { 56 | Write-Host -Object "$SpacesBefore[e] $Text [Error: $ErrorMessage]" -ForegroundColor $ColorError 57 | if ($PreAppend) { 58 | Write-Host -Object "$($TextBefore)" -NoNewline -ForegroundColor $ColorError 59 | } 60 | Write-Host -Object "$Text [Time: $TimeToExecute]" -ForegroundColor $ColorError 61 | $Time.Stop() 62 | return $false 63 | break 64 | } else { 65 | if ($PreAppend) { 66 | Write-Host -Object "$($TextBefore)" -NoNewline -ForegroundColor $ColorBefore 67 | } 68 | Write-Host -Object "$Text [Time: $TimeToExecute]" -ForegroundColor $ColorTime 69 | } 70 | if (-not $Continue) { 71 | $Time.Stop() 72 | } 73 | } -------------------------------------------------------------------------------- /Public/Convert-CommandsToList.ps1: -------------------------------------------------------------------------------- 1 | function Convert-CommandsToList { 2 | [cmdletbinding()] 3 | param( 4 | [parameter(Mandatory)][string] $ModuleName, 5 | [string[]] $CommandTypes 6 | ) 7 | 8 | $Commands = Get-Command -Module $ModuleName 9 | $CommandsOnly = $Commands | Where-Object { $_.CommandType -eq 'Function' } 10 | 11 | $List = [ordered] @{} 12 | foreach ($Command in $CommandsOnly) { 13 | if ($Command.Name.StartsWith('Get')) { 14 | $CommandType = 'Get' 15 | } elseif ($Command.Name.StartsWith('Set')) { 16 | $CommandType = 'Set' 17 | } else { 18 | $CommandType = 'Other' 19 | } 20 | if ($CommandType -ne 'Other') { 21 | $Name = $Command.Name.Replace("Get-", '').Replace("Set-", '') 22 | if (-not $List[$Name]) { 23 | $List[$Name] = [PSCustomObject] @{ 24 | #Get = $CommandType -eq 'Get' 25 | Get = if ($CommandType -eq 'Get') { $Command.Name } else { '' } 26 | #Set = $CommandType -eq 'Set' 27 | Set = if ($CommandType -eq 'Set') { $Command.Name } else { '' } 28 | } 29 | } else { 30 | $List[$Name].$CommandType = $Command.Name 31 | } 32 | } 33 | } 34 | 35 | $List.Values 36 | } -------------------------------------------------------------------------------- /Public/Get-MissingFunctions.ps1: -------------------------------------------------------------------------------- 1 | function Get-MissingFunctions { 2 | [CmdletBinding()] 3 | param( 4 | [alias('Path')][string] $FilePath, 5 | [alias('ScriptBlock')][scriptblock] $Code, 6 | [string[]] $Functions, 7 | [switch] $Summary, 8 | [switch] $SummaryWithCommands, 9 | [Array] $ApprovedModules, 10 | [Array] $IgnoreFunctions 11 | ) 12 | $ListCommands = [System.Collections.Generic.List[Object]]::new() 13 | if ($FilePath) { 14 | $CommandsUsedInCode = Get-ScriptCommands -FilePath $FilePath 15 | } elseif ($Code) { 16 | $CommandsUsedInCode = Get-ScriptCommands -Code $Code 17 | } else { 18 | return 19 | } 20 | if ($IgnoreFunctions.Count -gt 0) { 21 | $Result = foreach ($_ in $CommandsUsedInCode) { 22 | if ($IgnoreFunctions -notcontains $_) { 23 | $_ 24 | } 25 | } 26 | } else { 27 | $Result = $CommandsUsedInCode 28 | } 29 | #$FilteredCommands = Get-FilteredScriptCommands -Commands $Result -NotUnknown -NotCmdlet -Functions $Functions -NotApplication -FilePath $FilePath 30 | [Array] $FilteredCommands = Get-FilteredScriptCommands -Commands $Result -Functions $Functions -FilePath $FilePath -ApprovedModules $ApprovedModules 31 | foreach ($_ in $FilteredCommands) { 32 | $ListCommands.Add($_) 33 | } 34 | # Ensures even one object is array 35 | [Array] $FilteredCommandsName = foreach ($Name in $FilteredCommands.Name) { 36 | $Name 37 | } 38 | # this gets commands along their ScriptBlock 39 | # $FilteredCommands = Get-RecursiveCommands -Commands $FilteredCommands 40 | [Array] $FunctionsOutput = foreach ($_ in $ListCommands) { 41 | if ($_.ScriptBlock) { 42 | if ($ApprovedModules.Count -gt 0 -and $_.Source -in $ApprovedModules) { 43 | "function $($_.Name) { $($_.ScriptBlock) }" 44 | } elseif ($ApprovedModules.Count -eq 0) { 45 | #"function $($_.Name) { $($_.ScriptBlock) }" 46 | } 47 | } 48 | } 49 | 50 | if ($FunctionsOutput.Count -gt 0) { 51 | $IgnoreAlreadyKnownCommands = ($FilteredCommandsName + $IgnoreFunctions) | Sort-Object -Unique 52 | $ScriptBlockMissing = [scriptblock]::Create($FunctionsOutput) 53 | $AnotherRun = Get-MissingFunctions -SummaryWithCommands -ApprovedModules $ApprovedModules -Code $ScriptBlockMissing -IgnoreFunctions $IgnoreAlreadyKnownCommands 54 | } 55 | 56 | if ($SummaryWithCommands) { 57 | if ($AnotherRun) { 58 | $Hash = @{ } 59 | $Hash.Summary = foreach ($_ in $FilteredCommands + $AnotherRun.Summary) { 60 | $_ 61 | } 62 | $Hash.SummaryFiltered = foreach ($_ in $ListCommands + $AnotherRun.SummaryFiltered) { 63 | $_ 64 | } 65 | $Hash.Functions = foreach ($_ in $FunctionsOutput + $AnotherRun.Functions) { 66 | $_ 67 | } 68 | } else { 69 | $Hash = @{ 70 | Summary = $FilteredCommands 71 | SummaryFiltered = $ListCommands 72 | Functions = $FunctionsOutput 73 | } 74 | } 75 | return $Hash 76 | } elseif ($Summary) { 77 | if ($AnotherRun) { 78 | foreach ($_ in $ListCommands + $AnotherRun.SummaryFiltered) { 79 | $_ 80 | } 81 | } else { 82 | return $ListCommands 83 | } 84 | } else { 85 | return $FunctionsOutput 86 | } 87 | } -------------------------------------------------------------------------------- /Public/Get-ProjectVersion.ps1: -------------------------------------------------------------------------------- 1 | function Get-ProjectVersion { 2 | [CmdletBinding()] 3 | param( 4 | [Parameter()] 5 | [string]$ModuleName, 6 | [Parameter()] 7 | [string]$Path = (Get-Location).Path, 8 | [Parameter()] 9 | [string[]]$ExcludeFolders = @() 10 | ) 11 | 12 | $RepoRoot = $Path 13 | $DefaultExcludes = @('obj','bin') 14 | $AllExcludes = $DefaultExcludes + $ExcludeFolders | Select-Object -Unique 15 | 16 | $CsprojFiles = Get-ChildItem -Path $RepoRoot -Filter "*.csproj" -Recurse | Where-Object { 17 | $file = $_ 18 | ($AllExcludes.Count -eq 0 -or -not ($AllExcludes | Where-Object { 19 | $_ -and $_.Trim() -ne '' -and $file.FullName -and $file.FullName.ToLower().Contains($_.ToLower()) 20 | })) 21 | } 22 | $PsdFiles = Get-ChildItem -Path $RepoRoot -Filter "*.psd1" -Recurse | Where-Object { 23 | $file = $_ 24 | ($AllExcludes.Count -eq 0 -or -not ($AllExcludes | Where-Object { 25 | $_ -and $_.Trim() -ne '' -and $file.FullName -and $file.FullName.ToLower().Contains($_.ToLower()) 26 | })) 27 | } 28 | $BuildScriptFiles = Get-ChildItem -Path $RepoRoot -Filter "Build-Module.ps1" -Recurse | Where-Object { 29 | $file = $_ 30 | ($AllExcludes.Count -eq 0 -or -not ($AllExcludes | Where-Object { 31 | $_ -and $_.Trim() -ne '' -and $file.FullName -and $file.FullName.ToLower().Contains($_.ToLower()) 32 | })) 33 | } 34 | 35 | # Filter csproj files by ModuleName if provided 36 | $targetCsprojFiles = $CsprojFiles 37 | if ($ModuleName) { 38 | $targetCsprojFiles = $CsprojFiles | Where-Object { $_.BaseName -eq $ModuleName } 39 | } 40 | 41 | foreach ($csProj in $targetCsprojFiles) { 42 | $version = Get-CurrentVersionFromCsProj -ProjectFile $csProj.FullName 43 | if ($version) { 44 | [PSCustomObject]@{ 45 | Version = $version 46 | Source = $csProj.FullName 47 | Type = "C# Project" 48 | } 49 | } 50 | } 51 | 52 | # Filter psd1 files by ModuleName if provided 53 | $targetPsdFiles = $PsdFiles 54 | if ($ModuleName) { 55 | $targetPsdFiles = $PsdFiles | Where-Object { $_.BaseName -eq $ModuleName } 56 | } 57 | 58 | foreach ($psd1 in $targetPsdFiles) { 59 | $version = Get-CurrentVersionFromPsd1 -ManifestFile $psd1.FullName 60 | if ($version) { 61 | [PSCustomObject]@{ 62 | Version = $version 63 | Source = $psd1.FullName 64 | Type = "PowerShell Module" 65 | } 66 | } 67 | } 68 | 69 | foreach ($buildScript in $BuildScriptFiles) { 70 | $version = Get-CurrentVersionFromBuildScript -ScriptFile $buildScript.FullName 71 | if ($version) { 72 | [PSCustomObject]@{ 73 | Version = $version 74 | Source = $buildScript.FullName 75 | Type = "Build Script" 76 | } 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /Public/Initialize-PortableModule.ps1: -------------------------------------------------------------------------------- 1 | function Initialize-PortableModule { 2 | [CmdletBinding()] 3 | param( 4 | [alias('ModuleName')][string] $Name, 5 | [string] $Path = $PSScriptRoot, 6 | [switch] $Download, 7 | [switch] $Import 8 | ) 9 | 10 | if ($PSVersionTable.PSVersion.Major -gt 5) { 11 | $Encoding = 'UTF8BOM' 12 | } else { 13 | $Encoding = 'UTF8' 14 | } 15 | 16 | if (-not $Name) { 17 | Write-Warning "Initialize-ModulePortable - Module name not given. Terminating." 18 | return 19 | } 20 | if (-not $Download -and -not $Import) { 21 | Write-Warning "Initialize-ModulePortable - Please choose Download/Import switch. Terminating." 22 | return 23 | } 24 | if ($Download) { 25 | try { 26 | if (-not $Path -or -not (Test-Path -LiteralPath $Path)) { 27 | $null = New-Item -ItemType Directory -Path $Path -Force 28 | } 29 | Save-Module -Name $Name -LiteralPath $Path -WarningVariable WarningData -WarningAction SilentlyContinue -ErrorAction Stop 30 | } catch { 31 | $ErrorMessage = $_.Exception.Message 32 | if ($WarningData) { 33 | Write-Warning "Initialize-ModulePortable - $WarningData" 34 | } 35 | Write-Warning "Initialize-ModulePortable - Error $ErrorMessage" 36 | return 37 | } 38 | } 39 | if ($Download -or $Import) { 40 | [Array] $Modules = Get-RequiredModule -Path $Path -Name $Name | Where-Object { $null -ne $_ } 41 | if ($null -ne $Modules) { 42 | [array]::Reverse($Modules) 43 | } 44 | $CleanedModules = [System.Collections.Generic.List[string]]::new() 45 | foreach ($_ in $Modules) { 46 | if ($CleanedModules -notcontains $_) { 47 | $CleanedModules.Add($_) 48 | } 49 | } 50 | $CleanedModules.Add($Name) 51 | $Items = foreach ($_ in $CleanedModules) { 52 | Get-ChildItem -LiteralPath "$Path\$_" -Filter '*.psd1' -Recurse -ErrorAction SilentlyContinue -Depth 1 53 | } 54 | [Array] $PSD1Files = $Items.FullName 55 | } 56 | if ($Download) { 57 | $ListFiles = foreach ($PSD1 in $PSD1Files) { 58 | $PSD1.Replace("$Path", '$PSScriptRoot') 59 | } 60 | # Build File 61 | $Content = @( 62 | '$Modules = @(' 63 | foreach ($_ in $ListFiles) { 64 | " `"$_`"" 65 | } 66 | ')' 67 | "foreach (`$_ in `$Modules) {" 68 | " Import-Module `$_ -Verbose:`$false -Force" 69 | "}" 70 | ) 71 | $Content | Set-Content -Path $Path\$Name.ps1 -Force -Encoding $Encoding 72 | } 73 | if ($Import) { 74 | $ListFiles = foreach ($PSD1 in $PSD1Files) { 75 | $PSD1 76 | } 77 | foreach ($_ in $ListFiles) { 78 | Import-Module $_ -Verbose:$false -Force 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /Public/Initialize-PortableScript.ps1: -------------------------------------------------------------------------------- 1 | function Initialize-PortableScript { 2 | [cmdletBinding()] 3 | param( 4 | [string] $FilePath, 5 | [string] $OutputPath, 6 | [Array] $ApprovedModules 7 | ) 8 | 9 | if ($PSVersionTable.PSVersion.Major -gt 5) { 10 | $Encoding = 'UTF8BOM' 11 | } else { 12 | $Encoding = 'UTF8' 13 | } 14 | 15 | $Output = Get-MissingFunctions -FilePath $FilePath -SummaryWithCommands -ApprovedModules $ApprovedModules 16 | $Script = Get-Content -LiteralPath $FilePath -Encoding UTF8 17 | $FinalScript = @( 18 | $Output.Functions 19 | $Script 20 | ) 21 | $FinalScript | Set-Content -LiteralPath $OutputPath -Encoding $Encoding 22 | $Output 23 | } -------------------------------------------------------------------------------- /Public/Initialize-ProjectManager.ps1: -------------------------------------------------------------------------------- 1 | function Initialize-ProjectManager { 2 | <# 3 | .SYNOPSIS 4 | Builds VSCode Project manager config from filesystem 5 | 6 | .DESCRIPTION 7 | Builds VSCode Project manager config from filesystem 8 | 9 | .PARAMETER Path 10 | Path to where the projects are located 11 | 12 | .PARAMETER DisableSorting 13 | Disables sorting of the projects by last modified date 14 | 15 | .EXAMPLE 16 | Initialize-ProjectManager -Path "C:\Support\GitHub" 17 | 18 | .EXAMPLE 19 | Initialize-ProjectManager -Path "C:\Support\GitHub" -DisableSorting 20 | 21 | .NOTES 22 | General notes 23 | #> 24 | [cmdletBinding()] 25 | param( 26 | [parameter(Mandatory)][string] $Path, 27 | [switch] $DisableSorting 28 | ) 29 | $ProjectsPath = Get-ChildItem -LiteralPath $Path -Directory 30 | 31 | $SortedProjects = foreach ($Project in $ProjectsPath) { 32 | $AllFiles = Get-ChildItem -LiteralPath $Project.FullName -Exclude ".\.git" -Recurse -Depth 2 -File 33 | $NewestFile = $AllFiles | Sort-Object -Descending -Property LastWriteTime | Select-Object -First 1 34 | 35 | [PSCustomObject] @{ 36 | name = $Project.name 37 | FullName = $Project.FullName 38 | LastWriteTime = $NewestFile.LastWriteTime 39 | } 40 | 41 | } 42 | if (-not $DisableSorting) { 43 | $SortedProjects = $SortedProjects | Sort-Object -Descending -Property LastWriteTime 44 | } 45 | 46 | $ProjectManager = foreach ($Project in $SortedProjects) { 47 | [PSCustomObject] @{ 48 | name = $Project.name 49 | rootPath = $Project.FullName 50 | paths = @() 51 | tags = @() 52 | enabled = $true 53 | } 54 | } 55 | $PathProjects = @( 56 | [io.path]::Combine($Env:APPDATA, "Code\User\globalStorage\alefragnani.project-manager"), 57 | [io.path]::Combine($Env:APPDATA, "Cursor\User\globalStorage\alefragnani.project-manager"), 58 | [io.path]::Combine($Env:APPDATA, "Cursor - Insiders\User\globalStorage\alefragnani.project-manager"), 59 | [io.path]::Combine($Env:APPDATA, "Code - Insiders\User\globalStorage\alefragnani.project-manager") 60 | ) 61 | 62 | 63 | foreach ($Project in $PathProjects) { 64 | if (Test-Path -LiteralPath $Project) { 65 | $JsonPath = [io.path]::Combine($Project, 'projects.json') 66 | if (Test-Path -LiteralPath $JsonPath) { 67 | Get-Content -LiteralPath $JsonPath -Encoding UTF8 | Set-Content -LiteralPath "$JsonPath.backup" 68 | } 69 | $ProjectManager | ConvertTo-Json | Set-Content -LiteralPath $JsonPath 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /Public/New-ConfigurationCommand.ps1: -------------------------------------------------------------------------------- 1 | function New-ConfigurationCommand { 2 | [CmdletBinding()] 3 | param( 4 | [string] $ModuleName, 5 | [string[]] $CommandName 6 | ) 7 | 8 | $Configuration = [ordered] @{ 9 | Type = 'Command' 10 | Configuration = [ordered] @{ 11 | ModuleName = $ModuleName 12 | CommandName = $CommandName 13 | } 14 | } 15 | $Configuration 16 | } -------------------------------------------------------------------------------- /Public/New-ConfigurationDocumentation.ps1: -------------------------------------------------------------------------------- 1 | function New-ConfigurationDocumentation { 2 | <# 3 | .SYNOPSIS 4 | Enables or disables creation of documentation from the module using PlatyPS 5 | 6 | .DESCRIPTION 7 | Enables or disables creation of documentation from the module using PlatyPS 8 | 9 | .PARAMETER Enable 10 | Enables creation of documentation from the module. If not specified, the documentation will not be created. 11 | 12 | .PARAMETER StartClean 13 | Removes all files from the documentation folder before creating new documentation. 14 | Otherwise the `Update-MarkdownHelpModule` will be used to update the documentation. 15 | 16 | .PARAMETER UpdateWhenNew 17 | Updates the documentation right after running `New-MarkdownHelp` due to platyPS bugs. 18 | 19 | .PARAMETER Path 20 | Path to the folder where documentation will be created. 21 | 22 | .PARAMETER PathReadme 23 | Path to the readme file that will be used for the documentation. 24 | 25 | .PARAMETER Tool 26 | Tool to use for documentation generation. By default `HelpOut` is used. 27 | Available options are `PlatyPS` and `HelpOut`. 28 | 29 | .EXAMPLE 30 | New-ConfigurationDocumentation -Enable:$false -StartClean -UpdateWhenNew -PathReadme 'Docs\Readme.md' -Path 'Docs' 31 | 32 | .EXAMPLE 33 | New-ConfigurationDocumentation -Enable -PathReadme 'Docs\Readme.md' -Path 'Docs' 34 | 35 | .NOTES 36 | General notes 37 | #> 38 | [CmdletBinding()] 39 | param( 40 | [switch] $Enable, 41 | [switch] $StartClean, 42 | [switch] $UpdateWhenNew, 43 | [Parameter(Mandatory)][string] $Path, 44 | [Parameter(Mandatory)][string] $PathReadme, 45 | [ValidateSet('PlatyPS', 'HelpOut')][string] $Tool = 'PlatyPS' 46 | ) 47 | 48 | if ($Tool -eq 'PlatyPS') { 49 | $ModuleExists = Get-Module -Name 'PlatyPS' -ListAvailable 50 | if (-not $ModuleExists) { 51 | Write-Warning "Module PlatyPS is not installed. Please install it using Install-Module PlatyPS -Force -Verbose" 52 | return 53 | } 54 | } elseif ($Tool -eq 'HelpOut') { 55 | $ModuleExists = Get-Module -Name 'HelpOut' -ListAvailable 56 | if (-not $ModuleExists) { 57 | Write-Warning "Module HelpOut is not installed. Please install it using Install-Module HelpOut -Force -Verbose" 58 | return 59 | } 60 | } else { 61 | return 62 | } 63 | if ($Path -or $PathReadme) { 64 | $Option = [ordered] @{ 65 | Type = 'Documentation' 66 | Configuration = [ordered] @{ 67 | Path = $Path 68 | PathReadme = $PathReadme 69 | } 70 | } 71 | $Option 72 | } 73 | 74 | if ($Enable -or $StartClean -or $UpdateWhenNew) { 75 | $Option = [ordered]@{ 76 | Type = 'BuildDocumentation' 77 | Configuration = [ordered]@{ 78 | Enable = $Enable 79 | StartClean = $StartClean 80 | UpdateWhenNew = $UpdateWhenNew 81 | Tool = $Tool 82 | } 83 | } 84 | $Option 85 | } 86 | } -------------------------------------------------------------------------------- /Public/New-ConfigurationExecute.ps1: -------------------------------------------------------------------------------- 1 | function New-ConfigurationExecute { 2 | [CmdletBinding()] 3 | param( 4 | 5 | ) 6 | } -------------------------------------------------------------------------------- /Public/New-ConfigurationImportModule.ps1: -------------------------------------------------------------------------------- 1 | function New-ConfigurationImportModule { 2 | <# 3 | .SYNOPSIS 4 | Creates a configuration for importing PowerShell modules. 5 | 6 | .DESCRIPTION 7 | This function generates a configuration object for importing PowerShell modules. It allows specifying whether to import the current module itself and/or any required modules. 8 | 9 | .PARAMETER ImportSelf 10 | Indicates whether to import the current module itself. 11 | 12 | .PARAMETER ImportRequiredModules 13 | Indicates whether to import any required modules specified in the module manifest. 14 | 15 | .EXAMPLE 16 | New-ConfigurationImportModule -ImportSelf -ImportRequiredModules 17 | 18 | .NOTES 19 | This function helps in creating a standardized import configuration for PowerShell modules. 20 | #> 21 | [CmdletBinding()] 22 | param( 23 | [switch] $ImportSelf, 24 | [switch] $ImportRequiredModules 25 | ) 26 | 27 | $Output = [ordered] @{ 28 | Type = 'ImportModules' 29 | ImportModules = [ordered] @{} 30 | } 31 | if ($PSBoundParameters.Keys.Contains('ImportSelf')) { 32 | $Output['ImportModules']['Self'] = $ImportSelf 33 | } 34 | if ($PSBoundParameters.Keys.Contains('ImportRequiredModules')) { 35 | $Output['ImportModules']['RequiredModules'] = $ImportRequiredModules 36 | } 37 | if ($VerbosePreference) { 38 | $Output['ImportModules']['Verbose'] = $true 39 | } 40 | $Output 41 | } -------------------------------------------------------------------------------- /Public/New-ConfigurationInformation.ps1: -------------------------------------------------------------------------------- 1 | function New-ConfigurationInformation { 2 | [cmdletbinding()] 3 | param( 4 | [string] $FunctionsToExportFolder, 5 | [string] $AliasesToExportFolder, 6 | [string[]] $ExcludeFromPackage, 7 | [string[]] $IncludeRoot, 8 | [string[]] $IncludePS1, 9 | [string[]] $IncludeAll, 10 | [scriptblock] $IncludeCustomCode, 11 | [System.Collections.IDictionary] $IncludeToArray, 12 | [string] $LibrariesCore, 13 | [string] $LibrariesDefault, 14 | [string] $LibrariesStandard 15 | ) 16 | 17 | $Configuration = [ordered] @{ 18 | FunctionsToExportFolder = $FunctionsToExportFolder 19 | AliasesToExportFolder = $AliasesToExportFolder 20 | ExcludeFromPackage = $ExcludeFromPackage 21 | IncludeRoot = $IncludeRoot 22 | IncludePS1 = $IncludePS1 23 | IncludeAll = $IncludeAll 24 | IncludeCustomCode = $IncludeCustomCode 25 | IncludeToArray = $IncludeToArray 26 | LibrariesCore = $LibrariesCore 27 | LibrariesDefault = $LibrariesDefault 28 | LibrariesStandard = $LibrariesStandard 29 | } 30 | Remove-EmptyValue -Hashtable $Configuration 31 | 32 | $Option = @{ 33 | Type = 'Information' 34 | Configuration = $Configuration 35 | } 36 | $Option 37 | } -------------------------------------------------------------------------------- /Public/New-ConfigurationModuleSkip.ps1: -------------------------------------------------------------------------------- 1 | function New-ConfigurationModuleSkip { 2 | <# 3 | .SYNOPSIS 4 | Provides a way to ignore certain commands or modules during build process and continue module building on errors. 5 | 6 | .DESCRIPTION 7 | Provides a way to ignore certain commands or modules during build process and continue module building on errors. 8 | During build if a build module can't find require module or command it will fail the build process to prevent incomplete module from being created. 9 | This option allows to skip certain modules or commands and continue building the module. 10 | This is useful for commands we know are not available on all systems, or we get them different way. 11 | 12 | .PARAMETER IgnoreModuleName 13 | Ignore module name or names. If the module is not available on the system it will be ignored and build process will continue. 14 | 15 | .PARAMETER IgnoreFunctionName 16 | Ignore function name or names. If the function is not available in the module it will be ignored and build process will continue. 17 | 18 | .PARAMETER Force 19 | This switch will force build process to continue even if the module or command is not available (aka you know what you are doing) 20 | 21 | .EXAMPLE 22 | New-ConfigurationModuleSkip -IgnoreFunctionName 'Invoke-Formatter', 'Find-Module' -IgnoreModuleName 'platyPS' 23 | 24 | .NOTES 25 | General notes 26 | #> 27 | [CmdletBinding()] 28 | param( 29 | [string[]] $IgnoreModuleName, 30 | [string[]] $IgnoreFunctionName, 31 | [switch] $Force 32 | ) 33 | 34 | $Configuration = [ordered] @{ 35 | Type = 'ModuleSkip' 36 | Configuration = [ordered] @{ 37 | IgnoreModuleName = $IgnoreModuleName 38 | IgnoreFunctionName = $IgnoreFunctionName 39 | Force = $Force 40 | } 41 | } 42 | Remove-EmptyValue -Hashtable $Configuration.Configuration 43 | $Configuration 44 | 45 | } -------------------------------------------------------------------------------- /Public/New-ConfigurationPlaceHolder.ps1: -------------------------------------------------------------------------------- 1 | function New-ConfigurationPlaceHolder { 2 | <# 3 | .SYNOPSIS 4 | Command helping define custom placeholders replacing content within a script or module during the build process. 5 | 6 | .DESCRIPTION 7 | Command helping define custom placeholders replacing content within a script or module during the build process. 8 | It modifies only the content of the script or module (PSM1) and does not modify the sources. 9 | 10 | .PARAMETER CustomReplacement 11 | Hashtable array with custom placeholders to replace. Each hashtable must contain two keys: Find and Replace. 12 | 13 | .PARAMETER Find 14 | The string to find in the script or module content. 15 | 16 | .PARAMETER Replace 17 | The string to replace the Find string in the script or module content. 18 | 19 | .EXAMPLE 20 | New-ConfigurationPlaceHolder -Find '{CustomName}' -Replace 'SpecialCase' 21 | 22 | .EXAMPLE 23 | New-ConfigurationPlaceHolder -CustomReplacement @( 24 | @{ Find = '{CustomName}'; Replace = 'SpecialCase' } 25 | @{ Find = '{CustomVersion}'; Replace = '1.0.0' } 26 | ) 27 | 28 | .NOTES 29 | General notes 30 | #> 31 | [CmdletBinding(DefaultParameterSetName = 'FindAndReplace')] 32 | param( 33 | [Parameter(Mandatory, ParameterSetName = 'CustomReplacement')][System.Collections.IDictionary[]] $CustomReplacement, 34 | [Parameter(Mandatory, ParameterSetName = 'FindAndReplace')][string] $Find, 35 | [Parameter(Mandatory, ParameterSetName = 'FindAndReplace')][string] $Replace 36 | ) 37 | 38 | foreach ($Replacement in $CustomReplacement) { 39 | [ordered] @{ 40 | Type = 'PlaceHolder' 41 | Configuration = $Replacement 42 | } 43 | } 44 | if ($PSBoundParameters.ContainsKey("Find") -and $PSBoundParameters.ContainsKey("Replace")) { 45 | [ordered] @{ 46 | Type = 'PlaceHolder' 47 | Configuration = @{ 48 | Find = $Find 49 | Replace = $Replace 50 | } 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /Public/New-ConfigurationTest.ps1: -------------------------------------------------------------------------------- 1 | function New-ConfigurationTest { 2 | [CmdletBinding()] 3 | param( 4 | #[Parameter(Mandatory)][ValidateSet('BeforeMerge', 'AfterMerge')][string[]] $When, 5 | [Parameter(Mandatory)][string] $TestsPath, 6 | [switch] $Enable, 7 | [switch] $Force 8 | ) 9 | 10 | if ($Enable) { 11 | if ($null -eq $IsWindows -or $IsWindows -eq $true) { 12 | $TestsPath = $TestsPath.Replace('/', '\') 13 | } else { 14 | $TestsPath = $TestsPath.Replace('\', '/') 15 | } 16 | # lets temporary set it here only, not sure if it's worth before merge 17 | $When = 'AfterMerge' 18 | foreach ($W in $When) { 19 | $Configuration = [ordered] @{ 20 | Type = "Tests$W" 21 | Configuration = [ordered] @{ 22 | When = $W 23 | TestsPath = $TestsPath 24 | Force = $Force.ispresent 25 | } 26 | } 27 | Remove-EmptyValue -Hashtable $Configuration.Configuration 28 | $Configuration 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /Public/Set-ProjectVersion.ps1: -------------------------------------------------------------------------------- 1 | function Set-ProjectVersion { 2 | [CmdletBinding(SupportsShouldProcess)] 3 | param( 4 | [Parameter()] 5 | [ValidateSet('Major', 'Minor', 'Build', 'Revision')] 6 | [string]$VersionType = '', 7 | [Parameter()] 8 | [ValidatePattern('^\d+\.\d+\.\d+(\.\d+)?$')] 9 | [string]$NewVersion = '', 10 | [Parameter()] 11 | [string]$ModuleName = '', 12 | [Parameter()] 13 | [string]$Path = (Get-Location).Path, 14 | [Parameter()] 15 | [string[]]$ExcludeFolders = @(), 16 | [switch] $PassThru 17 | ) 18 | 19 | $RepoRoot = $Path 20 | $DefaultExcludes = @('obj', 'bin') 21 | $AllExcludes = $DefaultExcludes + $ExcludeFolders | Select-Object -Unique 22 | 23 | $CsprojFiles = Get-ChildItem -Path $RepoRoot -Filter "*.csproj" -Recurse | Where-Object { 24 | $file = $_ 25 | ($AllExcludes.Count -eq 0 -or -not ($AllExcludes | Where-Object { 26 | $_ -and $_.Trim() -ne '' -and $file.FullName -and $file.FullName.ToLower().Contains($_.ToLower()) 27 | })) 28 | } 29 | $PsdFiles = Get-ChildItem -Path $RepoRoot -Filter "*.psd1" -Recurse | Where-Object { 30 | $file = $_ 31 | ($AllExcludes.Count -eq 0 -or -not ($AllExcludes | Where-Object { 32 | $_ -and $_.Trim() -ne '' -and $file.FullName -and $file.FullName.ToLower().Contains($_.ToLower()) 33 | })) 34 | } 35 | $BuildScriptFiles = Get-ChildItem -Path $RepoRoot -Filter "Build-Module.ps1" -Recurse | Where-Object { 36 | $file = $_ 37 | ($AllExcludes.Count -eq 0 -or -not ($AllExcludes | Where-Object { 38 | $_ -and $_.Trim() -ne '' -and $file.FullName -and $file.FullName.ToLower().Contains($_.ToLower()) 39 | })) 40 | } 41 | 42 | # Filter csproj files by ModuleName if provided 43 | $targetCsprojFiles = $CsprojFiles 44 | if ($ModuleName) { 45 | $targetCsprojFiles = $CsprojFiles | Where-Object { $_.BaseName -eq $ModuleName } 46 | } 47 | 48 | # Filter psd1 files by ModuleName if provided 49 | $targetPsdFiles = $PsdFiles 50 | if ($ModuleName) { 51 | $targetPsdFiles = $PsdFiles | Where-Object { $_.BaseName -eq $ModuleName } 52 | } 53 | 54 | # Determine current version from the first available file 55 | $currentVersion = $null 56 | if ($targetCsprojFiles.Count -gt 0) { 57 | $currentVersion = Get-CurrentVersionFromCsProj -ProjectFile $targetCsprojFiles[0].FullName 58 | } elseif ($targetPsdFiles.Count -gt 0) { 59 | $currentVersion = Get-CurrentVersionFromPsd1 -ManifestFile $targetPsdFiles[0].FullName 60 | } elseif ($BuildScriptFiles.Count -gt 0) { 61 | $currentVersion = Get-CurrentVersionFromBuildScript -ScriptFile $BuildScriptFiles[0].FullName 62 | } 63 | if (-not $currentVersion) { 64 | Write-Error "Could not determine current version from any project files." 65 | return 66 | } 67 | if (-not [string]::IsNullOrWhiteSpace($NewVersion)) { 68 | $newVersion = $NewVersion 69 | } else { 70 | $newVersion = Update-VersionNumber -Version $currentVersion -Type $VersionType 71 | } 72 | 73 | $CurrentVersions = Get-ProjectVersion -Path $RepoRoot -ExcludeFolders $AllExcludes 74 | $CurrentVersionHash = @{} 75 | foreach ($C in $CurrentVersions) { 76 | $CurrentVersionHash[$C.Source] = $C.Version 77 | } 78 | $Output = @( 79 | foreach ($csProj in $targetCsprojFiles) { 80 | Update-VersionInCsProj -ProjectFile $csProj.FullName -Version $newVersion -WhatIf:$WhatIfPreference -CurrentVersionHash $CurrentVersionHash 81 | } 82 | foreach ($psd1 in $targetPsdFiles) { 83 | Update-VersionInPsd1 -ManifestFile $psd1.FullName -Version $newVersion -WhatIf:$WhatIfPreference -CurrentVersionHash $CurrentVersionHash 84 | } 85 | foreach ($buildScript in $BuildScriptFiles) { 86 | Update-VersionInBuildScript -ScriptFile $buildScript.FullName -Version $newVersion -WhatIf:$WhatIfPreference -CurrentVersionHash $CurrentVersionHash 87 | } 88 | ) 89 | if ($PassThru) { 90 | $Output 91 | } 92 | } -------------------------------------------------------------------------------- /Public/Test-Basic.ps1: -------------------------------------------------------------------------------- 1 | function Test-BasicModule { 2 | [cmdletBinding()] 3 | param( 4 | [string] $Path, 5 | [string] $Type 6 | ) 7 | if ($Type -contains 'Encoding') { 8 | Get-ChildItem -LiteralPath $Path -Recurse -Filter '*.ps1' | Get-Encoding 9 | } 10 | } -------------------------------------------------------------------------------- /Public/Test-ScriptModule.ps1: -------------------------------------------------------------------------------- 1 | function Test-ScriptModule { 2 | [cmdletbinding()] 3 | param( 4 | [string] $ModuleName, 5 | [ValidateSet('Name', 'CommandType', 'ModuleName', 'Source')] $SortName, 6 | [switch] $Unique 7 | ) 8 | $Module = Get-Module -ListAvailable $ModuleName 9 | $Path = Join-Path -Path $Module.ModuleBase -ChildPath $Module.RootModule 10 | $Output = Test-ScriptFile -Path $Path 11 | if ($Unique) { 12 | $Output = $Output | Sort-Object -Property 'Name' -Unique:$Unique 13 | } 14 | if ($SortName) { 15 | $Output | Sort-Object -Property $SortName 16 | } else { 17 | $Output 18 | } 19 | } -------------------------------------------------------------------------------- /Sources/PSPublishModule/PSPublishModule.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.10.35027.167 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PSPublishModule", "PSPublishModule\PSPublishModule.csproj", "{319706C7-84F2-48FE-98A8-F89CABAD50FA}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {319706C7-84F2-48FE-98A8-F89CABAD50FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {319706C7-84F2-48FE-98A8-F89CABAD50FA}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {319706C7-84F2-48FE-98A8-F89CABAD50FA}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {319706C7-84F2-48FE-98A8-F89CABAD50FA}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {FBCF2ABB-4092-4C5F-98E4-8E4B05BB6029} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /Sources/PSPublishModule/PSPublishModule/Initialize.cs: -------------------------------------------------------------------------------- 1 | namespace PSPublishModule; 2 | 3 | /// 4 | /// Dummy class to make the module visible to the module manager. 5 | /// 6 | public class Initialize { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /Sources/PSPublishModule/PSPublishModule/OnImportAndRemove.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Management.Automation; 4 | using System.Reflection; 5 | 6 | public class OnModuleImportAndRemove : IModuleAssemblyInitializer, IModuleAssemblyCleanup { 7 | public void OnImport() { 8 | if (IsNetFramework()) { 9 | AppDomain.CurrentDomain.AssemblyResolve += MyResolveEventHandler; 10 | } 11 | } 12 | 13 | public void OnRemove(PSModuleInfo module) { 14 | if (IsNetFramework()) { 15 | AppDomain.CurrentDomain.AssemblyResolve -= MyResolveEventHandler; 16 | } 17 | } 18 | 19 | private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args) { 20 | //This code is used to resolve the assemblies 21 | //Console.WriteLine($"Resolving {args.Name}"); 22 | var directoryPath = Path.GetDirectoryName(typeof(OnModuleImportAndRemove).Assembly.Location); 23 | var filesInDirectory = Directory.GetFiles(directoryPath); 24 | 25 | foreach (var file in filesInDirectory) { 26 | var fileName = Path.GetFileName(file); 27 | var assemblyName = Path.GetFileNameWithoutExtension(file); 28 | 29 | if (args.Name.StartsWith(assemblyName)) { 30 | //Console.WriteLine($"Loading {args.Name} assembly {fileName}"); 31 | return Assembly.LoadFile(file); 32 | } 33 | } 34 | return null; 35 | } 36 | 37 | private bool IsNetFramework() { 38 | // Get the version of the CLR 39 | Version clrVersion = System.Environment.Version; 40 | // Check if the CLR version is 4.x.x.x 41 | return clrVersion.Major == 4; 42 | } 43 | 44 | private bool IsNetCore() { 45 | return System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription.StartsWith(".NET Core", StringComparison.OrdinalIgnoreCase); 46 | } 47 | 48 | private bool IsNet5OrHigher() { 49 | return System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription.StartsWith(".NET 5", StringComparison.OrdinalIgnoreCase) || 50 | System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription.StartsWith(".NET 6", StringComparison.OrdinalIgnoreCase) || 51 | System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription.StartsWith(".NET 7", StringComparison.OrdinalIgnoreCase) || 52 | System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription.StartsWith(".NET 8", StringComparison.OrdinalIgnoreCase); 53 | } 54 | } -------------------------------------------------------------------------------- /Sources/PSPublishModule/PSPublishModule/PSPublishModule.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net472;netstandard2.0;net8.0 5 | PSPublishModule 6 | PSPublishModule 7 | PSPublishModule 8 | 1.0.0 9 | false 10 | Evotec 11 | Przemyslaw Klys 12 | latest 13 | true 14 | 15 | 16 | 17 | true 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Tests/Build-Module.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe 'Build-Module' { 2 | It 'Create New Module' { 3 | $ModuleName = 'NewTestModule123456' 4 | $Path = "$Env:TEMP\Junk" 5 | 6 | # lets remove junk first if it exists 7 | $FullModulePath = [io.Path]::Combine($Path, $ModuleName) 8 | if (Test-Path -Path $FullModulePath) { 9 | Remove-Item -Path $FullModulePath -Recurse -Force 10 | } 11 | $Exists = Test-Path -Path $FullModulePath 12 | $Exists | Should -BeFalse 13 | 14 | $Exists = Test-Path -Path $FullModulePath 15 | $Exists | Should -BeFalse 16 | 17 | # This deals with OneDrive redirection or similar 18 | $DirectoryModulesCore = "$([Environment]::GetFolderPath([Environment+SpecialFolder]::MyDocuments))\PowerShell\Modules" 19 | $DirectoryModules = "$([Environment]::GetFolderPath([Environment+SpecialFolder]::MyDocuments))\WindowsPowerShell\Modules" 20 | $Desktop = [IO.path]::Combine($DirectoryModules, $ModuleName) 21 | $Core = [IO.path]::Combine($DirectoryModulesCore, $ModuleName) 22 | 23 | if (Test-Path -Path $Desktop) { 24 | Remove-Item -Path $Desktop -Recurse -Force 25 | } 26 | if (Test-Path -Path $Core) { 27 | Remove-Item -Path $Core -Recurse -Force 28 | } 29 | 30 | $Exists = Test-Path -Path $Desktop 31 | $Exists | Should -BeFalse 32 | 33 | $Exists = Test-Path -Path $Core 34 | $Exists | Should -BeFalse 35 | 36 | # lets crete the path to folder as we create it deep in temp 37 | New-Item -Path $Path -ItemType Directory -Force | Out-Null 38 | 39 | # Lets build module 40 | Build-Module -Path $Path -ModuleName $ModuleName 41 | 42 | # lets see if module is created 43 | $Exists = Test-Path -Path $FullModulePath 44 | $Exists | Should -BeTrue 45 | 46 | # lets find if all files are copied 47 | $FilesRelative = "$ModuleName.psd1", "$ModuleName.psm1", "CHANGELOG.MD", ".gitignore", "LICENSE", "README.MD" 48 | foreach ($File in $FilesRelative) { 49 | $FilePath = [io.Path]::Combine($FullModulePath, $File) 50 | $Exists = Test-Path -Path $FilePath 51 | $Exists | Should -BeTrue 52 | 53 | $Item = Get-Item -Path $FilePath 54 | $Item.Length | Should -BeGreaterThan 0 55 | } 56 | $FilesFullPath = [io.path]::Combine($FullModulePath, "Build" , "Build-Module.ps1") 57 | foreach ($File in $FilesFullPath) { 58 | $Exists = Test-Path -Path $File 59 | $Exists | Should -BeTrue 60 | } 61 | $Directories = "Build", "Examples", "Ignore", "Private", 'Public' 62 | foreach ($Directory in $Directories) { 63 | $Exists = Test-Path -Path ([io.Path]::Combine($FullModulePath, $Directory)) -PathType Container 64 | $Exists | Should -BeTrue 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /Tests/Remove-Comments.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe 'Remove-Comments' { 2 | It 'Save to variable' { 3 | $FilePath = "$PSScriptRoot\Input\RemoveCommentsTests.ps1" 4 | $Output = Remove-Comments -SourceFilePath $FilePath 5 | $LineByLine = $Output -split "`r`n" 6 | $LineByLine.Count | Should -Be 71 7 | } 8 | It 'Save to file' { 9 | $FilePath = "$PSScriptRoot\Input\RemoveCommentsTests.ps1" 10 | $OutputFilePath = "$Env:Temp\RemoveCommentsTests1.ps1" 11 | Remove-Item -Path $OutputFilePath -Force -ErrorAction SilentlyContinue 12 | Remove-Comments -SourceFilePath $FilePath -DestinationFilePath $OutputFilePath 13 | $Output = Get-Content -Path $OutputFilePath 14 | $Output.Count | Should -Be 71 15 | } 16 | It 'Save to file - RemoveAllEmptyLines' { 17 | $FilePath = "$PSScriptRoot\Input\RemoveCommentsTests.ps1" 18 | $OutputFilePath = "$Env:Temp\RemoveCommentsTests2.ps1" 19 | Remove-Item -Path $OutputFilePath -Force -ErrorAction SilentlyContinue 20 | Remove-Comments -SourceFilePath $FilePath -DestinationFilePath $OutputFilePath -RemoveAllEmptyLines 21 | $Output = Get-Content -Path $OutputFilePath 22 | $Output.Count | Should -Be 45 23 | } 24 | It 'Save to file - RemoveEmptyLines' { 25 | $FilePath = "$PSScriptRoot\Input\RemoveCommentsTests.ps1" 26 | $OutputFilePath = "$Env:Temp\RemoveCommentsTests3.ps1" 27 | Remove-Item -Path $OutputFilePath -Force -ErrorAction SilentlyContinue 28 | Remove-Comments -SourceFilePath $FilePath -DestinationFilePath $OutputFilePath -RemoveEmptyLines 29 | $Output = Get-Content -Path $OutputFilePath 30 | $Output.Count | Should -Be 57 31 | } 32 | 33 | It 'Save to file - RemoveEmptyLines' { 34 | $FilePath = "$PSScriptRoot\Input\RemoveCommentsTests.ps1" 35 | $OutputFilePath = "$Env:Temp\RemoveCommentsTests4.ps1" 36 | Remove-Item -Path $OutputFilePath -Force -ErrorAction SilentlyContinue 37 | Remove-Comments -SourceFilePath $FilePath -DestinationFilePath $OutputFilePath -RemoveCommentsInParamBlock -RemoveCommentsBeforeParamBlock -RemoveAllEmptyLines 38 | $Output = Get-Content -Path $OutputFilePath 39 | $Output.Count | Should -Be 28 40 | } 41 | } -------------------------------------------------------------------------------- /Tests/Step-Version.Tests.ps1: -------------------------------------------------------------------------------- 1 | Describe 'Step-Version' { 2 | It 'Testing version 0.1.X' { 3 | if (-not (Get-Module -ListAvailable -Name 'PSPublishModule')) { 4 | $ModuleToLoad = "$PSScriptRoot\..\PSPublishModule.psd1" 5 | } else { 6 | $ModuleToLoad = 'PSPublishModule' 7 | } 8 | $Features = Import-Module $ModuleToLoad -PassThru 9 | $Output = & $Features { 10 | Step-Version -Module 'PowerShellManager' -ExpectedVersion '0.1.X' 11 | } 12 | $Output | Should -Be "0.1.3" 13 | } 14 | It "Testing version 0.2.X" { 15 | if (-not (Get-Module -ListAvailable -Name 'PSPublishModule')) { 16 | $ModuleToLoad = "$PSScriptRoot\..\PSPublishModule.psd1" 17 | } else { 18 | $ModuleToLoad = 'PSPublishModule' 19 | } 20 | $Features = Import-Module $ModuleToLoad -PassThru 21 | $Output = & $Features { 22 | Step-Version -Module 'PowerShellManager' -ExpectedVersion '0.2.X' 23 | } 24 | $Output | Should -Be "0.2.0" 25 | } 26 | } --------------------------------------------------------------------------------