Powershell Vscode Precommit

Automating PowerShell Code Formatting with Pre-Commit Hooks #

The Problem #

If you’re working on a PowerShell project with multiple developers, you’ve probably experienced the pain of inconsistent code formatting. One developer uses tabs, another uses spaces. Braces are sometimes on the same line, sometimes on a new line. It’s a mess, and code reviews become debates about formatting instead of logic.

VS Code’s PowerShell extension has a great “Format Document” feature, but let’s be honest—developers forget to use it.

The Solution #

Enter pre-commit hooks combined with a PowerShell formatter. In this post, I’ll show you how to set up automatic PowerShell code formatting that:

  • Runs automatically on every commit
  • Uses PSScriptAnalyzer (the same tool VS Code uses)
  • Maintains consistent formatting across your team
  • Works in CI/CD pipelines

Prerequisites #

You’ll need:

  • Git
  • Python 3.12+
  • PowerShell 5.1 or later
  • The pre-commit framework

Step 1: Install Pre-Commit Framework #

Pre-commit is a framework for managing git hooks. Install it with pip:

pip install pre-commit

Verify the installation:

pre-commit --version

Step 2: Set Up the PowerShell Formatter #

We’ll use a fantastic script from nathan815’s PowerShell-Formatter that wraps PSScriptAnalyzer.

Create the pre-commit folder structure #

mkdir pre-commit

Download the formatter script #

Invoke-RestMethod -Uri "https://raw.githubusercontent.com/nathan815/PowerShell-Formatter/main/FormatCode.ps1" -OutFile "pre-commit/FormatCode.ps1"

Install PSScriptAnalyzer #

The formatter requires PSScriptAnalyzer module:

Install-Module -Name PSScriptAnalyzer -Scope CurrentUser -Force -RequiredVersion 1.23.0

Or use the built-in installation option:

.\pre-commit\FormatCode.ps1 -InstallDependencies

Step 3: Configure Formatting Rules #

Create pre-commit/PSScriptAnalyzerSettings.psd1 to define your formatting rules:

@{
    IncludeRules = @(
        "PSPlaceOpenBrace",
        "PSPlaceCloseBrace",
        "PSUseConsistentIndentation",
        "PSUseConsistentWhitespace",
        "PSAlignAssignmentStatement",
        "PSUseCorrectCasing"
    )
    Rules = @{
        PSPlaceOpenBrace = @{
            Enable = $true
            OnSameLine = $true
            NewLineAfter = $true
            IgnoreOneLineBlock = $true
        }
        PSPlaceCloseBrace = @{
            Enable = $true
            NewLineAfter = $true
            IgnoreOneLineBlock = $true
            NoEmptyLineBefore = $false
        }
        PSUseConsistentIndentation = @{
            Enable = $true
            IndentationSize = 4
            PipelineIndentation = 'IncreaseIndentationForFirstPipeline'
            Kind = 'space'
        }
        PSUseConsistentWhitespace = @{
            Enable = $true
            CheckInnerBrace = $true
            CheckOpenBrace = $true
            CheckOpenParen = $true
            CheckOperator = $true
            CheckPipe = $true
            CheckPipeForRedundantWhitespace = $true
            CheckSeparator = $true
            CheckParameter = $false
        }
        PSAlignAssignmentStatement = @{
            Enable = $true
            CheckHashtable = $true
        }
        PSUseCorrectCasing = @{
            Enable = $true
        }
    }
}

These rules match VS Code’s PowerShell extension defaults: 4-space indentation, braces on the same line, consistent whitespace, and proper cmdlet casing.

Step 4: Configure Pre-Commit #

Create .pre-commit-config.yaml in your repository root:

repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v6.0.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
      - id: fix-byte-order-marker

  - repo: local
    hooks:
      - id: powershell-formatter
        name: PowerShell Code Formatter
        entry: powershell.exe -NoProfile -ExecutionPolicy Bypass -File pre-commit/FormatCode.ps1 -File
        language: system
        types: [powershell]
        pass_filenames: true

default_language_version:
  python: python3

The key part is the local repo hook that runs the PowerShell formatter on all .ps1 and .psm1 files.

Step 5: Install the Git Hooks #

Install pre-commit in your repository:

pre-commit install

This creates the actual git hook file in .git/hooks/pre-commit.

Step 6: Test It Out #

Create a test file with intentionally bad formatting:

# test-format.ps1
function Test-Formatting{
param($name,$value)
if($name -eq "test"){
Write-Host "Hello $name"
}
$result=Get-Process|Where-Object{$_.Name -eq "powershell"}
return $result
}

Stage and commit it:

git add test-format.ps1
git commit -m "test: formatting"

You’ll see the formatter run and fix the formatting! The commit will initially fail because files were modified. This is intentional—it lets you review the changes:

# Review the formatted changes
git diff test-format.ps1

# Stage the formatted version
git add test-format.ps1

# Commit again - will succeed this time
git commit -m "test: formatting"

The formatted file will look like this:

# test-format.ps1
function Test-Formatting {
    param($name, $value)
    if ($name -eq "test") {
        Write-Host "Hello $name"
    }
    $result = Get-Process | Where-Object { $_.Name -eq "powershell" }
    return $result
}

Beautiful! Proper spacing, consistent indentation, and clean formatting.

Manual Formatting #

You can also run the formatter manually:

# Format all PowerShell files
.\pre-commit\FormatCode.ps1

# Format a specific directory
.\pre-commit\FormatCode.ps1 -Directory ".\src"

# Format a single file
.\pre-commit\FormatCode.ps1 -File ".\src\MyModule.psm1"

# Check formatting without modifying (for CI)
.\pre-commit\FormatCode.ps1 -CheckOnly

CI/CD Integration #

Add this to your GitLab CI or GitHub Actions workflow to ensure all code is formatted:

# GitLab CI example
format-check:
  script:
    - pwsh -File pre-commit/FormatCode.ps1 -CheckOnly

The -CheckOnly flag makes the script exit with code 1 if any files need reformatting, perfect for CI validation.

Workflow Benefits #

Once set up, the workflow is seamless:

  1. Write code in your normal style
  2. Commit → formatter automatically fixes formatting
  3. Review the changes (if any)
  4. Stage and commit again → passes

Your team gets:

  • ✅ Consistent code style across the entire codebase
  • ✅ No more formatting debates in code reviews
  • ✅ Automatic enforcement via pre-commit hooks
  • ✅ CI validation to catch any bypasses
  • ✅ Zero manual effort after initial setup

Customization #

Don’t like the default rules? Customize PSScriptAnalyzerSettings.psd1:

  • Change indentation size
  • Move braces to new lines
  • Adjust whitespace rules
  • Enable/disable specific formatting rules

See the PSScriptAnalyzer rules reference for all available options.

Troubleshooting #

Hook doesn’t run on commit #

Make sure you installed it:

pre-commit install

PSScriptAnalyzer not found #

Install the module:

.\pre-commit\FormatCode.ps1 -InstallDependencies

Need to bypass the hook temporarily #

Use --no-verify (not recommended):

git commit --no-verify -m "skip formatting"

Final Thoughts #

Automating PowerShell code formatting with pre-commit hooks has been a game-changer for our team. No more inconsistent indentation, no more whitespace debates, and code reviews focus on what matters—the logic.

The setup takes about 10 minutes, and the benefits last forever. If you’re working on any PowerShell project with multiple developers, I highly recommend giving this a try.

Resources #