Skip to content
Closed
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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# IT-ToolBox - Change History

## 3.1.0 - 2026-10-24

- Add Test-IsGuid from PowerShell-Functions as a supported dependency-free validator, bringing the exported API to 30 commands.
- Preserve N/D/B/P format acceptance, zero-GUID acceptance, whitespace rejection and one Boolean per pipeline record.
- Update manifest, loader, README inventory and packaged-module regression expectations for 3.1.0.
- Retain the logger fixes from 3.0.1; no new mandatory module dependencies.

## 3.0.1 - 2026-10-24

- Share logger mutex identities for case-only path aliases on macOS, conservatively serializing distinct case-only names on case-sensitive Mac volumes.
Expand Down
5 changes: 3 additions & 2 deletions IT-ToolBox.psd1
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@{
RootModule = 'IT-ToolBox.psm1'
ModuleVersion = '3.0.1'
ModuleVersion = '3.1.0'
GUID = '02c0c748-00ba-4e8f-b8ce-6aa7e4cefe08'
Author = 'Daniele Catanesi - SingularVector'
CompanyName = 'Community'
Expand All @@ -19,6 +19,7 @@
'Test-FileName'
'Test-IsValidPath'
'Test-IsIP'
'Test-IsGuid'
'Test-IsDate'
'Test-IsEmail'
'Test-IsUrl'
Expand All @@ -44,7 +45,7 @@
AliasesToExport = @()
PrivateData = @{
PSData = @{
ReleaseNotes = '3.0.1: Fix macOS case-alias log locking and reject non-filesystem log destinations. Retains the 29-command API. See CHANGELOG.md.'
ReleaseNotes = '3.1.0: Add dependency-free Test-IsGuid syntax validation with pipeline support. Includes 3.0.1 logger fixes; exports 30 commands. See CHANGELOG.md.'
Tags = @('Infrastructure', 'Automation', 'Logging')
LicenseUri = 'https://github.com/SingularVector/IT-ToolBox/blob/master/LICENSE'
ProjectUri = 'https://github.com/SingularVector/IT-ToolBox'
Expand Down
1 change: 1 addition & 0 deletions IT-ToolBox.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Export-ModuleMember -Function @(
'Test-FileName'
'Test-IsValidPath'
'Test-IsIP'
'Test-IsGuid'
'Test-IsDate'
'Test-IsEmail'
'Test-IsUrl'
Expand Down
37 changes: 37 additions & 0 deletions Public/Test-IsGuid.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
function Test-IsGuid
{
<#
.SYNOPSIS
Tests a complete GUID string using defined .NET formats.
.DESCRIPTION
Accepts N (32 digits), D (dashed), B (matched braces) and P (matched
parentheses). Rejects surrounding whitespace, extra lines, mixed optional
delimiters and the X initializer format. Null and empty input return false.
The all-zero GUID is syntactically valid; this does not test object existence.
#>
[CmdletBinding()]
[OutputType([bool])]
param (
[Parameter(Mandatory, Position = 0, ValueFromPipeline)]
[AllowNull()]
[AllowEmptyString()]
[string]$ObjectGuid
)

process
{
if ([string]::IsNullOrWhiteSpace($ObjectGuid) -or $ObjectGuid -match '\s')
{
return $false
}
$parsed = [guid]::Empty
foreach ($format in @('N', 'D', 'B', 'P'))
{
if ([guid]::TryParseExact($ObjectGuid, $format, [ref]$parsed))
{
return $true
}
}
return $false
}
}
27 changes: 19 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

[![PowerShell 7.4+](https://img.shields.io/badge/PowerShell-7.4%2B-5391FE?logo=powershell)](https://github.com/PowerShell/PowerShell)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](./LICENSE)
[![Version: 3.0.1](https://img.shields.io/badge/version-3.0.1-blue.svg)](./CHANGELOG.md)
[![Version: 3.1.0](https://img.shields.io/badge/version-3.1.0-blue.svg)](./CHANGELOG.md)
[![Testing wanted](https://img.shields.io/badge/testing-wanted-yellow.svg)](https://github.com/SingularVector/IT-ToolBox/issues/new/choose)

> **Testing wanted — help validate IT-ToolBox 3.0.1 in real environments.**
> **Testing wanted — help validate IT-ToolBox 3.1.0 in real environments.**
> Feedback is especially useful for Windows AD report chains, remote CIM uptime,
> API authentication and platform clipboard behavior.
> [Report a bug](https://github.com/SingularVector/IT-ToolBox/issues/new/choose)
Expand Down Expand Up @@ -38,17 +38,17 @@ and remote CIM commands have the platform requirements listed below.

## Release status

**IT-ToolBox 3.0.1** contains the 29-command API documented below, including the
standalone timer alignment and updated module metadata. The manifest, loader,
**IT-ToolBox 3.1.0** contains the 30-command API documented below, including GUID
syntax validation and the logger fixes from 3.0.1. The manifest, loader,
command inventory and installable archive use the same supported function set.
See the [3.0.1 release notes](./CHANGELOG.md) for the changes and migration details.
See the [3.1.0 release notes](./CHANGELOG.md) for the changes and migration details.

Release builds should use the reviewed 3.0.1 commit or tag rather than a moving
Release builds should use the reviewed 3.1.0 commit or tag rather than a moving
master checkout. Build and installation instructions are in [Packaging](./docs/Packaging.md).

## Status and requirements

The module has **29 exported functions**, matching the manifest and loader.
The module has **30 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
Expand Down Expand Up @@ -120,6 +120,7 @@ parameter help and the sections below for compatibility details.
| `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-IsGuid` | Validate N/D/B/P GUID text without looking up an object. |
| `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. |
Expand Down Expand Up @@ -214,7 +215,7 @@ elapsed duration expressed in hours. These switches are mutually exclusive.
- All commands formerly retained in `Staging/v3/` now have supported implementations.
Its README records the migration. Exchange/AzureAD session wrappers and the global
certificate-validation bypass have been removed; their source remains in Git history.
- Only the twenty-nine listed commands are exported. Private helpers, variables and aliases
- Only the thirty listed commands are exported. Private helpers, variables and aliases
are not exported. Do not treat v3 as a drop-in replacement for every v2 script:
removed commands and documented parameter, output and encryption changes require
migration. No restoration of removed service wrappers is promised.
Expand Down Expand Up @@ -247,6 +248,16 @@ See [CHANGELOG.md](./CHANGELOG.md) for history. Released under the [MIT License]

## Validation semantics

`Test-IsGuid` accepts complete N (32 hexadecimal digits), D (dashed), B (braced)
and P (parenthesized) GUID strings. It rejects surrounding whitespace, mixed
brackets and the X initializer format. Null and empty inputs return false; the
all-zero GUID is syntactically valid. One Boolean is returned per pipeline input.
This checks syntax only, not whether a directory object or resource exists.

```powershell
'00000000-0000-0000-0000-000000000000', 'invalid' | Test-IsGuid
```

Filename and path checks are lexical checks, not guarantees of existence, permissions
or filesystem limits. Filename rules default to the host platform; use
`-WindowsCompatible` to validate Windows names on another platform. Path checks do
Expand Down
28 changes: 28 additions & 0 deletions Tests/Guid.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
BeforeAll { Import-Module (Join-Path $PSScriptRoot '../IT-ToolBox.psd1') -Force -ErrorAction Stop }
Describe 'GUID syntax contract' {
It 'accepts <Value>' -ForEach @(
@{Value='7761bf39-9a9f-42c8-869f-7c6e2689811a'}
@{Value='7761BF39-9A9F-42C8-869F-7C6E2689811A'}
@{Value='7761bf399a9f42c8869f7c6e2689811a'}
@{Value='{7761bf39-9a9f-42c8-869f-7c6e2689811a}'}
@{Value='(7761bf39-9a9f-42c8-869f-7c6e2689811a)'}
@{Value='00000000-0000-0000-0000-000000000000'}
) { Test-IsGuid $Value | Should -BeTrue }
It 'rejects malformed or unsupported input: <Value>' -ForEach @(
@{Value=$null};@{Value=''};@{Value=' '};@{Value='not-a-guid'}
@{Value='7761bf39-9a9f-42c8-869f-7c6e2689811a}'}
@{Value='{7761bf39-9a9f-42c8-869f-7c6e2689811a)'}
@{Value='{7761bf399a9f42c8869f7c6e2689811a}'}
@{Value='7761bf39-9a9f42c8-869f-7c6e2689811a'}
@{Value="junk`n7761bf39-9a9f-42c8-869f-7c6e2689811a`njunk"}
@{Value="7761bf39-9a9f-42c8-869f-7c6e2689811a`n"}
@{Value=' 7761bf39-9a9f-42c8-869f-7c6e2689811a'}
@{Value='{0x7761bf39,0x9a9f,0x42c8,{0x86,0x9f,0x7c,0x6e,0x26,0x89,0x81,0x1a}}'}
) { Test-IsGuid -ObjectGuid $Value | Should -BeFalse }
It 'returns one Boolean per pipeline record' {
$r=@('bad','','00000000-0000-0000-0000-000000000000') | Test-IsGuid
$r.Count | Should -Be 3
($r -join ',') | Should -BeExactly 'False,False,True'
foreach($v in $r){$v | Should -BeOfType ([bool])}
}
}
2 changes: 1 addition & 1 deletion Tests/IntegrationBoundary.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ finally {
$result.ErrorPreference | Should -Be 'Continue'
$result.WarningPreference | Should -Be 'Continue'
$result.LocationPreserved | Should -BeTrue
$result.ExportCount | Should -Be 29
$result.ExportCount | Should -Be 30
$result.HistoricalExports | Should -Be 0
}
}
4 changes: 2 additions & 2 deletions Tests/Module.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ BeforeAll {
Describe 'IT-ToolBox module boundary' {
It 'has a valid manifest' {
$manifest = Test-ModuleManifest $manifestPath -ErrorAction Stop
$manifest.Version | Should -Be ([version]'3.0.1')
$manifest.Version | Should -Be ([version]'3.1.0')
}

It 'exports exactly the supported commands' {
$expected = @('New-LogEntry', 'New-Timer', 'Get-TimerStatus', 'Stop-Timer', 'Get-ElapsedTime', 'Get-ScriptDirectory', 'Get-ScriptName', 'Test-FileName', 'Test-IsValidPath', 'Test-IsIP', 'Test-IsDate', 'Test-IsEmail', 'Test-IsUrl', 'Convert-LogonTimestamp', 'Get-OsUpTime', 'Remove-SpecialCharacters', 'Test-RegistryValue', 'Test-IsValidDn', 'Test-IsValidUpn', 'Get-ReportChain', 'New-StringEncryption', 'New-StringDecryption', 'New-RandomString', 'New-RandomPassword', 'New-PhoneticPassword', 'New-ApiRequest', 'New-StringConversion', 'Get-StringCheckSum', 'Get-StringHashCode') | Sort-Object
$expected = @('New-LogEntry', 'New-Timer', 'Get-TimerStatus', 'Stop-Timer', 'Get-ElapsedTime', 'Get-ScriptDirectory', 'Get-ScriptName', 'Test-FileName', 'Test-IsValidPath', 'Test-IsIP', 'Test-IsGuid', 'Test-IsDate', 'Test-IsEmail', 'Test-IsUrl', 'Convert-LogonTimestamp', 'Get-OsUpTime', 'Remove-SpecialCharacters', 'Test-RegistryValue', 'Test-IsValidDn', 'Test-IsValidUpn', 'Get-ReportChain', 'New-StringEncryption', 'New-StringDecryption', 'New-RandomString', 'New-RandomPassword', 'New-PhoneticPassword', 'New-ApiRequest', 'New-StringConversion', 'Get-StringCheckSum', 'Get-StringHashCode') | Sort-Object
$actual = @($module.ExportedFunctions.Keys | Sort-Object)
($actual -join ',') | Should -Be ($expected -join ',')
$module.ExportedVariables.Count | Should -Be 0
Expand Down
10 changes: 5 additions & 5 deletions Tests/Packaging.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ BeforeAll {
$package = & $buildScript -OutputDirectory (Join-Path $TestDrive 'output [literal]')
$extractRoot = Join-Path $TestDrive 'extracted'
[IO.Compression.ZipFile]::ExtractToDirectory($package.ArchivePath, $extractRoot)
$moduleRoot = Join-Path $extractRoot 'IT-ToolBox/3.0.1'
$moduleRoot = Join-Path $extractRoot 'IT-ToolBox/3.1.0'
}

Describe 'Installable module packaging' {
It 'uses the manifest release version and conventional module layout' {
$package.Version | Should -Be '3.0.1'
[IO.Path]::GetFileName($package.ArchivePath) | Should -Be 'IT-ToolBox-3.0.1.zip'
$package.Version | Should -Be '3.1.0'
[IO.Path]::GetFileName($package.ArchivePath) | Should -Be 'IT-ToolBox-3.1.0.zip'
Test-ModuleManifest (Join-Path $moduleRoot 'IT-ToolBox.psd1') -ErrorAction Stop | Should -Not -BeNullOrEmpty
foreach ($name in @('LICENSE', 'CONTRIBUTING.md', 'SECURITY.md')) {
Test-Path -LiteralPath (Join-Path $moduleRoot $name) | Should -BeTrue
Expand Down Expand Up @@ -45,7 +45,7 @@ Describe 'Installable module packaging' {
$code = @"
`$ErrorActionPreference = 'Stop'
`$env:PSModulePath = '$escapedRoot' + [IO.Path]::PathSeparator + `$env:PSModulePath
`$module = Import-Module IT-ToolBox -RequiredVersion 3.0.1 -Force -PassThru
`$module = Import-Module IT-ToolBox -RequiredVersion 3.1.0 -Force -PassThru
New-LogEntry -LogMessage 'Packaged logger' -BufferOnly
[pscustomobject]@{
ExportCount = `$module.ExportedFunctions.Count
Expand All @@ -59,7 +59,7 @@ New-LogEntry -LogMessage 'Packaged logger' -BufferOnly
$LASTEXITCODE | Should -Be 0
$result = $output | ConvertFrom-Json
$result.ModuleBase | Should -Be $moduleRoot
$result.ExportCount | Should -Be 29
$result.ExportCount | Should -Be 30
$result.Buffer.Count | Should -Be 1
$result.Buffer[0] | Should -Match '\[INFO\]: Packaged logger$'
}
Expand Down
12 changes: 6 additions & 6 deletions docs/Packaging.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Build and install the module

Build from the reviewed 3.0.1 release commit or tag using PowerShell 7.4 or later.
The manifest version is 3.0.1, with no prerelease suffix. Preserve that source
Build from the reviewed 3.1.0 release commit or tag using PowerShell 7.4 or later.
The manifest version is 3.1.0, with no prerelease suffix. Preserve that source
revision alongside the archive when distributing it.

Run from the repository root:
Expand All @@ -11,12 +11,12 @@ Invoke-Pester ./Tests
./scripts/Build-Module.ps1
```

The script creates artifacts/IT-ToolBox-3.0.1.zip and returns its path,
The script creates artifacts/IT-ToolBox-3.1.0.zip and returns its path,
version and file count. It takes the version from the manifest without modifying
it. Use -OutputDirectory to choose another local destination. An existing archive
causes a terminating error; use a different destination for another build.

The ZIP contains IT-ToolBox/3.0.1/ with the manifest, loader, Public and Private
The ZIP contains IT-ToolBox/3.1.0/ with the manifest, loader, Public and Private
implementation files, license, README, changelog, contributing guide, security policy and Markdown
documents in docs/.
Tests, build scripts, Legacy, Staging, Git metadata and external binaries are
Expand All @@ -26,8 +26,8 @@ in a separate session; the old decoder is not distributed in this archive.
Extract into a new directory, then verify or import the extracted manifest:

```powershell
Expand-Archive -LiteralPath './artifacts/IT-ToolBox-3.0.1.zip' -DestinationPath './module-install'
Import-Module './module-install/IT-ToolBox/3.0.1/IT-ToolBox.psd1' -Force
Expand-Archive -LiteralPath './artifacts/IT-ToolBox-3.1.0.zip' -DestinationPath './module-install'
Import-Module './module-install/IT-ToolBox/3.1.0/IT-ToolBox.psd1' -Force
Get-Command -Module IT-ToolBox
```

Expand Down
Loading