# Create VPN Connection for Peaceful Spirit with Pre-Login Access
# Run as Administrator

param(
    [string]$VpnServer = "",  # VPN server address (IP or hostname)
    [string]$Username = "",
    [string]$Password = "",
    [string]$ConnectionName = "Peaceful Spirit VPN",
    [string]$TunnelType = "L2tp",  # Options: Pptp, L2tp, Sstp, IKEv2, Automatic
    [string]$L2tpPsk = "",  # Pre-shared key for L2TP (if using L2TP)
    [string]$RemoteNetwork = "192.168.0.0/24",  # Remote network to route through VPN
    [string]$DnsServer = "192.168.0.2",  # DNS server at remote site
    [switch]$SplitTunneling = $true  # Enable split tunneling (default: true)
)

# Ensure running as Administrator
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Write-Host "[ERROR] This script must be run as Administrator" -ForegroundColor Red
    Write-Host "Right-click PowerShell and select 'Run as Administrator'" -ForegroundColor Yellow
    exit 1
}

Write-Host "=========================================="
Write-Host "Peaceful Spirit VPN Setup"
Write-Host "=========================================="
Write-Host ""

# Prompt for missing parameters
if ([string]::IsNullOrWhiteSpace($VpnServer)) {
    $VpnServer = Read-Host "Enter VPN server address (IP or hostname)"
}

if ([string]::IsNullOrWhiteSpace($Username)) {
    $Username = Read-Host "Enter VPN username"
}

if ([string]::IsNullOrWhiteSpace($Password)) {
    $SecurePassword = Read-Host "Enter VPN password" -AsSecureString
    $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)
    $Password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
}

if ($TunnelType -eq "L2tp" -and [string]::IsNullOrWhiteSpace($L2tpPsk)) {
    $L2tpPsk = Read-Host "Enter L2TP Pre-Shared Key (leave blank if not using)"
}

Write-Host ""
Write-Host "[INFO] Configuration:"
Write-Host "  VPN Server: $VpnServer"
Write-Host "  Username: $Username"
Write-Host "  Connection Name: $ConnectionName"
Write-Host "  Tunnel Type: $TunnelType"
Write-Host "  Remote Network: $RemoteNetwork"
Write-Host "  DNS Server: $DnsServer"
Write-Host "  Split Tunneling: $SplitTunneling"
Write-Host ""

# Remove existing connection if it exists
Write-Host "[1/6] Checking for existing VPN connection..."
$existingVpn = Get-VpnConnection -Name $ConnectionName -AllUserConnection -ErrorAction SilentlyContinue
if ($existingVpn) {
    Write-Host "  [INFO] Removing existing connection..."
    Remove-VpnConnection -Name $ConnectionName -AllUserConnection -Force
    Write-Host "  [OK] Existing connection removed"
} else {
    Write-Host "  [OK] No existing connection found"
}

# Create VPN connection (AllUserConnection for pre-login access)
Write-Host ""
Write-Host "[2/6] Creating VPN connection..."

$vpnParams = @{
    Name = $ConnectionName
    ServerAddress = $VpnServer
    TunnelType = $TunnelType
    AllUserConnection = $true
    RememberCredential = $true
    SplitTunneling = $SplitTunneling
    PassThru = $true
}

# Add L2TP Pre-Shared Key if provided
if ($TunnelType -eq "L2tp" -and -not [string]::IsNullOrWhiteSpace($L2tpPsk)) {
    $vpnParams['L2tpPsk'] = $L2tpPsk
    $vpnParams['AuthenticationMethod'] = 'MsChapv2'  # Use MS-CHAPv2 for L2TP/IPSec with PSK
    $vpnParams['EncryptionLevel'] = 'Required'
}

try {
    $vpn = Add-VpnConnection @vpnParams
    Write-Host "  [OK] VPN connection created"
    if ($SplitTunneling) {
        Write-Host "  [OK] Split tunneling enabled (only remote network traffic uses VPN)"
    }
} catch {
    Write-Host "  [ERROR] Failed to create VPN connection: $_" -ForegroundColor Red
    exit 1
}

# Add route for remote network
Write-Host ""
Write-Host "[3/6] Configuring route for remote network..."
try {
    # Add route for specified remote network through VPN
    Add-VpnConnectionRoute -ConnectionName $ConnectionName -DestinationPrefix $RemoteNetwork -AllUserConnection
    Write-Host "  [OK] Route added: $RemoteNetwork via VPN"

    # Configure DNS servers for the VPN connection
    Set-DnsClientServerAddress -InterfaceAlias $ConnectionName -ServerAddresses $DnsServer -ErrorAction SilentlyContinue
    Write-Host "  [OK] DNS server configured: $DnsServer"
} catch {
    Write-Host "  [WARNING] Could not configure route: $_" -ForegroundColor Yellow
    Write-Host "  [INFO] You may need to add the route manually after connecting"
}

