[ Web Proxy ]
URL:
Viewing: https://docs.psscriptbuilder.com/cmdlets/../../tutorials/building-your-first-project/ [Back]  [Original]

Building Your First Project - PSScriptBuilder Docs
Skip to content
logo [logo]
PSScriptBuilder Docs
Building Your First Project
[Go]
PSScriptBuilder/PSScriptBuilder
logo [logo] PSScriptBuilder Docs

Building Your First Project

This tutorial walks you through building a complete PSScriptBuilder project from scratch. You will create the source files, configure PSScriptBuilder, write a template and a build script, and run your first build. By the end, you have a single deployable .ps1 generated from multiple source files with all dependencies automatically resolved.

If you already have an existing project and want to adopt PSScriptBuilder, see Migrating to PSScriptBuilder instead.

Prerequisites: PSScriptBuilder installed see Installation.


What We're Building

A small HR project with two enums, three classes, and one function enough to demonstrate dependency resolution and multi-collector builds. The final project structure looks like this:

HRTools/
 psscriptbuilder.config.json
 Build-HRTools.ps1
 src/
    Enums/
       Department.ps1
       EmploymentStatus.ps1
    Classes/
       Address.ps1
       Person.ps1
       Employee.ps1
    Public/
        New-Employee.ps1
 build/
     Templates/
        HRTools.ps1.template
     Output/

1. Create the Directory Structure

Create the project folder and all subdirectories:

New-Item -ItemType Directory -Path "HRTools\src\Enums",
                                   "HRTools\src\Classes",
                                   "HRTools\src\Public",
                                   "HRTools\build\Templates",
                                   "HRTools\build\Output"
Set-Location HRTools

2. Write the Source Files

Each source file contains exactly one component. PSScriptBuilder discovers the files automatically file names do not need to match class or enum names, but it is good practice.

Enums

src/Enums/Department.ps1
enum Department {
    Engineering
    HumanResources
    Finance
    Marketing
}
src/Enums/EmploymentStatus.ps1
enum EmploymentStatus {
    Active
    OnLeave
    Terminated
    Retired
}

Classes

src/Classes/Address.ps1
class Address {
    [string] $Street
    [string] $City
    [string] $PostalCode
    [string] $Country

    Address([string] $street, [string] $city, [string] $postalCode, [string] $country) {
        $this.Street     = $street
        $this.City       = $city
        $this.PostalCode = $postalCode
        $this.Country    = $country
    }
}
src/Classes/Person.ps1
class Person {
    [string] $FirstName
    [string] $LastName

    Person([string] $firstName, [string] $lastName) {
        $this.FirstName = $firstName
        $this.LastName  = $lastName
    }
}

Employee inherits from Person and references Address, Department, and EmploymentStatus. PSScriptBuilder detects these dependencies automatically and ensures that all prerequisites appear before Employee in the output regardless of the order files are on disk.

src/Classes/Employee.ps1
class Employee : Person {
    [Address]          $Address
    [Department]       $Department
    [EmploymentStatus] $Status
    [DateTime]         $HireDate
    [decimal]          $Salary

    Employee(
        [string]           $firstName,
        [string]           $lastName,
        [Address]          $address,
        [Department]       $department,
        [DateTime]         $hireDate,
        [decimal]          $salary
    ) : base($firstName, $lastName) {
        $this.Address    = $address
        $this.Department = $department
        $this.Status     = [EmploymentStatus]::Active
        $this.HireDate   = $hireDate
        $this.Salary     = $salary
    }
}

Functions

src/Public/New-Employee.ps1
Function New-Employee {
    [CmdletBinding()]
    [OutputType([Employee])]
    param(
        [Parameter(Mandatory)]
        [string] $FirstName,

        [Parameter(Mandatory)]
        [string] $LastName,

        [Parameter(Mandatory)]
        [Address] $Address,

        [Parameter(Mandatory)]
        [Department] $Department,

        [Parameter(Mandatory)]
        [DateTime] $HireDate,

        [Parameter(Mandatory)]
        [decimal] $Salary
    )

    return [Employee]::new($FirstName, $LastName, $Address, $Department, $HireDate, $Salary)
}

3. Add the Configuration File

Run the following cmdlet from the project root to generate psscriptbuilder.config.json:

New-PSScriptBuilderConfiguration

The generated file contains all required fields pre-filled with sensible defaults. The two fields you will use most are build.templatePath and build.outputPath both already point to the build\Templates and build\Output directories you created in step 1.

For a full explanation of all fields, see the Configuration Guide.


4. Create the Template

The template defines the structure of the generated output file. Each {{Token}} placeholder is replaced with the collected and dependency-ordered source code of the corresponding collector.

Create build/Templates/HRTools.ps1.template:

build/Templates/HRTools.ps1.template
{{ENUM_DEFINITIONS}}

{{CLASS_DEFINITIONS}}

{{FUNCTION_DEFINITIONS}}

The placeholders map to the collectors you will configure in the next step:

Placeholder Collector type
{{ENUM_DEFINITIONS}} Enum
{{CLASS_DEFINITIONS}} Class
{{FUNCTION_DEFINITIONS}} Function

For a full explanation of placeholder syntax and the three validation modes, see the Templates Guide.


5. Write the Build Script

Create Build-HRTools.ps1 at the project root. The build script sets the project root, configures the collectors, and invokes the build:

Build-HRTools.ps1
using module PSScriptBuilder

Set-PSScriptBuilderProjectRoot -Path $PSScriptRoot

$config = Get-PSScriptBuilderConfiguration

$contentCollector = New-PSScriptBuilderContentCollector |
    Add-PSScriptBuilderCollector -Type Enum     -IncludePath 'src\Enums'   |
    Add-PSScriptBuilderCollector -Type Class    -IncludePath 'src\Classes' |
    Add-PSScriptBuilderCollector -Type Function -IncludePath 'src\Public'

$buildParams = @{
    ContentCollector = $contentCollector
    TemplatePath     = Join-Path $config.Build.TemplatePath 'HRTools.ps1.template'
    OutputPath       = Join-Path $config.Build.OutputPath   'HRTools.ps1'
}

Invoke-PSScriptBuilderBuild @buildParams | Format-PSScriptBuilderBuildResult

Set-PSScriptBuilderProjectRoot tells PSScriptBuilder where to resolve relative paths from. $PSScriptRoot is the directory of the currently running script always the correct value when calling this from a build script.

Get-PSScriptBuilderConfiguration reads psscriptbuilder.config.json and returns a typed object. Using $config.Build.TemplatePath and $config.Build.OutputPath means you only need to update the config file if the directories change not the build script.


6. Run the Build

From the project root:

.\Build-HRTools.ps1

Expected output:

Build Summary
  Output : ...\build\Output\HRTools.ps1
  Size   : 2.14 KB
  Time   : 312.45 ms

Components
  Enums     : 2
  Classes   : 3
  Functions : 1
  Total     : 6

The generated build/Output/HRTools.ps1 contains all components in the correct load order: enums first, then classes in dependency order (Address and Person before Employee), then functions. You did not specify any ordering PSScriptBuilder resolved it automatically from the AST.


Next Steps


See Also

Back to top

Web Proxy Viewer  |  New URL  |  Original Page