Skip to content

Instantly share code, notes, and snippets.

@sajdoko
Last active November 10, 2025 18:47
Show Gist options
  • Select an option

  • Save sajdoko/7a78e6bf9bc4b39c323b49a4e205fbdd to your computer and use it in GitHub Desktop.

Select an option

Save sajdoko/7a78e6bf9bc4b39c323b49a4e205fbdd to your computer and use it in GitHub Desktop.
This PowerShell script migrates the projects and MySQL databases from XAMPP to Laragon by copying project files from the htdocs directory to Laragon's www folder and exporting/importing all databases between the two environments.
<#
.SYNOPSIS
Migrates web projects and databases from XAMPP to Laragon
.DESCRIPTION
This script automates the migration of:
- Web projects from xampp/htdocs to laragon/www
- MySQL databases from XAMPP to Laragon
- Apache virtual host configurations
.NOTES
Make sure to unlock the script first: Unblock-File -Path ".\migrate-xampp-to-laragon.ps1"
Run this script as Administrator
#>
# Configuration
$xamppPath = "C:\xampp"
$laragonPath = "C:\laragon"
$logFile = "C:\migration-log.txt"
# Color output functions
function Write-Success { param($message) Write-Host $message -ForegroundColor Green }
function Write-Info { param($message) Write-Host $message -ForegroundColor Cyan }
function Write-Warning { param($message) Write-Host $message -ForegroundColor Yellow }
function Write-Error { param($message) Write-Host $message -ForegroundColor Red }
# Logging function
function Write-Log {
param($message)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
"$timestamp - $message" | Out-File -FilePath $logFile -Append
Write-Info $message
}
# Check if running as Administrator
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdmin) {
Write-Error "This script must be run as Administrator!"
Write-Warning "Please right-click the script and select 'Run as Administrator'"
pause
exit
}
Write-Host "`n========================================" -ForegroundColor Magenta
Write-Host " XAMPP to Laragon Migration Script" -ForegroundColor Magenta
Write-Host "========================================`n" -ForegroundColor Magenta
Write-Log "Migration started"
# Verify paths exist
if (-not (Test-Path $xamppPath)) {
Write-Error "XAMPP path not found: $xamppPath"
exit
}
if (-not (Test-Path $laragonPath)) {
Write-Error "Laragon path not found: $laragonPath"
exit
}
# Paths
$xamppHtdocs = Join-Path $xamppPath "htdocs"
$laragonWww = Join-Path $laragonPath "www"
$xamppMysqlData = Join-Path $xamppPath "mysql\data"
$laragonMysqlData = Join-Path $laragonPath "bin\mysql\mysql-*\data"
# Step 1: Stop services
Write-Host "`n[STEP 1] Stopping Services..." -ForegroundColor Yellow
Write-Log "Stopping XAMPP and Laragon services"
try {
# Stop XAMPP services
Write-Info "Stopping XAMPP Apache..."
Stop-Service -Name "Apache2.4" -ErrorAction SilentlyContinue
Stop-Process -Name "httpd" -Force -ErrorAction SilentlyContinue
Write-Info "Stopping XAMPP MySQL..."
Stop-Service -Name "mysql" -ErrorAction SilentlyContinue
Stop-Process -Name "mysqld" -Force -ErrorAction SilentlyContinue
# Stop Laragon services
Write-Info "Stopping Laragon services..."
Stop-Process -Name "laragon" -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 3
Write-Success "Services stopped successfully"
}
catch {
Write-Warning "Some services may already be stopped: $_"
}
# Step 2: Backup Laragon
Write-Host "`n[STEP 2] Creating Backup..." -ForegroundColor Yellow
$backupPath = Join-Path $laragonPath "backup_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
try {
if (Test-Path $laragonWww) {
Write-Info "Backing up existing Laragon www folder to: $backupPath"
Copy-Item -Path $laragonWww -Destination $backupPath -Recurse -Force
Write-Success "Backup created successfully"
}
}
catch {
Write-Warning "Backup failed: $_"
}
# Step 3: Migrate Web Projects
Write-Host "`n[STEP 3] Migrating Web Projects..." -ForegroundColor Yellow
Write-Log "Starting web projects migration"
if (Test-Path $xamppHtdocs) {
$projects = Get-ChildItem -Path $xamppHtdocs -Directory
Write-Info "Found $($projects.Count) projects in XAMPP htdocs"
foreach ($project in $projects) {
$sourcePath = $project.FullName
$destPath = Join-Path $laragonWww $project.Name
Write-Info "Migrating: $($project.Name)..."
try {
if (Test-Path $destPath) {
Write-Warning " Project already exists in Laragon. Skipping: $($project.Name)"
Write-Log "Skipped existing project: $($project.Name)"
}
else {
Copy-Item -Path $sourcePath -Destination $destPath -Recurse -Force
Write-Success " Migrated: $($project.Name)"
Write-Log "Migrated project: $($project.Name)"
}
}
catch {
Write-Error " Failed to migrate: $($project.Name) - $_"
Write-Log "ERROR: Failed to migrate $($project.Name) - $_"
}
}
Write-Success "Web projects migration completed"
}
else {
Write-Warning "XAMPP htdocs folder not found"
}
# Step 4: Export MySQL Databases
Write-Host "`n[STEP 4] Exporting MySQL Databases..." -ForegroundColor Yellow
Write-Log "Starting database export"
$dumpPath = Join-Path $env:TEMP "xampp_db_dumps"
New-Item -ItemType Directory -Path $dumpPath -Force | Out-Null
$xamppMysqlBin = Join-Path $xamppPath "mysql\bin"
$mysqldump = Join-Path $xamppMysqlBin "mysqldump.exe"
$mysql = Join-Path $xamppMysqlBin "mysql.exe"
if (Test-Path $mysqldump) {
Write-Info "Starting XAMPP MySQL temporarily for export..."
# Start XAMPP MySQL temporarily
$mysqlProcess = Start-Process -FilePath (Join-Path $xamppPath "mysql\bin\mysqld.exe") -ArgumentList "--console" -PassThru -WindowStyle Hidden
Start-Sleep -Seconds 5
try {
# Get list of databases (excluding system databases)
$getDatabases = "SELECT schema_name FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema', 'performance_schema', 'mysql', 'phpmyadmin', 'sys')"
$databases = & $mysql -u root -e $getDatabases --skip-column-names 2>$null
if ($databases) {
$dbList = $databases -split "`n" | Where-Object { $_ -and $_.Trim() }
Write-Info "Found $($dbList.Count) databases to export"
foreach ($db in $dbList) {
$db = $db.Trim()
if ($db) {
$dumpFile = Join-Path $dumpPath "$db.sql"
Write-Info "Exporting database: $db..."
try {
& $mysqldump -u root $db --result-file=$dumpFile 2>$null
if (Test-Path $dumpFile) {
Write-Success " Exported: $db"
Write-Log "Exported database: $db"
}
}
catch {
Write-Error " Failed to export: $db - $_"
Write-Log "ERROR: Failed to export $db - $_"
}
}
}
}
else {
Write-Warning "No databases found or unable to connect to MySQL"
}
}
catch {
Write-Warning "Database export error: $_"
}
finally {
# Stop XAMPP MySQL
Stop-Process -Id $mysqlProcess.Id -Force -ErrorAction SilentlyContinue
Stop-Process -Name "mysqld" -Force -ErrorAction SilentlyContinue
}
}
else {
Write-Warning "mysqldump.exe not found. Skipping database export."
Write-Info "You may need to manually export your databases using phpMyAdmin"
}
# Step 5: Import Databases to Laragon
Write-Host "`n[STEP 5] Importing Databases to Laragon..." -ForegroundColor Yellow
Write-Log "Starting database import to Laragon"
# Find Laragon MySQL binary
$laragonMysqlBin = Get-ChildItem -Path (Join-Path $laragonPath "bin\mysql") -Directory | Sort-Object Name -Descending | Select-Object -First 1
if ($laragonMysqlBin) {
$laragonMysql = Join-Path $laragonMysqlBin.FullName "bin\mysql.exe"
Write-Info "Starting Laragon MySQL..."
$laragonMysqld = Join-Path $laragonMysqlBin.FullName "bin\mysqld.exe"
$laragonMysqlProcess = Start-Process -FilePath $laragonMysqld -ArgumentList "--console" -PassThru -WindowStyle Hidden
Start-Sleep -Seconds 5
try {
$sqlFiles = Get-ChildItem -Path $dumpPath -Filter "*.sql"
foreach ($sqlFile in $sqlFiles) {
$dbName = $sqlFile.BaseName
Write-Info "Importing database: $dbName..."
try {
# Create database
$createDb = "CREATE DATABASE IF NOT EXISTS ``$dbName`` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
$createDb | & $laragonMysql -u root 2>$null
# Import data
Get-Content $sqlFile.FullName | & $laragonMysql -u root $dbName 2>$null
Write-Success " Imported: $dbName"
Write-Log "Imported database: $dbName"
}
catch {
Write-Error " Failed to import: $dbName - $_"
Write-Log "ERROR: Failed to import $dbName - $_"
}
}
}
catch {
Write-Warning "Database import error: $_"
}
finally {
# Stop Laragon MySQL
Stop-Process -Id $laragonMysqlProcess.Id -Force -ErrorAction SilentlyContinue
Stop-Process -Name "mysqld" -Force -ErrorAction SilentlyContinue
}
}
else {
Write-Warning "Laragon MySQL not found. Please import databases manually."
}
# Step 6: Migration Summary
Write-Host "`n========================================" -ForegroundColor Magenta
Write-Host " Migration Summary" -ForegroundColor Magenta
Write-Host "========================================" -ForegroundColor Magenta
Write-Info "`nMigrated Projects Location: $laragonWww"
if (Test-Path $dumpPath) {
Write-Info "Database Dumps Location: $dumpPath"
}
Write-Info "Migration Log: $logFile"
Write-Host "`n" -NoNewline
Write-Warning "IMPORTANT NEXT STEPS:"
Write-Host "1. Start Laragon and verify all services are running" -ForegroundColor White
Write-Host "2. Update database connection settings in your projects:" -ForegroundColor White
Write-Host " - Host: localhost or 127.0.0.1" -ForegroundColor White
Write-Host " - Username: root" -ForegroundColor White
Write-Host " - Password: (empty by default in Laragon)" -ForegroundColor White
Write-Host "3. Test each project in your browser" -ForegroundColor White
Write-Host "4. Update virtual hosts if needed (Laragon auto-creates them)" -ForegroundColor White
Write-Host "5. Check Apache/PHP configurations if needed" -ForegroundColor White
Write-Host "`n" -NoNewline
Write-Success "Migration completed successfully!"
Write-Log "Migration completed"
Write-Host "`nPress any key to exit..." -ForegroundColor Gray
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment