Public/Get-VesterTest.ps1
function Get-VesterTest { <# .SYNOPSIS Gather Vester test filepaths and details of each test. .DESCRIPTION Get-VesterTest looks for .Vester.ps1 files, excludes some if the -Scope or -Name parameters were specified, and then inspects each test file. File path and detailed properties about each test are returned. By default, all tests included with the module are inspected, and only three properties are displayed: Name, Scope, and Description. "Get-Help Get-VesterTest -Examples" for more details. .EXAMPLE Get-VesterTest -Verbose Displays the Name, Scope, and Description of all Vester test files packaged with the module. Verbose messages are available, if extra info is desired. .EXAMPLE Get-VesterTest | Select-Object -First 1 | Format-List * Returns the first Vester test found from the module. "Format-List *" displays all properties, instead of the default three. .EXAMPLE Get-VesterTest -Scope Cluster,vCenter Returns all Vester tests that apply to the "Cluster" and "vCenter" scopes. .EXAMPLE Get-VesterTest -Name 'CPU-Limits','ntp*' Returns tests named "CPU-Limits" and tests starting with "NTP". -Name is case insensitive. .EXAMPLE Get-VesterTest -Path C:\Vester\CustomTest.Vester.ps1 -Path can be used to retrieve tests outside of the Vester module install. Here, it collects info from CustomTest to return. .EXAMPLE Get-VesterTest -Path C:\Vester\ -Path can also be pointed at a directory containing custom tests. Get-VesterTest will search here for all .Vester.ps1 files, recursively. (Note that the immediate parent folder of all test files should have a name matching the test's intended scope, like "VM".) .EXAMPLE Get-VesterTest -Scope VM -Simple Returns only the file path of each test, instead of rich object details. Invoke-Vester currently expects paths only, so this saves a little time when supplying a filtered test suite to Invoke-Vester. .INPUTS [System.Object] Accepts piped input(s) for parameter -Path. .OUTPUTS [PSCustomObject] / [Vester.Test] PSCustomObjects (with custom typename "Vester.Test") are returned. [System.String] If -Simple is active, only strings with each file's full path are returned. .NOTES "Get-Help about_Vester" for more information. .LINK https://wahlnetwork.github.io/Vester .LINK https://github.com/WahlNetwork/Vester #> [CmdletBinding()] param ( # The file/folder path(s) to retrieve test info from. # If a directory, child .Vester.ps1 files are gathered recursively. [Parameter(ValueFromPipeline = $true)] [ValidateScript({ If ($_.FullName) {Test-Path $_.FullName} Else {Test-Path $_} })] [object[]]$Path = "$(Split-Path -Parent $PSScriptRoot)\Tests\", # Return only test files belonging to the specified Vester scope(s). # Vester determines test file scope by the name of its parent directory. [ValidateSet('Cluster','DSCluster','Host','Network','vCenter','VM')] [string[]]$Scope = @('Cluster','DSCluster','Host','Network','vCenter','VM'), # Filter results by test name (e.g. "DRS-Enabled" or "*DRS*"). # -Name parameter is not case sensitive. [string[]]$Name, # Simply return the full path of the file, instead of a rich object # Faster, as it does not inspect the contents of each Vester test file [switch]$Simple ) BEGIN { Write-Verbose '[Get-VesterTest] Function called' # Using $PSBoundParameters to set variable $Get If (-not $PSBoundParameters.ContainsKey('Path')) { Write-Verbose "-Path not specified; searching default module path" $PSBoundParameters.Add('Path', $Path) } If (-not $PSBoundParameters.ContainsKey('Scope')) { Write-Verbose "-Scope not specified; including all scopes" $PSBoundParameters.Add('Scope', $Scope) } # Construct empty array to throw file paths of tests into $TestFiles = New-Object 'System.Collections.Generic.List[PSCustomObject]' } PROCESS { # Need to ForEach if multiple -Test locations ForEach ($TestPath in $Path) { # Gracefully handle FileSystemInfo objects (Get-Item / Get-ChildItem) If ($TestPath.FullName) { $TestPath = $TestPath.FullName } If (Test-Path $TestPath -PathType Container) { # If Test-Path finds a folder, get all *.Vester.ps1 files beneath it Write-Verbose "Discovering .Vester.ps1 files below directory '$TestPath'" # Leverage PSBoundParameters and splatting to pass only needed parameters $Get = Get-VesterChildItem @PSBoundParameters If ($Get) { Write-Verbose "Discovered $($Get.Count) Vester test files" If ($Simple) { # Keep only the full file path $Get.FullName | ForEach-Object { $TestFiles.Add($_) } } Else { # Extract details of each test file $Get | ForEach-Object { Write-Verbose "Processing Vester test file $($_.Name)" $Vest = Extract-VestDetails -Object $_ # Add each *.Vester.ps1 file found to the array $TestFiles.Add($Vest) } #ForEach Get } } Else { throw "No *.Vester.ps1 files found at location '$TestPath'" } #If Get $Get = $null } ElseIf ($TestPath -like '*.Vester.ps1') { If ($Simple) { # Keep only the full file path $TestFiles.Add($Vest) } Else { # Extract details of the file Write-Verbose "Processing Vester test file $TestPath" $Get = Get-VesterChildItem -Path $TestPath $Vest = Extract-VestDetails -Object $_ $TestFiles.Add($Vest) $Get = $null } } Else { # Because Vester tests have a very specific format, # and for future discoverability of that test if parent folder is specified, # prefer that tests are consciously named *.Vester.ps1 throw "'$TestPath' does not match the *.Vester.ps1 naming convention for test files." } #If Test-Path } #ForEach -Test param entry } #process END { If (-not $Simple) { # Reduce default property set for readability $TypeData = @{ TypeName = 'Vester.Test' DefaultDisplayPropertySet = 'Name','Scope','Description' } # Include -Force to avoid errors after the first run Update-TypeData @TypeData -Force } $TestFiles } #end } #function |