├── .build └── tasks │ ├── Build-Module.ModuleBuilder.build.ps1 │ ├── ChocolateyPackage.build.ps1 │ ├── Clean.ModuleBuilder.build.ps1 │ ├── Create_Changelog_Branch.build.ps1 │ ├── Create_Release_Git_Tag.build.ps1 │ ├── DeployAll.PSDeploy.build.ps1 │ ├── DscResource.Test.build.ps1 │ ├── GuestConfig.build.ps1 │ ├── Invoke-Pester.pester.build.ps1 │ ├── JaCoCo.coverage.build.ps1 │ ├── SetPsModulePath.build.ps1 │ ├── generateHelp.PlatyPS.build.ps1 │ └── release.module.build.ps1 ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── General.md │ ├── Problem_with_module.yml │ └── config.yml └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .markdownlint.json ├── .vscode ├── analyzersettings.psd1 ├── launch.json ├── settings.json └── tasks.json ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── GitVersion.yml ├── LICENSE ├── README.md ├── RequiredModules.psd1 ├── Resolve-Dependency.ps1 ├── Resolve-Dependency.psd1 ├── SECURITY.md ├── Sampler ├── Private │ ├── Get-SamplerProjectModuleManifest.ps1 │ └── New-SamplerXmlJaCoCoCounter.ps1 ├── Public │ ├── Add-Sample.ps1 │ ├── Convert-SamplerHashtableToString.ps1 │ ├── Get-BuiltModuleVersion.ps1 │ ├── Get-ClassBasedResourceName.ps1 │ ├── Get-CodeCoverageThreshold.ps1 │ ├── Get-MofSchemaName.ps1 │ ├── Get-OperatingSystemShortName.ps1 │ ├── Get-PesterOutputFileFileName.ps1 │ ├── Get-Psm1SchemaName.ps1 │ ├── Get-SamplerAbsolutePath.ps1 │ ├── Get-SamplerBuildVersion.ps1 │ ├── Get-SamplerBuiltModuleBase.ps1 │ ├── Get-SamplerBuiltModuleManifest.ps1 │ ├── Get-SamplerCodeCoverageOutputFile.ps1 │ ├── Get-SamplerCodeCoverageOutputFileEncoding.ps1 │ ├── Get-SamplerModuleInfo.ps1 │ ├── Get-SamplerModuleRootPath.ps1 │ ├── Get-SamplerProjectName.ps1 │ ├── Get-SamplerSourcePath.ps1 │ ├── Invoke-SamplerGit.ps1 │ ├── Merge-JaCoCoReport.ps1 │ ├── New-SampleModule.ps1 │ ├── New-SamplerJaCoCoDocument.ps1 │ ├── New-SamplerPipeline.ps1 │ ├── Out-SamplerXml.ps1 │ ├── Set-SamplerPSModulePath.ps1 │ ├── Split-ModuleVersion.ps1 │ └── Update-JaCoCoStatistic.ps1 ├── Sampler.psd1 ├── Sampler.psm1 ├── Templates │ ├── Build │ │ ├── CHANGELOG.md.template │ │ ├── CODE_OF_CONDUCT.md │ │ ├── CONTRIBUTING.md │ │ ├── README.md.template │ │ ├── RequiredModules.psd1.template │ │ ├── Resolve-Dependency.ps1 │ │ ├── Resolve-Dependency.psd1.template │ │ ├── SECURITY.dsccommunity.md │ │ ├── SECURITY.generic.md │ │ ├── build.ps1 │ │ ├── build.yaml.template │ │ └── plasterManifest.xml │ ├── ChocolateyPackage │ │ ├── myPackage │ │ │ ├── README.md │ │ │ ├── _TODO.txt │ │ │ ├── mypackage.nuspec.template │ │ │ └── tools │ │ │ │ ├── LICENSE.txt │ │ │ │ ├── VERIFICATION.txt │ │ │ │ ├── chocolateybeforemodify.ps1 │ │ │ │ ├── chocolateyinstall.ps1 │ │ │ │ └── chocolateyuninstall.ps1 │ │ ├── plasterManifest.xml │ │ └── tests │ │ │ └── ChocolateyPackage │ │ │ └── myPackage │ │ │ ├── myPackage.PesterV4.tests.ps1 │ │ │ └── myPackage.PesterV5.tests.ps1 │ ├── ChocolateyPipeline │ │ ├── chocobuild.yml.template │ │ └── plasterManifest.xml │ ├── ClassFolderResource │ │ ├── 1.Ensure.ps1.template │ │ ├── DSC_ClassFolder.ps1 │ │ ├── Private │ │ │ ├── ConvertTo-HashtableFromObject.ps1 │ │ │ ├── Set-FileAttribute.ps1 │ │ │ └── Test-FileAttribute.ps1 │ │ ├── Reason.ps1.template │ │ ├── en-US │ │ │ └── DSC_ClassFolder.strings.psd1 │ │ ├── plasterManifest.xml │ │ └── tests │ │ │ └── Unit │ │ │ ├── ClassResource │ │ │ └── DSC_ClassFolder.tests.ps1 │ │ │ └── Private │ │ │ ├── ConvertTo-HashtableFromObject.tests.ps1 │ │ │ ├── Set-FileAttribute.tests.ps1 │ │ │ └── Test-FileAttribute.tests.ps1 │ ├── ClassResource │ │ ├── 1.Ensure.ps1.template │ │ ├── DSC_ClassResource.ps1.template │ │ ├── Private │ │ │ ├── ConvertTo-HashtableFromObject.ps1 │ │ │ ├── Get-DummyObject.ps1 │ │ │ └── Set-HelpFunctionProperty.ps1 │ │ ├── Reason.ps1.template │ │ ├── en-US │ │ │ └── DSC_ClassResource.strings.psd1.template │ │ ├── plasterManifest.xml │ │ └── tests │ │ │ └── Unit │ │ │ ├── ClassResource │ │ │ └── DSC_ClassResource.tests.ps1.template │ │ │ └── Private │ │ │ └── ConvertTo-HashtableFromObject.tests.ps1.template │ ├── Classes │ │ ├── Classes │ │ │ ├── 1.class1.ps1 │ │ │ ├── 2.class2.ps1 │ │ │ ├── 3.class11.ps1 │ │ │ └── 4.class12.ps1 │ │ ├── plasterManifest.xml │ │ └── tests │ │ │ └── Unit │ │ │ └── Classes │ │ │ ├── class1.tests.ps1 │ │ │ ├── class11.tests.ps1 │ │ │ ├── class12.tests.ps1 │ │ │ └── class2.tests.ps1 │ ├── Composite │ │ ├── Composite.schema.psm1.template │ │ └── plasterManifest.xml │ ├── Enum │ │ ├── Enum.ps1.template │ │ └── plasterManifest.xml │ ├── Examples │ │ ├── README.md │ │ └── Resources │ │ │ └── Folder │ │ │ ├── 1-DscResourceTemplate_CreateFolderAsSystemConfig.ps1 │ │ │ ├── 2-DscResourceTemplate_CreateFolderAsUserConfig.ps1 │ │ │ └── 3-DscResourceTemplate_RemoveFolderConfig.ps1 │ ├── GCPackage │ │ ├── GCPackages │ │ │ └── MyGuestConfigPackage │ │ │ │ └── MyGuestConfigPackage.config.ps1.template │ │ └── plasterManifest.xml │ ├── Git │ │ ├── GitVersion.yml.template │ │ ├── gitattributes │ │ └── gitignore │ ├── GithubConfig │ │ ├── ISSUE_TEMPLATE │ │ │ ├── General.md │ │ │ ├── Problem_with_module.yml.template │ │ │ ├── Problem_with_resource.yml.template │ │ │ ├── Resource_proposal.yml │ │ │ └── config.yml.template │ │ ├── PULL_REQUEST_TEMPLATE.md │ │ ├── PULL_REQUEST_TEMPLATE_dsccommunity.md │ │ └── plasterManifest.xml │ ├── HelperSubModules │ │ ├── Modules │ │ │ └── HelperSubmodule │ │ │ │ └── HelperSubmodule.psm1 │ │ └── plasterManifest.xml │ ├── MofResource │ │ ├── DSC_Folder │ │ │ ├── DSC_Folder.psm1 │ │ │ ├── DSC_Folder.schema.mof │ │ │ └── en-US │ │ │ │ └── DSC_Folder.strings.psd1 │ │ ├── Modules │ │ │ └── Folder.Common │ │ │ │ └── Folder.Common.psm1 │ │ ├── plasterManifest.xml │ │ └── tests │ │ │ └── Unit │ │ │ ├── DSCResources │ │ │ └── DSC_Folder.tests.ps1.template │ │ │ └── Modules │ │ │ └── Folder.Common.tests.ps1 │ ├── PrivateFunction │ │ ├── Get-PrivateFunction.ps1.template │ │ ├── Get-PrivateFunction.tests.ps1.template │ │ └── plasterManifest.xml │ ├── PublicCallPrivateFunctions │ │ └── plasterManifest.xml │ ├── PublicFunction │ │ ├── Get-Something.ps1.template │ │ ├── Get-Something.tests.ps1.template │ │ └── plasterManifest.xml │ ├── Sampler │ │ ├── CHANGELOG.md.template │ │ ├── CODE_OF_CONDUCT.md │ │ ├── CONTRIBUTING.md │ │ ├── Get-PrivateFunction.ps1 │ │ ├── Get-PrivateFunction.tests.ps1.template │ │ ├── Get-Something.ps1 │ │ ├── Get-Something.tests.ps1.template │ │ ├── LICENSES │ │ │ ├── LICENSE.Apache.template │ │ │ └── LICENSE.MIT.template │ │ ├── README.md │ │ ├── README.md.template │ │ ├── README_dsccommunity.md.template │ │ ├── about_ModuleName.help.template │ │ ├── appveyor.yml │ │ ├── azure-pipelines.yml.template │ │ ├── azure-pipelines_dsccommunity.yml.template │ │ ├── codecov.yml.template │ │ ├── kitchen.yml.template │ │ ├── markdownlint.json │ │ ├── module.template │ │ ├── module.tests.ps1.template │ │ └── plasterManifest.xml │ └── VscodeConfig │ │ ├── analyzersettings.psd1 │ │ ├── extensions.json │ │ ├── plasterManifest.xml │ │ ├── settings.json │ │ └── tasks.json ├── WikiSource │ └── Home.md ├── assets │ ├── Sampler_512.png │ └── sampler.svg ├── en-US │ ├── Sampler.strings.psd1 │ └── about_Sampler.help.txt ├── scripts │ └── Set-SamplerTaskVariable.ps1 └── suffix.ps1 ├── azure-pipelines.yml ├── build.ps1 ├── build.yaml ├── codecov.yml └── tests ├── Integration ├── IntegrationTestHelpers.psm1 ├── PlasterTemplates │ ├── Build │ │ └── BuildPlasterTemplate.Integration.Tests.ps1 │ ├── ChocolateyPipeline │ │ └── ChocolateyPipelinePlasterTemplate.Integration.Tests.ps1 │ ├── ClassFolderResource │ │ └── AddClassFolderResource.integration.Tests.ps1 │ ├── ClassResource │ │ └── AddClassResource.integration.Tests.ps1 │ ├── Classes │ │ └── AddClasses.integration.Tests.ps1 │ ├── Composite │ │ └── AddCompositeResource.integration.Tests.ps1 │ ├── Enum │ │ └── AddEnum.integration.Tests.ps1 │ ├── GCPackage │ │ └── GCPackages.integration.Tests.ps1 │ ├── GithubConfig │ │ └── GithubConfigPlasterTemplate.Integration.tests.ps1 │ ├── HelperSubmodules │ │ └── HelperSubmodules.integration.tests.ps1 │ ├── MofResource │ │ └── AddMofResource.integration.Tests.ps1 │ ├── PrivateFunction │ │ └── AddPrivateFunction.integration.Tests.ps1 │ ├── PublicCallPrivateFunctions │ │ └── AddPublicCallPrivateFunctions.integration.Tests.ps1 │ ├── PublicFunction │ │ └── AddPublicFunction.integration.Tests.ps1 │ ├── Sampler │ │ ├── CompleteSamplePlasterTemplate.Integration.Tests.ps1 │ │ ├── CustomModulePlasterTemplate.Integration.Tests.ps1 │ │ ├── DscCommunityPlasterTemplate.Integration.Tests.ps1 │ │ ├── SimpleModuleNoBuildPlasterTemplate.Integration.Tests.ps1 │ │ └── SimpleModulePlasterTemplate.Integration.Tests.ps1 │ └── VscodeConfig │ │ └── VscodeConfigPlasterTemplate.Integration.tests.ps1 ├── ResolveDependencies.Integration.Tests.ps1 ├── SimpleModule.Integration.Tests.ps1 └── Tasks │ └── Set-SamplerTaskVariable.Tests.ps1 ├── QA └── module.tests.ps1 └── Unit ├── Private ├── Get-SamplerProjectModuleManifest.tests.ps1 └── New-SamplerXmlJaCoCoCounter.tests.ps1 ├── Public ├── Add-Sample.tests.ps1 ├── Convert-SamplerHashtableToString.tests.ps1 ├── Get-BuiltModuleVersion.tests.ps1 ├── Get-ClassBasedResourceName.tests.ps1 ├── Get-CodeCoverageThreshold.tests.ps1 ├── Get-MofSchemaName.tests.ps1 ├── Get-OperatingSystemShortName.tests.ps1 ├── Get-PesterOutputFileFileName.tests.ps1 ├── Get-Psm1SchemaName.tests.ps1 ├── Get-SamplerAbsolutePath.tests.ps1 ├── Get-SamplerBuildVersion.tests.ps1 ├── Get-SamplerBuiltModuleBase.tests.ps1 ├── Get-SamplerBuiltModuleManifest.tests.ps1 ├── Get-SamplerCodeCoverageOutputFile.tests.ps1 ├── Get-SamplerCodeCoverageOutputFileEncoding.tests.ps1 ├── Get-SamplerModuleInfo.tests.ps1 ├── Get-SamplerModuleRootPath.tests.ps1 ├── Get-SamplerProjectName.tests.ps1 ├── Get-SamplerSourcePath.tests.ps1 ├── Invoke-SamplerGit.Tests.ps1 ├── Merge-JaCoCoReport.tests.ps1 ├── New-SampleModule.tests.ps1 ├── New-SamplerJaCoCoDocument.tests.ps1 ├── New-SamplerPipeline.tests.ps1 ├── Out-SamplerXml.tests.ps1 ├── Set-SamplerPSModulePath.tests.ps1 ├── Split-ModuleVersion.tests.ps1 └── Update-JaCoCoStatistic.tests.ps1 ├── TestHelpers ├── Get-XmlAttribute.ps1 ├── MockSetSamplerTaskVariable.ps1 └── SetSamplerTaskVariableTestHelpers.psm1 ├── scripts └── Set-SamplerTaskVariable.Tests.ps1 └── tasks ├── Build-Module.ModuleBuilder.build.Tests.ps1 ├── ChocolateyPackage.build.Tests.ps1 ├── Clean.ModuleBuilder.build.Tests.ps1 ├── Create_Changelog_Branch.build.Tests.ps1 ├── Create_Release_Git_Tag.build.Tests.ps1 ├── DeployAll.PSDeploy.build.Tests.ps1 ├── GuestConfig.build.Tests.ps1 ├── Invoke-Pester.pester.build.Tests.ps1 ├── JaCoCo.coverage.build.Tests.ps1 ├── SetPsModulePath.build.Tests.ps1 ├── generateHelp.PlatyPS.build.Tests.ps1 └── release.module.build.Tests.ps1 /.build/tasks/Clean.ModuleBuilder.build.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | # Base directory of all output (default to 'output') 3 | [Parameter()] 4 | [string] 5 | $OutputDirectory = (property OutputDirectory (Join-Path -Path $BuildRoot -ChildPath 'output')), 6 | 7 | [Parameter()] 8 | [string] 9 | $RequiredModulesDirectory = (property RequiredModulesDirectory $(Join-Path -Path $OutputDirectory -ChildPath 'RequiredModules')) 10 | ) 11 | 12 | # Removes the OutputDirectory\modules (errors if Pester is loaded) 13 | task CleanAll Clean, CleanModule 14 | 15 | # Synopsis: Deleting the content of the Build Output folder, except ./modules 16 | task Clean { 17 | $OutputDirectory = Get-SamplerAbsolutePath -Path $OutputDirectory -RelativeTo $BuildRoot 18 | $FolderToExclude = Split-Path -Leaf -Path $RequiredModulesDirectory 19 | 20 | Write-Build -Color Green "Removing $OutputDirectory\* excluding $FolderToExclude" 21 | 22 | Get-ChildItem -Path $OutputDirectory -Exclude $FolderToExclude | Remove-Item -Force -Recurse 23 | } 24 | 25 | # Synopsis: Removes the Modules from OutputDirectory\Modules folder, might fail if there's an handle on one file. 26 | task CleanModule { 27 | $OutputDirectory = Get-SamplerAbsolutePath -Path $OutputDirectory -RelativeTo $BuildRoot 28 | 29 | Write-Build -Color Green "Removing $OutputDirectory\*" 30 | 31 | Get-ChildItem $OutputDirectory | Remove-Item -Force -Recurse -ErrorAction 'Stop' 32 | } 33 | -------------------------------------------------------------------------------- /.build/tasks/DeployAll.PSDeploy.build.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter()] 3 | [string] 4 | $BuildOutput = (property BuildOutput 'output'), 5 | 6 | [Parameter()] 7 | [string] 8 | $ProjectName = (property ProjectName ''), 9 | 10 | [Parameter()] 11 | $DeploymentTags = (property DeploymentTags ''), 12 | 13 | [Parameter()] 14 | $DeployConfig = (property DeployConfig 'Deploy.PSDeploy.ps1') 15 | ) 16 | 17 | # Synopsis: Deploy everything configured in PSDeploy 18 | task Deploy_with_PSDeploy { 19 | if ([System.String]::IsNullOrEmpty($ProjectName)) 20 | { 21 | $ProjectName = Get-SamplerProjectName -BuildRoot $BuildRoot 22 | } 23 | 24 | $BuildOutput = Get-SamplerAbsolutePath -Path $BuildOutput -RelativeTo $BuildRoot 25 | $DeployFile = Get-SamplerAbsolutePath -Path $DeployConfig -RelativeTo $BuildRoot 26 | "Deploying Module based on $DeployConfig config" 27 | 28 | $InvokePSDeployArgs = @{ 29 | Path = $DeployFile 30 | Force = $true 31 | } 32 | 33 | if ($DeploymentTags) 34 | { 35 | $null = $InvokePSDeployArgs.Add('Tags', $DeploymentTags) 36 | } 37 | 38 | Import-Module PSDeploy 39 | Invoke-PSDeploy @InvokePSDeployArgs 40 | } 41 | -------------------------------------------------------------------------------- /.build/tasks/SetPsModulePath.build.ps1: -------------------------------------------------------------------------------- 1 | param 2 | ( 3 | [Parameter()] 4 | [System.String] 5 | $BuiltModuleSubdirectory = (property BuiltModuleSubdirectory ''), 6 | 7 | [Parameter()] 8 | $BuildInfo = (property BuildInfo @{ }) 9 | ) 10 | 11 | <# 12 | Configuring this task in the 'build.yaml' file looks like this: 13 | 14 | SetPSModulePath: 15 | #PSModulePath: C:\Users\Install\OneDrive\Documents\WindowsPowerShell\Modules;C:\Program Files\WindowsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules;c:\Users\Install\.vscode\extensions\ms-vscode.powershell-2022.5.1\modules; 16 | RemovePersonal: true 17 | RemoveProgramFiles: true 18 | RemoveWindows: false 19 | SetSystemDefault: false 20 | #> 21 | 22 | Task Set_PSModulePath { 23 | 24 | . Set-SamplerTaskVariable 25 | 26 | $param = $PSBoundParameters 27 | 28 | $mainConfigurationKey = 'SetPsModulePath' 29 | $configurationKeys = 'PSModulePath', 30 | 'RemovePersonal', 31 | 'RemoveProgramFiles', 32 | 'RemoveWindows', 33 | 'SetSystemDefault', 34 | 'PassThru' 35 | 36 | foreach ($configKey in $configurationKeys) 37 | { 38 | if (-not (Get-Variable -Name $configKey -ValueOnly -ErrorAction SilentlyContinue)) 39 | { 40 | # Variable is not set in context, use $BuildInfo.$mainConfigurationKey.$configKey 41 | $configValue = $BuildInfo.$mainConfigurationKey.$configKey 42 | if ($configValue) 43 | { 44 | $param.$configKey = $configValue 45 | Set-Variable -Name $configKey -Value $configValue 46 | Write-Build DarkGray "`t...Set $configKey to $configValue" 47 | } 48 | } 49 | } 50 | 51 | Set-Variable -Name RequiredModulesDirectory -Value $RequiredModulesDirectory 52 | Set-Variable -Name BuiltModuleSubdirectory -Value $BuiltModuleSubdirectory 53 | 54 | $param.BuiltModuleSubdirectory = $BuiltModuleSubdirectory 55 | $param.RequiredModulesDirectory = $RequiredModulesDirectory 56 | 57 | if ($param.PSModulePath) 58 | { 59 | $param.PSModulePath = $ExecutionContext.InvokeCommand.ExpandString($param.PSModulePath) 60 | } 61 | 62 | $newPSModulePath = Set-SamplerPSModulePath @param -PassThru 63 | Write-Build darkGray "`t...The new 'PSModulePath' is '$newPSModulePath'" 64 | 65 | } 66 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Needed for publishing of examples, build worker defaults to core.autocrlf=input. 2 | * text eol=crlf 3 | 4 | *.svg eol=lf 5 | 6 | # Ensure any exe files are treated as binary 7 | *.exe binary 8 | *.jpg binary 9 | *.xl* binary 10 | *.pfx binary 11 | *.png binary 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/General.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: General question or documentation update 3 | about: If you have a general question or documentation update suggestion around the resource module. 4 | --- 5 | 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: "Virtual PowerShell User Group #DSC channel" 4 | url: https://dsccommunity.org/community/contact/ 5 | about: "To talk to the community and maintainers of Sampler, please visit the #DSC channel." 6 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Pull Request 2 | 3 | 15 | 16 | ## Pull Request (PR) description 17 | 18 | 39 | 40 | ## Task list 41 | 42 | 50 | 51 | - [ ] The PR represents a single logical change. i.e. Cosmetic updates should go in different PRs. 52 | - [ ] Added an entry under the Unreleased section of in the CHANGELOG.md as per [format](https://keepachangelog.com/en/1.0.0/). 53 | - [ ] Local clean build passes without issue or fail tests (`build.ps1 -ResolveDependency`). 54 | - [ ] Documentation added/updated in README.md. 55 | - [ ] Comment-based help added/updated. 56 | - [ ] Localization strings added/updated in all localization files as appropriate. 57 | - [ ] Unit tests added/updated. See [DSC Community Testing Guidelines](https://dsccommunity.org/guidelines/testing-guidelines). 58 | - [ ] Integration tests added/updated (where possible). See [DSC Community Testing Guidelines](https://dsccommunity.org/guidelines/testing-guidelines). 59 | - [ ] New/changed code adheres to [DSC Community Style Guidelines](https://dsccommunity.org/styleguidelines). 60 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | output/* 2 | .kitchen/* 3 | **.bak 4 | .kitchen.local.yml 5 | **.nupkg 6 | 7 | !**/README.md 8 | DscResource.tests 9 | Sampler/Modules/DscResource.Common 10 | -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "default": true, 3 | "MD029": { 4 | "style": "one" 5 | }, 6 | "MD013": true, 7 | "MD024": false, 8 | "MD034": false, 9 | "no-hard-tabs": true 10 | } 11 | -------------------------------------------------------------------------------- /.vscode/analyzersettings.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | CustomRulePath = '.\output\RequiredModules\DscResource.AnalyzerRules' 3 | includeDefaultRules = $true 4 | IncludeRules = @( 5 | # DSC Resource Kit style guideline rules. 6 | 'PSAvoidDefaultValueForMandatoryParameter', 7 | 'PSAvoidDefaultValueSwitchParameter', 8 | 'PSAvoidInvokingEmptyMembers', 9 | 'PSAvoidNullOrEmptyHelpMessageAttribute', 10 | 'PSAvoidUsingCmdletAliases', 11 | 'PSAvoidUsingComputerNameHardcoded', 12 | 'PSAvoidUsingDeprecatedManifestFields', 13 | 'PSAvoidUsingEmptyCatchBlock', 14 | 'PSAvoidUsingInvokeExpression', 15 | 'PSAvoidUsingPositionalParameters', 16 | 'PSAvoidShouldContinueWithoutForce', 17 | 'PSAvoidUsingWMICmdlet', 18 | 'PSAvoidUsingWriteHost', 19 | 'PSDSCReturnCorrectTypesForDSCFunctions', 20 | 'PSDSCStandardDSCFunctionsInResource', 21 | 'PSDSCUseIdenticalMandatoryParametersForDSC', 22 | 'PSDSCUseIdenticalParametersForDSC', 23 | 'PSMisleadingBacktick', 24 | 'PSMissingModuleManifestField', 25 | 'PSPossibleIncorrectComparisonWithNull', 26 | 'PSProvideCommentHelp', 27 | 'PSReservedCmdletChar', 28 | 'PSReservedParams', 29 | 'PSUseApprovedVerbs', 30 | 'PSUseCmdletCorrectly', 31 | 'PSUseOutputTypeCorrectly', 32 | 'PSAvoidGlobalVars', 33 | 'PSAvoidUsingConvertToSecureStringWithPlainText', 34 | 'PSAvoidUsingPlainTextForPassword', 35 | 'PSAvoidUsingUsernameAndPasswordParams', 36 | 'PSDSCUseVerboseMessageInDSCResource', 37 | 'PSShouldProcess', 38 | 'PSUseDeclaredVarsMoreThanAssignments', 39 | 'PSUsePSCredentialType', 40 | 41 | 'Measure-*' 42 | ) 43 | 44 | } 45 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "PowerShell: Interactive Session", 9 | "type": "PowerShell", 10 | "request": "launch" 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "powershell.codeFormatting.openBraceOnSameLine": false, 3 | "powershell.codeFormatting.newLineAfterOpenBrace": true, 4 | "powershell.codeFormatting.newLineAfterCloseBrace": true, 5 | "powershell.codeFormatting.whitespaceBeforeOpenBrace": true, 6 | "powershell.codeFormatting.whitespaceBeforeOpenParen": true, 7 | "powershell.codeFormatting.whitespaceAroundOperator": true, 8 | "powershell.codeFormatting.whitespaceAfterSeparator": true, 9 | "powershell.codeFormatting.ignoreOneLineBlock": false, 10 | "powershell.codeFormatting.pipelineIndentationStyle": "IncreaseIndentationAfterEveryPipeline", 11 | "powershell.codeFormatting.preset": "Custom", 12 | "powershell.codeFormatting.alignPropertyValuePairs": true, 13 | "powershell.codeFormatting.addWhitespaceAroundPipe": true, 14 | "powershell.codeFormatting.useCorrectCasing": true, 15 | "powershell.codeFormatting.autoCorrectAliases": true, 16 | "powershell.integratedConsole.showOnStartup": true, 17 | "powershell.developer.bundledModulesPath": "${cwd}/output/RequiredModules", 18 | "powershell.scriptAnalysis.settingsPath": ".vscode\\analyzersettings.psd1", 19 | "powershell.scriptAnalysis.enable": true, 20 | "files.trimTrailingWhitespace": true, 21 | "files.trimFinalNewlines": true, 22 | "files.insertFinalNewline": true, 23 | "files.associations": { 24 | "*.ps1xml": "xml" 25 | }, 26 | "cSpell.words": [ 27 | "COMPANYNAME", 28 | "ICONURI", 29 | "LICENSEURI", 30 | "PROJECTURI", 31 | "RELEASENOTES", 32 | "buildhelpers", 33 | "endregion", 34 | "gitversion", 35 | "icontains", 36 | "keepachangelog", 37 | "notin", 38 | "pscmdlet", 39 | "steppable" 40 | ], 41 | "[markdown]": { 42 | "files.trimTrailingWhitespace": false, 43 | "files.encoding": "utf8" 44 | }, 45 | "powershell.pester.useLegacyCodeLens": false, 46 | "pester.testFilePath": [ 47 | "[tT]ests/[uU]nit/*/*.[tT]ests.[pP][sS]1" 48 | "[tT]ests/[qQ][aA]/*.[tT]ests.[pP][sS]1" 49 | ], 50 | "pester.runTestsInNewProcess": false, 51 | "pester.pesterModulePath": "./output/RequiredModules/Pester", 52 | "powershell.pester.codeLens": true, 53 | "pester.suppressCodeLensNotice": true 54 | } 55 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | This project has adopted the [DSC Community Code of Conduct](https://dsccommunity.org/code_of_conduct). 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Please check out common DSC Community [contributing guidelines](https://dsccommunity.org/guidelines/contributing). 4 | 5 | If you want to contribute code to this repository and is new to contributing 6 | on GitHub then start with the guide [Getting Started as a Contributor](https://dsccommunity.org/guidelines/getting-started/). 7 | 8 | ## Running the Tests 9 | 10 | If want to know how to run this module's tests you can look at the [Testing Guidelines](https://dsccommunity.org/guidelines/testing-guidelines/#running-tests). 11 | -------------------------------------------------------------------------------- /GitVersion.yml: -------------------------------------------------------------------------------- 1 | mode: ContinuousDelivery 2 | next-version: 0.90 3 | major-version-bump-message: '\s?(breaking|major|breaking\schange)' 4 | minor-version-bump-message: '(adds?|features?|minor)\b' 5 | patch-version-bump-message: '\s?(fix|patch)' 6 | no-bump-message: '\+semver:\s?(none|skip)' 7 | assembly-informational-format: '{NuGetVersionV2}+Sha.{Sha}.Date.{CommitDate}' 8 | branches: 9 | master: 10 | tag: preview 11 | regex: ^main$ 12 | pull-request: 13 | tag: PR 14 | feature: 15 | tag: useBranchName 16 | increment: Minor 17 | regex: f(eature(s)?)?[\/-] 18 | source-branches: ['master'] 19 | hotfix: 20 | tag: fix 21 | increment: Patch 22 | regex: (hot)?fix(es)?[\/-] 23 | source-branches: ['master'] 24 | 25 | ignore: 26 | sha: [] 27 | merge-message-formats: {} 28 | 29 | 30 | # feature: 31 | # tag: useBranchName 32 | # increment: Minor 33 | # regex: f(eature(s)?)?[/-] 34 | # source-branches: ['master'] 35 | # hotfix: 36 | # tag: fix 37 | # increment: Patch 38 | # regex: (hot)?fix(es)?[/-] 39 | # source-branches: ['master'] 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Gael Colas 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. 22 | -------------------------------------------------------------------------------- /RequiredModules.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | <# 3 | This is only required if you need to use the method PowerShellGet & PSDepend 4 | It is not required for PSResourceGet or ModuleFast (and will be ignored). 5 | See Resolve-Dependency.psd1 on how to enable methods. 6 | #> 7 | #PSDependOptions = @{ 8 | # AddToPath = $true 9 | # Target = 'output\RequiredModules' 10 | # Parameters = @{ 11 | # Repository = 'PSGallery' 12 | # } 13 | #} 14 | 15 | InvokeBuild = 'latest' 16 | PSScriptAnalyzer = 'latest' 17 | Pester = 'latest' 18 | Plaster = 'latest' 19 | ModuleBuilder = 'latest' 20 | MarkdownLinkCheck = 'latest' 21 | ChangelogManagement = 'latest' 22 | 'Sampler.GitHubTasks' = 'latest' 23 | 'DscResource.Test' = 'latest' 24 | 'DscResource.AnalyzerRules' = 'latest' 25 | xDscResourceDesigner = 'latest' 26 | PlatyPS = 'latest' 27 | 'DscResource.DocGenerator' = 'latest' 28 | } 29 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | ## Security 2 | 3 | We take the security of our modules seriously, which includes all source 4 | code repositories managed through our GitHub organization. 5 | 6 | If you believe you have found a security vulnerability in this repository, 7 | please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | The repository has enabled the ability to report a security vulnerability 12 | through GitHub new issue (separate button called "Report a vulnerability"). 13 | See [Privately reporting a security vulnerability](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability) 14 | for more information. 15 | 16 | > [!CAUTION] 17 | > Please do not report security vulnerabilities through a **public** GitHub issues 18 | > or other public forum. 19 | 20 | You should receive a response within 48 hours. If for some reason you do not, 21 | please follow up privately to one or several maintainers of the repository. 22 | The easiest way to do so is to send us a direct message via Twitter (X), 23 | Slack, Discord, or find us on some other social platform. 24 | 25 | Please include the requested information listed below (as much as you can 26 | provide) to help us better understand the nature and scope of the possible issue: 27 | 28 | * Type of issue 29 | * Full paths of source file(s) related to the manifestation of the issue 30 | * The location of the affected source code (tag/branch/commit or direct URL) 31 | * Any special configuration required to reproduce the issue 32 | * Step-by-step instructions to reproduce the issue 33 | * Proof-of-concept or exploit code (if possible) 34 | * Impact of the issue, including how an attacker might exploit the issue 35 | 36 | This information will help us triage your report more quickly. 37 | 38 | ## Preferred Languages 39 | 40 | We prefer all communications to be in English. 41 | -------------------------------------------------------------------------------- /Sampler/Private/Get-SamplerProjectModuleManifest.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Gets the path to the Module manifest in the source folder. 5 | 6 | .DESCRIPTION 7 | This command finds the Module Manifest of the current Sampler project, 8 | regardless of the name of the source folder (src, source, or MyProjectName). 9 | It looks for psd1 that are not build.psd1 or analyzersettings, 1 folder under 10 | the $BuildRoot, and where a property ModuleVersion is set. 11 | 12 | This allows to deduct the Module name's from that module Manifest. 13 | 14 | .PARAMETER BuildRoot 15 | Root folder where the build is called, usually the root of the repository. 16 | 17 | .EXAMPLE 18 | Get-SamplerProjectModuleManifest -BuildRoot . 19 | 20 | #> 21 | function Get-SamplerProjectModuleManifest 22 | { 23 | [CmdletBinding()] 24 | [OutputType([System.IO.FileInfo])] 25 | param 26 | ( 27 | [Parameter(Mandatory = $true)] 28 | [System.String] 29 | $BuildRoot 30 | ) 31 | 32 | $excludeFiles = @( 33 | 'build.psd1' 34 | 'analyzersettings.psd1' 35 | ) 36 | 37 | $moduleManifestItem = Get-ChildItem -Path "$BuildRoot\*\*.psd1" -Exclude $excludeFiles | 38 | Where-Object -FilterScript { 39 | ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and 40 | $(Test-ModuleManifest -Path $_.FullName -ErrorAction 'SilentlyContinue' ).Version 41 | } 42 | 43 | if ($moduleManifestItem.Count -gt 1) 44 | { 45 | throw ("Found more than one project folder containing a module manifest, please make sure there are only one; `n Manifest: {0}" -f ($moduleManifestItem.FullName -join "`n Manifest: ")) 46 | } 47 | else 48 | { 49 | return $moduleManifestItem 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Sampler/Private/New-SamplerXmlJaCoCoCounter.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Returns a new JaCoCo XML counter node with the specified covered and missed 5 | attributes. 6 | 7 | .DESCRIPTION 8 | Returns a new JaCoCo XML counter node with the specified covered and missed 9 | attributes. 10 | 11 | .PARAMETER XmlNode 12 | The XML node that the element should be part appended to as a child. 13 | 14 | .PARAMETER CounterType 15 | The JaCoCo counter type. 16 | 17 | .PARAMETER Covered 18 | The number of covered lines to be used as the value for the covered XML 19 | attribute. 20 | 21 | .PARAMETER Missed 22 | The number of missed lines to be used as the value for the missed XML 23 | attribute. 24 | 25 | .PARAMETER PassThru 26 | Returns the element that was created. 27 | 28 | .EXAMPLE 29 | New-SamplerXmlJaCoCoCounter -XmlDocument $myXml -CounterType 'CLASS' -Covered 1 -Missed 2 30 | #> 31 | function New-SamplerXmlJaCoCoCounter 32 | { 33 | [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] 34 | [CmdletBinding()] 35 | [OutputType([System.Xml.XmlElement])] 36 | param 37 | ( 38 | [Parameter(Mandatory = $true)] 39 | [System.Xml.XmlNode] 40 | $XmlNode, 41 | 42 | [Parameter(Mandatory = $true)] 43 | [ValidateSet('CLASS', 'LINE', 'METHOD', 'INSTRUCTION')] 44 | [System.String] 45 | $CounterType, 46 | 47 | [Parameter()] 48 | [System.UInt32] 49 | $Covered = 0, 50 | 51 | [Parameter()] 52 | [System.UInt32] 53 | $Missed = 0, 54 | 55 | [Parameter()] 56 | [System.Management.Automation.SwitchParameter] 57 | $PassThru 58 | 59 | ) 60 | 61 | $xmlElement = $XmlNode.OwnerDocument.CreateElement('counter') 62 | 63 | $xmlElement.SetAttribute('type', $CounterType) 64 | $xmlElement.SetAttribute('missed', $Missed) 65 | $xmlElement.SetAttribute('covered', $Covered) 66 | 67 | $XmlNode.AppendChild($xmlElement) | Out-Null 68 | 69 | if ($PassThru.IsPresent) 70 | { 71 | return $xmlElement 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Sampler/Public/Convert-SamplerHashtableToString.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Converts an Hashtable to its string representation, recursively. 5 | 6 | .DESCRIPTION 7 | Convert an Hashtable to a string representation. 8 | For instance, this hashtable: 9 | @{a=1;b=2; c=3; d=@{dd='abcd'}} 10 | Becomes: 11 | a=1; b=2; c=3; d={dd=abcd} 12 | 13 | .PARAMETER Hashtable 14 | Hashtable to convert to string. 15 | 16 | .EXAMPLE 17 | Convert-SamplerhashtableToString -Hashtable @{a=1;b=2; c=3; d=@{dd='abcd'}} 18 | 19 | .NOTES 20 | This command is not specific to Sampler projects, but is named that way 21 | to avoid conflict with other modules. 22 | #> 23 | function Convert-SamplerHashtableToString 24 | { 25 | param 26 | ( 27 | [Parameter()] 28 | [System.Collections.Hashtable] 29 | $Hashtable 30 | ) 31 | $values = @() 32 | foreach ($pair in $Hashtable.GetEnumerator()) 33 | { 34 | if ($pair.Value -is [System.Array]) 35 | { 36 | $str = "$($pair.Key)=($($pair.Value -join ","))" 37 | } 38 | elseif ($pair.Value -is [System.Collections.Hashtable]) 39 | { 40 | $str = "$($pair.Key)={$(Convert-SamplerHashtableToString -Hashtable $pair.Value)}" 41 | } 42 | else 43 | { 44 | $str = "$($pair.Key)=$($pair.Value)" 45 | } 46 | $values += $str 47 | } 48 | 49 | [array]::Sort($values) 50 | return ($values -join "; ") 51 | } 52 | -------------------------------------------------------------------------------- /Sampler/Public/Get-BuiltModuleVersion.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Get the module version from the module built by Sampler. 5 | 6 | .DESCRIPTION 7 | Will read the ModuleVersion and PrivateData.PSData.Prerelease tag of the Module Manifest 8 | that has been built by Sampler, by looking into the OutputDirectory where the Project's 9 | Module should have been built. 10 | 11 | .PARAMETER OutputDirectory 12 | Output directory (usually as defined by the Project). 13 | By default it is set to 'output' in a Sampler project. 14 | 15 | .PARAMETER BuiltModuleSubdirectory 16 | Sub folder where you want to build the Module to (instead of $OutputDirectory/$ModuleName). 17 | This is especially useful when you want to build DSC Resources, but you don't want the 18 | `Get-DscResource` command to find several instances of the same DSC Resources because 19 | of the overlapping $Env:PSmodulePath (`$buildRoot/output` for the built module and `$buildRoot/output/RequiredModules`). 20 | 21 | In most cases I would recommend against setting $BuiltModuleSubdirectory. 22 | 23 | .PARAMETER VersionedOutputDirectory 24 | Whether the Module is built with its versioned Subdirectory, as you would see it on a System. 25 | For instance, if VersionedOutputDirectory is $true, the built module's ModuleBase would be: `output/MyModuleName/2.0.1/` 26 | 27 | .PARAMETER ModuleName 28 | Name of the Module to retrieve the version from its manifest (See Get-SamplerProjectName). 29 | 30 | .EXAMPLE 31 | Get-BuiltModuleVersion -OutputDirectory 'output' -ProjectName Sampler 32 | 33 | #> 34 | function Get-BuiltModuleVersion 35 | { 36 | [CmdletBinding()] 37 | [OutputType([System.String])] 38 | param 39 | ( 40 | [Parameter(Mandatory = $true)] 41 | [ValidateNotNull()] 42 | [System.String] 43 | $OutputDirectory, 44 | 45 | [Parameter()] 46 | [AllowNull()] 47 | [System.String] 48 | $BuiltModuleSubdirectory, 49 | 50 | [Parameter(Mandatory = $true)] 51 | [Alias('ProjectName')] 52 | [System.String] 53 | $ModuleName, 54 | 55 | [Parameter()] 56 | [System.Management.Automation.SwitchParameter] 57 | $VersionedOutputDirectory 58 | ) 59 | 60 | $BuiltModuleManifestPath = Get-SamplerBuiltModuleManifest @PSBoundParameters 61 | 62 | Write-Verbose -Message ( 63 | "Get the module version from module manifest in path '{0}'." -f $BuiltModuleManifestPath 64 | ) 65 | 66 | $moduleInfo = Import-PowerShellDataFile -Path $BuiltModuleManifestPath -ErrorAction 'Stop' 67 | 68 | $ModuleVersion = $moduleInfo.ModuleVersion 69 | 70 | if ($moduleInfo.PrivateData.PSData.Prerelease) 71 | { 72 | $ModuleVersion = $ModuleVersion + '-' + $moduleInfo.PrivateData.PSData.Prerelease 73 | } 74 | 75 | $moduleVersionParts = Split-ModuleVersion -ModuleVersion $ModuleVersion 76 | 77 | Write-Verbose -Message ( 78 | "Current module version is '{0}'." -f $moduleVersionParts.ModuleVersion 79 | ) 80 | 81 | return $moduleVersionParts.ModuleVersion 82 | } 83 | -------------------------------------------------------------------------------- /Sampler/Public/Get-ClassBasedResourceName.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Get the Names of the Class-based DSC Resources defined in a file using AST. 5 | 6 | .DESCRIPTION 7 | This command returns all Class-based Resource Names in a file, 8 | by parsing the file and looking for classes with the [DscResource()] attribute. 9 | 10 | For MOF-based DSC Resources, look at the `Get-MofSchemaName` function. 11 | 12 | .PARAMETER Path 13 | Path of the file to parse and search the Class-Based DSC Resources. 14 | 15 | .EXAMPLE 16 | Get-ClassBasedResourceName -Path source/Classes/MyDscResource.ps1 17 | 18 | Get-ClassBasedResourceName -Path (Join-Path -Path (Get-Module MyResourceModule).ModuleBase -ChildPath (Get-Module MyResourceModule).RootModule) 19 | 20 | #> 21 | function Get-ClassBasedResourceName 22 | { 23 | [CmdletBinding()] 24 | [OutputType([String[]])] 25 | param 26 | ( 27 | [Parameter(Mandatory = $true)] 28 | [Alias('FilePath')] 29 | [System.String] 30 | $Path 31 | ) 32 | 33 | $ast = [System.Management.Automation.Language.Parser]::ParseFile($Path, [ref]$null, [ref]$null) 34 | 35 | $classDefinition = $ast.FindAll( 36 | { 37 | ($args[0].GetType().Name -like "TypeDefinitionAst") -and ` 38 | ($args[0].Attributes.TypeName.Name -contains 'DscResource') 39 | }, 40 | $true 41 | ) 42 | 43 | return $classDefinition.Name 44 | 45 | } 46 | -------------------------------------------------------------------------------- /Sampler/Public/Get-CodeCoverageThreshold.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Gets the CodeCoverageThreshod from Runtime parameter or from BuildInfo. 5 | 6 | .DESCRIPTION 7 | This function will override the CodeCoverageThreshold by the value 8 | provided at runtime if any. 9 | 10 | .PARAMETER RuntimeCodeCoverageThreshold 11 | Runtime value for the Pester CodeCoverageThreshold (can be $null). 12 | 13 | .PARAMETER BuildInfo 14 | BuildInfo object as defined by the Build.yml. 15 | 16 | .EXAMPLE 17 | Get-CodeCoverageThreshold -RuntimeCodeCoverageThreshold 0 18 | 19 | #> 20 | function Get-CodeCoverageThreshold 21 | { 22 | [CmdletBinding()] 23 | [OutputType([System.String])] 24 | param 25 | ( 26 | [Parameter()] 27 | [System.String] 28 | [AllowNull()] 29 | $RuntimeCodeCoverageThreshold, 30 | 31 | [Parameter()] 32 | [PSObject] 33 | $BuildInfo 34 | ) 35 | 36 | # If no codeCoverageThreshold configured at runtime, look for BuildInfo settings. 37 | if ([String]::IsNullOrEmpty($RuntimeCodeCoverageThreshold)) 38 | { 39 | if ($BuildInfo -and $BuildInfo.ContainsKey('Pester') -and $BuildInfo.Pester.ContainsKey('CodeCoverageThreshold')) 40 | { 41 | $codeCoverageThreshold = $BuildInfo.Pester.CodeCoverageThreshold 42 | 43 | Write-Debug -Message "Loaded Code Coverage Threshold from Config file: $codeCoverageThreshold %." 44 | } 45 | elseif ($BuildInfo -and $BuildInfo.ContainsKey('Pester') -and $BuildInfo.Pester.ContainsKey('Configuration') -and $BuildInfo.Pester.Configuration.CodeCoverage.CoveragePercentTarget) 46 | { 47 | $codeCoverageThreshold = $BuildInfo.Pester.Configuration.CodeCoverage.CoveragePercentTarget 48 | 49 | Write-Debug -Message "Loaded Code Coverage Threshold from Config file in Pester advanced configuration: $codeCoverageThreshold %." 50 | } 51 | else 52 | { 53 | $codeCoverageThreshold = 0 54 | 55 | Write-Debug -Message "No code coverage threshold value found (param nor config), using the default value." 56 | } 57 | } 58 | else 59 | { 60 | $codeCoverageThreshold = [int] $RuntimeCodeCoverageThreshold 61 | 62 | Write-Debug -Message "Loading CodeCoverage Threshold from Parameter ($codeCoverageThreshold %)." 63 | } 64 | 65 | return $codeCoverageThreshold 66 | } 67 | -------------------------------------------------------------------------------- /Sampler/Public/Get-OperatingSystemShortName.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Returns the Platform name. 5 | 6 | .DESCRIPTION 7 | Gets whether the platform is Windows, Linux or MacOS. 8 | 9 | .EXAMPLE 10 | Get-OperatingSystemShortName # no Parameter needed 11 | 12 | .NOTES 13 | General notes 14 | #> 15 | function Get-OperatingSystemShortName 16 | { 17 | [CmdletBinding()] 18 | param () 19 | 20 | $osShortName = if ($IsWindows -or $PSVersionTable.PSVersion.Major -le 5) 21 | { 22 | 'Windows' 23 | } 24 | elseif ($IsMacOS) 25 | { 26 | 'MacOS' 27 | } 28 | else 29 | { 30 | 'Linux' 31 | } 32 | 33 | return $osShortName 34 | } 35 | -------------------------------------------------------------------------------- /Sampler/Public/Get-PesterOutputFileFileName.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Gets a descriptive file name to be used as Pester Output file name. 5 | 6 | .DESCRIPTION 7 | Creates a file name to be used as Pester Output xml file composed like so: 8 | "${ProjectName}_v${ModuleVersion}.${OsShortName}.${PowerShellVersion}.xml" 9 | 10 | .PARAMETER ProjectName 11 | Name of the Project or module being built. 12 | 13 | .PARAMETER ModuleVersion 14 | Module Version currently defined (including pre-release but without the metadata). 15 | 16 | .PARAMETER OsShortName 17 | Platform name either Windows, Linux, or MacOS. 18 | 19 | .PARAMETER PowerShellVersion 20 | Version of PowerShell the tests have been running on. 21 | 22 | .EXAMPLE 23 | Get-PesterOutputFileFileName -ProjectName 'Sampler' -ModuleVersion 0.110.4-preview001 -OsShortName Windows -PowerShellVersion 5.1 24 | 25 | .NOTES 26 | General notes 27 | #> 28 | function Get-PesterOutputFileFileName 29 | { 30 | param 31 | ( 32 | [Parameter(Mandatory = $true)] 33 | [System.String] 34 | $ProjectName, 35 | 36 | [Parameter(Mandatory = $true)] 37 | [System.String] 38 | $ModuleVersion, 39 | 40 | [Parameter(Mandatory = $true)] 41 | [System.String] 42 | $OsShortName, 43 | 44 | [Parameter(Mandatory = $true)] 45 | [System.String] 46 | $PowerShellVersion 47 | ) 48 | 49 | return '{0}_v{1}.{2}.{3}.xml' -f $ProjectName, $ModuleVersion, $OsShortName, $PowerShellVersion 50 | } 51 | -------------------------------------------------------------------------------- /Sampler/Public/Get-Psm1SchemaName.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Gets the Name of composite DSC resources from their *.schema.psm1 file. 4 | 5 | .DESCRIPTION 6 | This function looks within a composite DSC resource's *.schema.psm1 file 7 | to find the name and friendly name of the class. 8 | 9 | .PARAMETER Path 10 | Path to the DSC Resource *.schema.psm1 file. 11 | 12 | .EXAMPLE 13 | Get-Psm1SchemaName -Path Source/DSCResources/MyCompositeResource/MyCompositeResource.schema.psm1 14 | 15 | #> 16 | 17 | function Get-Psm1SchemaName 18 | { 19 | [CmdletBinding()] 20 | [OutputType([string[]])] 21 | param 22 | ( 23 | [Parameter( 24 | Mandatory = $true, 25 | ValueFromPipeline = $true 26 | )] 27 | [System.String] 28 | $Path 29 | ) 30 | 31 | process 32 | { 33 | $rawContent = Get-Content -Path $Path -Raw 34 | $parseErrors = $null 35 | $tokens = $null 36 | 37 | $ast = [System.Management.Automation.Language.Parser]::ParseInput($rawContent, [ref]$tokens, [ref]$parseErrors) 38 | $configurations = $ast.FindAll( { $args[0] -is [System.Management.Automation.Language.ConfigurationDefinitionAst] }, $true) 39 | 40 | if ($configurations.Count -ne 1) 41 | { 42 | Write-Error "It is expected to find only 1 configuration in the file '$Path' but found $($configurations.Count)" 43 | } 44 | else 45 | { 46 | Write-Verbose "Found Configuration '$($configurations[0].InstanceName)'" 47 | $configurations[0].InstanceName.Value 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /Sampler/Public/Get-SamplerBuiltModuleManifest.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Get the module manifest from a module built by Sampler. 5 | 6 | .DESCRIPTION 7 | Based on a project's OutputDirectory, BuiltModuleSubdirectory, 8 | ModuleName and whether the built module is within a VersionedOutputDirectory; 9 | this function will resolve the expected ModuleManifest of that Module. 10 | 11 | .PARAMETER OutputDirectory 12 | Output directory (usually as defined by the Project). 13 | By default it is set to 'output' in a Sampler project. 14 | 15 | .PARAMETER BuiltModuleSubdirectory 16 | Sub folder where you want to build the Module to (instead of $OutputDirectory/$ModuleName). 17 | This is especially useful when you want to build DSC Resources, but you don't want the 18 | `Get-DscResource` command to find several instances of the same DSC Resources because 19 | of the overlapping $Env:PSmodulePath (`$buildRoot/output` for the built module and `$buildRoot/output/RequiredModules`). 20 | 21 | In most cases I would recommend against setting $BuiltModuleSubdirectory. 22 | 23 | .PARAMETER ModuleName 24 | Name of the Module to retrieve the version from its manifest (See Get-SamplerProjectName). 25 | 26 | .PARAMETER VersionedOutputDirectory 27 | Whether the Module is built with its versioned Subdirectory, as you would see it on a System. 28 | For instance, if VersionedOutputDirectory is $true, the built module's ModuleBase would be: `output/MyModuleName/2.0.1/` 29 | 30 | .PARAMETER ModuleVersion 31 | Allows to specify a specific ModuleVersion to search the ModuleBase if known. 32 | If the ModuleVersion is not known but the VersionedOutputDirectory is set to $true, 33 | a wildcard (*) will be used so that the path can be resolved by Get-Item or similar commands. 34 | 35 | .EXAMPLE 36 | Get-SamplerBuiltModuleManifest -OutputDirectory C:\src\output -BuiltModuleSubdirectory 'Module' -ModuleName 'stuff' -ModuleVersion 3.1.2-preview001 37 | # C:\src\output\Module\stuff\3.1.2\stuff.psd1 38 | 39 | .NOTES 40 | See Get-SamplerBuiltModuleBase as this command only extrapolates the Manifest file from the 41 | Build module base, using the ModuleName parameter. 42 | #> 43 | function Get-SamplerBuiltModuleManifest 44 | { 45 | [CmdletBinding()] 46 | [OutputType([System.String])] 47 | param 48 | ( 49 | [Parameter(Mandatory = $true)] 50 | [ValidateNotNull()] 51 | [System.String] 52 | $OutputDirectory, 53 | 54 | [Parameter()] 55 | [AllowNull()] 56 | [System.String] 57 | $BuiltModuleSubdirectory, 58 | 59 | [Parameter(Mandatory = $true)] 60 | [Alias('ProjectName')] 61 | [ValidateNotNull()] 62 | [System.String] 63 | $ModuleName, 64 | 65 | [Parameter()] 66 | [System.Management.Automation.SwitchParameter] 67 | $VersionedOutputDirectory, 68 | 69 | [Parameter()] 70 | [System.String] 71 | $ModuleVersion = '*' 72 | ) 73 | 74 | $BuiltModuleBase = Get-SamplerBuiltModuleBase @PSBoundParameters 75 | 76 | Get-SamplerAbsolutePath -Path ('{0}.psd1' -f $ModuleName) -RelativeTo $BuiltModuleBase 77 | } 78 | -------------------------------------------------------------------------------- /Sampler/Public/Get-SamplerCodeCoverageOutputFile.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Resolves the CodeCoverage output file path from the project's BuildInfo. 5 | 6 | .DESCRIPTION 7 | When the Pester CodeCoverageOutputFile is configured in the 8 | buildinfo (aka Build.yml), this function will expand the path 9 | (if it contains variables), and resolve to it's absolute path if needed. 10 | 11 | .PARAMETER BuildInfo 12 | The BuildInfo object represented in the Build.yml. 13 | 14 | .PARAMETER PesterOutputFolder 15 | The Pester output folder (that can be overridden at runtime). 16 | 17 | .EXAMPLE 18 | Get-SamplerCodeCoverageOutputFile -BuildInfo $buildInfo -PesterOuputFolder 'C:\src\MyModule\Output\testResults 19 | 20 | #> 21 | function Get-SamplerCodeCoverageOutputFile 22 | { 23 | [CmdletBinding()] 24 | param 25 | ( 26 | [Parameter(Mandatory = $true)] 27 | [PSObject] 28 | $BuildInfo, 29 | 30 | [Parameter(Mandatory = $true)] 31 | [System.String] 32 | $PesterOutputFolder 33 | ) 34 | 35 | $codeCoverageOutputFile = $null 36 | 37 | if ($BuildInfo.ContainsKey('Pester') -and $BuildInfo.Pester.ContainsKey('CodeCoverageOutputFile')) 38 | { 39 | $codeCoverageOutputFile = $ExecutionContext.InvokeCommand.ExpandString($BuildInfo.Pester.CodeCoverageOutputFile) 40 | } 41 | elseif ($BuildInfo.ContainsKey('Pester') -and $BuildInfo.Pester.ContainsKey('Configuration') -and $BuildInfo.Pester.Configuration.CodeCoverage.OutputPath) 42 | { 43 | $codeCoverageOutputFile = $ExecutionContext.InvokeCommand.ExpandString($BuildInfo.Pester.Configuration.CodeCoverage.OutputPath) 44 | } 45 | 46 | if (-not [System.String]::IsNullOrEmpty($codeCoverageOutputFile)) 47 | { 48 | if (-not (Split-Path -Path $codeCoverageOutputFile -IsAbsolute)) 49 | { 50 | $codeCoverageOutputFile = Join-Path -Path $PesterOutputFolder -ChildPath $codeCoverageOutputFile 51 | 52 | Write-Debug -Message "Absolute path to code coverage output file is $codeCoverageOutputFile." 53 | } 54 | } 55 | else 56 | { 57 | # Make sure to return the value as $null if it for some reason was set to an empty string. 58 | $codeCoverageOutputFile = $null 59 | } 60 | 61 | return $codeCoverageOutputFile 62 | } 63 | -------------------------------------------------------------------------------- /Sampler/Public/Get-SamplerCodeCoverageOutputFileEncoding.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Returns the Configured encoding for Pester code coverage file from BuildInfo. 5 | 6 | .DESCRIPTION 7 | This function returns the CodeCoverageOutputFileEncoding (Pester v5+) as 8 | configured in the BuildInfo (build.yml). 9 | 10 | .PARAMETER BuildInfo 11 | Build Configuration object as defined in the Build.yml. 12 | 13 | .EXAMPLE 14 | Get-SamplerCodeCoverageOutputFileEncoding -BuildInfo $buildInfo 15 | 16 | #> 17 | function Get-SamplerCodeCoverageOutputFileEncoding 18 | { 19 | [CmdletBinding()] 20 | param 21 | ( 22 | [Parameter(Mandatory = $true)] 23 | [PSObject] 24 | $BuildInfo 25 | ) 26 | 27 | if ($BuildInfo.ContainsKey('Pester') -and $BuildInfo.Pester.ContainsKey('CodeCoverageOutputFileEncoding')) 28 | { 29 | $codeCoverageOutputFileEncoding = $BuildInfo.Pester.CodeCoverageOutputFileEncoding 30 | } 31 | else 32 | { 33 | $codeCoverageOutputFileEncoding = $null 34 | } 35 | 36 | return $codeCoverageOutputFileEncoding 37 | } 38 | -------------------------------------------------------------------------------- /Sampler/Public/Get-SamplerModuleInfo.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Loads the PowerShell data file of a module manifest. 5 | 6 | .DESCRIPTION 7 | This function loads a psd1 (usually a module manifest), and return the hashtable. 8 | This implementation works around the issue where Windows PowerShell version have issues 9 | with the pwsh $Env:PSModulePath such as in vscode with the vscode powershell extension. 10 | 11 | .PARAMETER ModuleManifestPath 12 | Path to the ModuleManifest to load. This will not use Import-Module because the 13 | module may not be finished building, and might be missing some information to make 14 | it a valid module manifest. 15 | 16 | .EXAMPLE 17 | Get-SamplerModuleInfo -ModuleManifestPath C:\src\MyProject\output\MyProject\MyProject.psd1 18 | 19 | #> 20 | function Get-SamplerModuleInfo 21 | { 22 | [CmdletBinding()] 23 | [OutputType([hashtable])] 24 | param 25 | ( 26 | [Parameter(Mandatory = $true)] 27 | [Alias('Path')] 28 | [ValidateNotNull()] 29 | [System.String] 30 | $ModuleManifestPath 31 | ) 32 | 33 | $isImportPowerShellDataFileAvailable = Get-Command -Name Import-PowerShellDataFile -ErrorAction SilentlyContinue 34 | 35 | if ($PSversionTable.PSversion.Major -le 5 -and -not $isImportPowerShellDataFileAvailable) 36 | { 37 | Import-Module -Name Microsoft.PowerShell.Utility -RequiredVersion 3.1.0.0 38 | } 39 | 40 | Import-PowerShellDataFile -Path $ModuleManifestPath -ErrorAction 'Stop' 41 | } 42 | -------------------------------------------------------------------------------- /Sampler/Public/Get-SamplerModuleRootPath.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Gets the absolute ModuleRoot path (the psm1) of a module. 5 | 6 | .DESCRIPTION 7 | This function reads the module manifest (.psd1) and if the ModuleRoot property 8 | is defined, it will resolve its absolute path based on the ModuleManifest's Path. 9 | 10 | If no ModuleRoot is defined, then this function will return $null. 11 | 12 | .PARAMETER ModuleManifestPath 13 | The path (relative to the current working directory or absolute) to the ModuleManifest to 14 | read to find the ModuleRoot. 15 | 16 | .EXAMPLE 17 | Get-SamplerModuleRootPath -ModuleManifestPath C:\src\MyModule\output\MyModule\2.3.4\MyModule.psd1 18 | # C:\src\MyModule\output\MyModule\2.3.4\MyModule.psm1 19 | 20 | #> 21 | function Get-SamplerModuleRootPath 22 | { 23 | [CmdletBinding()] 24 | [OutputType([System.String])] 25 | param 26 | ( 27 | [Parameter(Mandatory = $true)] 28 | [Alias('Path')] 29 | [ValidateNotNull()] 30 | [System.String] 31 | $ModuleManifestPath 32 | ) 33 | 34 | $moduleInfo = Get-SamplerModuleInfo @PSBoundParameters 35 | 36 | if ($moduleInfo.Keys -contains 'RootModule') 37 | { 38 | Get-SamplerAbsolutePath -Path $moduleInfo.RootModule -RelativeTo (Split-Path -Parent -Path $ModuleManifestPath) 39 | } 40 | else 41 | { 42 | return $null 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Sampler/Public/Get-SamplerProjectName.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Gets the Project Name based on the ModuleManifest if Available. 5 | 6 | .DESCRIPTION 7 | Finds the Module Manifest through `Get-SamplerProjectModuleManifest` 8 | and deduce ProjectName based on the BaseName of that manifest. 9 | 10 | .PARAMETER BuildRoot 11 | BuildRoot of the Sampler project to search the Module manifest from. 12 | 13 | .EXAMPLE 14 | Get-SamplerProjectName -BuildRoot 'C:\src\MyModule' 15 | 16 | #> 17 | function Get-SamplerProjectName 18 | { 19 | [CmdletBinding()] 20 | [OutputType([System.String])] 21 | param 22 | ( 23 | [Parameter(Mandatory = $true)] 24 | [System.String] 25 | $BuildRoot 26 | ) 27 | 28 | return (Get-SamplerProjectModuleManifest -BuildRoot $BuildRoot).BaseName 29 | } 30 | -------------------------------------------------------------------------------- /Sampler/Public/Get-SamplerSourcePath.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Gets the project's source Path based on the ModuleManifest location. 5 | 6 | .DESCRIPTION 7 | By finding the ModuleManifest of the project using `Get-SamplerProjectModuleManifest` 8 | this function assumes that the source folder is the parent folder of 9 | that module manifest. 10 | This allows the source folder to be src, source, or the Module name's, without 11 | hardcoding the name. 12 | 13 | .PARAMETER BuildRoot 14 | BuildRoot of the Sampler project to search the Module manifest from. 15 | 16 | .EXAMPLE 17 | Get-SamplerSourcePath -BuildRoot 'C:\src\MyModule' 18 | 19 | #> 20 | function Get-SamplerSourcePath 21 | { 22 | [CmdletBinding()] 23 | [OutputType([System.String])] 24 | param 25 | ( 26 | [Parameter(Mandatory = $true)] 27 | [System.String] 28 | $BuildRoot 29 | ) 30 | 31 | $SamplerProjectModuleManifest = Get-SamplerProjectModuleManifest -BuildRoot $BuildRoot 32 | $samplerSrcPathToTest = Join-Path -Path $BuildRoot -ChildPath 'src' 33 | $samplerSourcePathToTest = Join-Path -Path $BuildRoot -ChildPath 'source' 34 | 35 | if ($null -ne $SamplerProjectModuleManifest) 36 | { 37 | return $SamplerProjectModuleManifest.Directory.FullName 38 | } 39 | elseif ($null -eq $SamplerProjectModuleManifest -and (Test-Path -Path $samplerSourcePathToTest)) 40 | { 41 | Write-Debug -Message ('The ''source'' path ''{0}'' was found.' -f $samplerSourcePathToTest) 42 | return $samplerSourcePathToTest 43 | } 44 | elseif ($null -eq $SamplerProjectModuleManifest -and (Test-Path -Path $samplerSrcPathToTest)) 45 | { 46 | Write-Debug -Message ('The ''src'' path ''{0}'' was found.' -f $samplerSrcPathToTest) 47 | return $samplerSrcPathToTest 48 | } 49 | else 50 | { 51 | throw 'Module Source Path not found.' 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Sampler/Public/Invoke-SamplerGit.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Executes git with the provided arguments. 4 | 5 | .DESCRIPTION 6 | This command executes git with the provided arguments and throws an error 7 | if the call failed. 8 | 9 | .PARAMETER Argument 10 | Specifies the arguments to call git with. It is passes as an array of strings, 11 | e.g. @('tag', 'v2.0.0'). 12 | 13 | .EXAMPLE 14 | Invoke-SamplerGit -Argument @('config', 'user.name', 'MyName') 15 | 16 | Calls git to set user name in the git config. 17 | 18 | .NOTES 19 | Git does not throw an error that can be caught by the pipeline. For example 20 | this git command error but does not throw 'hello' as one would expect. 21 | ``` 22 | PS> try { git describe --contains } catch { throw 'hello' } 23 | fatal: cannot describe '144e0422398e89cc8451ebba738c0a410b628302' 24 | ``` 25 | So we have to determine if git worked or not by checking the last exit code 26 | and then throw an error to stop the pipeline. 27 | #> 28 | function Invoke-SamplerGit 29 | { 30 | param 31 | ( 32 | [Parameter(Mandatory = $true)] 33 | [System.String[]] 34 | $Argument 35 | ) 36 | 37 | # The catch is triggered only if 'git' can't be found. 38 | try 39 | { 40 | & git $Argument 41 | } 42 | catch 43 | { 44 | throw $_ 45 | } 46 | 47 | <# 48 | This will trigger an error if git returned an error code from the above 49 | execution. Git will also have outputted an error message to the console 50 | so we just need to throw a generic error. 51 | #> 52 | if ($LASTEXITCODE) 53 | { 54 | throw "git returned exit code $LASTEXITCODE indicated failure." 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Sampler/Public/Out-SamplerXml.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Outputs an XML document to a file. 5 | 6 | .DESCRIPTION 7 | Outputs an XML document to the file specified in the parameter Path. 8 | 9 | .PARAMETER XmlDocument 10 | The XML document to format. 11 | 12 | .PARAMETER Path 13 | The path to the file name to write to. 14 | 15 | .PARAMETER Encoding 16 | Specifies the encoding for the file. 17 | 18 | .EXAMPLE 19 | Out-SamplerXml -Path 'C:\temp\my.xml' -XmlDocument '' -Encoding 'UTF8' 20 | #> 21 | function Out-SamplerXml 22 | { 23 | [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] 24 | [CmdletBinding()] 25 | param 26 | ( 27 | [Parameter(Mandatory = $true)] 28 | [System.Xml.XmlDocument] 29 | $XmlDocument, 30 | 31 | [Parameter(Mandatory = $true)] 32 | [System.String] 33 | $Path, 34 | 35 | [Parameter()] 36 | [ValidateSet('ASCII', 'BigEndianUnicode', 'Default', 'Latin1', 'Unicode', 'UTF32', 'UTF7', 'UTF8')] 37 | [System.String] 38 | $Encoding = 'UTF8' 39 | ) 40 | 41 | $xmlSettings = New-Object -TypeName 'System.Xml.XmlWriterSettings' 42 | 43 | $xmlSettings.Encoding = [System.Text.Encoding]::$Encoding 44 | 45 | $xmlWriter = [System.Xml.XmlWriter]::Create($Path, $xmlSettings) 46 | 47 | $XmlDocument.Save($xmlWriter) 48 | 49 | $XmlWriter.Flush() 50 | $xmlWriter.Close() 51 | } 52 | -------------------------------------------------------------------------------- /Sampler/Public/Split-ModuleVersion.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Parse a SemVer2 Version string. 5 | 6 | .DESCRIPTION 7 | This function parses a SemVer (semver.org) version string into an object 8 | with the following properties: 9 | - Version: The version without tag or metadata, as used by folder versioning in PowerShell modules. 10 | - PreReleaseString: A Publish-Module compliant prerelease tag (see below). 11 | - ModuleVersion: The Version and Prerelease tag compliant with Publish-Module. 12 | 13 | For instance, this is a valid SemVer: `1.15.0-pr0224-0022+Sha.47ae45eb2cfed02b249f239a7c55e5c71b26ab76.Date.2020-01-07` 14 | The Metadata is stripped: `1.15.0-pr0224-0022` 15 | The Version is `1.15.0`. 16 | The prerelease tag is `-pr0224-0022` 17 | However, Publish-Module (or NuGet/PSGallery) does not support such pre-release, 18 | so this function only keep the first part `-pr0224` 19 | 20 | .PARAMETER ModuleVersion 21 | Full SemVer version string with (optional) metadata and prerelease tag to be parsed. 22 | 23 | .EXAMPLE 24 | Split-ModuleVersion -ModuleVersion '1.15.0-pr0224-0022+Sha.47ae45eb2cfed02b249f239a7c55e5c71b26ab76.Date.2020-01-07' 25 | 26 | # Version PreReleaseString ModuleVersion 27 | # ------- ---------------- ------------- 28 | # 1.15.0 pr0224 1.15.0-pr0224 29 | 30 | #> 31 | function Split-ModuleVersion 32 | { 33 | [CmdletBinding()] 34 | [OutputType([System.Management.Automation.PSCustomObject])] 35 | param 36 | ( 37 | [Parameter()] 38 | [System.String] 39 | $ModuleVersion 40 | ) 41 | 42 | <# 43 | This handles a previous version of the module that suggested to pass 44 | a version string with metadata in the CI pipeline that can look like 45 | this: 1.15.0-pr0224-0022+Sha.47ae45eb2cfed02b249f239a7c55e5c71b26ab76.Date.2020-01-07 46 | #> 47 | $ModuleVersion = ($ModuleVersion -split '\+', 2)[0] 48 | 49 | $moduleVersion, $preReleaseString = $ModuleVersion -split '-', 2 50 | 51 | <# 52 | The cmldet Publish-Module does not yet support semver compliant 53 | pre-release strings. If the prerelease string contains a dash ('-') 54 | then the dash and everything behind is removed. For example 55 | 'pr54-0012' is parsed to 'pr54'. 56 | #> 57 | $validPreReleaseString, $preReleaseStringSuffix = $preReleaseString -split '-' 58 | 59 | if ($validPreReleaseString) 60 | { 61 | $fullModuleVersion = $moduleVersion + '-' + $validPreReleaseString 62 | } 63 | else 64 | { 65 | $fullModuleVersion = $moduleVersion 66 | } 67 | 68 | $moduleVersionParts = [PSCustomObject]@{ 69 | Version = $moduleVersion 70 | PreReleaseString = $validPreReleaseString 71 | ModuleVersion = $fullModuleVersion 72 | } 73 | 74 | return $moduleVersionParts 75 | } 76 | -------------------------------------------------------------------------------- /Sampler/Sampler.psm1: -------------------------------------------------------------------------------- 1 | # This file is not needed, a COMPILED version will be built by ModuleBuilder 2 | ##Import Enum 3 | 4 | foreach ($Enum in (Get-ChildItem "$PSScriptRoot\Enum" -ErrorAction SilentlyContinue)) 5 | { 6 | . $Enum 7 | } 8 | 9 | ##Import Classes 10 | 11 | foreach ($class in (Get-ChildItem "$PSScriptRoot\Classes" -ErrorAction SilentlyContinue)) 12 | { 13 | . $Class 14 | } 15 | 16 | #Get public and private function definition files. 17 | $Public = @( Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -ErrorAction SilentlyContinue ) 18 | $Private = @( Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -ErrorAction SilentlyContinue ) 19 | 20 | #Dot source the files 21 | foreach ($import in @($Public + $Private)) 22 | { 23 | try 24 | { 25 | Write-Verbose "Importing $($Import.FullName)" 26 | . $import.FullName 27 | } 28 | catch 29 | { 30 | Write-Error -Message "Failed to import function $($import.fullName): $_" 31 | } 32 | } 33 | 34 | Export-ModuleMember -Function $Public.Basename 35 | -------------------------------------------------------------------------------- /Sampler/Templates/Build/CHANGELOG.md.template: -------------------------------------------------------------------------------- 1 | <% 2 | "# Changelog for ${PLASTER_PARAM_ProjectName}" 3 | %> 4 | 5 | The format is based on and uses the types of changes according to [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [Unreleased] 9 | 10 | ### Added 11 | 12 | - For new features. 13 | 14 | ### Changed 15 | 16 | - For changes in existing functionality. 17 | 18 | ### Deprecated 19 | 20 | - For soon-to-be removed features. 21 | 22 | ### Removed 23 | 24 | - For now removed features. 25 | 26 | ### Fixed 27 | 28 | - For any bug fix. 29 | 30 | ### Security 31 | 32 | - In case of vulnerabilities. 33 | -------------------------------------------------------------------------------- /Sampler/Templates/Build/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | This project has adopted the [DSC Community Code of Conduct](https://dsccommunity.org/code_of_conduct). 4 | -------------------------------------------------------------------------------- /Sampler/Templates/Build/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Please check out common DSC Community [contributing guidelines](https://dsccommunity.org/guidelines/contributing). 4 | 5 | If you want to contribute code to this repository and is new to contributing 6 | on GitHub then start with the guide [Getting Started as a Contributor](https://dsccommunity.org/guidelines/getting-started/). 7 | 8 | ## Running the Tests 9 | 10 | If want to know how to run this module's tests you can look at the [Testing Guidelines](https://dsccommunity.org/guidelines/testing-guidelines/#running-tests). 11 | -------------------------------------------------------------------------------- /Sampler/Templates/Build/README.md.template: -------------------------------------------------------------------------------- 1 | <% 2 | @" 3 | # {0} 4 | 5 | {1} 6 | 7 | ## Make it yours 8 | 9 | --- 10 | Generated with Plaster and the Sampler template 11 | 12 | "@ -f $PLASTER_PARAM_ProjectName,$PLASTER_PARAM_ModuleDescription 13 | %> 14 | 15 | This is a sample Readme 16 | -------------------------------------------------------------------------------- /Sampler/Templates/Build/RequiredModules.psd1.template: -------------------------------------------------------------------------------- 1 | @{ 2 | <# 3 | This is only required if you need to use the method PowerShellGet & PSDepend 4 | It is not required for PSResourceGet or ModuleFast (and will be ignored). 5 | See Resolve-Dependency.psd1 on how to enable methods. 6 | #> 7 | #PSDependOptions = @{ 8 | # AddToPath = $true 9 | # Target = 'output\RequiredModules' 10 | # Parameters = @{ 11 | <% 12 | if (-not [System.String]::IsNullOrEmpty($PLASTER_PARAM_CustomRepo)) { 13 | # Pull Modules from Custom Repository Name 14 | " # Repository = '$PLASTER_PARAM_CustomRepo'" 15 | } 16 | else { 17 | " # Repository = 'PSGallery'" 18 | } 19 | %> 20 | # } 21 | #} 22 | 23 | InvokeBuild = 'latest' 24 | PSScriptAnalyzer = 'latest' 25 | Pester = 'latest' 26 | ModuleBuilder = 'latest' 27 | ChangelogManagement = 'latest' 28 | Sampler = 'latest' 29 | <% 30 | If ($PLASTER_PARAM_ModuleType -in @('dsccommunity','CompleteSample','CompleteModule') -or $PLASTER_PARAM_UseGitHub -eq 'true' -or $PLASTER_PARAM_Features -Contains ('All') -or $PLASTER_PARAM_Features -Contains ('DSCResources')) { 31 | @" 32 | 'Sampler.GitHubTasks' = 'latest' 33 | "@ 34 | } 35 | %> 36 | <% 37 | If ($PLASTER_PARAM_ModuleType -in @('dsccommunity','CompleteSample','CompleteModule') -or $PLASTER_PARAM_Features -Contains ('All') -or $PLASTER_PARAM_Features -Contains ('DSCResources')) { 38 | @" 39 | MarkdownLinkCheck = 'latest' 40 | "@ 41 | } 42 | %> 43 | <% 44 | If ($PLASTER_PARAM_ModuleType -in @('dsccommunity','CompleteSample') -or $PLASTER_PARAM_Features -Contains ('All') -or $PLASTER_PARAM_Features -Contains ('DSCResources')) { 45 | @" 46 | 'DscResource.Common' = 'latest' 47 | 'DscResource.Test' = 'latest' 48 | 'DscResource.AnalyzerRules' = 'latest' 49 | xDscResourceDesigner = 'latest' 50 | 'DscResource.DocGenerator' = 'latest' 51 | "@ 52 | } 53 | %> 54 | } 55 | -------------------------------------------------------------------------------- /Sampler/Templates/Build/SECURITY.dsccommunity.md: -------------------------------------------------------------------------------- 1 | ## Security 2 | 3 | The DSC Community takes the security of our modules seriously, which 4 | includes all source code repositories managed through our GitHub organization. 5 | 6 | If you believe you have found a security vulnerability in any DSC Community 7 | owned repository, please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | If the repository has enabled the ability to report a security vulnerability 12 | through GitHub new issue (separate button called "Report a vulnerability") 13 | then use that. See [Privately reporting a security vulnerability](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability) 14 | for more information. 15 | 16 | > [!CAUTION] 17 | > Please do not report security vulnerabilities through a **public** GitHub issues 18 | > or other public forum. 19 | 20 | If the repository does not have that option then please report the security 21 | issue privately to one or several maintainers of the repository, or several 22 | members of the DSC Community organization. The easiest way to do so is to 23 | send us a direct message via Twitter (X), Slack, Discord, or find us on some 24 | other social platform. 25 | 26 | You should receive a response within 48 hours. If for some reason you do not, 27 | please follow up to other member of the community. 28 | 29 | Please include the requested information listed below (as much as you can 30 | provide) to help us better understand the nature and scope of the possible issue: 31 | 32 | * Type of issue 33 | * Full paths of source file(s) related to the manifestation of the issue 34 | * The location of the affected source code (tag/branch/commit or direct URL) 35 | * Any special configuration required to reproduce the issue 36 | * Step-by-step instructions to reproduce the issue 37 | * Proof-of-concept or exploit code (if possible) 38 | * Impact of the issue, including how an attacker might exploit the issue 39 | 40 | This information will help us triage your report more quickly. 41 | 42 | ## Preferred Languages 43 | 44 | We prefer all communications to be in English. 45 | -------------------------------------------------------------------------------- /Sampler/Templates/Build/SECURITY.generic.md: -------------------------------------------------------------------------------- 1 | ## Security 2 | 3 | We take the security of our modules seriously, which includes all source 4 | code repositories managed through our GitHub organization. 5 | 6 | If you believe you have found a security vulnerability in any of our 7 | repository, please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | If the repository has enabled the ability to report a security vulnerability 12 | through GitHub new issue (separate button called "Report a vulnerability") 13 | then use that. See [Privately reporting a security vulnerability](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability) 14 | for more information. 15 | 16 | > [!CAUTION] 17 | > Please do not report security vulnerabilities through a **public** GitHub issues 18 | > or other public forum. 19 | 20 | If the repository does not have that option then please 21 | report the security issue privately to one or several maintainers of the 22 | repository. The easiest way to do so is to send us a direct message via 23 | Twitter (X), Slack, Discord, or find us on some other social platform. 24 | 25 | You should receive a response within 48 hours. If for some reason you do not, 26 | please follow up by other means or to other contributors. 27 | 28 | Please include the requested information listed below (as much as you can 29 | provide) to help us better understand the nature and scope of the possible issue: 30 | 31 | * Type of issue 32 | * Full paths of source file(s) related to the manifestation of the issue 33 | * The location of the affected source code (tag/branch/commit or direct URL) 34 | * Any special configuration required to reproduce the issue 35 | * Step-by-step instructions to reproduce the issue 36 | * Proof-of-concept or exploit code (if possible) 37 | * Impact of the issue, including how an attacker might exploit the issue 38 | 39 | This information will help us triage your report more quickly. 40 | 41 | ## Preferred Languages 42 | 43 | We prefer all communications to be in English. 44 | -------------------------------------------------------------------------------- /Sampler/Templates/ChocolateyPackage/myPackage/tools/LICENSE.txt: -------------------------------------------------------------------------------- 1 |  2 | Note: Include this file if including binaries you have the right to distribute. 3 | Otherwise delete. this file. 4 | 5 | ===DELETE ABOVE THIS LINE AND THIS LINE=== 6 | 7 | From: 8 | 9 | LICENSE 10 | 11 | 12 | -------------------------------------------------------------------------------- /Sampler/Templates/ChocolateyPackage/myPackage/tools/VERIFICATION.txt: -------------------------------------------------------------------------------- 1 |  2 | Note: Include this file if including binaries you have the right to distribute. 3 | Otherwise delete. this file. If you are the software author, you can change this 4 | mention you are the author of the software. 5 | 6 | ===DELETE ABOVE THIS LINE AND THIS LINE=== 7 | 8 | VERIFICATION 9 | Verification is intended to assist the Chocolatey moderators and community 10 | in verifying that this package's contents are trustworthy. 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sampler/Templates/ChocolateyPackage/myPackage/tools/chocolateybeforemodify.ps1: -------------------------------------------------------------------------------- 1 | # This runs in 0.9.10+ before upgrade and uninstall. 2 | # Use this file to do things like stop services prior to upgrade or uninstall. 3 | # NOTE: It is an anti-pattern to call chocolateyUninstall.ps1 from here. If you 4 | # need to uninstall an MSI prior to upgrade, put the functionality in this 5 | # file without calling the uninstall script. Make it idempotent in the 6 | # uninstall script so that it doesn't fail when it is already uninstalled. 7 | # NOTE: For upgrades - like the uninstall script, this script always runs from 8 | # the currently installed version, not from the new upgraded package version. 9 | -------------------------------------------------------------------------------- /Sampler/Templates/ChocolateyPackage/tests/ChocolateyPackage/myPackage/myPackage.PesterV4.tests.ps1: -------------------------------------------------------------------------------- 1 | # Check package XML 2 | # - packageName is valid (no space, prefer -) 3 | # - version is valid 4 | # - URL is valid (PackageSourceUrl, projectUrl, iconUrl, licenseUrl, docsUrl, bugTrackerUrl) 5 | # - validate dependencies (otpional) 6 | # - If the chocolatey*ps1 use Get-UninstallRegistryKey or Get-PP... validate that choco extension 1.1.0 is present 7 | # - validate the files that get packaged 8 | -------------------------------------------------------------------------------- /Sampler/Templates/ChocolateyPackage/tests/ChocolateyPackage/myPackage/myPackage.PesterV5.tests.ps1: -------------------------------------------------------------------------------- 1 | # Check package XML 2 | # - packageName is valid (no space, prefer -) 3 | # - version is valid 4 | # - URL is valid (PackageSourceUrl, projectUrl, iconUrl, licenseUrl, docsUrl, bugTrackerUrl) 5 | # - validate dependencies (otpional) 6 | # - If the chocolatey*ps1 use Get-UninstallRegistryKey or Get-PP... validate that choco extension 1.1.0 is present 7 | # - validate the files that get packaged 8 | -------------------------------------------------------------------------------- /Sampler/Templates/ClassFolderResource/1.Ensure.ps1.template: -------------------------------------------------------------------------------- 1 | enum Ensure 2 | { 3 | Absent 4 | Present 5 | } 6 | -------------------------------------------------------------------------------- /Sampler/Templates/ClassFolderResource/Private/ConvertTo-HashtableFromObject.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Convert any object to hashtable 4 | 5 | .PARAMETER InputObject 6 | The object that should convert to hashtable. 7 | #> 8 | function ConvertTo-HashtableFromObject 9 | { 10 | [CmdletBinding()] 11 | [OutputType([Hashtable])] 12 | param 13 | ( 14 | [Parameter(Mandatory = $true,ValueFromPipeline=$true)] 15 | [PSObject] 16 | $InputObject 17 | ) 18 | $hashResult = @{} 19 | 20 | $InputObject.psobject.Properties | Foreach-Object { 21 | $hashResult[$_.Name] = $_.Value 22 | } 23 | 24 | return $hashResult 25 | 26 | } 27 | -------------------------------------------------------------------------------- /Sampler/Templates/ClassFolderResource/Private/Set-FileAttribute.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Sets or removes an attribute on a folder. 5 | 6 | .PARAMETER Folder 7 | The System.IO.DirectoryInfo object of the folder that should have the 8 | attribute set or removed. 9 | 10 | .PARAMETER Attribute 11 | The name of the attribute from the enum System.IO.FileAttributes. 12 | 13 | .PARAMETER Enabled 14 | If the attribute should be enabled or disabled. 15 | #> 16 | function Set-FileAttribute 17 | { 18 | [CmdletBinding()] 19 | [OutputType([System.IO.DirectoryInfo])] 20 | param 21 | ( 22 | [Parameter(Mandatory = $true)] 23 | [System.IO.DirectoryInfo] 24 | $Folder, 25 | 26 | [Parameter(Mandatory = $true)] 27 | [System.IO.FileAttributes] 28 | $Attribute, 29 | 30 | [Parameter(Mandatory = $true)] 31 | [System.Boolean] 32 | $Enabled 33 | ) 34 | 35 | switch ($Enabled) 36 | { 37 | $true 38 | { 39 | $Folder.Attributes = $Folder.Attributes -bor [System.IO.FileAttributes]$Attribute 40 | } 41 | 42 | $false 43 | { 44 | $Folder.Attributes = $Folder.Attributes -bxor [System.IO.FileAttributes]$Attribute 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Sampler/Templates/ClassFolderResource/Private/Test-FileAttribute.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Test if an attribute on a folder is present. 5 | 6 | .PARAMETER Folder 7 | The System.IO.DirectoryInfo object of the folder that should be checked 8 | for the attribute. 9 | 10 | .PARAMETER Attribute 11 | The name of the attribute from the enum System.IO.FileAttributes. 12 | #> 13 | function Test-FileAttribute 14 | { 15 | [CmdletBinding()] 16 | [OutputType([System.Boolean])] 17 | param 18 | ( 19 | [Parameter(Mandatory = $true)] 20 | [System.IO.DirectoryInfo] 21 | $Folder, 22 | 23 | [Parameter(Mandatory = $true)] 24 | [System.IO.FileAttributes] 25 | $Attribute 26 | ) 27 | 28 | $attributeValue = $Folder.Attributes -band [System.IO.FileAttributes]::$Attribute 29 | $isPresent = $false 30 | 31 | if ($attributeValue -gt 0 ) 32 | { 33 | $isPresent = $true 34 | } 35 | 36 | return $isPresent 37 | } 38 | -------------------------------------------------------------------------------- /Sampler/Templates/ClassFolderResource/Reason.ps1.template: -------------------------------------------------------------------------------- 1 | class Reason 2 | { 3 | [DscProperty()] 4 | [string] $Phrase 5 | 6 | [DscProperty()] 7 | [string] $Code 8 | } 9 | -------------------------------------------------------------------------------- /Sampler/Templates/ClassFolderResource/en-US/DSC_ClassFolder.strings.psd1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | The localized resource strings in English (en-US) for the 4 | resource DSC_CLassFolder. 5 | #> 6 | 7 | ConvertFrom-StringData @' 8 | RetrieveFolder = Retrieving folder information of '{0}'. 9 | FolderFound = Folder was found, evaluating all properties. 10 | FolderNotFound = Folder was not found. 11 | CreateFolder = Creating folder '{0}'. 12 | EvaluateProperties = Evaluating properties of folder '{0}'. 13 | SettingProperties = Setting properties to correct values of folder '{0}'. 14 | RemoveFolder = Removing folder '{0}'. 15 | FolderFoundShouldBeNot = Folder {0} was found, but should be absent. 16 | DontBeReadOnly = Folder should be {0} for ReadOnly attribute, but he is {1}. 17 | DontBeHidden = Folder should be {0} for Hidden attribute, but he is {1}. 18 | '@ 19 | -------------------------------------------------------------------------------- /Sampler/Templates/ClassFolderResource/tests/Unit/Private/ConvertTo-HashtableFromObject.tests.ps1: -------------------------------------------------------------------------------- 1 | $ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path 2 | $ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object { 3 | ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and 4 | $(try { Test-ModuleManifest $_.FullName -ErrorAction Stop }catch{$false}) } 5 | ).BaseName 6 | 7 | Import-Module $ProjectName 8 | 9 | InModuleScope $ProjectName { 10 | 11 | Describe 'Helper function ConvertTo-HashtableFromObject' { 12 | BeforeAll { 13 | $mockAttribute = 'ReadOnly' 14 | $script:mockFolderObjectPath = Join-Path -Path $TestDrive -ChildPath 'FolderTest' 15 | $script:mockFolderObject = New-Item -Path $script:mockFolderObjectPath -ItemType 'Directory' -Force 16 | $script:mockFolderObject.Attributes = [System.IO.FileAttributes]::$mockAttribute 17 | } 18 | 19 | BeforeEach{ 20 | $script:instance = [DSC_ClassFolder]::new() 21 | $script:instance.Path = $script:mockFolderObjectPath 22 | $script:instance.Ensure = [Ensure]::Present 23 | } 24 | 25 | Context 'When instance of class is convert to hashtable' { 26 | BeforeEach { 27 | 28 | } 29 | It 'Should not Throw' { 30 | {$script:convertHashtable = $script:instance | ConvertTo-HashtableFromObject} | Should -Not -Throw 31 | } 32 | 33 | It 'Should be a Hashtable' { 34 | $script:convertHashtable | Should -BeOfType [hashtable] 35 | } 36 | 37 | It 'Should have the same count of properties' { 38 | $script:convertHashtable.keys.count | Should -Be $script:instance.psobject.Properties.Name.count 39 | } 40 | It 'Should be the same value of key' { 41 | $script:instance.psobject.Properties.Name | ForEach-Object { 42 | $script:convertHashtable.ContainsKey($_) | Should -BeTrue 43 | $script:convertHashtable.$_ | Should -Be $instance.$_ 44 | } 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Sampler/Templates/ClassFolderResource/tests/Unit/Private/Set-FileAttribute.tests.ps1: -------------------------------------------------------------------------------- 1 | $ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path 2 | $ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object { 3 | ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and 4 | $(try { Test-ModuleManifest $_.FullName -ErrorAction Stop }catch{$false}) } 5 | ).BaseName 6 | 7 | Import-Module $ProjectName 8 | 9 | InModuleScope $ProjectName { 10 | Describe 'Helper function Set-FileAttribute' { 11 | BeforeAll { 12 | $mockAttribute = 'ReadOnly' 13 | $script:mockFolderObjectPath = Join-Path -Path $TestDrive -ChildPath 'FolderTest' 14 | $script:mockFolderObject = New-Item -Path $script:mockFolderObjectPath -ItemType 'Directory' -Force 15 | $script:mockFolderObject.Attributes = [System.IO.FileAttributes]::$mockAttribute 16 | } 17 | 18 | BeforeEach{ 19 | $script:instance = [DSC_ClassFolder]::new() 20 | $script:instance.Path = $script:mockFolderObjectPath 21 | $script:instance.Ensure = [Ensure]::Present 22 | } 23 | 24 | Context 'When a folder should have a specific attribute with SetFileAttribute function' { 25 | It 'Should set the folder to the specific attribute' { 26 | $script:instance.Hidden = $true 27 | { Set-FileAttribute -Folder $script:mockFolderObject -Attribute 'Hidden' -Enabled $script:instance.Hidden } | Should -Not -Throw 28 | 29 | Test-FileAttribute -Folder $script:mockFolderObject -Attribute 'Hidden' | Should -BeTrue 30 | } 31 | } 32 | 33 | Context 'When a folder does not have a specific attribute with SetFileAttribute function' { 34 | It 'Should return $false' { 35 | $script:instance.Hidden = $false 36 | { Set-FileAttribute -Folder $script:mockFolderObject -Attribute 'Hidden' -Enabled $script:instance.Hidden } | Should -Not -Throw 37 | 38 | Test-FileAttribute -Folder $script:mockFolderObject -Attribute 'Hidden' | Should -BeFalse 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Sampler/Templates/ClassFolderResource/tests/Unit/Private/Test-FileAttribute.tests.ps1: -------------------------------------------------------------------------------- 1 | $ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path 2 | $ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object { 3 | ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and 4 | $(try { Test-ModuleManifest $_.FullName -ErrorAction Stop }catch{$false}) } 5 | ).BaseName 6 | 7 | Import-Module $ProjectName 8 | 9 | InModuleScope $ProjectName { 10 | Describe 'Helper function Test-FileAttribute' { 11 | BeforeAll { 12 | $mockAttribute = 'ReadOnly' 13 | $script:mockFolderObjectPath = Join-Path -Path $TestDrive -ChildPath 'FolderTest' 14 | $script:mockFolderObject = New-Item -Path $script:mockFolderObjectPath -ItemType 'Directory' -Force 15 | $script:mockFolderObject.Attributes = [System.IO.FileAttributes]::$mockAttribute 16 | } 17 | 18 | BeforeEach{ 19 | $script:instance = [DSC_ClassFolder]::new() 20 | $script:instance.Path = $script:mockFolderObjectPath 21 | $script:instance.Ensure = [Ensure]::Present 22 | } 23 | 24 | Context 'When a folder has a specific attribute with Test-FileAttribute function' { 25 | It 'Should set the folder to the specific attribute' { 26 | $testFileAttributeResult = Test-FileAttribute -Folder $script:mockFolderObject -Attribute $mockAttribute 27 | $testFileAttributeResult | Should -BeTrue 28 | } 29 | } 30 | 31 | Context 'When a folder does not have a specific attribute with Test-FileAttribute function' { 32 | It 'Should set the folder to the specific attribute' { 33 | $testFileAttributeResult = Test-FileAttribute -Folder $script:mockFolderObject -Attribute 'Hidden' 34 | $testFileAttributeResult | Should -BeFalse 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Sampler/Templates/ClassResource/1.Ensure.ps1.template: -------------------------------------------------------------------------------- 1 | enum Ensure 2 | { 3 | Absent 4 | Present 5 | } 6 | -------------------------------------------------------------------------------- /Sampler/Templates/ClassResource/Private/ConvertTo-HashtableFromObject.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Convert any object to hashtable 4 | 5 | .PARAMETER InputObject 6 | The object that should convert to hashtable. 7 | #> 8 | function ConvertTo-HashtableFromObject 9 | { 10 | [CmdletBinding()] 11 | [OutputType([Hashtable])] 12 | param 13 | ( 14 | [Parameter(Mandatory = $true,ValueFromPipeline=$true)] 15 | [PSObject] 16 | $InputObject 17 | ) 18 | $hashResult = @{} 19 | 20 | $InputObject.psobject.Properties | Foreach-Object { 21 | $hashResult[$_.Name] = $_.Value 22 | } 23 | 24 | return $hashResult 25 | 26 | } 27 | -------------------------------------------------------------------------------- /Sampler/Templates/ClassResource/Private/Get-DummyObject.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | This function is use to generate a dummy object for sampler template. 5 | It can be replace by real function. 6 | Or if you use a .net object, you can rename this function and replace 7 | this content. 8 | 9 | .PARAMETER Name 10 | It's dummy parameter 11 | #> 12 | function Get-DummyObject 13 | { 14 | [CmdletBinding()] 15 | [OutputType([pscustomobject])] 16 | param 17 | ( 18 | [Parameter(Mandatory = $true)] 19 | [string] 20 | $Name 21 | ) 22 | 23 | [pscustomobject]@{ 24 | Name = $Name 25 | PropertyMandatory = $true 26 | PropertyBoolReadWrite = $false 27 | PropertyBoolReadOnly = $true 28 | PropertyStringReadOnly = 'This is a readonly string' 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Sampler/Templates/ClassResource/Private/Set-HelpFunctionProperty.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Sets a property on a dummy object. 5 | This function is just an example of how to use an helper function 6 | in Class based resource. 7 | 8 | .PARAMETER Object 9 | A dummy Object 10 | 11 | .PARAMETER Property 12 | The name of the property from the dummy object that you want to change. 13 | 14 | .PARAMETER Value 15 | Value of the property. 16 | #> 17 | function Set-HelpFunctionProperty 18 | { 19 | [CmdletBinding()] 20 | [OutputType([System.IO.DirectoryInfo])] 21 | param 22 | ( 23 | [Parameter(Mandatory = $true)] 24 | [pscustomobject] 25 | $Object, 26 | 27 | [Parameter(Mandatory = $true)] 28 | [string] 29 | $Property, 30 | 31 | [Parameter(Mandatory = $true)] 32 | $Value 33 | ) 34 | 35 | $Object.$Property = $Value 36 | } 37 | -------------------------------------------------------------------------------- /Sampler/Templates/ClassResource/Reason.ps1.template: -------------------------------------------------------------------------------- 1 | class Reason 2 | { 3 | [DscProperty()] 4 | [string] $Phrase 5 | 6 | [DscProperty()] 7 | [string] $Code 8 | } 9 | -------------------------------------------------------------------------------- /Sampler/Templates/ClassResource/en-US/DSC_ClassResource.strings.psd1.template: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | The localized resource strings in English (en-US) for the 4 | resource DSC_<%=$PLASTER_PARAM_ResourceName %>. 5 | #> 6 | 7 | <# 8 | Exemple of StringData for Class based resource 9 | #> 10 | ConvertFrom-StringData @' 11 | RetrieveItem = Retrieving Item information of '{0}'. 12 | ItemFound = Item was found, evaluating all properties. 13 | ItemNotFound = Item was not found. 14 | CreateItem = Creating Item '{0}'. 15 | EvaluateProperties = Evaluating properties of item '{0}'. 16 | SettingProperties = Setting properties to correct values of item '{0}'. 17 | RemoveItem = Removing item '{0}'. 18 | ItemFoundShouldBeNot = Item {0} was found, but should be absent. 19 | DontBePropertyMandatory = Item should be {0} for PropertyMandatory property, but he is {1}. 20 | DontBePropertyBoolReadWrite = Item should be {0} for PropertyBoolReadWrite attribute, but he is {1}. 21 | '@ 22 | -------------------------------------------------------------------------------- /Sampler/Templates/ClassResource/tests/Unit/Private/ConvertTo-HashtableFromObject.tests.ps1.template: -------------------------------------------------------------------------------- 1 | $ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path 2 | $ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object { 3 | ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and 4 | $(try { Test-ModuleManifest $_.FullName -ErrorAction Stop }catch{$false}) } 5 | ).BaseName 6 | 7 | Import-Module $ProjectName 8 | 9 | InModuleScope $ProjectName { 10 | 11 | Describe 'Helper function ConvertTo-HashtableFromObject' { 12 | BeforeAll { 13 | $script:mockItemName = 'dummyName' 14 | $script:mockItem = [pscustomobject]@{ 15 | Name = $script:mockItemName 16 | PropertyMandatory = $true 17 | PropertyBoolReadWrite = $false 18 | } 19 | } 20 | 21 | BeforeEach{ 22 | $script:instanceDesiredState = [DSC_<%=$PLASTER_PARAM_ResourceName %>]::new() 23 | $script:instanceDesiredState.Name = $script:mockItemName 24 | $script:instanceDesiredState.Ensure = [Ensure]::Present 25 | } 26 | 27 | Context 'When instance of class is convert to hashtable' { 28 | BeforeEach { 29 | 30 | } 31 | It 'Should not Throw' { 32 | {$script:convertHashtable = $script:instanceDesiredState | ConvertTo-HashtableFromObject} | Should -Not -Throw 33 | } 34 | 35 | It 'Should be a Hashtable' { 36 | $script:convertHashtable | Should -BeOfType [hashtable] 37 | } 38 | 39 | It 'Should have the same count of properties' { 40 | $script:convertHashtable.keys.count | Should -Be $script:instanceDesiredState.psobject.Properties.Name.count 41 | } 42 | It 'Should be the same value of key' { 43 | $script:instanceDesiredState.psobject.Properties.Name | ForEach-Object { 44 | $script:convertHashtable.ContainsKey($_) | Should -BeTrue 45 | $script:convertHashtable.$_ | Should -Be $instanceDesiredState.$_ 46 | } 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Sampler/Templates/Classes/Classes/1.class1.ps1: -------------------------------------------------------------------------------- 1 | class Class1 2 | { 3 | [string]$Name = 'Class1' 4 | 5 | Class1() 6 | { 7 | #default Constructor 8 | } 9 | 10 | [String] ToString() 11 | { 12 | # Typo "calss" is intentional 13 | return ( 'This calss is {0}' -f $this.Name) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Sampler/Templates/Classes/Classes/2.class2.ps1: -------------------------------------------------------------------------------- 1 | class Class2 2 | { 3 | [string]$Name = 'Class2' 4 | 5 | Class2() 6 | { 7 | #default constructor 8 | } 9 | 10 | [String] ToString() 11 | { 12 | return ( 'This calss is {0}' -f $this.Name) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Sampler/Templates/Classes/Classes/3.class11.ps1: -------------------------------------------------------------------------------- 1 | class Class11 : Class1 2 | { 3 | [string]$Name = 'Class11' 4 | 5 | Class11 () 6 | { 7 | } 8 | 9 | [String] ToString() 10 | { 11 | return ( 'This calss is {0}:{1}' -f $this.Name,'class1') 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Sampler/Templates/Classes/Classes/4.class12.ps1: -------------------------------------------------------------------------------- 1 | class Class12 : Class1 2 | { 3 | [string]$Name = 'Class12' 4 | 5 | Class12 () 6 | { 7 | } 8 | 9 | [String] ToString() 10 | { 11 | return ( 'This calss is {0}:{1}' -f $this.Name,'class1') 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Sampler/Templates/Classes/plasterManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | Classes 6 | 94a2bcc5-e4d1-4c45-8949-f693ad57e99e 7 | 0.0.1 8 | Enum Template 9 | A template to add some classes with inheritence and order to a Sampler Project 10 | Gael Colas 11 | Sampler,Template, Build, Module 12 | 13 | 14 | 15 | 16 | 20 | 21 | 22 | 23 | 24 | 27 | 28 | 31 | 32 | 33 | 34 | 37 | 40 | 43 | 46 | 47 | 48 | 51 | 54 | 57 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Sampler/Templates/Classes/tests/Unit/Classes/class1.tests.ps1: -------------------------------------------------------------------------------- 1 | $ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path 2 | $ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object { 3 | ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and 4 | $(try { Test-ModuleManifest $_.FullName -ErrorAction Stop }catch{$false}) } 5 | ).BaseName 6 | 7 | Import-Module $ProjectName 8 | 9 | InModuleScope $ProjectName { 10 | Describe class1 { 11 | Context 'Type creation' { 12 | It 'Has created a type named class1' { 13 | 'class1' -as [Type] | Should -BeOfType [Type] 14 | } 15 | } 16 | 17 | Context 'Constructors' { 18 | It 'Has a default constructor' { 19 | $instance = [class1]::new() 20 | $instance | Should -Not -BeNullOrEmpty 21 | $instance.GetType().Name | Should -Be 'class1' 22 | } 23 | } 24 | 25 | Context 'Methods' { 26 | BeforeEach { 27 | $instance = [class1]::new() 28 | } 29 | 30 | It 'Overrides the ToString method' { 31 | # Typo "calss" is inherited from definition. Preserved here as validation is demonstrative. 32 | $instance.ToString() | Should -Be 'This calss is class1' 33 | } 34 | } 35 | 36 | Context 'Properties' { 37 | BeforeEach { 38 | $instance = [class1]::new() 39 | } 40 | 41 | It 'Has a Name property' { 42 | $instance.Name | Should -Be 'Class1' 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Sampler/Templates/Classes/tests/Unit/Classes/class11.tests.ps1: -------------------------------------------------------------------------------- 1 | $ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path 2 | $ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object { 3 | ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and 4 | $(try { Test-ModuleManifest $_.FullName -ErrorAction Stop }catch{$false}) } 5 | ).BaseName 6 | 7 | Import-Module $ProjectName 8 | 9 | InModuleScope $ProjectName { 10 | Describe class11 { 11 | Context 'Type creation' { 12 | It 'Has created a type named class11' { 13 | 'class11' -as [Type] | Should -BeOfType [Type] 14 | } 15 | } 16 | 17 | Context 'Constructors' { 18 | It 'Has a default constructor' { 19 | $instance = [class11]::new() 20 | $instance | Should -Not -BeNullOrEmpty 21 | $instance.GetType().Name | Should -Be 'class11' 22 | } 23 | } 24 | 25 | Context 'Methods' { 26 | BeforeEach { 27 | $instance = [class11]::new() 28 | } 29 | 30 | It 'Overrides the ToString method' { 31 | # Typo "calss" is inherited from definition. Preserved here as validation is demonstrative. 32 | $instance.ToString() | Should -Be 'This calss is class11:class1' 33 | } 34 | } 35 | 36 | Context 'Properties' { 37 | BeforeEach { 38 | $instance = [class11]::new() 39 | } 40 | 41 | It 'Has a Name property' { 42 | $instance.Name | Should -Be 'Class11' 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Sampler/Templates/Classes/tests/Unit/Classes/class12.tests.ps1: -------------------------------------------------------------------------------- 1 | $ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path 2 | $ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object { 3 | ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and 4 | $(try { Test-ModuleManifest $_.FullName -ErrorAction Stop }catch{$false}) } 5 | ).BaseName 6 | 7 | Import-Module $ProjectName 8 | 9 | InModuleScope $ProjectName { 10 | Describe class12 { 11 | Context 'Type creation' { 12 | It 'Has created a type named class12' { 13 | 'class12' -as [Type] | Should -BeOfType [Type] 14 | } 15 | } 16 | 17 | Context 'Constructors' { 18 | It 'Has a default constructor' { 19 | $instance = [class12]::new() 20 | $instance | Should -Not -BeNullOrEmpty 21 | $instance.GetType().Name | Should -Be 'class12' 22 | } 23 | } 24 | 25 | Context 'Methods' { 26 | BeforeEach { 27 | $instance = [class12]::new() 28 | } 29 | 30 | It 'Overrides the ToString method' { 31 | # Typo "calss" is inherited from definition. Preserved here as validation is demonstrative. 32 | $instance.ToString() | Should -Be 'This calss is class12:class1' 33 | } 34 | } 35 | 36 | Context 'Properties' { 37 | BeforeEach { 38 | $instance = [class12]::new() 39 | } 40 | 41 | It 'Has a Name property' { 42 | $instance.Name | Should -Be 'Class12' 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Sampler/Templates/Classes/tests/Unit/Classes/class2.tests.ps1: -------------------------------------------------------------------------------- 1 | $ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path 2 | $ProjectName = (Get-ChildItem $ProjectPath\*\*.psd1 | Where-Object { 3 | ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and 4 | $(try { Test-ModuleManifest $_.FullName -ErrorAction Stop }catch{$false}) } 5 | ).BaseName 6 | 7 | Import-Module $ProjectName 8 | 9 | InModuleScope $ProjectName { 10 | Describe class2 { 11 | Context 'Type creation' { 12 | It 'Has created a type named class2' { 13 | 'class2' -as [Type] | Should -BeOfType [Type] 14 | } 15 | } 16 | 17 | Context 'Constructors' { 18 | It 'Has a default constructor' { 19 | $instance = [class2]::new() 20 | $instance | Should -Not -BeNullOrEmpty 21 | $instance.GetType().Name | Should -Be 'class2' 22 | } 23 | } 24 | 25 | Context 'Methods' { 26 | BeforeEach { 27 | $instance = [class2]::new() 28 | } 29 | 30 | It 'Overrides the ToString method' { 31 | # Typo "calss" is inherited from definition. Preserved here as validation is demonstrative. 32 | $instance.ToString() | Should -Be 'This calss is class2' 33 | } 34 | } 35 | 36 | Context 'Properties' { 37 | BeforeEach { 38 | $instance = [class2]::new() 39 | } 40 | 41 | It 'Has a Name property' { 42 | $instance.Name | Should -Be 'Class2' 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Sampler/Templates/Composite/Composite.schema.psm1.template: -------------------------------------------------------------------------------- 1 | Configuration <%=$PLASTER_PARAM_CompositeName %> 2 | { 3 | param ( 4 | 5 | ) 6 | 7 | # Import-DscResource -ModuleName x -ModuleVersion y 8 | 9 | File MyFileResource { 10 | Ensure = 'Present' 11 | DestinationPath = 'C:\txt.txt' 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Sampler/Templates/Composite/plasterManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | Composite 6 | d784c581-4659-4864-92b5-656d5c172cb1 7 | 0.0.1 8 | DSC Composite Resource Template 9 | A template to add a Composite resource (aka Configuration) to a Sampler Project 10 | Gael Colas 11 | Sampler,Template, Build, Module 12 | 13 | 14 | 15 | 16 | 17 | 18 | 23 | 24 | 25 | 26 | 27 | 30 | 31 | 32 | 35 | 36 | 37 | 40 | 41 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /Sampler/Templates/Enum/Enum.ps1.template: -------------------------------------------------------------------------------- 1 | enum <%= $PLASTER_PARAM_EnumName %> 2 | { 3 | Thing = 1 4 | OtherThing = 2 5 | } 6 | -------------------------------------------------------------------------------- /Sampler/Templates/Enum/plasterManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | Enum 6 | 52746f4d-8270-4e0b-8bd8-a8a5e9619a6b 7 | 0.0.1 8 | Enum Template 9 | A template to add an Enum to a Sampler Project 10 | Gael Colas 11 | Sampler,Template, Build, Module 12 | 13 | 14 | 15 | 16 | 17 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Sampler/Templates/Examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | This will help to understand how to setup certain scenarios with the DscResource.Template resource module. 4 | 5 | ## Resource examples 6 | 7 | These are the links to the examples for each individual resource. 8 | 9 | - [Folder](/Resources/Folder) 10 | -------------------------------------------------------------------------------- /Sampler/Templates/Examples/Resources/Folder/1-DscResourceTemplate_CreateFolderAsSystemConfig.ps1: -------------------------------------------------------------------------------- 1 | <#PSScriptInfo 2 | .VERSION 1.0.0 3 | .GUID 2d10cefd-b6c3-4728-98cc-0469318bac95 4 | .AUTHOR Microsoft Corporation 5 | .COMPANYNAME Microsoft Corporation 6 | .COPYRIGHT 7 | .TAGS DSCConfiguration 8 | .LICENSEURI https://github.com/PowerShell/PowerShellGet/blob/master/LICENSE 9 | .PROJECTURI https://github.com/PowerShell/PowerShellGet 10 | .ICONURI 11 | .EXTERNALMODULEDEPENDENCIES 12 | .REQUIREDSCRIPTS 13 | .EXTERNALSCRIPTDEPENDENCIES 14 | .RELEASENOTES First version. 15 | .PRIVATEDATA 2016-Datacenter,2016-Datacenter-Server-Core 16 | #> 17 | 18 | #Requires -module 'DscResource.Template' 19 | 20 | <# 21 | .SYNOPSIS 22 | Configuration that will create a folder using the account SYSTEM. 23 | 24 | .DESCRIPTION 25 | Configuration that will create a folder using the account SYSTEM. 26 | 27 | .PARAMETER NodeName 28 | The names of one or more nodes to compile a configuration for. 29 | Defaults to 'localhost'. 30 | 31 | .PARAMETER Path 32 | The path to the folder to create, include the folder that will be created, 33 | i.e. 'C:\DscTemp1'. 34 | 35 | .EXAMPLE 36 | DscResourceTemplate_CreateFolderAsSystemConfig -Path 'C:\DscTemp1' 37 | 38 | Compiles a configuration that creates the folder 'C:\DscTemp1' as SYSTEM. 39 | 40 | .EXAMPLE 41 | $configurationParameters = @{ 42 | Path = 'C:\DscTemp1' 43 | } 44 | Start-AzureRmAutomationDscCompilationJob -ResourceGroupName '' -AutomationAccountName '' -ConfigurationName 'DscResourceTemplate_CreateFolderAsSystemConfig' -Parameters $configurationParameters 45 | 46 | Compiles a configuration in Azure Automation that creates the folder 47 | 'C:\DscTemp1' as SYSTEM. 48 | Replace the and with correct values. 49 | #> 50 | Configuration DscResourceTemplate_CreateFolderAsSystemConfig 51 | { 52 | param 53 | ( 54 | [Parameter()] 55 | [System.String[]] 56 | $NodeName = 'localhost', 57 | 58 | [Parameter(Mandatory = $true)] 59 | [ValidateNotNullOrEmpty()] 60 | [System.String] 61 | $Path 62 | ) 63 | 64 | Import-DscResource -ModuleName 'DscResource.Template' 65 | 66 | node $NodeName 67 | { 68 | Folder 'CreateFolder' 69 | { 70 | Path = $Path 71 | ReadOnly = $false 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Sampler/Templates/Examples/Resources/Folder/2-DscResourceTemplate_CreateFolderAsUserConfig.ps1: -------------------------------------------------------------------------------- 1 | <#PSScriptInfo 2 | .VERSION 1.0.0 3 | .GUID d30fd99e-405d-4f3e-a76f-ca03710fe701 4 | .AUTHOR Microsoft Corporation 5 | .COMPANYNAME Microsoft Corporation 6 | .COPYRIGHT 7 | .TAGS DSCConfiguration 8 | .LICENSEURI https://github.com/PowerShell/PowerShellGet/blob/master/LICENSE 9 | .PROJECTURI https://github.com/PowerShell/PowerShellGet 10 | .ICONURI 11 | .EXTERNALMODULEDEPENDENCIES 12 | .REQUIREDSCRIPTS 13 | .EXTERNALSCRIPTDEPENDENCIES 14 | .RELEASENOTES First version. 15 | .PRIVATEDATA 2016-Datacenter,2016-Datacenter-Server-Core 16 | #> 17 | 18 | #Requires -module 'DscResource.Template' 19 | 20 | <# 21 | .SYNOPSIS 22 | Configuration that will create a folder using the account passad in the 23 | parameter InstallCredential. 24 | 25 | .DESCRIPTION 26 | Configuration that will create a folder using the account passad in the 27 | parameter InstallCredential. 28 | 29 | .PARAMETER NodeName 30 | The names of one or more nodes to compile a configuration for. 31 | Defaults to 'localhost'. 32 | 33 | .PARAMETER Path 34 | The path to the folder to create, include the folder that will be created, 35 | i.e. 'C:\DscTemp1'. 36 | 37 | .PARAMETER InstallCredential 38 | The account used to create the folder. 39 | 40 | .EXAMPLE 41 | DscResourceTemplate_CreateFolderAsUserConfig -Path 'C:\DscTemp1' 42 | 43 | Compiles a configuration that creates the folder 'C:\DscTemp1' as SYSTEM. 44 | 45 | .EXAMPLE 46 | $configurationParameters = @{ 47 | Path = 'C:\DscTemp1' 48 | } 49 | Start-AzureRmAutomationDscCompilationJob -ResourceGroupName '' -AutomationAccountName '' -ConfigurationName 'DscResourceTemplate_CreateFolderAsUserConfig' -Parameters $configurationParameters 50 | 51 | Compiles a configuration in Azure Automation that creates the folder 52 | 'C:\DscTemp1' as SYSTEM. 53 | Replace the and with correct values. 54 | #> 55 | Configuration DscResourceTemplate_CreateFolderAsUserConfig 56 | { 57 | param 58 | ( 59 | [Parameter()] 60 | [System.String[]] 61 | $NodeName = 'localhost', 62 | 63 | [Parameter(Mandatory = $true)] 64 | [ValidateNotNullOrEmpty()] 65 | [System.String] 66 | $Path, 67 | 68 | [Parameter(Mandatory = $true)] 69 | [ValidateNotNullOrEmpty()] 70 | [System.Management.Automation.PSCredential] 71 | $InstallCredential 72 | ) 73 | 74 | Import-DscResource -ModuleName 'DscResource.Template' 75 | 76 | node $NodeName 77 | { 78 | Folder 'CreateFolder' 79 | { 80 | Path = $Path 81 | ReadOnly = $false 82 | 83 | PsDscRunAsCredential = $InstallCredential 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Sampler/Templates/Examples/Resources/Folder/3-DscResourceTemplate_RemoveFolderConfig.ps1: -------------------------------------------------------------------------------- 1 | <#PSScriptInfo 2 | .VERSION 1.0.0 3 | .GUID d30fd99e-405d-4f3e-a76f-ca03710fe701 4 | .AUTHOR Microsoft Corporation 5 | .COMPANYNAME Microsoft Corporation 6 | .COPYRIGHT 7 | .TAGS DSCConfiguration 8 | .LICENSEURI https://github.com/PowerShell/PowerShellGet/blob/master/LICENSE 9 | .PROJECTURI https://github.com/PowerShell/PowerShellGet 10 | .ICONURI 11 | .EXTERNALMODULEDEPENDENCIES 12 | .REQUIREDSCRIPTS 13 | .EXTERNALSCRIPTDEPENDENCIES 14 | .RELEASENOTES First version. 15 | .PRIVATEDATA 2016-Datacenter,2016-Datacenter-Server-Core 16 | #> 17 | 18 | #Requires -module 'DscResource.Template' 19 | 20 | <# 21 | .SYNOPSIS 22 | Configuration that will remove a folder. 23 | 24 | .DESCRIPTION 25 | Configuration that will remove a folder. 26 | 27 | .PARAMETER NodeName 28 | The names of one or more nodes to compile a configuration for. 29 | Defaults to 'localhost'. 30 | 31 | .PARAMETER Path 32 | The path to the folder to remove. 33 | 34 | .EXAMPLE 35 | DscResourceTemplate_RemoveFolderConfig -Path 'C:\DscTemp1' 36 | 37 | Compiles a configuration that creates the folder 'C:\DscTemp1' as SYSTEM. 38 | 39 | .EXAMPLE 40 | $configurationParameters = @{ 41 | Path = 'C:\DscTemp1' 42 | } 43 | Start-AzureRmAutomationDscCompilationJob -ResourceGroupName '' -AutomationAccountName '' -ConfigurationName 'DscResourceTemplate_RemoveFolderConfig' -Parameters $configurationParameters 44 | 45 | Compiles a configuration in Azure Automation that creates the folder 46 | 'C:\DscTemp1' as SYSTEM. 47 | Replace the and with correct values. 48 | #> 49 | Configuration DscResourceTemplate_RemoveFolderConfig 50 | { 51 | param 52 | ( 53 | [Parameter()] 54 | [System.String[]] 55 | $NodeName = 'localhost', 56 | 57 | [Parameter(Mandatory = $true)] 58 | [ValidateNotNullOrEmpty()] 59 | [System.String] 60 | $Path 61 | ) 62 | 63 | Import-DscResource -ModuleName 'DscResource.Template' 64 | 65 | node $NodeName 66 | { 67 | Folder 'RemoveFolder' 68 | { 69 | Ensure = 'Absent' 70 | Path = $Path 71 | ReadOnly = $false 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Sampler/Templates/GCPackage/GCPackages/MyGuestConfigPackage/MyGuestConfigPackage.config.ps1.template: -------------------------------------------------------------------------------- 1 | configuration <%= $PLASTER_PARAM_GCPackageName %> { 2 | Import-DscResource -ModuleName MyModule 3 | 4 | MyResource MyModule { 5 | Ensure = 'Present' 6 | KeyProperty = 'key' 7 | Property = 'Value' 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Sampler/Templates/GCPackage/plasterManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | GCPackages 6 | e2e70839-6b8c-477f-a069-8ddcf693c6dc 7 | 0.0.1 8 | Azure Policy Guest Configuration Package template 9 | An Azure Policy Guest Configuration Package template to build your packages from DSC configurations, to be used by policies 10 | Gael Colas 11 | GuestConfiguration, Azure, Policy, Arc, Sampler, Template, Build, Module 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 33 | 34 | 35 | 38 | 39 | 40 | 43 | 44 | 45 | 48 | 49 | 50 | 51 | 52 | }(\r|\r\n)*$ 53 | GuestConfiguration = 'latest'`r`n}`r`n 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /Sampler/Templates/Git/GitVersion.yml.template: -------------------------------------------------------------------------------- 1 | mode: ContinuousDelivery 2 | next-version: 0.0.1 3 | major-version-bump-message: '(breaking\schange|breaking|major)\b' 4 | minor-version-bump-message: '(adds?|features?|minor)\b' 5 | patch-version-bump-message: '\s?(fix|patch)' 6 | no-bump-message: '\+semver:\s?(none|skip)' 7 | assembly-informational-format: '{NuGetVersionV2}+Sha.{Sha}.Date.{CommitDate}' 8 | branches: 9 | master: 10 | tag: preview 11 | regex: ^<%= ${PLASTER_PARAM_MainGitBranch} %>$ 12 | pull-request: 13 | tag: PR 14 | feature: 15 | tag: useBranchName 16 | increment: Minor 17 | regex: f(eature(s)?)?[\/-] 18 | source-branches: ['master'] 19 | hotfix: 20 | tag: fix 21 | increment: Patch 22 | regex: (hot)?fix(es)?[\/-] 23 | source-branches: ['master'] 24 | 25 | ignore: 26 | sha: [] 27 | merge-message-formats: {} 28 | 29 | 30 | # feature: 31 | # tag: useBranchName 32 | # increment: Minor 33 | # regex: f(eature(s)?)?[/-] 34 | # source-branches: ['master'] 35 | # hotfix: 36 | # tag: fix 37 | # increment: Patch 38 | # regex: (hot)?fix(es)?[/-] 39 | # source-branches: ['master'] 40 | -------------------------------------------------------------------------------- /Sampler/Templates/Git/gitattributes: -------------------------------------------------------------------------------- 1 | # Needed for publishing of examples, build worker defaults to core.autocrlf=input. 2 | * text eol=autocrlf 3 | 4 | *.mof text eol=crlf 5 | *.sh text eol=lf 6 | *.svg eol=lf 7 | 8 | # Ensure any exe files are treated as binary 9 | *.exe binary 10 | *.jpg binary 11 | *.xl* binary 12 | *.pfx binary 13 | *.png binary 14 | *.dll binary 15 | *.so binary 16 | -------------------------------------------------------------------------------- /Sampler/Templates/Git/gitignore: -------------------------------------------------------------------------------- 1 | output/ 2 | 3 | **.bak 4 | *.local.* 5 | !**/README.md 6 | .kitchen/ 7 | 8 | *.nupkg 9 | *.suo 10 | *.user 11 | *.coverage 12 | .vs 13 | .psproj 14 | .sln 15 | markdownissues.txt 16 | node_modules 17 | package-lock.json 18 | -------------------------------------------------------------------------------- /Sampler/Templates/GithubConfig/ISSUE_TEMPLATE/General.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: General question or documentation update 3 | about: If you have a general question or documentation update suggestion around the resource module. 4 | --- 5 | 8 | -------------------------------------------------------------------------------- /Sampler/Templates/GithubConfig/ISSUE_TEMPLATE/Resource_proposal.yml: -------------------------------------------------------------------------------- 1 | name: New resource proposal 2 | description: If you have a new resource proposal that you think should be added to this resource module. 3 | title: "NewResourceName: New resource proposal" 4 | labels: [] 5 | assignees: [] 6 | body: 7 | - type: markdown 8 | attributes: 9 | value: | 10 | Please replace `NewResourceName` in the issue title (above) with your proposed resource name. 11 | 12 | Thank you for contributing and making this resource module better! 13 | - type: textarea 14 | id: description 15 | attributes: 16 | label: Resource proposal 17 | description: Provide information how this resource will/should work and how it will help users. 18 | validations: 19 | required: true 20 | - type: textarea 21 | id: proposedProperties 22 | attributes: 23 | label: Proposed properties 24 | description: | 25 | List all the proposed properties that the resource should have (key, required, write, and/or read). For each property provide a detailed description, the data type, if a default value should be used, and if the property is limited to a set of values. 26 | value: | 27 | Property | Type qualifier | Data type | Description | Default value | Allowed values 28 | --- | --- | --- | --- | --- | --- 29 | PropertyName | Key | String | Detailed description | None | None 30 | validations: 31 | required: true 32 | - type: textarea 33 | id: considerations 34 | attributes: 35 | label: Special considerations or limitations 36 | description: | 37 | Provide any considerations or limitations you can think of that a contributor should take in account when coding the proposed resource, and or what limitations a user will encounter or should consider when using the proposed resource. 38 | validations: 39 | required: true 40 | -------------------------------------------------------------------------------- /Sampler/Templates/GithubConfig/ISSUE_TEMPLATE/config.yml.template: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | <% 3 | if ($PLASTER_PARAM_ModuleType -in @('dsccommunity','CompleteSample')) 4 | { 5 | 'contact_links: 6 | - name: "Virtual PowerShell User Group #DSC channel" 7 | url: https://dsccommunity.org/community/contact/ 8 | about: "To talk to the community and maintainers of DSC Community, please visit the #DSC channel."' 9 | } 10 | %> 11 | -------------------------------------------------------------------------------- /Sampler/Templates/GithubConfig/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Pull Request 2 | 3 | 16 | 17 | ## Pull Request (PR) description 18 | 19 | 40 | 41 | ## Task list 42 | 43 | 51 | 52 | - [ ] The PR represents a single logical change. i.e. Cosmetic updates should go in different PRs. 53 | - [ ] Added an entry under the Unreleased section of in the CHANGELOG.md as per [format](https://keepachangelog.com/en/1.0.0/). 54 | - [ ] Local clean build passes without issue or fail tests (`build.ps1 -ResolveDependency`). 55 | - [ ] Resource documentation added/updated in README.md. 56 | - [ ] Resource parameter descriptions added/updated in README.md, schema.mof 57 | and comment-based help. 58 | - [ ] Comment-based help added/updated. 59 | - [ ] Localization strings added/updated in all localization files as appropriate. 60 | - [ ] Examples appropriately added/updated. 61 | - [ ] Unit tests added/updated. See [DSC Resource Testing Guidelines](https://github.com/PowerShell/DscResources/blob/master/TestsGuidelines.md). 62 | - [ ] Integration tests added/updated (where possible). See [DSC Resource Testing Guidelines](https://github.com/PowerShell/DscResources/blob/master/TestsGuidelines.md). 63 | - [ ] New/changed code adheres to [DSC Resource Style Guidelines](https://github.com/PowerShell/DscResources/blob/master/StyleGuidelines.md) and [Best Practices](https://github.com/PowerShell/DscResources/blob/master/BestPractices.md). 64 | -------------------------------------------------------------------------------- /Sampler/Templates/GithubConfig/PULL_REQUEST_TEMPLATE_dsccommunity.md: -------------------------------------------------------------------------------- 1 | 12 | 13 | #### Pull Request (PR) description 14 | 15 | 19 | 20 | #### This Pull Request (PR) fixes the following issues 21 | 22 | 30 | 31 | #### Task list 32 | 33 | 40 | 41 | - [ ] Added an entry to the change log under the Unreleased section of the file CHANGELOG.md. 42 | Entry should say what was changed and how that affects users (if applicable), and 43 | reference the issue being resolved (if applicable). 44 | - [ ] Resource documentation added/updated in README.md. 45 | - [ ] Resource parameter descriptions added/updated in README.md, schema.mof and comment-based 46 | help. 47 | - [ ] Comment-based help added/updated. 48 | - [ ] Localization strings added/updated in all localization files as appropriate. 49 | - [ ] Examples appropriately added/updated. 50 | - [ ] Unit tests added/updated. See [DSC Community Testing Guidelines](https://dsccommunity.org/guidelines/testing-guidelines). 51 | - [ ] Integration tests added/updated (where possible). See [DSC Community Testing Guidelines](https://dsccommunity.org/guidelines/testing-guidelines). 52 | - [ ] New/changed code adheres to [DSC Community Style Guidelines](https://dsccommunity.org/styleguidelines). 53 | -------------------------------------------------------------------------------- /Sampler/Templates/GithubConfig/plasterManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | GithubConfig 6 | 56036e8d-ce2e-4b9c-82e4-156443cd0a25 7 | 0.0.1 8 | GithubConfig Template 9 | A template to add a .github config to a Sampler Project 10 | Gael Colas 11 | Sampler,Template, Build, Module, github 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 26 | 27 | 30 | 31 | 34 | 35 | 38 | 39 | 42 | 43 | 46 | 47 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /Sampler/Templates/HelperSubModules/Modules/HelperSubmodule/HelperSubmodule.psm1: -------------------------------------------------------------------------------- 1 | # This is an example of helper module 2 | -------------------------------------------------------------------------------- /Sampler/Templates/HelperSubModules/plasterManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | Enum 6 | 8ef55295-024e-4677-9760-1ae3e27131d7 7 | 0.0.1 8 | Submodule Template 9 | A template to add a submodule to a Sampler Project 10 | Gael Colas 11 | Sampler,Template, Build, Module 12 | 13 | 14 | 15 | 16 | 17 | 18 | 23 | 24 | 25 | 26 | 27 | 30 | 33 | 34 | 35 | 38 | 39 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Sampler/Templates/MofResource/DSC_Folder/DSC_Folder.schema.mof: -------------------------------------------------------------------------------- 1 | [ClassVersion("1.0.0.0"), FriendlyName("Folder")] 2 | class DSC_Folder : OMI_BaseResource 3 | { 4 | [Key, Description("The path to the folder to create.")] String Path; 5 | [Required, Description("If the files in the folder should be read only.")] Boolean ReadOnly; 6 | [Write, Description("If the folder attribute should be hidden. Default value is $false.")] Boolean Hidden; 7 | [Write, Description("Specifies the desired state of the folder. When set to 'Present', the folder will be created. When set to 'Absent', the folder will be removed. Default value is 'Present'."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; 8 | [Read, Description("If sharing is be enabled or disabled.")] Boolean Shared; 9 | [Read, Description("The name of the shared resource.")] String ShareName; 10 | }; 11 | -------------------------------------------------------------------------------- /Sampler/Templates/MofResource/DSC_Folder/en-US/DSC_Folder.strings.psd1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | The localized resource strings in English (en-US) for the 4 | resource DSC_Folder. 5 | #> 6 | 7 | ConvertFrom-StringData @' 8 | RetrieveFolder = Retrieving folder information of '{0}'. 9 | FolderFound = Folder was found, evaluating all properties. 10 | FolderNotFound = Folder was not found. 11 | CreateFolder = Creating folder '{0}'. 12 | EvaluateProperties = Evaluating properties of folder '{0}'. 13 | SettingProperties = Setting properties to correct values of folder '{0}'. 14 | RemoveFolder = Removing folder '{0}'. 15 | '@ 16 | -------------------------------------------------------------------------------- /Sampler/Templates/MofResource/Modules/Folder.Common/Folder.Common.psm1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Test if an attribute on a folder is present. 5 | 6 | .PARAMETER Folder 7 | The System.IO.DirectoryInfo object of the folder that should be checked 8 | for the attribute. 9 | 10 | .PARAMETER Attribute 11 | The name of the attribute from the enum System.IO.FileAttributes. 12 | #> 13 | function Test-FileAttribute 14 | { 15 | [CmdletBinding()] 16 | [OutputType([System.Boolean])] 17 | param 18 | ( 19 | [Parameter(Mandatory = $true)] 20 | [System.IO.DirectoryInfo] 21 | $Folder, 22 | 23 | [Parameter(Mandatory = $true)] 24 | [System.IO.FileAttributes] 25 | $Attribute 26 | ) 27 | 28 | $attributeValue = $Folder.Attributes -band [System.IO.FileAttributes]::$Attribute 29 | 30 | switch ($attributeValue) 31 | { 32 | { $_ -gt 0 } 33 | { 34 | $isPresent = $true 35 | } 36 | 37 | default 38 | { 39 | $isPresent = $false 40 | } 41 | } 42 | 43 | return $isPresent 44 | } 45 | 46 | <# 47 | .SYNOPSIS 48 | Sets or removes an attribute on a folder. 49 | 50 | .PARAMETER Folder 51 | The System.IO.DirectoryInfo object of the folder that should have the 52 | attribute set or removed. 53 | 54 | .PARAMETER Attribute 55 | The name of the attribute from the enum System.IO.FileAttributes. 56 | 57 | .PARAMETER Enabled 58 | If the attribute should be enabled or disabled. 59 | #> 60 | function Set-FileAttribute 61 | { 62 | [CmdletBinding()] 63 | [OutputType([System.IO.DirectoryInfo])] 64 | param 65 | ( 66 | [Parameter(Mandatory = $true)] 67 | [System.IO.DirectoryInfo] 68 | $Folder, 69 | 70 | [Parameter(Mandatory = $true)] 71 | [System.IO.FileAttributes] 72 | $Attribute, 73 | 74 | [Parameter(Mandatory = $true)] 75 | [System.Boolean] 76 | $Enabled 77 | ) 78 | 79 | switch ($Enabled) 80 | { 81 | $true 82 | { 83 | $Folder.Attributes = [System.IO.FileAttributes]::$Attribute 84 | 85 | } 86 | 87 | $false 88 | { 89 | $Folder.Attributes -= [System.IO.FileAttributes]::$Attribute 90 | } 91 | } 92 | } 93 | 94 | Export-ModuleMember -Function Set-FileAttribute, Test-FileAttribute 95 | -------------------------------------------------------------------------------- /Sampler/Templates/MofResource/plasterManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | MofResource 6 | 740f0631-a6bd-42f2-a7b4-9488b83d2fab 7 | 0.0.1 8 | DSC MOF based Resource Template 9 | A template to add a MOF based resource to a Sampler Project 10 | Gael Colas 11 | Sampler,Template, Build, Module 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | 33 | 34 | 35 | 38 | 41 | 44 | 45 | 46 | 49 | 50 | 53 | 54 | 57 | 58 | 59 | 62 | 63 | 64 | 67 | 68 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /Sampler/Templates/PrivateFunction/Get-PrivateFunction.ps1.template: -------------------------------------------------------------------------------- 1 | function <%= $PLASTER_PARAM_PrivateFunctionName %> 2 | { 3 | <# 4 | .SYNOPSIS 5 | This is a sample Private function only visible within the module. 6 | 7 | .DESCRIPTION 8 | This sample function is not exported to the module and only return the data passed as parameter. 9 | 10 | .EXAMPLE 11 | $null = <%=$PLASTER_PARAM_PrivateFunctionName %> -PrivateData 'NOTHING TO SEE HERE' 12 | 13 | .PARAMETER PrivateData 14 | The PrivateData parameter is what will be returned without transformation. 15 | 16 | #> 17 | [cmdletBinding()] 18 | [OutputType([string])] 19 | param 20 | ( 21 | [Parameter()] 22 | [String] 23 | $PrivateData 24 | ) 25 | 26 | process 27 | { 28 | Write-Output $PrivateData 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /Sampler/Templates/PrivateFunction/Get-PrivateFunction.tests.ps1.template: -------------------------------------------------------------------------------- 1 | $ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path 2 | $ProjectName = ((Get-ChildItem -Path $ProjectPath\*\*.psd1).Where{ 3 | ($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and 4 | $(try { Test-ModuleManifest $_.FullName -ErrorAction Stop } catch { $false } ) 5 | }).BaseName 6 | 7 | 8 | Import-Module $ProjectName 9 | 10 | InModuleScope $ProjectName { 11 | Describe Get-PrivateFunction { 12 | Context 'Default' { 13 | BeforeEach { 14 | $return = Get-PrivateFunction -PrivateData 'string' 15 | } 16 | 17 | It 'Returns a single object' { 18 | ($return | Measure-Object).Count | Should -Be 1 19 | } 20 | 21 | It 'Returns a string based on the parameter PrivateData' { 22 | $return | Should -Be 'string' 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Sampler/Templates/PrivateFunction/plasterManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | PrivateFunction 6 | e75b7b6a-6ae5-40b7-8ad8-b0bae0512184 7 | 0.0.1 8 | Private function with tests Template 9 | A template to add a private function to a Sampler Project 10 | Gael Colas 11 | Sampler,Template, Build, Module 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Sampler/Templates/PublicCallPrivateFunctions/plasterManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | PublicCallPrivateFunctions 6 | d784c581-4659-4864-92b5-656d5c172cb1 7 | 0.0.1 8 | Public function calling a private function and tests Template 9 | A template to add a Public function calling a private one to a Sampler Project 10 | Gael Colas 11 | Sampler,Template, Build, Module 12 | 13 | 14 | 15 | 16 | 17 | 18 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Sampler/Templates/PublicFunction/Get-Something.ps1.template: -------------------------------------------------------------------------------- 1 | function <%= $PLASTER_PARAM_PublicFunctionName %> 2 | { 3 | <# 4 | .SYNOPSIS 5 | Sample Function to return input string. 6 | 7 | .DESCRIPTION 8 | This function is only a sample Advanced function that returns the Data given via parameter Data. 9 | 10 | .EXAMPLE 11 | <%= $PLASTER_PARAM_PublicFunctionName %> -Data 'Get me this text' 12 | 13 | 14 | .PARAMETER Data 15 | The Data parameter is the data that will be returned without transformation. 16 | 17 | #> 18 | [cmdletBinding( 19 | SupportsShouldProcess = $true, 20 | ConfirmImpact = 'Low' 21 | )] 22 | [OutputType([string])] 23 | param 24 | ( 25 | [Parameter( 26 | Mandatory = $true 27 | , ValueFromPipeline = $true 28 | , ValueFromPipelineByPropertyName = $true 29 | )] 30 | [String] 31 | $Data 32 | ) 33 | 34 | process 35 | { 36 | if ($pscmdlet.ShouldProcess($Data)) 37 | { 38 | Write-Verbose ('Returning the data: {0}' -f $Data) 39 | <% 40 | if ($PLASTER_PARAM_PrivateFunctionName) 41 | { 42 | " $PLASTER_PARAM_PrivateFunctionName -PrivateData `$Data" 43 | } 44 | else 45 | { 46 | " `$Data" 47 | } 48 | %> 49 | } 50 | else 51 | { 52 | Write-Verbose 'oh dear' 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Sampler/Templates/PublicFunction/plasterManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | PublicFunction 6 | e75b7b6a-6ae5-40b7-8ad8-b0bae0512184 7 | 0.0.1 8 | Public function function with tests Template 9 | A template to add a Public function to a Sampler Project 10 | Gael Colas 11 | Sampler,Template, Build, Module 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Sampler/Templates/Sampler/CHANGELOG.md.template: -------------------------------------------------------------------------------- 1 | <% 2 | "# Changelog for ${PLASTER_PARAM_ModuleName}" 3 | %> 4 | 5 | The format is based on and uses the types of changes according to [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [Unreleased] 9 | 10 | ### Added 11 | 12 | - For new features. 13 | 14 | ### Changed 15 | 16 | - For changes in existing functionality. 17 | 18 | ### Deprecated 19 | 20 | - For soon-to-be removed features. 21 | 22 | ### Removed 23 | 24 | - For now removed features. 25 | 26 | ### Fixed 27 | 28 | - For any bug fix. 29 | 30 | ### Security 31 | 32 | - In case of vulnerabilities. 33 | -------------------------------------------------------------------------------- /Sampler/Templates/Sampler/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | This project has adopted the [DSC Community Code of Conduct](https://dsccommunity.org/code_of_conduct). 4 | -------------------------------------------------------------------------------- /Sampler/Templates/Sampler/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Please check out common DSC Community [contributing guidelines](https://dsccommunity.org/guidelines/contributing). 4 | 5 | ## Running the Tests 6 | 7 | If want to know how to run this module's tests you can look at the [Testing Guidelines](https://dsccommunity.org/guidelines/testing-guidelines/#running-tests) 8 | -------------------------------------------------------------------------------- /Sampler/Templates/Sampler/Get-PrivateFunction.ps1: -------------------------------------------------------------------------------- 1 | function Get-PrivateFunction 2 | { 3 | <# 4 | .SYNOPSIS 5 | This is a sample Private function only visible within the module. 6 | 7 | .DESCRIPTION 8 | This sample function is not exported to the module and only return the data passed as parameter. 9 | 10 | .EXAMPLE 11 | $null = Get-PrivateFunction -PrivateData 'NOTHING TO SEE HERE' 12 | 13 | .PARAMETER PrivateData 14 | The PrivateData parameter is what will be returned without transformation. 15 | 16 | #> 17 | [cmdletBinding()] 18 | [OutputType([string])] 19 | param 20 | ( 21 | [Parameter()] 22 | [String] 23 | $PrivateData 24 | ) 25 | 26 | process 27 | { 28 | Write-Output $PrivateData 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /Sampler/Templates/Sampler/Get-PrivateFunction.tests.ps1.template: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | $script:dscModuleName = '<%= ${PLASTER_PARAM_ModuleName} %>' 3 | 4 | Import-Module -Name $script:dscModuleName 5 | } 6 | 7 | AfterAll { 8 | # Unload the module being tested so that it doesn't impact any other tests. 9 | Get-Module -Name $script:dscModuleName -All | Remove-Module -Force 10 | } 11 | 12 | Describe Get-PrivateFunction { 13 | Context 'When calling the function with string value' { 14 | It 'Should return a single object' { 15 | InModuleScope -ModuleName $dscModuleName { 16 | $return = Get-PrivateFunction -PrivateData 'string' 17 | 18 | ($return | Measure-Object).Count | Should -Be 1 19 | } 20 | } 21 | 22 | It 'Should return a string based on the parameter PrivateData' { 23 | InModuleScope -ModuleName $dscModuleName { 24 | $return = Get-PrivateFunction -PrivateData 'string' 25 | 26 | $return | Should -Be 'string' 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Sampler/Templates/Sampler/Get-Something.ps1: -------------------------------------------------------------------------------- 1 | function Get-Something 2 | { 3 | <# 4 | .SYNOPSIS 5 | Sample Function to return input string. 6 | 7 | .DESCRIPTION 8 | This function is only a sample Advanced function that returns the Data given via parameter Data. 9 | 10 | .EXAMPLE 11 | Get-Something -Data 'Get me this text' 12 | 13 | 14 | .PARAMETER Data 15 | The Data parameter is the data that will be returned without transformation. 16 | 17 | #> 18 | [cmdletBinding( 19 | SupportsShouldProcess = $true, 20 | ConfirmImpact = 'Low' 21 | )] 22 | param 23 | ( 24 | [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] 25 | [String] 26 | $Data 27 | ) 28 | 29 | process 30 | { 31 | if ($pscmdlet.ShouldProcess($Data)) 32 | { 33 | Write-Verbose ('Returning the data: {0}' -f $Data) 34 | Get-PrivateFunction -PrivateData $Data 35 | } 36 | else 37 | { 38 | Write-Verbose 'oh dear' 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Sampler/Templates/Sampler/Get-Something.tests.ps1.template: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | $script:dscModuleName = '<%= ${PLASTER_PARAM_ModuleName} %>' 3 | 4 | Import-Module -Name $script:dscModuleName 5 | } 6 | 7 | AfterAll { 8 | # Unload the module being tested so that it doesn't impact any other tests. 9 | Get-Module -Name $script:dscModuleName -All | Remove-Module -Force 10 | } 11 | 12 | Describe Get-Something { 13 | BeforeAll { 14 | Mock -CommandName Get-PrivateFunction -MockWith { 15 | # This return the value passed to the Get-PrivateFunction parameter $PrivateData. 16 | $PrivateData 17 | } -ModuleName $dscModuleName 18 | } 19 | 20 | Context 'When passing values using named parameters' { 21 | It 'Should call the private function once' { 22 | { Get-Something -Data 'value' } | Should -Not -Throw 23 | 24 | Should -Invoke -CommandName Get-PrivateFunction -Exactly -Times 1 -Scope It -ModuleName $dscModuleName 25 | } 26 | 27 | It 'Should return a single object' { 28 | $return = Get-Something -Data 'value' 29 | 30 | ($return | Measure-Object).Count | Should -Be 1 31 | } 32 | 33 | It 'Should return the correct string value' { 34 | $return = Get-Something -Data 'value' 35 | 36 | $return | Should -Be 'value' 37 | } 38 | } 39 | 40 | Context 'When passing values over the pipeline' { 41 | It 'Should call the private function two times' { 42 | { 'value1', 'value2' | Get-Something } | Should -Not -Throw 43 | 44 | Should -Invoke -CommandName Get-PrivateFunction -Exactly -Times 2 -Scope It -ModuleName $dscModuleName 45 | } 46 | 47 | It 'Should return an array with two items' { 48 | $return = 'value1', 'value2' | Get-Something 49 | 50 | $return.Count | Should -Be 2 51 | } 52 | 53 | It 'Should return an array with the correct string values' { 54 | $return = 'value1', 'value2' | Get-Something 55 | 56 | $return[0] | Should -Be 'value1' 57 | $return[1] | Should -Be 'value2' 58 | } 59 | 60 | It 'Should accept values from the pipeline by property name' { 61 | $return = 'value1', 'value2' | ForEach-Object { 62 | [PSCustomObject]@{ 63 | Data = $_ 64 | OtherProperty = 'other' 65 | } 66 | } | Get-Something 67 | 68 | $return[0] | Should -Be 'value1' 69 | $return[1] | Should -Be 'value2' 70 | } 71 | } 72 | 73 | Context 'When passing WhatIf' { 74 | It 'Should support the parameter WhatIf' { 75 | (Get-Command -Name 'Get-Something').Parameters.ContainsKey('WhatIf') | Should -Be $true 76 | } 77 | 78 | It 'Should not call the private function' { 79 | { Get-Something -Data 'value' -WhatIf } | Should -Not -Throw 80 | 81 | Should -Invoke -CommandName Get-PrivateFunction -Exactly -Times 0 -Scope It -ModuleName $dscModuleName 82 | } 83 | 84 | It 'Should return $null' { 85 | $return = Get-Something -Data 'value' -WhatIf 86 | 87 | $return | Should -BeNullOrEmpty 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Sampler/Templates/Sampler/LICENSES/LICENSE.Apache.template: -------------------------------------------------------------------------------- 1 | <% 2 | "`nCopyright (c) {0} {1}`n" -f ([datetime]::Now.Year),$PLASTER_PARAM_ModuleAuthor 3 | %> 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. -------------------------------------------------------------------------------- /Sampler/Templates/Sampler/LICENSES/LICENSE.MIT.template: -------------------------------------------------------------------------------- 1 | MIT License 2 | <% 3 | "`nCopyright (c) {0} {1}`n" -f ([datetime]::Now.Year),$PLASTER_PARAM_ModuleAuthor 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. -------------------------------------------------------------------------------- /Sampler/Templates/Sampler/README.md.template: -------------------------------------------------------------------------------- 1 | <% 2 | @" 3 | # {0} 4 | 5 | {1} 6 | 7 | ## Make it yours 8 | 9 | --- 10 | Generated with Plaster and the SampleModule template 11 | 12 | "@ -f $PLASTER_PARAM_ModuleName,$PLASTER_PARAM_ModuleDescription 13 | %> 14 | 15 | This is a sample Readme 16 | 17 | ## Make it yours -------------------------------------------------------------------------------- /Sampler/Templates/Sampler/about_ModuleName.help.template: -------------------------------------------------------------------------------- 1 | TOPIC 2 | <% 3 | " about_{0}" -f $PLASTER_PARAM_ModuleName 4 | %> 5 | 6 | SHORT DESCRIPTION 7 | <% 8 | " {0}" -f $PLASTER_PARAM_ModuleDescription 9 | %> 10 | 11 | LONG DESCRIPTION 12 | <% 13 | " {0}" -f $PLASTER_PARAM_ModuleDescription 14 | %> 15 | 16 | EXAMPLES 17 | PS C:\> {{ add examples here }} 18 | 19 | NOTE: 20 | Thank you to all those who contributed to this module, by writing code, sharing opinions, and provided feedback. 21 | 22 | TROUBLESHOOTING NOTE: 23 | Look out on the Github repository for issues and new releases. 24 | 25 | SEE ALSO 26 | - {{ Please add Project URI such as github }}} 27 | 28 | KEYWORDS 29 | {{ Add comma separated keywords here }} 30 | -------------------------------------------------------------------------------- /Sampler/Templates/Sampler/appveyor.yml: -------------------------------------------------------------------------------- 1 | 2 | os: WMF 5 3 | 4 | build: false 5 | 6 | build_script: 7 | - ps: . .\.build.ps1 -ResolveDependency 8 | -------------------------------------------------------------------------------- /Sampler/Templates/Sampler/codecov.yml.template: -------------------------------------------------------------------------------- 1 | codecov: 2 | require_ci_to_pass: no 3 | # master should be the baseline for reporting 4 | branch: <%= ${PLASTER_PARAM_MainGitBranch} %> 5 | 6 | comment: 7 | layout: "reach, diff, flags, files" 8 | behavior: default 9 | 10 | coverage: 11 | range: 50..80 12 | round: down 13 | precision: 0 14 | 15 | status: 16 | project: 17 | default: 18 | # Set the overall project code coverage requirement to 70% 19 | target: 70 20 | patch: 21 | default: 22 | # Set the pull request requirement to not regress overall coverage by more than 5% 23 | # and let codecov.io set the goal for the code changed in the patch. 24 | target: auto 25 | threshold: 5 26 | <% 27 | if ($PLASTER_PARAM_ModuleType -in @('dsccommunity')) { 28 | @" 29 | 30 | # This is not needed if the module only contain class-based resources. 31 | fixes: 32 | - '^\d+\.\d+\.\d+::source' # move path "X.Y.Z" => "source" 33 | 34 | "@ 35 | } 36 | %> 37 | # Use this if there are paths that should not be part of the code coverage, for 38 | # example a deprecated function where tests has been removed. 39 | #ignore: 40 | # - 'source/Public/Get-Deprecated.ps1' 41 | -------------------------------------------------------------------------------- /Sampler/Templates/Sampler/kitchen.yml.template: -------------------------------------------------------------------------------- 1 | --- 2 | provisioner: 3 | name: dsc 4 | dsc_local_configuration_manager_version: wmf5 5 | dsc_local_configuration_manager: 6 | reboot_if_needed: true 7 | configuration_mode_frequency_mins: 15 8 | debug_mode: none 9 | <% 10 | @" 11 | configuration_script_folder: {0}/examples 12 | "@ -f $PLASTER_PARAM_ModuleName 13 | %> 14 | configuration_script: dsc_configuration.ps1 15 | modules_path: modules 16 | retry_on_exit_code: 17 | - 35 18 | configuration_data_variable: configurationData 19 | modules_from_gallery: 20 | - xPSDesiredStateConfiguration 21 | #- PackageManagementProviderResource 22 | 23 | verifier: 24 | name: pester 25 | <% 26 | @" 27 | test_folder: {0}/tests/integration/ 28 | 29 | "@ -f $PLASTER_PARAM_ModuleName 30 | %> 31 | platforms: 32 | - name: win2012r2_PPB 33 | os_type: windows 34 | shell: powershell 35 | 36 | suites: 37 | - name: Default 38 | -------------------------------------------------------------------------------- /Sampler/Templates/Sampler/markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "default": true, 3 | "MD029": { 4 | "style": "one" 5 | }, 6 | "MD013": true, 7 | "MD024": false, 8 | "MD034": false, 9 | "no-hard-tabs": true 10 | } 11 | -------------------------------------------------------------------------------- /Sampler/Templates/Sampler/module.template: -------------------------------------------------------------------------------- 1 | <# 2 | This file is intentionally left empty. It is must be left here for the module 3 | manifest to refer to. It is recreated during the build process. 4 | #> 5 | -------------------------------------------------------------------------------- /Sampler/Templates/VscodeConfig/analyzersettings.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | CustomRulePath = '.\output\RequiredModules\DscResource.AnalyzerRules' 3 | includeDefaultRules = $true 4 | IncludeRules = @( 5 | # DSC Resource Kit style guideline rules. 6 | 'PSAvoidDefaultValueForMandatoryParameter', 7 | 'PSAvoidDefaultValueSwitchParameter', 8 | 'PSAvoidInvokingEmptyMembers', 9 | 'PSAvoidNullOrEmptyHelpMessageAttribute', 10 | 'PSAvoidUsingCmdletAliases', 11 | 'PSAvoidUsingComputerNameHardcoded', 12 | 'PSAvoidUsingDeprecatedManifestFields', 13 | 'PSAvoidUsingEmptyCatchBlock', 14 | 'PSAvoidUsingInvokeExpression', 15 | 'PSAvoidUsingPositionalParameters', 16 | 'PSAvoidShouldContinueWithoutForce', 17 | 'PSAvoidUsingWMICmdlet', 18 | 'PSAvoidUsingWriteHost', 19 | 'PSDSCReturnCorrectTypesForDSCFunctions', 20 | 'PSDSCStandardDSCFunctionsInResource', 21 | 'PSDSCUseIdenticalMandatoryParametersForDSC', 22 | 'PSDSCUseIdenticalParametersForDSC', 23 | 'PSMisleadingBacktick', 24 | 'PSMissingModuleManifestField', 25 | 'PSPossibleIncorrectComparisonWithNull', 26 | 'PSProvideCommentHelp', 27 | 'PSReservedCmdletChar', 28 | 'PSReservedParams', 29 | 'PSUseApprovedVerbs', 30 | 'PSUseCmdletCorrectly', 31 | 'PSUseOutputTypeCorrectly', 32 | 'PSAvoidGlobalVars', 33 | 'PSAvoidUsingConvertToSecureStringWithPlainText', 34 | 'PSAvoidUsingPlainTextForPassword', 35 | 'PSAvoidUsingUsernameAndPasswordParams', 36 | 'PSDSCUseVerboseMessageInDSCResource', 37 | 'PSShouldProcess', 38 | 'PSUseDeclaredVarsMoreThanAssignments', 39 | 'PSUsePSCredentialType', 40 | 41 | 'Measure-*' 42 | ) 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Sampler/Templates/VscodeConfig/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "davidanson.vscode-markdownlint", 4 | "ms-vscode.powershell", 5 | "streetsidesoftware.code-spell-checker", 6 | "redhat.vscode-yaml" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /Sampler/Templates/VscodeConfig/plasterManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | VscodeConfig 6 | 48fd55d5-306a-4f98-b65f-a516f652d228 7 | 0.0.2 8 | VscodeConfig Template 9 | A template to add a .vscode config with settings, Analyzersettings and tasks to a Sampler Project 10 | Gael Colas 11 | Sampler,Template, Build, Module, vscode 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | 24 | 27 | 28 | 29 | 32 | 33 | 34 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Sampler/Templates/VscodeConfig/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "powershell.codeFormatting.openBraceOnSameLine": false, 3 | "powershell.codeFormatting.newLineAfterOpenBrace": true, 4 | "powershell.codeFormatting.newLineAfterCloseBrace": true, 5 | "powershell.codeFormatting.whitespaceBeforeOpenBrace": true, 6 | "powershell.codeFormatting.whitespaceBeforeOpenParen": true, 7 | "powershell.codeFormatting.whitespaceAroundOperator": true, 8 | "powershell.codeFormatting.whitespaceAfterSeparator": true, 9 | "powershell.codeFormatting.ignoreOneLineBlock": false, 10 | "powershell.codeFormatting.pipelineIndentationStyle": "IncreaseIndentationAfterEveryPipeline", 11 | "powershell.codeFormatting.preset": "Custom", 12 | "powershell.codeFormatting.alignPropertyValuePairs": true, 13 | "powershell.developer.bundledModulesPath": "${cwd}/output/RequiredModules", 14 | "powershell.scriptAnalysis.settingsPath": ".vscode\\analyzersettings.psd1", 15 | "powershell.scriptAnalysis.enable": true, 16 | "files.trimTrailingWhitespace": true, 17 | "files.trimFinalNewlines": true, 18 | "files.insertFinalNewline": true, 19 | "files.associations": { 20 | "*.ps1xml": "xml" 21 | }, 22 | "cSpell.words": [ 23 | "COMPANYNAME", 24 | "ICONURI", 25 | "LICENSEURI", 26 | "PROJECTURI", 27 | "RELEASENOTES", 28 | "buildhelpers", 29 | "endregion", 30 | "gitversion", 31 | "icontains", 32 | "keepachangelog", 33 | "notin", 34 | "pscmdlet", 35 | "steppable" 36 | ], 37 | "[markdown]": { 38 | "files.trimTrailingWhitespace": false, 39 | "files.encoding": "utf8" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Sampler/WikiSource/Home.md: -------------------------------------------------------------------------------- 1 | # Welcome to the Sampler wiki 2 | 3 | *Sampler v#.#.#* 4 | 5 | Here you will find all the information you need to make use of Sampler. 6 | 7 | Please leave comments, feature requests, and bug reports for this module in 8 | the [issues section](https://github.com/gaelcolas/Sampler/issues) 9 | for this repository. 10 | 11 | ## Getting started 12 | 13 | To get started either: 14 | 15 | - Install from the PowerShell Gallery using PowerShellGet by running the 16 | following command: 17 | 18 | ```powershell 19 | Install-Module -Name Sampler -Repository PSGallery 20 | ``` 21 | 22 | ## Prerequisites 23 | 24 | - PowerShell 5.1 or higher 25 | 26 | ## Change log 27 | 28 | A full list of changes in each version can be found in the [change log](https://github.com/gaelcolas/Sampler/blob/main/CHANGELOG.md). 29 | -------------------------------------------------------------------------------- /Sampler/assets/Sampler_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gaelcolas/Sampler/1a8b5982399c56b1d2c91a853fecef9483ab9f2d/Sampler/assets/Sampler_512.png -------------------------------------------------------------------------------- /Sampler/en-US/Sampler.strings.psd1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | The localized resource strings in English (en-US). This file should only 4 | contain localized strings for private functions, public command, and classes 5 | (that are not a DSC resources). 6 | #> 7 | 8 | ConvertFrom-StringData @' 9 | '@ 10 | -------------------------------------------------------------------------------- /Sampler/en-US/about_Sampler.help.txt: -------------------------------------------------------------------------------- 1 | TOPIC 2 | about_Sampler 3 | 4 | SHORT DESCRIPTION 5 | Template for PowerShell Modules & DSC Resources 6 | 7 | LONG DESCRIPTION 8 | This project is an attempt to provide a template and build pipeline for Powershell 9 | modules and DSC Resources. 10 | 11 | EXAMPLES 12 | PS C:\> 13 | 14 | NOTE: 15 | Thank you to all those who contributed to this module, by writing code, sharing opinions, and provided feedback. 16 | 17 | TROUBLESHOOTING NOTE: 18 | Look out on the Github repository for issues and new releases. 19 | 20 | SEE ALSO 21 | - https://github.com/gaelcolas/Sampler 22 | 23 | KEYWORDS 24 | Module, Build, Task, Template 25 | -------------------------------------------------------------------------------- /Sampler/suffix.ps1: -------------------------------------------------------------------------------- 1 | # Inspired from https://github.com/nightroman/Invoke-Build/blob/64f3434e1daa806814852049771f4b7d3ec4d3a3/Tasks/Import/README.md#example-2-import-from-a-module-with-tasks 2 | Get-ChildItem -Path (Join-Path -Path $PSScriptRoot -ChildPath 'tasks\*') -Include '*.build.*' | 3 | ForEach-Object -Process { 4 | $ModuleName = ([System.IO.FileInfo] $MyInvocation.MyCommand.Name).BaseName 5 | $taskFileAliasName = "$($_.BaseName).$ModuleName.ib.tasks" 6 | 7 | Set-Alias -Name $taskFileAliasName -Value $_.FullName 8 | } 9 | 10 | $SetSamplerTaskVariableAliasName = 'Set-SamplerTaskVariable' 11 | $SetSamplerTaskVariableAliasValue = "$PSScriptRoot/scripts/Set-SamplerTaskVariable.ps1" 12 | Set-Alias -Name $SetSamplerTaskVariableAliasName -Value $SetSamplerTaskVariableAliasValue 13 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | require_ci_to_pass: no 3 | # main should be the baseline for reporting 4 | branch: main 5 | 6 | comment: 7 | layout: "reach, diff, flags, files" 8 | behavior: default 9 | 10 | coverage: 11 | range: 50..80 12 | round: down 13 | precision: 0 14 | 15 | status: 16 | project: 17 | default: 18 | # Set the overall project code coverage requirement to 70% 19 | target: 70 20 | patch: 21 | default: 22 | # Set the pull request requirement to not regress overall coverage by more than 5% 23 | # and let codecov.io set the goal for the code changed in the patch. 24 | target: auto 25 | threshold: 5 26 | 27 | fixes: 28 | - '^\d+\.\d+\.\d+\/tasks::.build/tasks' # move path "X.Y.Z/tasks" => ".build/tasks" 29 | - '^Sampler\/tasks::.build/tasks' # move path "Sampler/tasks" => ".build/tasks" 30 | 31 | ignore: 32 | - '.build\tasks\DscResource.Test.build.ps1' # Deprecated HQRM tasks 33 | -------------------------------------------------------------------------------- /tests/Integration/IntegrationTestHelpers.psm1: -------------------------------------------------------------------------------- 1 | function Install-TreeCommand 2 | { 3 | if (-not (Get-Command -Name 'tree' -ErrorAction 'SilentlyContinue')) 4 | { 5 | if ($IsMacOS) 6 | { 7 | brew install tree 8 | } 9 | 10 | if ($IsLinux) 11 | { 12 | sudo apt-get install tree 13 | } 14 | } 15 | } 16 | 17 | function Get-DirectoryTree 18 | { 19 | [CmdletBinding()] 20 | [OutputType([System.String])] 21 | param 22 | ( 23 | [Parameter(Mandatory = $true)] 24 | [System.String] 25 | $Path 26 | ) 27 | 28 | $treeOutput = switch ($true) 29 | { 30 | { $IsLinux -or $IsMacOS } 31 | { 32 | tree -a $Path 33 | } 34 | 35 | # Assume Windows 36 | default 37 | { 38 | tree /f $Path 39 | } 40 | } 41 | 42 | return $treeOutput 43 | } 44 | -------------------------------------------------------------------------------- /tests/Unit/Private/New-SamplerXmlJaCoCoCounter.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | $script:moduleName = 'Sampler' 3 | 4 | # If the module is not found, run the build task 'noop'. 5 | if (-not (Get-Module -Name $script:moduleName -ListAvailable)) 6 | { 7 | # Redirect all streams to $null, except the error stream (stream 2) 8 | & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null 9 | } 10 | 11 | # Re-import the module using force to get any code changes between runs. 12 | Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' 13 | 14 | $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName 15 | $PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName 16 | $PSDefaultParameterValues['Should:ModuleName'] = $script:moduleName 17 | } 18 | 19 | AfterAll { 20 | $PSDefaultParameterValues.Remove('Mock:ModuleName') 21 | $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') 22 | $PSDefaultParameterValues.Remove('Should:ModuleName') 23 | 24 | Remove-Module -Name $script:moduleName 25 | } 26 | 27 | Describe 'New-SamplerXmlJaCoCoCounter' { 28 | 29 | Context 'When calling without PassThru' { 30 | It 'Should append the correct element' { 31 | InModuleScope -ScriptBlock { 32 | $mockXmlDocument = New-Object -TypeName 'System.Xml.XmlDocument' 33 | $mockElement = $mockXmlDocument.CreateElement('report') 34 | 35 | { New-SamplerXmlJaCoCoCounter -XmlNode $mockElement -CounterType 'LINE' -Covered 2 -Missed 1 } | Should -Not -Throw 36 | 37 | $mockElement.OuterXml | Should -Be '' 38 | } 39 | } 40 | } 41 | 42 | Context 'When calling with PassThru' { 43 | It 'Should append the correct element' { 44 | InModuleScope -ScriptBlock { 45 | $mockXmlDocument = New-Object -TypeName 'System.Xml.XmlDocument' 46 | $mockElement = $mockXmlDocument.CreateElement('report') 47 | 48 | $result = New-SamplerXmlJaCoCoCounter -XmlNode $mockElement -CounterType 'LINE' -Covered 2 -Missed 1 -PassThru 49 | 50 | $mockElement.OuterXml | Should -Be '' 51 | 52 | $result.OuterXml | Should -Be '' 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tests/Unit/Public/Add-Sample.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | $script:moduleName = 'Sampler' 3 | 4 | # If the module is not found, run the build task 'noop'. 5 | if (-not (Get-Module -Name $script:moduleName -ListAvailable)) 6 | { 7 | # Redirect all streams to $null, except the error stream (stream 2) 8 | & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null 9 | } 10 | 11 | # Re-import the module using force to get any code changes between runs. 12 | Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' 13 | 14 | $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName 15 | $PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName 16 | $PSDefaultParameterValues['Should:ModuleName'] = $script:moduleName 17 | } 18 | 19 | AfterAll { 20 | $PSDefaultParameterValues.Remove('Mock:ModuleName') 21 | $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') 22 | $PSDefaultParameterValues.Remove('Should:ModuleName') 23 | 24 | Remove-Module -Name $script:moduleName 25 | } 26 | 27 | BeforeDiscovery { 28 | $testCases = @( 29 | <# 30 | If the templates do not define those parameters, Invoke-Plaster will fail and this test will catch it. 31 | The template integration is done separately, hence why we don't need to test it here. 32 | We only test that the Add-Sample parameters & parameter set work with the templates we have defined. 33 | #> 34 | @{ 35 | TestCaseName = 'classes' 36 | AddSampleParameters = @{ 37 | Sample = 'Classes' 38 | SourceDirectory = 'Source' 39 | } 40 | } 41 | @{ 42 | TestCaseName = 'ClassResource' 43 | AddSampleParameters = @{ 44 | Sample = 'ClassResource' 45 | ResourceName = 'MyResource' 46 | SourceDirectory = 'source' 47 | } 48 | } 49 | @{ 50 | TestCaseName = 'Examples' 51 | AddSampleParameters = @{ 52 | Sample = 'Examples' 53 | } 54 | } 55 | ) 56 | } 57 | 58 | Describe Add-Sample { 59 | Context 'Invoke plaster with correct parameters for template' { 60 | BeforeAll { 61 | Mock -CommandName Invoke-Plaster 62 | } 63 | 64 | It 'New-Sample module should call Invoke-Plaster with test case ' -ForEach $testCases { 65 | # Test drive does not exist during discovery phase so it needs to be set here. 66 | $AddSampleParameters.DestinationPath = $TestDrive 67 | 68 | { Sampler\Add-Sample @AddSampleParameters } | Should -Not -Throw 69 | 70 | Should -Invoke -CommandName Invoke-Plaster -Exactly -Times 1 -Scope It 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /tests/Unit/Public/Convert-SamplerHashtableToString.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | $script:moduleName = 'Sampler' 3 | 4 | # If the module is not found, run the build task 'noop'. 5 | if (-not (Get-Module -Name $script:moduleName -ListAvailable)) 6 | { 7 | # Redirect all streams to $null, except the error stream (stream 2) 8 | & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null 9 | } 10 | 11 | # Re-import the module using force to get any code changes between runs. 12 | Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' 13 | 14 | $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName 15 | $PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName 16 | $PSDefaultParameterValues['Should:ModuleName'] = $script:moduleName 17 | } 18 | 19 | AfterAll { 20 | $PSDefaultParameterValues.Remove('Mock:ModuleName') 21 | $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') 22 | $PSDefaultParameterValues.Remove('Should:ModuleName') 23 | 24 | Remove-Module -Name $script:moduleName 25 | } 26 | 27 | Describe 'Convert-SamplerHashtableToString' { 28 | It 'Should convert the hashtable with a single value to the expected string' { 29 | $result = Sampler\Convert-SamplerHashtableToString -Hashtable @{ 30 | a = 1 31 | } 32 | 33 | $result | Should -Be 'a=1' 34 | } 35 | 36 | It 'Should convert the hashtable with two values to the expected string' { 37 | $result = Sampler\Convert-SamplerHashtableToString -Hashtable @{ 38 | a = 1 39 | b = 2 40 | } 41 | 42 | $result | Should -Be 'a=1; b=2' 43 | } 44 | 45 | It 'Should convert the hashtable with a single child hashtable to the expected string' { 46 | $result = Sampler\Convert-SamplerHashtableToString -Hashtable @{ 47 | d = @{ 48 | dd = 'abcd' 49 | } 50 | } 51 | 52 | $result | Should -Be 'd={dd=abcd}' 53 | } 54 | 55 | It 'Should convert the hashtable with multiple values and levels to the expected string' { 56 | $result = Sampler\Convert-SamplerHashtableToString -Hashtable @{ 57 | a = 1 58 | b = 2 59 | c = 3 60 | d = @{ 61 | dd = @{ 62 | ddd = 'abcd' 63 | } 64 | } 65 | } 66 | 67 | $result | Should -Be 'a=1; b=2; c=3; d={dd={ddd=abcd}}' 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /tests/Unit/Public/Get-BuiltModuleVersion.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | $script:moduleName = 'Sampler' 3 | 4 | # If the module is not found, run the build task 'noop'. 5 | if (-not (Get-Module -Name $script:moduleName -ListAvailable)) 6 | { 7 | # Redirect all streams to $null, except the error stream (stream 2) 8 | & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null 9 | } 10 | 11 | # Re-import the module using force to get any code changes between runs. 12 | Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' 13 | 14 | $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName 15 | $PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName 16 | $PSDefaultParameterValues['Should:ModuleName'] = $script:moduleName 17 | } 18 | 19 | AfterAll { 20 | $PSDefaultParameterValues.Remove('Mock:ModuleName') 21 | $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') 22 | $PSDefaultParameterValues.Remove('Should:ModuleName') 23 | 24 | Remove-Module -Name $script:moduleName 25 | } 26 | 27 | Describe 'Get-BuiltModuleVersion' { 28 | BeforeAll { 29 | Mock -CommandName Get-SamplerBuiltModuleManifest -MockWith { 30 | return (Join-Path -Path $TestDrive -ChildPath 'MyModule.psd1') 31 | } 32 | } 33 | 34 | Context 'When module version is full release' { 35 | BeforeAll { 36 | Mock -CommandName Import-PowerShellDataFile -MockWith { 37 | return @{ 38 | 'ModuleVersion' = '2.1.1' 39 | } 40 | } 41 | } 42 | 43 | It 'Should return the correct semantic version' { 44 | $result = Sampler\Get-BuiltModuleVersion -OutputDirectory $TestDrive -ModuleName 'MyModule' 45 | 46 | $result | Should -Be '2.1.1' 47 | } 48 | } 49 | 50 | Context 'When module version is preview release' { 51 | BeforeAll { 52 | Mock -CommandName Import-PowerShellDataFile -MockWith { 53 | return @{ 54 | 'ModuleVersion' = '2.1.1' 55 | 'PrivateData' = @{ 56 | PSData = @{ 57 | Prerelease = 'preview.1' 58 | } 59 | } 60 | } 61 | } 62 | } 63 | 64 | It 'Should return the correct semantic version' { 65 | $result = Sampler\Get-BuiltModuleVersion -OutputDirectory $TestDrive -ModuleName 'MyModule' 66 | 67 | $result | Should -Be '2.1.1-preview.1' 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /tests/Unit/Public/Get-ClassBasedResourceName.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | $script:moduleName = 'Sampler' 3 | 4 | # If the module is not found, run the build task 'noop'. 5 | if (-not (Get-Module -Name $script:moduleName -ListAvailable)) 6 | { 7 | # Redirect all streams to $null, except the error stream (stream 2) 8 | & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null 9 | } 10 | 11 | # Re-import the module using force to get any code changes between runs. 12 | Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' 13 | 14 | $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName 15 | $PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName 16 | $PSDefaultParameterValues['Should:ModuleName'] = $script:moduleName 17 | } 18 | 19 | AfterAll { 20 | $PSDefaultParameterValues.Remove('Mock:ModuleName') 21 | $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') 22 | $PSDefaultParameterValues.Remove('Should:ModuleName') 23 | 24 | Remove-Module -Name $script:moduleName 25 | } 26 | 27 | Describe 'Get-ClassBasedResourceName' { 28 | BeforeAll { 29 | $classScriptFilePath = Join-Path -Path $TestDrive -ChildPath 'MockClassBasedResource.ps1' 30 | 31 | $mockScript = @' 32 | [DscResource()] 33 | class MockResourceName 34 | { 35 | [DscProperty(Key)] 36 | [System.String] 37 | $Name 38 | 39 | [DscProperty()] 40 | [System.String] 41 | $Parameter1 42 | 43 | [DnsRecordA] Get() 44 | { 45 | return @{ 46 | Name = $Name 47 | Parameter1 = $Parameter1 48 | } 49 | } 50 | 51 | [void] Set() 52 | { 53 | } 54 | 55 | [System.Boolean] Test() 56 | { 57 | return $true 58 | } 59 | } 60 | '@ 61 | $mockScript | Out-File -FilePath $classScriptFilePath -Encoding 'UTF8' -Force 62 | } 63 | 64 | It 'Should return the correct resource name' { 65 | 66 | $result = Sampler\Get-ClassBasedResourceName -Path $classScriptFilePath 67 | 68 | $result | Should -Be 'MockResourceName' 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /tests/Unit/Public/Get-PesterOutputFileFileName.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | $script:moduleName = 'Sampler' 3 | 4 | # If the module is not found, run the build task 'noop'. 5 | if (-not (Get-Module -Name $script:moduleName -ListAvailable)) 6 | { 7 | # Redirect all streams to $null, except the error stream (stream 2) 8 | & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null 9 | } 10 | 11 | # Re-import the module using force to get any code changes between runs. 12 | Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' 13 | 14 | $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName 15 | $PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName 16 | $PSDefaultParameterValues['Should:ModuleName'] = $script:moduleName 17 | } 18 | 19 | AfterAll { 20 | $PSDefaultParameterValues.Remove('Mock:ModuleName') 21 | $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') 22 | $PSDefaultParameterValues.Remove('Should:ModuleName') 23 | 24 | Remove-Module -Name $script:moduleName 25 | } 26 | 27 | Describe 'Get-PesterOutputFileFileName' { 28 | It 'should return the corret file name' { 29 | $getPesterOutputFileFileNameParameters = @{ 30 | ProjectName = 'MyModule' 31 | ModuleVersion = '2.0.0' 32 | OsShortName = 'Windows' 33 | PowerShellVersion = '7.2' 34 | } 35 | 36 | $result = Sampler\Get-PesterOutputFileFileName @getPesterOutputFileFileNameParameters 37 | 38 | $result | Should -Be 'MyModule_v2.0.0.Windows.7.2.xml' 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /tests/Unit/Public/Get-SamplerBuiltModuleManifest.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | $script:moduleName = 'Sampler' 3 | 4 | # If the module is not found, run the build task 'noop'. 5 | if (-not (Get-Module -Name $script:moduleName -ListAvailable)) 6 | { 7 | # Redirect all streams to $null, except the error stream (stream 2) 8 | & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null 9 | } 10 | 11 | # Re-import the module using force to get any code changes between runs. 12 | Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' 13 | 14 | $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName 15 | $PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName 16 | $PSDefaultParameterValues['Should:ModuleName'] = $script:moduleName 17 | } 18 | 19 | AfterAll { 20 | $PSDefaultParameterValues.Remove('Mock:ModuleName') 21 | $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') 22 | $PSDefaultParameterValues.Remove('Should:ModuleName') 23 | 24 | Remove-Module -Name $script:moduleName 25 | } 26 | 27 | Describe 'Get-SamplerBuiltModuleManifest' { 28 | BeforeAll { 29 | Mock -CommandName Get-SamplerBuiltModuleBase -MockWith { 30 | return (Join-Path -Path $TestDrive -ChildPath 'MyModule') 31 | } 32 | } 33 | 34 | It 'Should return the correct file path' { 35 | $result = Sampler\Get-SamplerBuiltModuleManifest -OutputDirectory $TestDrive -ModuleName 'MyModule' 36 | 37 | $result | Should -Be (Join-Path -Path $TestDrive -ChildPath (Join-Path -Path 'MyModule' -ChildPath 'MyModule.psd1')) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/Unit/Public/Get-SamplerCodeCoverageOutputFileEncoding.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | $script:moduleName = 'Sampler' 3 | 4 | # If the module is not found, run the build task 'noop'. 5 | if (-not (Get-Module -Name $script:moduleName -ListAvailable)) 6 | { 7 | # Redirect all streams to $null, except the error stream (stream 2) 8 | & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null 9 | } 10 | 11 | # Re-import the module using force to get any code changes between runs. 12 | Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' 13 | 14 | $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName 15 | $PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName 16 | $PSDefaultParameterValues['Should:ModuleName'] = $script:moduleName 17 | } 18 | 19 | AfterAll { 20 | $PSDefaultParameterValues.Remove('Mock:ModuleName') 21 | $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') 22 | $PSDefaultParameterValues.Remove('Should:ModuleName') 23 | 24 | Remove-Module -Name $script:moduleName 25 | } 26 | 27 | Describe 'Get-SamplerCodeCoverageOutputFileEncoding' { 28 | It 'Should return $null' { 29 | $result = Sampler\Get-SamplerCodeCoverageOutputFileEncoding -BuildInfo @{} 30 | 31 | $result | Should -BeNullOrEmpty 32 | } 33 | 34 | It 'Should return the correct file encoding' { 35 | $result = Sampler\Get-SamplerCodeCoverageOutputFileEncoding -BuildInfo @{ 36 | Pester = @{ 37 | CodeCoverageOutputFileEncoding = 'UTF8' 38 | } 39 | } 40 | 41 | $result | Should -Be 'UTF8' 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tests/Unit/Public/Get-SamplerModuleRootPath.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | $script:moduleName = 'Sampler' 3 | 4 | # If the module is not found, run the build task 'noop'. 5 | if (-not (Get-Module -Name $script:moduleName -ListAvailable)) 6 | { 7 | # Redirect all streams to $null, except the error stream (stream 2) 8 | & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null 9 | } 10 | 11 | # Re-import the module using force to get any code changes between runs. 12 | Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' 13 | 14 | $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName 15 | $PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName 16 | $PSDefaultParameterValues['Should:ModuleName'] = $script:moduleName 17 | } 18 | 19 | AfterAll { 20 | $PSDefaultParameterValues.Remove('Mock:ModuleName') 21 | $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') 22 | $PSDefaultParameterValues.Remove('Should:ModuleName') 23 | 24 | Remove-Module -Name $script:moduleName 25 | } 26 | 27 | Describe 'Get-SamplerModuleRootPath' { 28 | Context 'When module manifest does not contain the property RootModule' { 29 | BeforeAll { 30 | Mock -CommandName Get-SamplerModuleInfo -MockWith { 31 | return @{} 32 | } 33 | } 34 | 35 | It 'Should return $null' { 36 | $result = Sampler\Get-SamplerModuleRootPath -ModuleManifestPath $TestDrive 37 | 38 | $result | Should -BeNullOrEmpty 39 | } 40 | } 41 | 42 | Context 'When module manifest property RootModule' { 43 | BeforeAll { 44 | Mock -CommandName Get-SamplerModuleInfo -MockWith { 45 | return @{ 46 | RootModule = 'MyModule.psm1' 47 | } 48 | } 49 | } 50 | 51 | It 'Should return $null' { 52 | $result = Sampler\Get-SamplerModuleRootPath -ModuleManifestPath (Join-Path -Path $TestDrive -ChildPath 'MyModule') 53 | 54 | $result | Should -Be (Join-Path -Path $TestDrive -ChildPath 'MyModule.psm1') 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /tests/Unit/Public/Get-SamplerProjectName.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | $script:moduleName = 'Sampler' 3 | 4 | # If the module is not found, run the build task 'noop'. 5 | if (-not (Get-Module -Name $script:moduleName -ListAvailable)) 6 | { 7 | # Redirect all streams to $null, except the error stream (stream 2) 8 | & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null 9 | } 10 | 11 | # Re-import the module using force to get any code changes between runs. 12 | Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' 13 | 14 | $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName 15 | $PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName 16 | $PSDefaultParameterValues['Should:ModuleName'] = $script:moduleName 17 | } 18 | 19 | AfterAll { 20 | $PSDefaultParameterValues.Remove('Mock:ModuleName') 21 | $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') 22 | $PSDefaultParameterValues.Remove('Should:ModuleName') 23 | 24 | Remove-Module -Name $script:moduleName 25 | } 26 | 27 | Describe 'Get-SamplerProjectName' { 28 | BeforeAll { 29 | Mock -CommandName Get-SamplerProjectModuleManifest -MockWith { 30 | return @{ 31 | BaseName = 'MyModule' 32 | } 33 | } 34 | } 35 | 36 | It 'Should return the project name' { 37 | $result = Sampler\Get-SamplerProjectName -BuildRoot $TestDrive 38 | 39 | $result | Should -Be 'MyModule' 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/Unit/Public/New-SampleModule.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | $script:moduleName = 'Sampler' 3 | 4 | # If the module is not found, run the build task 'noop'. 5 | if (-not (Get-Module -Name $script:moduleName -ListAvailable)) 6 | { 7 | # Redirect all streams to $null, except the error stream (stream 2) 8 | & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null 9 | } 10 | 11 | # Re-import the module using force to get any code changes between runs. 12 | Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' 13 | 14 | $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName 15 | $PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName 16 | $PSDefaultParameterValues['Should:ModuleName'] = $script:moduleName 17 | } 18 | 19 | AfterAll { 20 | $PSDefaultParameterValues.Remove('Mock:ModuleName') 21 | $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') 22 | $PSDefaultParameterValues.Remove('Should:ModuleName') 23 | 24 | Remove-Module -Name $script:moduleName 25 | } 26 | 27 | BeforeDiscovery { 28 | $testCases = @( 29 | <# 30 | If the templates do not define those parameters, Invoke-Plaster will fail and this test will catch it. 31 | The template integration is done separately, hence why we don't need to test it here. 32 | We only test that the New-SampleModule parameters & parameter set work with the template we have defined. 33 | #> 34 | @{ 35 | TestCaseName = 'CompleteSample_NoLicense' 36 | NewSampleModuleParameters = @{ 37 | ModuleName = 'MyModule' 38 | ModuleVersion = '0.0.1' 39 | ModuleAuthor = "test user" 40 | LicenseType = 'None' 41 | ModuleType = 'CompleteSample' 42 | } 43 | } 44 | @{ 45 | TestCaseName = 'SimpleModule_MIT' 46 | NewSampleModuleParameters = @{ 47 | ModuleName = 'MyModule' 48 | ModuleVersion = '0.0.1' 49 | ModuleAuthor = "test user" 50 | LicenseType = 'MIT' 51 | ModuleType = 'SimpleModule' 52 | } 53 | } 54 | ) 55 | } 56 | 57 | Describe New-SampleModule { 58 | Context 'Invoke plaster with correct parameters for template' { 59 | BeforeAll { 60 | Mock -CommandName Invoke-Plaster 61 | } 62 | 63 | It 'New-Sample module should call Invoke-Plaster with test case ' -ForEach $testCases { 64 | $NewSampleModuleParameters.DestinationPath = $TestDrive 65 | 66 | { Sampler\New-SampleModule @NewSampleModuleParameters } | Should -Not -Throw 67 | 68 | Should -Invoke -CommandName Invoke-Plaster -Scope It -Times 1 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /tests/Unit/Public/New-SamplerPipeline.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | $script:moduleName = 'Sampler' 3 | 4 | # If the module is not found, run the build task 'noop'. 5 | if (-not (Get-Module -Name $script:moduleName -ListAvailable)) 6 | { 7 | # Redirect all streams to $null, except the error stream (stream 2) 8 | & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null 9 | } 10 | 11 | # Re-import the module using force to get any code changes between runs. 12 | Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' 13 | 14 | $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName 15 | $PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName 16 | $PSDefaultParameterValues['Should:ModuleName'] = $script:moduleName 17 | } 18 | 19 | AfterAll { 20 | $PSDefaultParameterValues.Remove('Mock:ModuleName') 21 | $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') 22 | $PSDefaultParameterValues.Remove('Should:ModuleName') 23 | 24 | Remove-Module -Name $script:moduleName 25 | } 26 | 27 | BeforeDiscovery { 28 | $testCases = @( 29 | <# 30 | If the templates do not define those parameters, Invoke-Plaster will fail and this test will catch it. 31 | The template integration is done separately, hence why we don't need to test it here. 32 | We only test that the Add-Sample parameters & parameter set work with the templates we have defined. 33 | #> 34 | @{ 35 | TestCaseName = 'Build' 36 | NewSamplerPipelineParameters = @{ 37 | Pipeline = 'Build' 38 | ProjectName = 'MyBuild' 39 | License = 'true' 40 | LicenseType = 'MIT' 41 | SourceDirectory = 'Source' 42 | MainGitBranch = 'main' 43 | ModuleDescription = 'some desc' 44 | CustomRepo = 'PSGallery' 45 | Features = 'All' 46 | } 47 | } 48 | @{ 49 | TestCaseName = 'ChocolateyPipeline' 50 | NewSamplerPipelineParameters = @{ 51 | Pipeline = 'ChocolateyPipeline' 52 | ProjectName = 'MyChoco' 53 | License = 'true' 54 | LicenseType = 'MIT' 55 | SourceDirectory = 'Source' 56 | MainGitBranch = 'main' 57 | ModuleDescription = 'some desc' 58 | CustomRepo = 'PSGallery' 59 | Features = 'All' 60 | } 61 | } 62 | ) 63 | } 64 | 65 | Describe New-SamplerPipeline { 66 | Context 'invoke plaster with correct parameters for template' { 67 | BeforeAll { 68 | Mock -CommandName Invoke-Plaster 69 | } 70 | 71 | It 'New-SamplerPipeline should call Invoke-Plaster with test case ' -ForEach $testCases { 72 | $NewSamplerPipelineParameters.DestinationPath = $TestDrive 73 | 74 | { Sampler\New-SamplerPipeline @NewSamplerPipelineParameters } | Should -Not -Throw 75 | 76 | Should -Invoke -CommandName Invoke-Plaster -Scope It -Times 1 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /tests/Unit/Public/Out-SamplerXml.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | $script:moduleName = 'Sampler' 3 | 4 | # If the module is not found, run the build task 'noop'. 5 | if (-not (Get-Module -Name $script:moduleName -ListAvailable)) 6 | { 7 | # Redirect all streams to $null, except the error stream (stream 2) 8 | & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null 9 | } 10 | 11 | # Re-import the module using force to get any code changes between runs. 12 | Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' 13 | 14 | $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName 15 | $PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName 16 | $PSDefaultParameterValues['Should:ModuleName'] = $script:moduleName 17 | } 18 | 19 | AfterAll { 20 | $PSDefaultParameterValues.Remove('Mock:ModuleName') 21 | $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') 22 | $PSDefaultParameterValues.Remove('Should:ModuleName') 23 | 24 | Remove-Module -Name $script:moduleName 25 | } 26 | 27 | Describe 'Out-SamplerXml' { 28 | BeforeAll { 29 | $mockXmlDocument = '' 30 | } 31 | 32 | It 'Should write a file with the correct content and correct encoding' { 33 | $mockPath = Join-Path -Path $TestDrive -ChildPath 'mockOutput.xml' 34 | 35 | $result = Sampler\Out-SamplerXml -XmlDocument $mockXmlDocument -Path $mockPath 36 | 37 | $contentsInFile = Get-Content -Path $mockPath -Raw 38 | 39 | $contentsInFile | Should -Be '' 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/Unit/Public/Split-ModuleVersion.tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | $script:moduleName = 'Sampler' 3 | 4 | # If the module is not found, run the build task 'noop'. 5 | if (-not (Get-Module -Name $script:moduleName -ListAvailable)) 6 | { 7 | # Redirect all streams to $null, except the error stream (stream 2) 8 | & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null 9 | } 10 | 11 | # Re-import the module using force to get any code changes between runs. 12 | Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' 13 | 14 | $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName 15 | $PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName 16 | $PSDefaultParameterValues['Should:ModuleName'] = $script:moduleName 17 | } 18 | 19 | AfterAll { 20 | $PSDefaultParameterValues.Remove('Mock:ModuleName') 21 | $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') 22 | $PSDefaultParameterValues.Remove('Should:ModuleName') 23 | 24 | Remove-Module -Name $script:moduleName 25 | } 26 | 27 | Describe 'Split-ModuleVersion' { 28 | It 'Should split a preview release module version' { 29 | $result = Sampler\Split-ModuleVersion -ModuleVersion '1.15.0-pr0224' 30 | 31 | $result.Version | Should -Be '1.15.0' 32 | $result.PreReleaseString | Should -Be 'pr0224' 33 | $result.ModuleVersion | Should -Be '1.15.0-pr0224' 34 | } 35 | 36 | It 'Should split preview release module version with build information suffix' { 37 | $result = Sampler\Split-ModuleVersion -ModuleVersion '1.15.0-pr0224-0022+Sha.47ae45eb2cfed02b249f239a7c55e5c71b26ab76.Date.2020-01-07' 38 | 39 | $result.Version | Should -Be '1.15.0' 40 | $result.PreReleaseString | Should -Be 'pr0224' 41 | $result.ModuleVersion | Should -Be '1.15.0-pr0224' 42 | } 43 | 44 | It 'Should split a full release module version' { 45 | $result = Sampler\Split-ModuleVersion -ModuleVersion '1.15.0' 46 | 47 | $result.Version | Should -Be '1.15.0' 48 | $result.PreReleaseString | Should -BeNullOrEmpty 49 | $result.ModuleVersion | Should -Be '1.15.0' 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /tests/Unit/TestHelpers/Get-XmlAttribute.ps1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | Returns a hashtable containing all the attributes in the given search query. 5 | 6 | .DESCRIPTION 7 | This command returns a hashtable containing all the attributes in the 8 | path provided in the parameter XPath. 9 | 10 | 11 | .PARAMETER XmlDocument 12 | Specifies an XML document to perform the search query on. 13 | 14 | .PARAMETER XPath 15 | Specifies an XPath search query. 16 | 17 | .EXAMPLE 18 | $xmlResult | Get-XmlAttribute -XPath '/report/counter[@type="LINE"]' 19 | 20 | #> 21 | function Get-XmlAttribute 22 | { 23 | [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand', '')] 24 | [CmdletBinding()] 25 | [OutputType([System.Collections.Hashtable])] 26 | param 27 | ( 28 | [Parameter(Mandatory = $true, ValueFromPipeline = $true)] 29 | [System.Xml.XmlDocument] 30 | $XmlDocument, 31 | 32 | [Parameter(Mandatory = $true)] 33 | [System.String] 34 | $XPath 35 | ) 36 | 37 | $attributeValues = @{} 38 | 39 | $filteredDocument = $XmlDocument | Select-Xml -XPath $XPath 40 | 41 | ($filteredDocument.Node | Select-Xml -XPath '@*').Node | ForEach-Object -Process { 42 | $attributeValues[$_.Name] = $_.Value 43 | } 44 | 45 | return $attributeValues 46 | } 47 | -------------------------------------------------------------------------------- /tests/Unit/TestHelpers/SetSamplerTaskVariableTestHelpers.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Returns the machine's PSModulePath. 4 | #> 5 | function Get-SystemPSModulePath 6 | { 7 | $psModulePath = [System.Environment]::GetEnvironmentVariable('PSModulePath', 'Machine') -split [System.IO.Path]::PathSeparator | 8 | Select-Object -Unique 9 | Where-Object { $_ -ne '' } 10 | 11 | return $psModulePath -join [System.IO.Path]::PathSeparator 12 | } 13 | 14 | <# 15 | .SYNOPSIS 16 | Returns the user's PSModulePath. 17 | #> 18 | function Get-UserPSModulePath 19 | { 20 | $psModulePath = $env:PSModulePath -split [System.IO.Path]::PathSeparator | 21 | Select-Object -Unique 22 | Where-Object { $_ -ne '' } 23 | 24 | return $psModulePath -join [System.IO.Path]::PathSeparator 25 | } 26 | 27 | <# 28 | .SYNOPSIS 29 | Removed duplicate entries from the given path. 30 | 31 | .PARAMETER Path 32 | The path to remove duplicate entries from. 33 | #> 34 | function Remove-DuplicateElementsInPath 35 | { 36 | param ( 37 | [Parameter(Mandatory = $true)] 38 | [string] 39 | $Path 40 | ) 41 | 42 | $value = $Path -split [System.IO.Path]::PathSeparator | 43 | Select-Object -Unique 44 | Where-Object { $_ -ne '' } 45 | 46 | return $value -join [System.IO.Path]::PathSeparator 47 | } 48 | 49 | <# 50 | .SYNOPSIS 51 | Returns if running on Windows. 52 | #> 53 | function Test-IsWindows 54 | { 55 | return [System.Environment]::OSVersion.Platform -like 'Win*' 56 | } 57 | -------------------------------------------------------------------------------- /tests/Unit/tasks/Clean.ModuleBuilder.build.Tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | $script:moduleName = 'Sampler' 3 | 4 | # If the module is not found, run the build task 'noop'. 5 | if (-not (Get-Module -Name $script:moduleName -ListAvailable)) 6 | { 7 | # Redirect all streams to $null, except the error stream (stream 2) 8 | & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null 9 | } 10 | 11 | # Re-import the module using force to get any code changes between runs. 12 | Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' 13 | } 14 | 15 | AfterAll { 16 | Remove-Module -Name $script:moduleName 17 | } 18 | 19 | Describe 'Clean.ModuleBuilder' { 20 | It 'Should have exported the alias correct' { 21 | $taskAlias = Get-Alias -Name 'Clean.ModuleBuilder.build.Sampler.ib.tasks' 22 | 23 | $taskAlias.Name | Should -Be 'Clean.ModuleBuilder.build.Sampler.ib.tasks' 24 | $taskAlias.ReferencedCommand | Should -Be 'Clean.ModuleBuilder.build.ps1' 25 | $taskAlias.Definition | Should -Match 'Sampler[\/|\\]\d+\.\d+\.\d+[\/|\\]tasks[\/|\\]Clean\.ModuleBuilder\.build\.ps1' 26 | } 27 | } 28 | 29 | Describe 'Clean' { 30 | BeforeAll { 31 | $taskAlias = Get-Alias -Name 'Clean.ModuleBuilder.build.Sampler.ib.tasks' 32 | 33 | $mockTaskParameters = @{ 34 | OutputDirectory = Join-Path -Path $TestDrive -ChildPath 'MyModule/output' 35 | } 36 | } 37 | 38 | Context 'When creating a preview release tag' { 39 | BeforeAll { 40 | Mock -CommandName Get-ChildItem 41 | Mock -CommandName Remove-Item 42 | } 43 | 44 | It 'Should run the build task without throwing' { 45 | { 46 | Invoke-Build -Task 'Clean' -File $taskAlias.Definition @mockTaskParameters 47 | } | Should -Not -Throw 48 | } 49 | } 50 | } 51 | 52 | Describe 'CleanModule' { 53 | BeforeAll { 54 | $taskAlias = Get-Alias -Name 'Clean.ModuleBuilder.build.Sampler.ib.tasks' 55 | 56 | $mockTaskParameters = @{ 57 | OutputDirectory = Join-Path -Path $TestDrive -ChildPath 'MyModule/output' 58 | } 59 | } 60 | 61 | Context 'When creating a preview release tag' { 62 | BeforeAll { 63 | Mock -CommandName Get-ChildItem 64 | Mock -CommandName Remove-Item 65 | } 66 | 67 | It 'Should run the build task without throwing' { 68 | { 69 | Invoke-Build -Task 'CleanModule' -File $taskAlias.Definition @mockTaskParameters 70 | } | Should -Not -Throw 71 | } 72 | } 73 | } 74 | 75 | Describe 'CleanAll' { 76 | BeforeAll { 77 | $taskAlias = Get-Alias -Name 'Clean.ModuleBuilder.build.Sampler.ib.tasks' 78 | 79 | $mockTaskParameters = @{ 80 | OutputDirectory = Join-Path -Path $TestDrive -ChildPath 'MyModule/output' 81 | } 82 | } 83 | 84 | Context 'When creating a preview release tag' { 85 | BeforeAll { 86 | Mock -CommandName Get-ChildItem 87 | Mock -CommandName Remove-Item 88 | } 89 | 90 | It 'Should run the build task without throwing' { 91 | { 92 | Invoke-Build -Task 'CleanAll' -File $taskAlias.Definition @mockTaskParameters 93 | } | Should -Not -Throw 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /tests/Unit/tasks/DeployAll.PSDeploy.build.Tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | $script:moduleName = 'Sampler' 3 | 4 | # If the module is not found, run the build task 'noop'. 5 | if (-not (Get-Module -Name $script:moduleName -ListAvailable)) 6 | { 7 | # Redirect all streams to $null, except the error stream (stream 2) 8 | & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null 9 | } 10 | 11 | # Re-import the module using force to get any code changes between runs. 12 | Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' 13 | } 14 | 15 | AfterAll { 16 | Remove-Module -Name $script:moduleName 17 | } 18 | 19 | Describe 'DeployAll.PSDeploy' { 20 | It 'Should have exported the alias correct' { 21 | $taskAlias = Get-Alias -Name 'DeployAll.PSDeploy.build.Sampler.ib.tasks' 22 | 23 | $taskAlias.Name | Should -Be 'DeployAll.PSDeploy.build.Sampler.ib.tasks' 24 | $taskAlias.ReferencedCommand | Should -Be 'DeployAll.PSDeploy.build.ps1' 25 | $taskAlias.Definition | Should -Match 'Sampler[\/|\\]\d+\.\d+\.\d+[\/|\\]tasks[\/|\\]DeployAll\.PSDeploy\.build\.ps1' 26 | } 27 | } 28 | 29 | Describe 'Deploy_with_PSDeploy' { 30 | BeforeAll { 31 | # Dot-source mocks 32 | . $PSScriptRoot/../TestHelpers/MockSetSamplerTaskVariable 33 | 34 | $taskAlias = Get-Alias -Name 'DeployAll.PSDeploy.build.Sampler.ib.tasks' 35 | 36 | $mockTaskParameters = @{ 37 | BuildOutput = Join-Path -Path $TestDrive -ChildPath 'MyModule/output' 38 | ProjectName = 'MyModule' 39 | } 40 | } 41 | 42 | It 'Should run the build task without throwing' { 43 | # Stub for Invoke-PSDeploy since the module is not part of Sampler build process. 44 | function Invoke-PSDeploy {} 45 | 46 | Mock -CommandName Import-Module 47 | Mock -CommandName Invoke-PSDeploy 48 | 49 | { 50 | Invoke-Build -Task 'Deploy_with_PSDeploy' -File $taskAlias.Definition @mockTaskParameters 51 | } | Should -Not -Throw 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/Unit/tasks/SetPsModulePath.build.Tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | $script:moduleName = 'Sampler' 3 | 4 | # If the module is not found, run the build task 'noop'. 5 | if (-not (Get-Module -Name $script:moduleName -ListAvailable)) 6 | { 7 | # Redirect all streams to $null, except the error stream (stream 2) 8 | & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' > $null 9 | } 10 | 11 | # Re-import the module using force to get any code changes between runs. 12 | Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' 13 | } 14 | 15 | AfterAll { 16 | Remove-Module -Name $script:moduleName 17 | } 18 | 19 | Describe 'SetPsModulePath' -Tag x { 20 | 21 | BeforeAll { 22 | $taskAlias = Get-Alias -Name 'SetPsModulePath.build.Sampler.ib.tasks' 23 | 24 | $mockTaskParameters = @{ 25 | #OutputDirectory = Join-Path -Path $TestDrive -ChildPath 'MyModule/output' 26 | } 27 | } 28 | 29 | It 'Should have exported the alias correct' { 30 | 31 | $taskAlias.Name | Should -Be 'SetPsModulePath.build.Sampler.ib.tasks' 32 | $taskAlias.ReferencedCommand | Should -Be 'SetPsModulePath.build.ps1' 33 | $taskAlias.Definition | Should -Match 'Sampler[\/|\\]\d+\.\d+\.\d+[\/|\\]tasks[\/|\\]SetPsModulePath\.build\.ps1' 34 | } 35 | 36 | Context 'When setting the PSModulePath' { 37 | BeforeAll { 38 | Mock -CommandName Set-SamplerPSModulePath 39 | } 40 | 41 | It 'Should run the build task without throwing' { 42 | { 43 | Invoke-Build -Task 'Set_PSModulePath' -File $taskAlias.Definition @mockTaskParameters 44 | } | Should -Not -Throw 45 | 46 | Assert-MockCalled -CommandName Set-SamplerPSModulePath -Exactly -Times 1 -Scope It 47 | } 48 | } 49 | } 50 | 51 | Describe 'CleanModule' { 52 | BeforeAll { 53 | $taskAlias = Get-Alias -Name 'Clean.ModuleBuilder.build.Sampler.ib.tasks' 54 | 55 | $mockTaskParameters = @{ 56 | OutputDirectory = Join-Path -Path $TestDrive -ChildPath 'MyModule/output' 57 | } 58 | } 59 | 60 | Context 'When creating a preview release tag' { 61 | BeforeAll { 62 | Mock -CommandName Get-ChildItem 63 | Mock -CommandName Remove-Item 64 | } 65 | 66 | It 'Should run the build task without throwing' { 67 | { 68 | Invoke-Build -Task 'CleanModule' -File $taskAlias.Definition @mockTaskParameters 69 | } | Should -Not -Throw 70 | } 71 | } 72 | } 73 | 74 | Describe 'CleanAll' { 75 | BeforeAll { 76 | $taskAlias = Get-Alias -Name 'Clean.ModuleBuilder.build.Sampler.ib.tasks' 77 | 78 | $mockTaskParameters = @{ 79 | OutputDirectory = Join-Path -Path $TestDrive -ChildPath 'MyModule/output' 80 | } 81 | } 82 | 83 | Context 'When creating a preview release tag' { 84 | BeforeAll { 85 | Mock -CommandName Get-ChildItem 86 | Mock -CommandName Remove-Item 87 | } 88 | 89 | It 'Should run the build task without throwing' { 90 | { 91 | Invoke-Build -Task 'CleanAll' -File $taskAlias.Definition @mockTaskParameters 92 | } | Should -Not -Throw 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /tests/Unit/tasks/generateHelp.PlatyPS.build.Tests.ps1: -------------------------------------------------------------------------------- 1 | BeforeAll { 2 | $script:moduleName = 'Sampler' 3 | 4 | # If the module is not found, run the build task 'noop'. 5 | if (-not (Get-Module -Name $script:moduleName -ListAvailable)) 6 | { 7 | # Redirect all streams to $null, except the error stream (stream 2) 8 | & "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null 9 | } 10 | 11 | # Re-import the module using force to get any code changes between runs. 12 | Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' 13 | } 14 | 15 | AfterAll { 16 | Remove-Module -Name $script:moduleName 17 | } 18 | 19 | Describe 'generateHelp.PlatyPS' { 20 | It 'Should have exported the alias correct' { 21 | $taskAlias = Get-Alias -Name 'generateHelp.PlatyPS.build.Sampler.ib.tasks' 22 | 23 | $taskAlias.Name | Should -Be 'generateHelp.PlatyPS.build.Sampler.ib.tasks' 24 | $taskAlias.ReferencedCommand | Should -Be 'generateHelp.PlatyPS.build.ps1' 25 | $taskAlias.Definition | Should -Match 'Sampler[\/|\\]\d+\.\d+\.\d+[\/|\\]tasks[\/|\\]generateHelp\.PlatyPS\.build\.ps1' 26 | } 27 | } 28 | 29 | <# 30 | The task runs pwsh.exe and pass commands in a separate session 31 | so it is not possible to mock the commands. 32 | 33 | TODO: The tasks should be refactored to not start a separat session. 34 | #> 35 | 36 | # Describe 'Generate_MAML_from_built_module' { 37 | # BeforeAll { 38 | # # Dot-source mocks 39 | # . $PSScriptRoot/../TestHelpers/MockSetSamplerTaskVariable 40 | 41 | # $taskAlias = Get-Alias -Name 'generateHelp.PlatyPS.build.Sampler.ib.tasks' 42 | 43 | # $mockTaskParameters = @{ 44 | # SourcePath = Join-Path -Path $TestDrive -ChildPath 'MyModule/source' 45 | # ProjectName = 'MyModule' 46 | # } 47 | 48 | # # Stubs for PlatyPS module functions 49 | # function New-MarkdownHelp {} 50 | # function New-ExternalHelp {} 51 | # } 52 | 53 | # It 'Should run the build task without throwing' { 54 | # Mock -CommandName Import-Module -RemoveParameterValidation 'Name' 55 | 56 | # Mock -CommandName New-MarkdownHelp 57 | # Mock -CommandName New-ExternalHelp 58 | 59 | # Mock -CommandName Get-ChildItem -MockWith { 60 | # return $TestDrive 61 | # } 62 | 63 | # Mock -CommandName Copy-Item 64 | 65 | # { 66 | # Invoke-Build -Task 'Generate_MAML_from_built_module' -File $taskAlias.Definition @mockTaskParameters 67 | # } | Should -Not -Throw 68 | 69 | # Should -Invoke -CommandName Copy-Item -Exactly -Times 1 -Scope It 70 | # } 71 | # } 72 | --------------------------------------------------------------------------------