Skip to content

Instantly share code, notes, and snippets.

@DrusTheAxe
Forked from milnak/GuidGen.ps1
Last active March 26, 2025 05:33
Show Gist options
  • Select an option

  • Save DrusTheAxe/e0684e988ae6dd945f21762132327656 to your computer and use it in GitHub Desktop.

Select an option

Save DrusTheAxe/e0684e988ae6dd945f21762132327656 to your computer and use it in GitHub Desktop.
PowerShell version of "GuidGen" application
<#
.SYNOPSIS
GUID generator
.DESCRIPTION
uuidgen.exe replacement.
Complete functional superset though some parameter syntax differs due to Powershell parameter handling:
| uuidgen | guidgen | Description |
|---------------|-----------------------|---------------------------------------|
| -x | --- (not supported) | Generate sequential (V1) UUIDs |
| -i | -Type IDLInterface | Output UUI as an initialized C struct |
| -s | -Type StructInterface | Output UUI as an initialized C struct |
| -c | -Upper | Output UUID in upper case |
| -o<filename> | -Path <filename> | Redirect output to a file |
| -n<number> | -N <number> | Number of UUIDs to generate |
| -v | --- (not supported) | Display version information |
| -h,? | -Help | Display command option summary |
.PARAMETER Type
Type of GUID output to generate.
.PARAMETER Upper
Emit GUID as upper case (default=lower case).
.PARAMETER N
Number of GUIDs to generate.
.PARAMETER Path
Specifies the file to redirect the output.
#>
param (
[ValidateSet('Raw', 'Ole', 'Define', 'Struct', 'Registry', 'AttributeBracket', 'AttributeBrace', 'IDLInterface', 'StructInterface')]
[Parameter(Position = 0)][string]$Type='Raw',
[switch]$Upper,
[int]$N=1,
[string]$Path
)
Set-StrictMode -Version 3.0
$ErrorActionPreference = "Stop"
function New-GuidObject {
$guid = (New-Guid).Guid
$m = Select-String `
-InputObject $guid `
-Pattern '([0-9A-Fa-f]{8})-([0-9A-Fa-f]{4})-([0-9A-Fa-f]{4})-([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})-([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})'
if ($Upper) {
$guid = $guid.ToUpper()
}
[PSCustomObject]@{
'Guid' = $guid
'Data1' = $m.Matches.Groups[1].Value
'Data2' = $m.Matches.Groups[2].Value
'Data3' = $m.Matches.Groups[3].Value
'Data4_1' = $m.Matches.Groups[4].Value
'Data4_2' = $m.Matches.Groups[5].Value
'Data4_3' = $m.Matches.Groups[6].Value
'Data4_4' = $m.Matches.Groups[7].Value
'Data4_5' = $m.Matches.Groups[8].Value
'Data4_6' = $m.Matches.Groups[9].Value
'Data4_7' = $m.Matches.Groups[10].Value
'Data4_8' = $m.Matches.Groups[11].Value
}
}
function New-GuidRaw {
'{0}' -f (New-GuidObject).Guid
}
function New-GuidOle {
$guid = New-GuidObject
"// {{{0}}}`nIMPLEMENT_OLECREATE(<<class>>, <<external_name>>,`n0x{1}, 0x{2}, 0x{3}, 0x{4}, 0x{5}, 0x{6}, 0x{7}, 0x{8}, 0x{9}, 0x{10}, 0x{11});" -f `
$guid.Guid, $guid.Data1, $guid.Data2, $guid.Data3, $guid.Data4_1, $guid.Data4_2, $guid.Data4_3, $guid.Data4_4, $guid.Data4_5, $guid.Data4_6, $guid.Data4_7, $guid.Data4_8
}
function New-GuidDefine {
$guid = New-GuidObject
"// {{{0}}}`nDEFINE_GUID(<<name>>,`n0x{1}, 0x{2}, 0x{3}, 0x{4}, 0x{5}, 0x{6}, 0x{7}, 0x{8}, 0x{9}, 0x{10}, 0x{11});" -f `
$guid.Guid, $guid.Data1, $guid.Data2, $guid.Data3, $guid.Data4_1, $guid.Data4_2, $guid.Data4_3, $guid.Data4_4, $guid.Data4_5, $guid.Data4_6, $guid.Data4_7, $guid.Data4_8
}
function New-GuidStruct {
$guid = New-GuidObject
"/* {{{0}}} */`nstatic const GUID <<name>> =`n{{ 0x{1}, 0x{2}, 0x{3}, {{ 0x{4}, 0x{5}, 0x{6}, 0x{7}, 0x{8}, 0x{9}, 0x{10}, 0x{11} }} }};" -f `
$guid.Guid, $guid.Data1, $guid.Data2, $guid.Data3, $guid.Data4_1, $guid.Data4_2, $guid.Data4_3, $guid.Data4_4, $guid.Data4_5, $guid.Data4_6, $guid.Data4_7, $guid.Data4_8
}
function New-GuidRegistry {
'{{{0}}}' -f (New-GuidObject).Guid
}
function New-GuidAttributeBracket {
'[Guid("{0}")]' -f (New-GuidObject).Guid
}
function New-GuidAttributeBrace {
'<Guid("{0}")>' -f (New-GuidObject).Guid
}
function New-GuidIDLInterface {
@"
[
uuid({0}),
version(1.0)
]
interface INTERFACENAME
{{
}}
"@ -f (New-GuidObject).Guid
}
function New-GuidStructInterface {
$guid = New-GuidObject
@"
INTERFACENAME = {{ /* {0} */
0x{1},
0x{2},
0x{3},
{{0x{4}, 0x{5}, 0x{6}, 0x{7}, 0x{8}, 0x{9}, 0x{10}, 0x{11}}}
}};
"@ -f $guid.Guid, $guid.Data1, $guid.Data2, $guid.Data3, $guid.Data4_1, $guid.Data4_2, $guid.Data4_3, $guid.Data4_4, $guid.Data4_5, $guid.Data4_6, $guid.Data4_7, $guid.Data4_8
}
$out = for ($i=0; $i -lt $N; $i++) {
switch ($Type) {
'Raw' { New-GuidRaw }
'Ole' { New-GuidOle }
'Define' { New-GuidDefine }
'Struct' { New-GuidStruct }
'Registry' { New-GuidRegistry }
'AttributeBracket' { New-GuidAttributeBracket }
'AttributeBrace' { New-GuidAttributeBrace }
'IDLInterface' { New-GuidIDLInterface }
'StructInterface' { New-GuidStructInterface }
}
}
if ($Path) {
Set-Content -Path $Path -Value $out
} else {
$out
}
@JeffMill
Copy link

JeffMill commented Mar 14, 2025

[switch]$Upper=$false,
[string]$Path=$null

no need to put defaults. these aren't marked [Mandatory] so PowerShell will use logical defaults ($Upper will be $false, and $Path will be $null)

@JeffMill
Copy link

    if (Test-Path -Path $Path -PathType Leaf)

-LiteralPath is preferable otherwise if $Path -eq 'out*.txt' then 'output.txt' will match.

@JeffMill
Copy link

JeffMill commented Mar 14, 2025

for ($i=0; $i -lt $N; $i++) {
...
}

Could also do:

$output = for ($i=0; $i -lt $N; $i++) {
...
}

if ($Path) { $output | Out-File ... }
else { $output }

which has the advantage of not needing to delete an existing file first, and doing a single write to the output file.

@DrusTheAxe
Copy link
Author

    if (Test-Path -Path $Path -PathType Leaf)

-LiteralPath is preferable otherwise if $Path -eq 'out*.txt' then 'output.txt' will match.

Good idea. Thanks

@DrusTheAxe
Copy link
Author

for ($i=0; $i -lt $N; $i++) {
...
}

Could also do:

$output = for ($i=0; $i -lt $N; $i++) {
...
}

if ($Path) { $output | Out-File ... }
else { $output }

which has the advantage of not needing to delete an existing file first, and doing a single write to the output file.

Super. Didn't realize $x=for... would capture the output of the loop but duh, should have. Thanks

@DrusTheAxe
Copy link
Author

[switch]$Upper=$false,
[string]$Path=$null

no need to put defaults. these aren't marked [Mandatory] so PowerShell will use logical defaults ($Upper will be $false, and $Path will be $null)

Indeed. Done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment