Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 16 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down
5 changes: 3 additions & 2 deletions IT-ToolBox.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -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 = @(
Expand Down Expand Up @@ -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'
Expand Down
4 changes: 3 additions & 1 deletion Public/Get-TimerStatus.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
62 changes: 14 additions & 48 deletions Public/Stop-Timer.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
}
151 changes: 66 additions & 85 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,66 +13,20 @@
> 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

| Area | Examples |
| --- | --- |
| 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

Expand All @@ -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.

Expand Down Expand Up @@ -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 <command> -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-inventory:start -->
| 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. |
<!-- command-inventory:end -->

```powershell
Import-Module ./IT-ToolBox.psd1
Expand Down Expand Up @@ -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
Expand Down
26 changes: 26 additions & 0 deletions Tests/Module.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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)<!-- command-inventory:start -->(.*?)<!-- command-inventory:end -->')
$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 ',')
}
}
6 changes: 5 additions & 1 deletion docs/Packaging.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Loading