This repository provides PowerShell scripts to set up and manage a customization environment for AVEVA Unified Engineering (UE) add-in development.
Before working with this repository, you'll need:
-
Visual Studio Code
- Download and install from code.visualstudio.com
- A free, lightweight code editor with excellent PowerShell support
-
GitHub Copilot (recommended)
- Install the GitHub Copilot extension in VS Code
- Requires a GitHub Copilot subscription (free for students, educators, and open source maintainers)
- Provides AI-powered assistance including the UE Customization Manager agent
-
AVEVA Unified Engineering
- Must be installed with the
UEcommand available in your PATH - Required for unpacking MSIX packages and running customizations
- Must be installed with the
-
PowerShell 7.0 or higher
- Install PowerShell 7 so
pwsh.exeis available - Scripts are designed for PowerShell (
pwsh.exe)
- Install PowerShell 7 so
- Open Visual Studio Code
- Install recommended extensions:
- GitHub Copilot - AI-powered code assistance
- PowerShell - PowerShell language support
- Clone or open this repository in VS Code:
git clone <repository-url> cd UnifiedEngineeringCustomizationFramework code .
This repository includes a GitHub Copilot agent (@ue-customization-manager) that provides intelligent assistance for managing your UE customization environment. The agent understands the entire workflow and can guide you through setup, add-in creation, and cleanup operations.
The UE Customization Manager agent:
- Guides script selection - Recommends the correct script based on your intent
- Explains workflows - Helps you understand the proper sequence of operations
- Validates operations - Warns about destructive operations and validates parameters
- Troubleshoots issues - Provides context-aware assistance based on README documentation
- Launches UE - Can start AVEVA Unified Engineering when requested
- Manages the lifecycle - From initial setup through add-in creation to final cleanup
You can interact with the agent using natural language in the GitHub Copilot chat. Here are example commands:
@ue-customization-manager I need to set up a new customization environment with an add-in called "DataExporter"
@ue-customization-manager What do I need to do before creating my first add-in?
@ue-customization-manager Set up the environment without creating an add-in yet
@ue-customization-manager Create a new add-in named "ReportGenerator"
@ue-customization-manager I want to add multiple add-ins: "ToolOne", "ToolTwo", and "ToolThree"
@ue-customization-manager What are the naming rules for add-ins?
@ue-customization-manager Remove the "OldAddin" add-in
@ue-customization-manager How do I delete an add-in I no longer need?
@ue-customization-manager List all the add-ins in my environment
@ue-customization-manager Start UE
@ue-customization-manager Launch unified engineering
@ue-customization-manager Run ue
@ue-customization-manager Open the application
Tip: The agent will ask if you want to supply optional UE launch values (module, project, username, password, mdb) and will forward them to
Start-UE.ps1for you.
@ue-customization-manager Clean up my environment
@ue-customization-manager I'm done with this project, how do I reset everything?
@ue-customization-manager Clear the environment but keep the template
@ue-customization-manager I'm getting an error about UE command not found
@ue-customization-manager The script says the environment doesn't exist
@ue-customization-manager What files will be deleted if I run Clear?
- Safer operations - The agent warns before destructive operations
- Faster workflow - No need to remember exact script names or parameters
- Better understanding - Explains what each operation does and why
- Context-aware - Knows the state of your environment and suggests appropriate next steps
- Error prevention - Validates parameters before running scripts
The scripts automate the process of:
- Creating a structured directory environment for UE customization
- Unpacking the UE MSIX installation package
- Configuring environment variables
- Managing add-in configurations
- Cleaning up the customization environment
.
├── scripts/ # PowerShell scripts directory
│ ├── Setup-UECustomizationEnvironment.ps1
│ ├── New-UEAddin.ps1
│ ├── Remove-UEAddin.ps1
│ ├── Clear-UECustomizationEnvironment.ps1
│ ├── Build-AddIns.ps1
│ ├── Start-UE.ps1
│ ├── UECustomizationFunctions.psm1
│ └── Tests/
│ └── Run-Tests.ps1
├── templates/ # Template directory for creating add-ins
│ ├── DockedFormAddInTemplate/ # Template for creating new add-ins
│ └── README.md
├── source/ # Source directory for add-in projects
│ ├── [AddinName]/ # Auto-generated add-in source (created by New-UEAddin.ps1)
│ └── README.md
├── addins/ # Add-in configuration and UIC files
├── samples/ # Extracted samples from MSIX
├── README.md
└── environment.json # Generated configuration (created by Setup)
Once set up, the customization environment will have the following structure:
CustomizationRootDir/
├── templates/ # Template directory
│ ├── TemplateAddIn/ # Template for creating new add-ins
│ └── Template.uic # Template for add-in UI configuration
├── source/ # Add-in source code directory
│ └── [AddinName]/ # Auto-generated copy of TemplateAddIn with substitutions
├── samples/ # Extracted samples from MSIX (generated by Setup)
├── addins/ # Add-in configuration and files
│ ├── DesignAddins.xml # Module-specific Addins entries (Model → Design)
│ ├── TagsAddins.xml # Engineering → Tags
│ ├── ConfigurationAddins.xml # EngineeringConfiguration → Configuration
│ ├── IsodraftAddins.xml # Isodraft → Isodraft
│ ├── DrawAddins.xml # Draw → Draw
│ ├── ParagonAddins.xml # Paragon → Paragon
│ ├── SpoolerAddins.xml # Spooler → Spooler
│ ├── MonitorAddins.xml # Monitor → Monitor
│ ├── DesignCustomization.xml # Module-specific customization entries (Model → Design)
│ ├── TagsCustomization.xml # Engineering → Tags
│ ├── ConfigurationCustomization.xml # EngineeringConfiguration → Configuration
│ ├── IsodraftCustomization.xml # Isodraft → Isodraft
│ ├── DrawCustomization.xml # Draw → Draw
│ ├── ParagonCustomization.xml # Paragon → Paragon
│ ├── SpoolerCustomization.xml # Spooler → Spooler
│ ├── MonitorCustomization.xml # Monitor → Monitor
│ ├── [AddinName].dll # Compiled add-in binaries
│ └── [AddinName].uic # Add-in UI configuration files
Purpose: Creates the initial customization environment and configures environment variables.
Parameters:
Force(optional): Skips cleanup confirmation and automatically cleans existing folders if they exist.
Usage:
# Setup with default directory (script's parent folder)
.\scripts\Setup-UECustomizationEnvironment.ps1
# Setup with Force flag to skip confirmations
.\scripts\Setup-UECustomizationEnvironment.ps1 -ForceWhat it does:
- Creates directory structure (addins, samples)
- Runs
UE -tool:unpackto extract the MSIX - Extracts samples from samples.zip
- Copies all XML configuration files matching
*Addins.xmlor*Customization*.xmlpatterns to addins folder - Creates
environment.jsoncontaining environment variable configuration - Sets environment variables at User level and applies them to the current session:
CAF_ADDINS_PATHCAF_UIC_PATHUNIFIED_ENGINEERING_REFERENCE_PATH
- If environment already exists, prompts user to either:
- Re-establish: Restore environment variables from the existing configuration
- Full setup: Clean samples and addins folders, then rebuild (source folder is preserved)
Requirements:
- PowerShell 7.0 or higher
UEcommand available in PATH- Access to
C:\Users\Public\Documents\AVEVA\Unpack\AVEVA.UnifiedEngineering
Purpose: Creates a new add-in configuration and source code by copying and renaming the selected template folder.
Parameters:
AddinName(required): Name of the add-in to create. Must contain only letters A-Z or a-z.Template(optional): Name of the template to use (e.g., "DockedFormAddInTemplate"). If not provided, the user will be prompted to select from available templates.Module(optional): UE module to target. Valid values:Model,Engineering,EngineeringConfiguration,Isodraft,Draw,Paragon,Spooler,Monitor. If omitted, the script prompts with a numbered list.
Validation Rules:
AddinNamemust contain only letters A-Z or a-z. No spaces, numbers, or special characters allowed.
Usage:
# Create an add-in and select template from prompt
.\scripts\New-UEAddin.ps1 -AddinName "MySecondAddin"
# Create an add-in with a specific template
.\scripts\New-UEAddin.ps1 -AddinName "MySecondAddin" -Template "DockedFormAddInTemplate"
# Create an add-in for a specific module (skips module prompt)
.\scripts\New-UEAddin.ps1 -AddinName "MyThirdAddin" -Module "Engineering"
# Create an add-in specifying both template and module
.\scripts\New-UEAddin.ps1 -AddinName "MyFourthAddin" -Template "DockedFormAddInTemplate" -Module "Model"What it does:
- Validates that
AddinNamecontains only A-Z/a-z characters - If no module is specified, prompts with a numbered list and maps the choice to file prefixes:
- Model
- Engineering
- EngineeringConfiguration
- Isodraft
- Draw
- Paragon
- Spooler
- Monitor
- If no template is specified, displays available templates from the
templates/folder and prompts the user to select one - Validates the customization environment exists
- Adds the add-in name to the module-specific
*Addins.xml(e.g.,TagsAddins.xmlfor Engineering) - If the chosen template contains a
.uicfile, adds aCustomizationFileentry to the module-specific*Customization.xml(e.g.,TagsCustomization.xml); otherwise skips customization - Copies the selected template folder from
templates/[TemplateName]tosource/[AddinName]- Uses robocopy to avoid locked files
- Excludes directories: bin, obj, .vs, logs, log
- Excludes files: *.user, *.suo, *.rsuser, *.userprefs, *.pdb, *.ipdb, *.iobj, *.obj, *.pch, *.log, *.tlog, *.tmp, *.cache, *.ilk
- Renames all files and folders containing the template name to the new add-in name
- Replaces all text occurrences of the template name within the copied folder with the new add-in name
Purpose: Removes an existing add-in configuration and source code from the customization environment.
Parameters:
AddinName(required): Name of the add-in to remove. Must contain only letters A-Z or a-z.Force(optional): Removes the add-in without prompting for confirmation.
Validation Rules:
AddinNamemust contain only letters A-Z or a-z. No spaces, numbers, or special characters allowed.
Usage:
# Remove an add-in with confirmation
.\scripts\Remove-UEAddin.ps1 -AddinName "MySecondAddin"
# Remove an add-in without confirmation
.\scripts\Remove-UEAddin.ps1 -AddinName "MySecondAddin" -ForceWhat it does:
- Validates that
AddinNamecontains only A-Z/a-z characters - Validates the customization environment exists
- Prompts for confirmation (unless
-Forceis used) - Removes the add-in entry from all
*Addins.xmlfiles underaddins/(e.g.,DesignAddins.xml,TagsAddins.xml, etc.) - Removes the CustomizationFile entry from all
*Customization.xmlfiles underaddins/(e.g.,DesignCustomization.xml,TagsCustomization.xml, etc.) - Deletes the
.uicfile for the add-in (if present) - Deletes the add-in DLL
addins/[AddinName].dll(if present) - Deletes the add-in source folder from
source/[AddinName]and all its contents
Purpose: Cleans up the customization environment by removing the samples and addins folders and optionally the environment configuration file. The source folder with custom add-in projects is preserved for selective removal.
Parameters:
Force(optional): Deletes folders and config without prompting for confirmation.
Usage:
# Clear with confirmation (prompts for each item)
.\scripts\Clear-UECustomizationEnvironment.ps1
# Clear without confirmation
.\scripts\Clear-UECustomizationEnvironment.ps1 -ForceWhat it does:
- Checks for existing
samples/,addins/, andenvironment.json - If no
-Forceflag, prompts for confirmation to delete each item (folder name and path shown) - Removes selected items:
samples/(entire folder - extracted sample code)addins/(entire folder - unpacked reference files)environment.json(environment configuration)
- Preserves the
source/folder - Your custom add-in projects are kept intact - To remove individual add-ins from the
source/folder, use Remove-UEAddin.ps1 - Leaves repo structure intact (templates/, scripts/, etc.) for future use
Purpose: Builds all .csproj files under a specified directory (any folder, not limited to samples or source).
Parameters:
Directory(required): Target directory to search recursively for.csprojfiles. Accepts relative paths (from repo root) or absolute paths.Configuration(optional): Build configuration; defaults toDebug.
Usage:
# Build all sample projects
pwsh -NoProfile -File scripts/Build-AddIns.ps1 -Directory samples
# Build all source projects
pwsh -NoProfile -File scripts/Build-AddIns.ps1 -Directory source
# Build a custom folder with Release configuration
pwsh -NoProfile -File scripts/Build-AddIns.ps1 -Directory C:\Path\To\Projects -Configuration ReleaseWhat it does:
- Resolves the provided directory (relative to repo root if not absolute).
- Finds all
.csprojfiles recursively beneath that directory. - Runs
dotnet buildfor each project with the chosen configuration and summarizes any failures.
Purpose: Launches AVEVA Unified Engineering with the customization environment variables restored from the environment configuration file, optionally forwarding UE launch arguments.
Parameters:
Module(optional, aliasmd): UE module to run (--module:<value>)Project(optional, aliasesproj,p): Project name (--project:<value>)Username(optional, aliasesuser,u): Username (--username:<value>)Password(optional, aliasespass,pw): Password (--password:<value>)Mdb(optional, aliasm): MDB name (--mdb:<value>)
Usage:
# Launch UE with restored environment
.\scripts\Start-UE.ps1
# Launch UE with verbose output
.\scripts\Start-UE.ps1 -Verbose
# Launch UE with optional UE arguments forwarded
.\scripts\Start-UE.ps1 -Module Model -Project APS -Username SYSTEM -Password XXXXXX -Mdb ALLWhat it does:
- Reads the environment configuration from
environment.json - Restores the customization environment variables (CAF_ADDINS_PATH, CAF_UIC_PATH, UNIFIED_ENGINEERING_REFERENCE_PATH, etc.) to both user and session scopes
- Builds an optional UE argument list from provided parameters and forwards them to the
ueexecutable - Launches the AVEVA Unified Engineering application
- Displays warnings if
environment.jsonis not found or environment restoration encounters issues
Requirements:
Setup-UECustomizationEnvironment.ps1must have been run previously to createenvironment.jsonUEcommand must be available in PATH- AVEVA Unified Engineering must be installed
The setup script creates and sets the following environment variables at the User level and applies them to the current session:
- CAF_ADDINS_PATH: Points to the addins folder (e.g.,
C:\Git\UnifiedEngineeringCustomizationFramework\addins\) - CAF_UIC_PATH: Points to the addins folder (e.g.,
C:\Git\UnifiedEngineeringCustomizationFramework\addins\) - UNIFIED_ENGINEERING_REFERENCE_PATH: Points to the unpacked UE binaries (e.g.,
C:\Users\Public\Documents\AVEVA\Unpack\AVEVA.UnifiedEngineering\4000.2507.304.3703)
These variables are persisted in the Windows Registry (User level) and restored automatically when Start-UE.ps1 is run.
All scripts that accept an AddinName parameter enforce strict validation:
- Allowed: A-Z, a-z only (e.g., "MyAddin", "CustomAddIn", "TestAddin")
- Not allowed: Numbers, spaces, hyphens, underscores, or special characters
- Error:
AddinName must only contain letters A-Z or a-z, with no spaces or special characters.
CustomizationRootDiris always set to the parent directory of the scripts folder (automatic, non-configurable)- All paths are handled safely; scripts create directories as needed
- Paths with spaces are handled correctly
The New-UEAddin.ps1 script uses robocopy to avoid locked files when copying TemplateAddIn:
- Retries up to 2 times on lock conflicts
- Automatically excludes
.gitignore-listed artifacts (bin, obj, .vs, temp files) - Fails gracefully with informative error messages if critical copy failures occur
# 1. Navigate to the repository directory
cd C:\Git\UnifiedEngineeringCustomizationFramework
# 2. Run setup to create the environment
.\scripts\Setup-UECustomizationEnvironment.ps1
# 3. Create your first add-in
.\scripts\New-UEAddin.ps1 -AddinName "MyFirstAddin"After setup completes:
source\MyFirstAddin\contains your first add-in's source codeaddins\MyFirstAddin.uiccontains the UI configurationenvironment.jsoncontains your environment configuration- Environment variables are set globally and will be restored when you run
Start-UE.ps1
# Create more add-ins from the template
.\scripts\New-UEAddin.ps1 -AddinName "MySecondAddin"
.\scripts\New-UEAddin.ps1 -AddinName "MyThirdAddin"
# Each creates:
# - source\[AddinName]\ (complete copy of the selected template with substitutions)
# - addins\[AddinName].uic (UI configuration file)# Build your add-in
.\scripts\Build-AddIns.ps1 -Directory source\MyFirstAddin
# Launch UE with your add-in
.\scripts\Start-UE.ps1Once created, edit your add-in source code:
- Navigate to
source\[AddinName]\ - All references to the template name have been replaced with your add-in name
- All file/folder names containing the template name have been renamed
- Modify the C# code, projects, and configuration as needed
# Remove a specific add-in (with confirmation)
.\scripts\Remove-UEAddin.ps1 -AddinName "MySecondAddin"
# Remove without confirmation
.\scripts\Remove-UEAddin.ps1 -AddinName "MySecondAddin" -Force# Clean up all generated content
.\scripts\Clear-UECustomizationEnvironment.ps1 -Force
# Run setup again for a fresh environment
.\scripts\Setup-UECustomizationEnvironment.ps1- Ensure the AVEVA Unified Engineering application is installed
- Add the UE installation directory to your PATH environment variable
- Run the setup script from a PowerShell session that has UE in its PATH
- Run
UE -tool:unpackmanually first to create the unpack directory - Default unpack location:
C:\Users\Public\Documents\AVEVA\Unpack\AVEVA.UnifiedEngineering
- Ensure
Setup-UECustomizationEnvironment.ps1has been run successfully - Check that the scripts are in the
scriptsfolder under the customization root
- Ensure your add-in name contains only letters (no numbers, spaces, or special characters)
- Example: ✓ "MyAddin", ✗ "My-Addin", ✗ "MyAddin2"
- The source or templates folder may be locked by another process (IDE, file explorer, etc.)
- Close any open IDEs or file explorers accessing these directories
- Try running the script again
- Close Visual Studio, GitHub Desktop, or other applications that may lock files
- Ensure no file explorers are open to the source directory
- Wait a moment and retry
- Run PowerShell as Administrator if you encounter permission issues
- Ensure you have write access to the customization directory
- Check that the environment variable
CAF_ADDINS_PATHis correctly set
- All scripts use
[CmdletBinding()]for advanced function features - Scripts follow PowerShell best practices from the PowerShell Practice and Style Guide
- All function names use approved PowerShell verbs
- Scripts include comprehensive error handling and user feedback
- Changes to XML files are automatically saved
[Add your license information here]
[Add author information here]