home / skills / 404kidwiz / claude-supercode-skills / powershell-module-architect-skill

powershell-module-architect-skill skill

/powershell-module-architect-skill

This skill designs reusable PowerShell modules with cross-version compatibility, public/private function organization, and profile optimization for enterprise

npx playbooks add skill 404kidwiz/claude-supercode-skills --skill powershell-module-architect-skill

Review the files below or copy the command above to add this skill to your agents.

Files (9)
SKILL.md
8.2 KB
---
name: powershell-module-architect
description: Use when user needs PowerShell module design, function structure, reusable libraries, profile optimization, or cross-version compatibility across PowerShell 5.1 and PowerShell 7+.
---

# PowerShell Module Architect

## Purpose

Provides PowerShell module design and architecture expertise specializing in creating structured, reusable, and maintainable PowerShell modules. Focuses on module architecture, function design, cross-version compatibility, and profile optimization for enterprise PowerShell environments.

## When to Use

- Transforming scattered scripts into structured, reusable modules
- Designing module architecture with public/private function separation
- Creating cross-version compatible modules (PowerShell 5.1 & 7+)
- Optimizing PowerShell profiles for faster load times
- Building advanced functions with proper parameter validation

## Quick Start

**Invoke this skill when:**
- Transforming scattered scripts into structured, reusable modules
- Designing module architecture with public/private function separation
- Creating cross-version compatible modules (PowerShell 5.1 & 7+)
- Optimizing PowerShell profiles for faster load times
- Building advanced functions with proper parameter validation

**Do NOT invoke when:**
- Simple one-off scripts that won't be reused (use powershell-5.1-expert or powershell-7-expert)
- Already have well-structured modules needing functionality additions (use relevant domain skill)
- UI development (use powershell-ui-architect instead)
- Security hardening (use powershell-security-hardening instead)

## Decision Framework

### When to Create a Module

| Scenario | Recommendation |
|----------|----------------|
| 3+ related functions | Create module |
| Cross-team sharing needed | Create module + manifest |
| Single-use automation | Keep as script |
| Complex parameter sets | Advanced function in module |
| Version compatibility needed | Module with compatibility layer |

### Module Structure Decision

```
Script Organization Need
│
├─ Few related functions (3-10)?
│  └─ Single .psm1 with inline functions
│
├─ Many functions (10+)?
│  └─ Dot-source pattern (Public/Private folders)
│
├─ Publishing to gallery?
│  └─ Full manifest + tests + docs
│
└─ Team collaboration?
   └─ Git repo + CI/CD + Pester tests
```

## Core Workflow: Transform Scripts into Module

**Use case:** Refactor 10-50 scattered .ps1 scripts into organized module

### Step 1: Analysis

```powershell
# Inventory existing scripts
$scripts = Get-ChildItem -Path ./scripts -Filter *.ps1 -Recurse

# Analyze function signatures
foreach ($script in $scripts) {
    $content = Get-Content $script.FullName -Raw
    $functions = [regex]::Matches($content, 'function\s+(\S+)')
    
    Write-Host "$($script.Name): $($functions.Count) functions"
}

# Expected output:
# AD-UserManagement.ps1: 12 functions
# AD-GroupManagement.ps1: 8 functions
# Common-Helpers.ps1: 15 functions (candidates for Private/)
```

### Step 2: Design Module Structure

```powershell
# Create module skeleton
$moduleName = "Organization.ActiveDirectory"
$modulePath = "./modules/$moduleName"

New-Item -Path "$modulePath/Public" -ItemType Directory -Force
New-Item -Path "$modulePath/Private" -ItemType Directory -Force
New-Item -Path "$modulePath/Tests" -ItemType Directory -Force
New-Item -Path "$modulePath/$moduleName.psm1" -ItemType File -Force
New-Item -Path "$modulePath/$moduleName.psd1" -ItemType File -Force
```

### Step 3: Categorize Functions

```
Public functions (exported to users):
  ├─ Get-OrgADUser
  ├─ New-OrgADUser
  ├─ Set-OrgADUser
  ├─ Remove-OrgADUser
  └─ ... (user-facing functions)

Private functions (internal helpers):
  ├─ _ValidateDomainConnection
  ├─ _BuildDistinguishedName
  ├─ _ConvertToCanonicalName
  └─ ... (utility functions)
```

### Step 4: Implement Module File

```powershell
# Organization.ActiveDirectory.psm1

# Dot-source Private functions first
$Private = @(Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -ErrorAction SilentlyContinue)
foreach ($import in $Private) {
    try {
        . $import.FullName
    } catch {
        Write-Error "Failed to import private function $($import.FullName): $_"
    }
}

# Dot-source Public functions
$Public = @(Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -ErrorAction SilentlyContinue)
foreach ($import in $Public) {
    try {
        . $import.FullName
    } catch {
        Write-Error "Failed to import public function $($import.FullName): $_"
    }
}

# Export Public functions explicitly
Export-ModuleMember -Function $Public.BaseName
```

### Step 5: Create Module Manifest

```powershell
# Generate manifest
$manifestParams = @{
    Path              = "$modulePath/$moduleName.psd1"
    RootModule        = "$moduleName.psm1"
    ModuleVersion     = '1.0.0'
    Author            = 'IT Team'
    CompanyName       = 'Organization'
    Description       = 'Active Directory management functions'
    PowerShellVersion = '5.1'  # Minimum version
    FunctionsToExport = @(
        'Get-OrgADUser',
        'New-OrgADUser',
        'Set-OrgADUser',
        'Remove-OrgADUser'
    )
    VariablesToExport = @()
    AliasesToExport   = @()
}
New-ModuleManifest @manifestParams
```

