diff --git a/Build-Plugin.ps1 b/Build-Plugin.ps1
new file mode 100644
index 0000000..eaa94bc
--- /dev/null
+++ b/Build-Plugin.ps1
@@ -0,0 +1,164 @@
+# Build-Plugin.ps1
+# Builds and packages the Service Tracker plugin for Disco ICT import
+#
+# Usage:
+# .\Build-Plugin.ps1 -DiscoBinPath "C:\Program Files\Disco\WebApp\bin"
+
+param(
+ [Parameter(Mandatory=$true)]
+ [string]$DiscoBinPath,
+
+ [string]$Configuration = "Release"
+)
+
+$ErrorActionPreference = "Stop"
+$PluginDir = $PSScriptRoot
+$PluginName = "Disco.Plugins.ServiceTracker"
+
+Write-Host "=== Service Tracker Plugin Builder ===" -ForegroundColor Cyan
+Write-Host "Disco bin path: $DiscoBinPath" -ForegroundColor Gray
+
+# --- Validate ---
+if (-not (Test-Path $DiscoBinPath)) {
+ Write-Error "Disco bin path not found: $DiscoBinPath"
+ exit 1
+}
+
+$requiredDlls = @("Disco.Services.dll", "Disco.Models.dll", "Disco.Data.dll")
+foreach ($dll in $requiredDlls) {
+ $dllPath = Join-Path $DiscoBinPath $dll
+ if (-not (Test-Path $dllPath)) {
+ Write-Error "Required assembly not found: $dllPath"
+ exit 1
+ }
+}
+Write-Host "All required Disco assemblies found" -ForegroundColor Green
+
+# --- Show Disco Assembly Versions ---
+Write-Host "`n--- Disco Assembly Versions ---" -ForegroundColor DarkGray
+foreach ($dll in $requiredDlls) {
+ $dllPath = Join-Path $DiscoBinPath $dll
+ try {
+ $asmName = [System.Reflection.AssemblyName]::GetAssemblyName($dllPath)
+ Write-Host " $dll : v$($asmName.Version)" -ForegroundColor Gray
+ } catch {
+ Write-Warning " $dll : could not read version - $($_.Exception.Message)"
+ }
+}
+
+# --- Find MSBuild ---
+$msbuild = $null
+$vsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
+if (Test-Path $vsWhere) {
+ $msbuild = & $vsWhere -latest -requires Microsoft.Component.MSBuild -find "MSBuild\**\Bin\MSBuild.exe" 2>$null | Select-Object -First 1
+}
+if (-not $msbuild -or -not (Test-Path $msbuild)) {
+ $msbuild = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe"
+}
+if (-not (Test-Path $msbuild)) {
+ Write-Error "MSBuild not found."
+ exit 1
+}
+Write-Host "Using MSBuild: $msbuild" -ForegroundColor Gray
+
+# --- Resolve all HintPaths to Disco bin ---
+$csproj = Join-Path $PluginDir "$PluginName.csproj"
+$csprojContent = Get-Content $csproj -Raw
+$csprojContent = [regex]::Replace($csprojContent, '[^<]+\\([^\\<]+\.dll)', "$DiscoBinPath\`$1")
+
+$tempCsproj = Join-Path $PluginDir "$PluginName.build.csproj"
+$csprojContent | Set-Content $tempCsproj -Encoding UTF8
+Write-Host "Assembly references resolved to $DiscoBinPath" -ForegroundColor Green
+
+# --- Build ---
+Write-Host "`nBuilding $PluginName ($Configuration)..." -ForegroundColor Yellow
+$buildOutput = Join-Path $PluginDir "bin\$Configuration"
+
+& $msbuild $tempCsproj /p:Configuration=$Configuration /p:OutputPath=$buildOutput /t:Build /v:minimal
+
+if ($LASTEXITCODE -ne 0) {
+ Remove-Item $tempCsproj -ErrorAction SilentlyContinue
+ Write-Error "Build failed!"
+ exit 1
+}
+Remove-Item $tempCsproj -ErrorAction SilentlyContinue
+
+$pluginDll = Join-Path $buildOutput "$PluginName.dll"
+if (-not (Test-Path $pluginDll)) {
+ Write-Error "Build output not found: $pluginDll"
+ exit 1
+}
+Write-Host "Build successful: $pluginDll" -ForegroundColor Green
+
+# --- Copy Dependencies for Reflection ---
+foreach ($dll in $requiredDlls) {
+ Copy-Item (Join-Path $DiscoBinPath $dll) $buildOutput -Force -ErrorAction SilentlyContinue
+}
+$extraDlls = @("EntityFramework.dll", "System.Web.Mvc.dll", "System.Web.WebPages.dll", "System.Web.Razor.dll", "RazorGenerator.Mvc.dll", "Newtonsoft.Json.dll")
+foreach ($dep in $extraDlls) {
+ $depPath = Join-Path $DiscoBinPath $dep
+ if (Test-Path $depPath) { Copy-Item $depPath $buildOutput -Force -ErrorAction SilentlyContinue }
+}
+
+# --- Generate Manual Manifest ---
+Write-Host "`n--- Manifest Generation ---" -ForegroundColor Yellow
+
+$version = [System.Reflection.AssemblyName]::GetAssemblyName($pluginDll).Version
+
+$manifest = [ordered]@{
+ Id = $PluginName
+ Name = "Service Tracker"
+ Author = "Jess Rogerson"
+ Url = "https://gitea.hideawaygaming.com.au/jessikitty/disco-service-tracker-plugin"
+ Version = $version.ToString()
+ AssemblyPath = "$PluginName.dll"
+ TypeName = "Disco.Plugins.ServiceTracker.ServiceTrackerPlugin"
+ ConfigurationHandlerTypeName = "Disco.Plugins.ServiceTracker.ConfigurationHandler.ServiceTrackerConfigurationHandler"
+ WebHandlerTypeName = "Disco.Plugins.ServiceTracker.WebHandler.ServiceTrackerWebHandler"
+ Features = @()
+}
+$manifestJson = $manifest | ConvertTo-Json -Depth 5
+$manifestJson | Set-Content (Join-Path $buildOutput "manifest.json") -Encoding UTF8
+Write-Host "manifest.json created" -ForegroundColor Green
+
+# --- Package ---
+Write-Host "`nPackaging .discoPlugin file..." -ForegroundColor Yellow
+
+$includeFiles = @("$PluginName.dll", "$PluginName.pdb", "manifest.json")
+$packageName = "$PluginName-$($version.ToString()).discoPlugin"
+$packagePath = Join-Path $PluginDir $packageName
+
+Get-ChildItem $PluginDir -Filter "*.discoPlugin" | Remove-Item -Force
+Get-ChildItem $PluginDir -Filter "*.zip" | Where-Object { $_.Name -like "$PluginName*" } | Remove-Item -Force
+
+$tempPkg = Join-Path $env:TEMP "discoplugin_$([guid]::NewGuid().ToString('N'))"
+New-Item -ItemType Directory -Path $tempPkg -Force | Out-Null
+$missingFiles = @()
+foreach ($f in $includeFiles) {
+ $src = Join-Path $buildOutput $f
+ if (Test-Path $src) {
+ Copy-Item $src $tempPkg -Force
+ } else {
+ $missingFiles += $f
+ }
+}
+
+if ($missingFiles.Count -gt 0) {
+ Write-Warning "Missing files not included in package: $($missingFiles -join ', ')"
+}
+
+Write-Host "Files in package:" -ForegroundColor Gray
+Get-ChildItem $tempPkg -File | ForEach-Object {
+ $size = [math]::Round($_.Length / 1KB, 1)
+ Write-Host " $($_.Name) ($size KB)" -ForegroundColor Gray
+}
+
+$zipPath = Join-Path $PluginDir "$PluginName-$($version.ToString()).zip"
+Compress-Archive -Path "$tempPkg\*" -DestinationPath $zipPath -Force
+Rename-Item $zipPath $packageName -Force
+Remove-Item $tempPkg -Recurse -Force
+
+$packageSize = [math]::Round((Get-Item $packagePath).Length / 1KB, 1)
+Write-Host "`n=== Package created: $packagePath ($($packageSize) KB) ===" -ForegroundColor Green
+Write-Host "Import into Disco ICT via: Configuration > Plugins > Install Plugin" -ForegroundColor Cyan
+Write-Host "`n=== BUILD COMPLETED SUCCESSFULLY ===" -ForegroundColor Green