# Configure VPN connection for pre-login (Windows logon screen)
Write-Host ""
Write-Host "[4/6] Configuring for pre-login access..."

# Set connection to be available before user logs on
$rasphonePath = "$env:ProgramData\Microsoft\Network\Connections\Pbk\rasphone.pbk"

if (Test-Path $rasphonePath) {
    # Modify rasphone.pbk to enable pre-login
    $rasphoneContent = Get-Content $rasphonePath -Raw

    # Find the connection section
    if ($rasphoneContent -match "\[$ConnectionName\]") {
        # Add or update UseRasCredentials setting
        $rasphoneContent = $rasphoneContent -replace "(?m)^UseRasCredentials=.*$", "UseRasCredentials=1"
        if ($rasphoneContent -notmatch "UseRasCredentials=") {
            $rasphoneContent = $rasphoneContent -replace "(\[$ConnectionName\])", "`$1`r`nUseRasCredentials=1"
        }

        Set-Content -Path $rasphonePath -Value $rasphoneContent
        Write-Host "  [OK] Pre-login access configured in rasphone.pbk"
    }
} else {
    Write-Host "  [WARNING] rasphone.pbk not found (connection still created)" -ForegroundColor Yellow
}

# Save credentials using rasdial
Write-Host ""
Write-Host "[5/6] Saving VPN credentials..."

try {
    # Connect once to save credentials
    $rasDialOutput = rasdial $ConnectionName $Username $Password 2>&1
    Start-Sleep -Seconds 2

    # Disconnect
    rasdial $ConnectionName /disconnect 2>&1 | Out-Null

    Write-Host "  [OK] Credentials saved"
} catch {
    Write-Host "  [WARNING] Could not save credentials via rasdial: $_" -ForegroundColor Yellow
}

# Set registry keys for pre-login VPN
Write-Host ""
Write-Host "[6/6] Configuring registry settings..."

try {
    # Enable pre-logon VPN
    $regPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"

    # Create or update registry values
    if (-not (Test-Path $regPath)) {
        New-Item -Path $regPath -Force | Out-Null
    }

    # Set UseRasCredentials to enable VPN before logon
    Set-ItemProperty -Path $regPath -Name "UseRasCredentials" -Value 1 -Type DWord

    Write-Host "  [OK] Registry settings configured"
} catch {
    Write-Host "  [WARNING] Could not set registry values: $_" -ForegroundColor Yellow
}

# Summary
Write-Host ""
Write-Host "=========================================="
Write-Host "Setup Complete!"
Write-Host "=========================================="
Write-Host ""
Write-Host "VPN Connection Details:"
Write-Host "  Name: $ConnectionName"
Write-Host "  Server: $VpnServer"
Write-Host "  Type: $TunnelType"
Write-Host "  Pre-Login: Enabled"
Write-Host "  Split Tunneling: $SplitTunneling"
Write-Host "  Remote Network: $RemoteNetwork"
Write-Host "  DNS Server: $DnsServer"
Write-Host ""
if ($SplitTunneling) {
    Write-Host "Network Traffic:"
    Write-Host "  - Traffic to $RemoteNetwork -> VPN tunnel"
    Write-Host "  - All other traffic -> Local internet connection"
    Write-Host ""
}

Write-Host "Testing Connection:"
Write-Host "  To test: rasdial `"$ConnectionName`""
Write-Host "  To disconnect: rasdial `"$ConnectionName`" /disconnect"
Write-Host ""
Write-Host "At Windows Login Screen:"
Write-Host "  1. Click the network icon (bottom right)"
Write-Host "  2. Select '$ConnectionName'"
Write-Host "  3. Click 'Connect'"
Write-Host "  4. Enter credentials if prompted"
Write-Host "  5. Log in to Windows after VPN connects"
Write-Host ""
Write-Host "PowerShell Connection:"
Write-Host "  Connect: rasdial `"$ConnectionName`" $Username [password]"
Write-Host "  Status: Get-VpnConnection -Name `"$ConnectionName`" -AllUserConnection"
Write-Host ""

# Test connection
Write-Host "Would you like to test the connection now? (Y/N)"
$test = Read-Host
if ($test -eq 'Y' -or $test -eq 'y') {
    Write-Host ""
    Write-Host "Testing VPN connection..."
    rasdial $ConnectionName $Username $Password

    Start-Sleep -Seconds 3

    Write-Host ""
    Write-Host "Connection status:"
    Get-VpnConnection -Name $ConnectionName -AllUserConnection | Select-Object Name, ConnectionStatus, ServerAddress

    Write-Host ""
    Write-Host "Disconnecting..."
    rasdial $ConnectionName /disconnect
    Write-Host "[OK] Test complete"
}

Write-Host ""
Write-Host "=========================================="
Write-Host "[SUCCESS] VPN setup complete!"
Write-Host "=========================================="