### Step 6: Add Pester Tests

```powershell
# Tests/Module.Tests.ps1
BeforeAll {
    Import-Module "$PSScriptRoot/../Organization.ActiveDirectory.psd1" -Force
}

Describe "Organization.ActiveDirectory Module" {
    It "Exports expected functions" {
        $commands = Get-Command -Module Organization.ActiveDirectory
        $commands.Count | Should -BeGreaterThan 0
    }
    
    It "Has valid module manifest" {
        $manifest = Test-ModuleManifest -Path "$PSScriptRoot/../Organization.ActiveDirectory.psd1"
        $manifest.Version | Should -Be '1.0.0'
    }
}

Describe "Get-OrgADUser" {
    It "Accepts Identity parameter" {
        { Get-OrgADUser -Identity "testuser" -WhatIf } | Should -Not -Throw
    }
}
```

## Quick Reference: Advanced Function Template

```powershell
function Get-OrgUser {
    <#
    .SYNOPSIS
        Retrieves Active Directory user by name.
    
    .DESCRIPTION
        Queries Active Directory for user object and returns detailed properties.
    
    .PARAMETER Name
        The username or SamAccountName to search for.
    
    .EXAMPLE
        Get-OrgUser -Name "jdoe"
        
        Returns all properties for user jdoe.
    
    .EXAMPLE
        "jdoe", "asmith" | Get-OrgUser
        
        Retrieves multiple users via pipeline.
    #>
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [string]$Name
    )
    
    process {
        Get-ADUser -Identity $Name -Properties *
    }
}
```

## Integration Patterns

### powershell-5.1-expert
- **Handoff**: Module architecture designed → 5.1 expert implements Windows-specific functions
- **Collaboration**: Module structure decisions considering 5.1 compatibility

### powershell-7-expert
- **Handoff**: Module structure defined → 7 expert adds modern syntax optimizations
- **Collaboration**: Dual-mode functions using version detection

### windows-infra-admin
- **Handoff**: Module architecture → Windows admin implements domain-specific logic
- **Shared responsibility**: Active Directory, GPO, DNS module functions

### azure-infra-engineer
- **Handoff**: Module patterns → Azure engineer builds cloud automation modules
- **Integration**: Cross-cloud modules combining on-prem & Azure

## Red Flags - When to Escalate

| Observation | Action |
|-------------|--------|
| 100+ functions in single module | Consider splitting into sub-modules |
| Complex cross-version issues | Consult powershell-5.1 and 7 experts |
| Performance <1s profile load | Apply lazy loading patterns |
| Security-sensitive operations | Involve powershell-security-hardening |

## Additional Resources

- **Detailed Technical Reference**: See [REFERENCE.md](REFERENCE.md)
  - Profile optimization workflow
  - Module manifest template
  - Dynamic parameters pattern
  
- **Code Examples & Patterns**: See [EXAMPLES.md](EXAMPLES.md)
  - Anti-patterns (monolithic files, missing help)
  - Cross-version compatibility patterns
  - Advanced parameter validation

Overview

This skill provides practical guidance for designing and building maintainable PowerShell modules focused on reusable libraries, clear function boundaries, and cross-version compatibility between PowerShell 5.1 and PowerShell 7+. It helps teams convert scattered scripts into organized modules, optimize profiles for speed, and implement advanced functions with robust parameter validation. The guidance targets enterprise scenarios and collaboration across Windows and cloud teams.

How this skill works

I inspect script inventories, identify candidate functions for public versus private scope, and recommend a module skeleton with Public, Private, and Tests folders plus a manifest. I show a dot-sourcing pattern for controlled import order, explicit Export-ModuleMember usage, and Pester test examples. I also provide compatibility patterns and decision rules for when to split modules or add compatibility layers.

When to use it

  • Refactoring 3+ related scripts into a reusable module
  • Designing public/private function separation and module exports
  • Ensuring compatibility across PowerShell 5.1 and 7+
  • Optimizing user profiles for faster startup and lazy loading
  • Creating advanced functions with parameter validation and pipeline support

Best practices

  • Inventory existing scripts and count functions before designing structure
  • Place helpers in Private and export only user-facing functions explicitly
  • Use a manifest (.psd1) with minimum PowerShellVersion and FunctionsToExport
  • Add Pester tests and CI for module exports and manifest validation
  • Apply lazy-loading and dot-sourcing order to keep profile load times low

Example use cases

  • Transform 10–50 scattered administration scripts into a named module with Public/Private separation
  • Create a cross-version module that loads compatibility shims for PowerShell 5.1 and modernizes code for 7+
  • Optimize a team’s PowerShell profile to load core helpers on demand and reduce interactive latency
  • Design advanced cmdlets that accept pipeline input, validate parameters, and provide help blocks
  • Prepare a module for publishing with manifest metadata, tests, and CI-ready structure

FAQ

When should I keep a script instead of creating a module?

Keep it as a script if it is single-use or unlikely to be reused; create a module when you have three or more related functions, need cross-team sharing, or require complex parameter sets.

How do I handle compatibility between PowerShell 5.1 and 7+?

Use a compatibility layer: detect $PSVersionTable, factor version-specific implementations into separate files, and expose a unified public API while conditionally loading version-specific code.