└── Community.Tests.ps1 /Community.Tests.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | This is a Pester test script meant to perform a series of checks on proprietary scripts and modules to ensure 4 | it does not contains any company-specific information. It is to be used as a final gate between private scripts/modules 5 | before sharing with the community. 6 | 7 | .EXAMPLE 8 | PS> $params = @{ 9 | Script = @{ 10 | Path = 'C:\Community.Tests.ps1' 11 | Parameters = @{ 12 | FolderPath = 'C:\Path' 13 | CompanyReference = 'Acme Corporation' 14 | } 15 | } 16 | PS> Invoke-Pester @params 17 | 18 | This example invokes Pester using this community test script to run tests against a company-specific script. 19 | 20 | .PARAMETER FolderPath 21 | A mandatory string parameter representing a folder full of PowerShell scripts. This folder will be recursively read 22 | for all PowerShell scripts and modules to process. 23 | 24 | .PARAMETER CompanyReference 25 | An optional parameter representing one or more strings separated by a comma that represent any company-specific strings 26 | that need to be removed prior to community sharing. 27 | 28 | #> 29 | [CmdletBinding()] 30 | param( 31 | [Parameter(Mandatory)] 32 | [ValidateNotNullOrEmpty()] 33 | [ValidateScript({ Test-Path -Path $_ -PathType Container })] 34 | [string]$FolderPath, 35 | 36 | [Parameter()] 37 | [ValidateNotNullOrEmpty()] 38 | [string[]]$CompanyReference 39 | ) 40 | 41 | ## Command names to ignore when searching for missing 42 | $defaultCommandNames = (Get-Command -Module 'CimCmdlets','DnsClient','Microsoft.PowerShell.*','Pester' -All).Name 43 | 44 | ## Modules to ignore with commnds when searching for missing 45 | $defaultModules = (Get-Module -Name 'Microsoft.PowerShell.*','Pester').Name 46 | 47 | ## Find all PowerShell files (PS1, PSM1) inside of the folder path 48 | if ($scripts = Get-ChildItem -Path $FolderPath -Recurse -Filter '*.ps*' | Sort-Object Name) { 49 | $scripts | foreach({ 50 | $script = $_.FullName 51 | $ast = [System.Management.Automation.Language.Parser]::ParseFile($script,[ref]$null,[ref]$null) 52 | 53 | ## Find all command references inside of the script 54 | $commandRefs = $ast.FindAll({$args[0] -is [System.Management.Automation.Language.CommandAst]},$true) 55 | 56 | ## If a Pester test script, find all mocks 57 | $script:commandRefNames = @() 58 | if ($testRefs = Select-String -path $script -Pattern "mock [`"|'](.*)[`"|']") { 59 | $testRefs = $testRefs.Matches 60 | $commandRefNames += $testRefs | foreach { 61 | $_.Groups[1].Value 62 | } 63 | } 64 | 65 | $script:commandRefNames += (@($commandRefs).foreach({ [string]$_.CommandElements[0] }) | Select-Object -Unique) 66 | $script:commandDeclarationNames = $ast.FindAll({ $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] }, $true) | Select-Object -ExpandProperty Name 67 | 68 | describe "[$($script)] Test" { 69 | 70 | if ($CompanyReference) { 71 | $companyRefRegex = ('({0})' -f ($CompanyReference -join '|')) 72 | if ($companyReferences = [regex]::Matches((Get-Content $script -Raw),$companyRefRegex)) { 73 | if ($companyReferences -ne $null) { 74 | $companyReferences = $companyReferences.Groups[1].Value 75 | } 76 | } 77 | } 78 | 79 | $properties = @( 80 | @{ 81 | Name = 'Command' 82 | Expression = { $alias = Get-Alias -Name $_ -ErrorAction Ignore 83 | if ($alias) { 84 | $alias.ResolvedCommandName 85 | } else { 86 | $_ 87 | } 88 | } 89 | } 90 | ) 91 | 92 | $privateCommandNames = $script:commandRefNames | Select-Object -Property $properties | Where { 93 | $_.Command -notin $defaultCommandNames -and 94 | $_.Command -notin $commandDeclarationNames -and 95 | $_.Command -match '^\w' -and 96 | $_.Command -notmatch 'powershell_ise\.exe' 97 | } | Select-Object -ExpandProperty Command 98 | 99 | $privateModuleNames = (Select-String -Path $script -Pattern 'Import-Module (.*)').where({ $_.Matches.Groups[1].Value -notin $defaultModules }) 100 | 101 | it 'has no references to our company-specific strings' { 102 | $companyReferences | should benullOrempty 103 | } 104 | 105 | it 'has no references to private functions' { 106 | $privateCommandNames | should be $null 107 | } 108 | 109 | it 'has no references to private modules' { 110 | $privateModuleNames | should benullOrempty 111 | } 112 | } 113 | }) 114 | } --------------------------------------------------------------------------------