InvokeSystems.Generator: Because Get-Random Isn’t Random Enough

(and neither is your keyboard mashing)

Every automation script eventually needs random values. Passwords for service accounts. API tokens. Test data. Unique identifiers. The temptation is always to reach for Get-Random or bang on the keyboard until it looks random enough.

Neither of those is actually secure.

Get-Random uses a pseudorandom number generator that’s fine for shuffling arrays or picking a random color, but unsuitable for cryptographic purposes. It’s deterministic, predictable if you know the seed, and absolutely not what you want protecting access to production systems.

Keyboard mashing produces patterns. Humans are terrible at randomness. We favor certain character sequences, avoid awkward key combinations, and create passwords that look random but cluster in predictable ways. “qwerty123!” feels random. It’s not.

What you actually need is cryptographic randomness: values generated from sources that are genuinely unpredictable and suitable for security-sensitive contexts. Windows provides this through RNGCryptoServiceProvider. Using it correctly is straightforward but tedious.

InvokeSystems.Generator wraps that tedium into simple functions that generate secure random values without making you think about entropy pools or byte array manipulation.

What It Generates

The module provides four core functions, each focused on a specific type of random value.

New-InvPassword generates passwords in two modes. Standard mode creates character-based passwords using configurable character sets: uppercase, lowercase, numbers, and special characters. You can exclude similar-looking characters like i, l, 1, O, and 0 to avoid transcription errors. Length is configurable from 4 to 256 characters.

Wordlist mode generates passphrases using the EFF Large Wordlist, a curated list of memorable, distinct words designed specifically for password generation. Four random words with optional appended numbers produce passwords that are both strong and memorizable. The module automatically downloads and caches the wordlist if it’s missing or stale.

New-InvRandomString creates arbitrary random strings from custom character sets. This is useful for tokens, identifiers, session keys, or anywhere you need a random string that isn’t a password. You define the character set, specify the length, and get back cryptographically secure randomness.

New-InvGuid generates GUIDs using [System.Guid]::NewGuid(). That method already uses cryptographic randomness internally, but wrapping it here provides consistency with the rest of the module and supports generating multiple GUIDs at once.

New-InvRandomNumber generates random integers within a specified range using secure random bytes. Unlike Get-Random, this provides cryptographic-quality randomness suitable for security-sensitive contexts like generating OTPs or random delays.

Every function supports a -Count parameter to generate multiple values in a single call. New-InvPassword also supports -AsSecureString to return passwords as SecureString objects for immediate use in credential creation without exposing plaintext.

Why Wordlist Passphrases Matter

Standard passwords are strong but hostile to humans. Zx9#mQp2!vL8 is secure. It’s also impossible to remember without a password manager, prone to transcription errors, and frustrating to type on a phone keyboard.

Wordlist passphrases solve this. Four random words from a 7,776-word list produce 160 bits of entropy (log2(7776^4)), which exceeds the strength of most 16-character random passwords. More importantly, “correct-horse-battery-staple” is memorable, easy to type, and less error-prone.

The EFF Large Wordlist was specifically designed for this use case. Words are distinct, memorable, and avoid profanity or cultural sensitivity issues. Each word maps to a unique five-digit dice roll, making the list auditable and reproducible.

The module downloads the wordlist from EFF’s official source on first use and caches it locally. A 14-day staleness check ensures the cache stays reasonably current without hammering their servers.

The Cryptographic Foundation

All randomness in this module comes from RNGCryptoServiceProvider, which interfaces with the Windows CryptoAPI to access the operating system’s entropy pool. This is the same source used by TLS, certificate generation, and other security-critical Windows components.

The implementation is straightforward. Request N random bytes. Use those bytes as indices into your character array or word list. Return the result. No seeds, no predictable patterns, no shortcuts.

Modulo bias is handled by generating more bytes than strictly necessary and using simple modulo arithmetic. For the scales involved here (character sets of 60-90 characters, wordlists of 7,776 words), the bias is negligible and doesn’t meaningfully reduce entropy.

What This Isn’t Trying to Be

InvokeSystems.Generator doesn’t implement custom cryptographic algorithms. It doesn’t try to be smarter than the operating system’s entropy sources. It doesn’t provide key derivation, hashing, or encryption.

It’s a thin, focused wrapper around RNGCryptoServiceProvider that makes generating secure random values easy and consistent. That’s the entire scope.

Password strength validation isn’t included. If you need to enforce complexity rules or check passwords against breach databases, use dedicated tools for that. This module generates strong passwords. Validating them is a different problem.

Tradeoffs and Limitations

Cryptographic randomness is slower than pseudorandom generation. For bulk operations generating thousands of values, that difference matters. For typical use cases (generating a few passwords or tokens), it’s imperceptible.

The wordlist requires an internet connection on first use and occupies about 100KB on disk. If that’s a problem for your environment, stick to standard mode.

SecureString objects are deprecated in .NET Core and provide limited protection in modern environments. The -AsSecureString parameter exists for compatibility with older APIs that require it, not because SecureString is inherently better than careful handling of plaintext strings.

Why This Module Exists

Every script that needs secure random values shouldn’t have to reimplement cryptographic random number generation. That’s error-prone, tedious, and leads to inconsistent implementations across a codebase.

Centralizing this logic in a module means one implementation, one set of tests, one place to fix bugs. It also provides a consistent interface across the InvokeSystems suite.

This isn’t revolutionary. It’s basic hygiene: don’t use weak randomness for security-sensitive operations, and don’t make developers implement the same thing repeatedly.

The code is boring. That’s the point.

Where This Fits

InvokeSystems.Generator is a building block for other modules and scripts. Use it to generate service account passwords during deployment, create API tokens for automation, generate test data that doesn’t accidentally reveal patterns, or provision unique identifiers that don’t collide.

Pair it with InvokeSystems.RestrictedTask and you can let users trigger password resets that generate secure credentials. Pair it with deployment scripts and you get consistent, auditable credential creation.

The module handles the “how to generate secure random values” problem so you can focus on what to do with them.