diff --git a/CHANGELOG.md b/CHANGELOG.md index 700380d..2c02476 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,21 @@ # IT-ToolBox - Change History -## 3.0.0 - 2026-10-14 - -- Remove beta prerelease metadata; retain the 29-command API and PowerShell 7.4 baseline. -- Add a prominent community testing invitation with actionable bug-report guidance. -- Align README, packaging documentation and security support status with 3.0.0. -- Update archive regression expectations for the stable version. - -Live AD, remote CIM and service authentication remain unverified against real -endpoints. This entry records release preparation; a GitHub release or Gallery -publication is a separate action. +## 3.0.0 - 2026-10-24 + +- Deliver the stable 29-command API on PowerShell 7.4+ (Core), with no mandatory external module dependencies at import. +- Retain the module GUID and remove beta prerelease metadata. +- Align Stop-Timer and Get-TimerStatus with the standalone functions: reject null timer arguments during binding, support common parameters and preserve Boolean results for valid calls. +- Simplify Stop-Timer exception handling, remove the unrelated AzureAD diagnostic and preserve elapsed time when stopping. +- Add module-level timer lifecycle, repeated-stop, elapsed-time preservation and caller/module preference regression tests. +- Update manifest attribution to SingularVector while retaining Daniele Catanesi's authorship; describe the module's actual scope. +- Replace repetitive README introductions with a complete 29-command inventory, platform requirements and timer behavior. +- Check that public functions, imported exports, manifest exports and documented commands remain aligned. +- Retain installable archive validation and regression tests on Windows, Linux and macOS. + +Migration from v2 includes removed service wrappers, updated string encryption and +changed validation/output contracts; see README.md before upgrading. Live AD, +remote CIM and service authentication were not integration-tested. These are +validation boundaries for this release, not additional bundled features. ## 3.0.0-beta1 - 2026-10-05 diff --git a/IT-ToolBox.psd1 b/IT-ToolBox.psd1 index ee9de02..aa9a132 100644 --- a/IT-ToolBox.psd1 +++ b/IT-ToolBox.psd1 @@ -2,10 +2,10 @@ RootModule = 'IT-ToolBox.psm1' ModuleVersion = '3.0.0' GUID = '02c0c748-00ba-4e8f-b8ce-6aa7e4cefe08' - Author = 'Daniele Catanesi - PsCustomObject' + Author = 'Daniele Catanesi - SingularVector' CompanyName = 'Community' Copyright = '(c) Daniele Catanesi. MIT License.' - Description = 'Reusable infrastructure automation utilities. PowerShell 7 infrastructure utilities.' + Description = 'PowerShell 7.4+ utilities for infrastructure automation: logging, validation, timing, string handling, password generation and API requests.' PowerShellVersion = '7.4' CompatiblePSEditions = @('Core') FunctionsToExport = @( @@ -44,6 +44,7 @@ AliasesToExport = @() PrivateData = @{ PSData = @{ + ReleaseNotes = '3.0.0: Stable 29-command PowerShell 7.4+ API; aligned timer validation and diagnostics; updated SingularVector metadata and command documentation. See CHANGELOG.md for migration and validation boundaries.' Tags = @('Infrastructure', 'Automation', 'Logging') LicenseUri = 'https://github.com/SingularVector/IT-ToolBox/blob/master/LICENSE' ProjectUri = 'https://github.com/SingularVector/IT-ToolBox' diff --git a/Public/Get-TimerStatus.ps1 b/Public/Get-TimerStatus.ps1 index ad9615c..1fec65d 100644 --- a/Public/Get-TimerStatus.ps1 +++ b/Public/Get-TimerStatus.ps1 @@ -18,13 +18,15 @@ function Get-TimerStatus System.Boolean #> + [CmdletBinding()] [OutputType([bool])] param ( [Parameter(Mandatory = $true)] + [ValidateNotNull()] [System.Diagnostics.Stopwatch] $Timer ) # Return the current running state of the supplied stopwatch. return $Timer.IsRunning -} \ No newline at end of file +} diff --git a/Public/Stop-Timer.ps1 b/Public/Stop-Timer.ps1 index 63e46bd..2997ee9 100644 --- a/Public/Stop-Timer.ps1 +++ b/Public/Stop-Timer.ps1 @@ -2,69 +2,35 @@ function Stop-Timer { <# .SYNOPSIS - Stops a stopwatch. - + Stops a stopwatch without resetting its elapsed time. .DESCRIPTION - Requires a [System.Diagnostics.Stopwatch] object and calls its Stop() method. - If no exception is raised, the function returns $true. - + Returns $true after stopping the supplied stopwatch. Stopping an already + stopped stopwatch also succeeds. Invalid input is rejected during binding. + If Stop() throws, reports a warning and returns $false. .PARAMETER Timer The stopwatch instance to stop. - .EXAMPLE Stop-Timer -Timer $Timer - .OUTPUTS System.Boolean #> - + [CmdletBinding()] [OutputType([bool])] param ( [Parameter(Mandatory = $true)] + [ValidateNotNull()] [System.Diagnostics.Stopwatch]$Timer ) - Begin - { - # Preserve the caller's current preference so it can be restored after the stop attempt. - [string]$currentConfig = $ErrorActionPreference - - # Fail fast so the catch block can report stopwatch-stop errors consistently. - $ErrorActionPreference = 'Stop' - } - - Process + try { - try - { - # Stop the supplied stopwatch. - $Timer.Stop() - - return $true - } - catch - { - # Capture the exception text for verbose output without changing the caller's state. - [string]$reportedException = $Error[0].Exception.Message - - Write-Warning -Message 'Exception reported while halting stopwatch - Use the -Verbose parameter for more details' - - if ([string]::IsNullOrEmpty($reportedException) -eq $false) - { - Write-Verbose -Message $reportedException - } - else - { - Write-Verbose -Message 'No inner exception reported by Disconnect-AzureAD cmdlet' - } - - return $false - } + $Timer.Stop() + return $true } - - End + catch { - # Restore the original error-action preference after the stopwatch operation finishes. - $ErrorActionPreference = $currentConfig + Write-Warning -Message 'Exception reported while stopping stopwatch; use -Verbose for details.' + Write-Verbose -Message $_.Exception.Message + return $false } -} \ No newline at end of file +} diff --git a/README.md b/README.md index e3bc09c..a1663e9 100644 --- a/README.md +++ b/README.md @@ -13,57 +13,10 @@ > module version. Redact credentials and private data; report vulnerabilities > through [the private security reporting route](./SECURITY.md). -PowerShell utilities for enterprise automation, secure logging, identity validation, -and cross-platform operational tooling. - -IT-ToolBox is a practical PowerShell module for real-world admin and infrastructure -workflows. It is designed for teams that want explicit validation, secure defaults, -and portable behavior without hidden magic or fragile assumptions. - -## Why it matters - -Operational work is full of small but expensive failures: invalid input, inconsistent -logging, brittle naming rules, and fragile automation built on assumptions. IT-ToolBox -was created to reduce those failure points with reusable PowerShell utilities that -prioritize safety, clarity, and portability across modern enterprise environments. - -## Why this project exists - -This project packages automation patterns that are often built ad hoc in enterprise -workplaces: filesystem validation, identity and DNS checks, log management, secure -string handling, and operational diagnostics. The result is a reusable toolkit that -prioritizes clarity, safety, and portability instead of one-off script logic. - -## Portfolio highlights - -- Cross-platform PowerShell 7.4+ design -- Secure logging and string-handling helpers with explicit safety boundaries -- Validation-first utilities for email, URLs, DNS, DN and UPN checks -- Operational helpers for timing, script context and filesystem hygiene -- Modernization work that preserves compatibility where it matters -- Built for real deployment scenarios, not just demo scripts - -## Use cases - -IT-ToolBox is designed for the kinds of tasks that recur in real administrative and -operations work: validating names and input, writing safe logs, enforcing naming rules, -tracing script context, and handling sensitive values without obscuring the logic behind -complex utility wrappers. - -Typical scenarios include: - -- validating user and endpoint input in scripts before commands run -- adding consistent, redactable logging to automation workflows -- generating secure random values and supporting password workflows -- checking script paths and operational timing in automation tooling -- normalizing filesystem names and reducing operational errors before actions execute - -## Project philosophy - -The module emphasizes four things: explicit validation, safe defaults, cross-platform -compatibility, and operational clarity. The goal is not to hide behavior behind clever -abstractions, but to provide reliable building blocks that are easy to reason about, -review, and adapt in production automation. +IT-ToolBox collects PowerShell utilities used in systems engineering and infrastructure +automation: logging, input validation, timing, string handling, password generation +and API requests. Most commands run on Windows, Linux and macOS; the AD, registry +and remote CIM commands have the platform requirements listed below. ## At a glance @@ -71,8 +24,9 @@ review, and adapt in production automation. | --- | --- | | Logging and operations | `New-LogEntry`, `New-Timer`, `Get-ElapsedTime`, `Stop-Timer` | | Validation | `Test-IsEmail`, `Test-IsUrl`, `Test-IsValidDn`, `Test-IsValidUpn` | -| Identity and AD helpers | `Get-ReportChain`, `Convert-LogonTimestamp`, `Test-RegistryValue` | -| Security and data handling | `New-StringEncryption`, `New-StringDecryption`, `New-PhoneticPassword`, `Get-StringHashCode` | +| Identity and AD helpers | `Get-ReportChain`, `Convert-LogonTimestamp`, `Test-IsValidUpn` | +| String handling and passwords | `New-StringEncryption`, `New-StringDecryption`, `New-PhoneticPassword`, `Get-StringHashCode` | +| OS and filesystem | `Get-OsUpTime`, `Remove-SpecialCharacters`, `Test-RegistryValue` | ## Documentation map @@ -82,24 +36,21 @@ review, and adapt in production automation. - [Changelog](./CHANGELOG.md) - [Security policy](./SECURITY.md) -## Project status and roadmap - -The module now targets the **3.0.0 release**. The supported API is covered by -cross-platform regression tests. Community testing is welcome, particularly for -the live integrations described below. Review the v2 migration notes before upgrading. +## Release status -Current roadmap focus: +**IT-ToolBox 3.0.0** contains the 29-command API documented below, including the +standalone timer alignment and updated module metadata. The manifest, loader, +command inventory and installable archive use the same supported function set. +See the [3.0.0 release notes](./CHANGELOG.md) for the changes and migration details. -- preserve the modern PowerShell 7.4+ compatibility baseline -- keep validation behavior explicit and predictable -- improve operational safety and logging semantics -- maintain a clean migration path from legacy patterns -- document integration boundaries and supported dependencies clearly +Release builds should use the reviewed 3.0.0 commit or tag rather than a moving +master checkout. Build and installation instructions are in [Packaging](./docs/Packaging.md). ## Status and requirements -This is **IT-ToolBox 3.0.0**. The modernization review is -complete; live AD, remote CIM and service authentication remain unverified. +The module has **29 exported functions**, matching the manifest and loader. +Automated tests cover the supported API; live AD, remote CIM and service +authentication remain unverified. Requires PowerShell 7.4 or later (Core edition). Windows PowerShell 5.1 is not supported. @@ -151,26 +102,44 @@ For development, see [CONTRIBUTING.md](./CONTRIBUTING.md). ## Command coverage -### Logging, timing and script context - -`New-LogEntry`, `New-Timer`, `Get-TimerStatus`, `Stop-Timer`, `Get-ElapsedTime`, -`Get-ScriptDirectory`, `Get-ScriptName` - -### Validation and identity - -`Test-FileName`, `Test-IsValidPath`, `Test-IsIP`, `Test-IsDate`, `Test-IsEmail`, -`Test-IsUrl`, `Test-IsValidDn`, `Test-IsValidUpn`, `Get-ReportChain` - -### Security, conversion and data handling +The following inventory lists every exported function. Source files in Public are +loaded by IT-ToolBox.psm1; IT-ToolBox.psd1 defines the supported exports. Internal +helpers in Private are not public commands. Use `Get-Help -Full` for +parameter help and the sections below for compatibility details. -`New-StringEncryption`, `New-StringDecryption`, `New-RandomString`, -`New-RandomPassword`, `New-PhoneticPassword`, `New-ApiRequest`, -`New-StringConversion`, `Get-StringCheckSum`, `Get-StringHashCode` - -### OS, filesystem and operational helpers - -`Convert-LogonTimestamp`, `Get-OsUpTime`, `Remove-SpecialCharacters`, -`Test-RegistryValue` + +| Command | Behavior and boundary | +| --- | --- | +| `New-LogEntry` | Write logs or manage the in-memory buffer; success output is opt-in. | +| `New-Timer` | Start a System.Diagnostics.Stopwatch. | +| `Get-TimerStatus` | Return whether a stopwatch is running. | +| `Stop-Timer` | Stop without resetting elapsed time; return a Boolean. | +| `Get-ElapsedTime` | Return a TimeSpan, an elapsed component or a numeric total. | +| `Get-ScriptDirectory` | Resolve the calling script directory or an explicit script path. | +| `Get-ScriptName` | Resolve the calling script filename or an explicit script path. | +| `Test-FileName` | Check lexical filename rules for the host or Windows compatibility. | +| `Test-IsValidPath` | Check path syntax without checking existence or permissions. | +| `Test-IsIP` | Check strict IP address syntax. | +| `Test-IsDate` | Check dates with current-culture or explicit format/culture rules. | +| `Test-IsEmail` | Check the documented bare mailbox syntax subset. | +| `Test-IsUrl` | Check supported absolute URL syntax; does not fetch the URL. | +| `Test-IsValidDn` | Check the documented practical DN syntax subset. | +| `Test-IsValidUpn` | Check username and DNS/IDN suffix syntax; no directory lookup. | +| `Get-ReportChain` | Query transitive reports in AD; requires Get-ADUser and AD access. | +| `New-StringEncryption` | Encrypt strings using the authenticated ITTB1 format and a passphrase. | +| `New-StringDecryption` | Decrypt and authenticate ITTB1 ciphertext with a passphrase. | +| `New-RandomString` | Generate a string using the original alphabet and cryptographic randomness. | +| `New-RandomPassword` | Generate a password from the original alphabet; no category-count guarantee. | +| `New-PhoneticPassword` | Generate passwords with explicit category counts and optional spelling/clipboard output. | +| `New-ApiRequest` | Send HTTP(S) requests with explicit authentication and redirect boundaries. | +| `New-StringConversion` | Apply the original character map and configurable space policy. | +| `Get-StringCheckSum` | Return a formatted digest; MD5 remains the compatibility default. | +| `Get-StringHashCode` | Return SHA-256 text, with an optional legacy representation. | +| `Convert-LogonTimestamp` | Convert a supplied FILETIME; zero produces no date. | +| `Get-OsUpTime` | Read local uptime or query Windows uptime through CIM. | +| `Remove-SpecialCharacters` | Preview or rename filesystem items using the original punctuation policy. | +| `Test-RegistryValue` | Check a literal registry value name on Windows. | + ```powershell Import-Module ./IT-ToolBox.psd1 @@ -208,6 +177,18 @@ directory for interactive calls. Specify a path to select a stable log filename. severity switch, or use `-BufferOnly -Level WARNING` / `ERROR`. Redaction is opt-in and does not guarantee detection of every secret. +## Stopwatch helpers + +`New-Timer` starts a stopwatch. `Get-TimerStatus` returns its running state, and +`Stop-Timer` stops it without resetting elapsed time. Stopping an already stopped +stopwatch succeeds. Both functions reject null timer arguments during binding. +`Stop-Timer` returns true on success, or a warning and false if Stop() throws; +`-Verbose` includes the caught exception message. + +`Get-ElapsedTime -ElapsedTime $timer` returns a TimeSpan. Component switches such as +`-Hours` return the component within that TimeSpan; `-TotalHours` returns the full +elapsed duration expressed in hours. These switches are mutually exclusive. + ## Migration from v2 - SCP and GnuPG wrappers and bundled WinSCP binaries are removed. Separate modules diff --git a/Tests/Module.Tests.ps1 b/Tests/Module.Tests.ps1 index a5a805e..0ee7469 100644 --- a/Tests/Module.Tests.ps1 +++ b/Tests/Module.Tests.ps1 @@ -64,3 +64,29 @@ Describe 'Elapsed-time input validation' { Get-ElapsedTime -ElapsedTime $timer @selector | Should -Be $timer.Elapsed.$Component } } + +Describe 'Documented module surface' { + BeforeAll { + $root = Split-Path $manifestPath -Parent + $exports = @( (Import-PowerShellDataFile $manifestPath).FunctionsToExport | Sort-Object ) + } + It 'documents exactly the manifest exports in the command inventory' { + $readme = Get-Content -LiteralPath (Join-Path $root 'README.md') -Raw + $inventory = [regex]::Match($readme, '(?s)(.*?)') + $inventory.Success | Should -BeTrue + $documented = @([regex]::Matches($inventory.Groups[1].Value, '(?m)^\| `([^`]+)` \|') | ForEach-Object { $_.Groups[1].Value } | Sort-Object) + $documented.Count | Should -Be $exports.Count + ($documented -join ',') | Should -Be ($exports -join ',') + } + It 'exports all top-level public functions without exposing additional commands' { + $publicFunctions = @(foreach ($file in Get-ChildItem (Join-Path $root 'Public') -Filter '*.ps1') { + $tokens = $null + $parseErrors = $null + $ast = [System.Management.Automation.Language.Parser]::ParseFile($file.FullName, [ref]$tokens, [ref]$parseErrors) + $parseErrors.Count | Should -Be 0 + $ast.EndBlock.Statements | Where-Object { $_ -is [System.Management.Automation.Language.FunctionDefinitionAst] } | ForEach-Object Name + }) | Sort-Object + ($publicFunctions -join ',') | Should -Be ($exports -join ',') + (@($module.ExportedFunctions.Keys | Sort-Object) -join ',') | Should -Be ($exports -join ',') + } +} diff --git a/docs/Packaging.md b/docs/Packaging.md index 17ebd1b..f71602e 100644 --- a/docs/Packaging.md +++ b/docs/Packaging.md @@ -1,6 +1,10 @@ # Build and install the module -Run from the repository root using PowerShell 7.4 or later: +Build from the reviewed 3.0.0 release commit or tag using PowerShell 7.4 or later. +The manifest version is 3.0.0, with no prerelease suffix. Preserve that source +revision alongside the archive when distributing it. + +Run from the repository root: ```powershell Invoke-Pester ./Tests