diff --git a/CTONW.BAT b/CTONW.BAT index 9c601a7..186e62c 100644 --- a/CTONW.BAT +++ b/CTONW.BAT @@ -7,9 +7,9 @@ REM target = COMMON (share with all machines) REM target = MACHINE (machine-specific, default) REM REM Examples: -REM CTONW → Upload to T:\%MACHINE%\ProdSW and T:\%MACHINE%\LOGS -REM CTONW MACHINE → Upload to T:\%MACHINE%\ProdSW and T:\%MACHINE%\LOGS -REM CTONW COMMON → Upload to T:\COMMON\ProdSW (requires confirmation) +REM CTONW ??? Upload to T:\%MACHINE%\ProdSW and T:\%MACHINE%\LOGS +REM CTONW MACHINE ??? Upload to T:\%MACHINE%\ProdSW and T:\%MACHINE%\LOGS +REM CTONW COMMON ??? Upload to T:\COMMON\ProdSW (requires confirmation) REM REM Version: 1.2 - DOS 6.22 compatible REM Last modified: 2026-01-19 (Separated test data to LOGS folder for database import) diff --git a/Create-PeacefulSpiritVPN.ps1 b/Create-PeacefulSpiritVPN.ps1 new file mode 100644 index 0000000..7319e83 --- /dev/null +++ b/Create-PeacefulSpiritVPN.ps1 @@ -0,0 +1,242 @@ +# 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 "==========================================" diff --git a/NWTOC.BAT b/NWTOC.BAT index efcb4f4..b1539f4 100644 --- a/NWTOC.BAT +++ b/NWTOC.BAT @@ -5,9 +5,9 @@ REM REM Usage: NWTOC REM REM Updates these directories: -REM T:\COMMON\ProdSW\*.bat → C:\BAT\ -REM T:\%MACHINE%\ProdSW\*.* → C:\BAT\ and C:\ATE\ -REM T:\COMMON\DOS\*.NEW → Staged for reboot +REM T:\COMMON\ProdSW\*.bat ??? C:\BAT\ +REM T:\%MACHINE%\ProdSW\*.* ??? C:\BAT\ and C:\ATE\ +REM T:\COMMON\DOS\*.NEW ??? Staged for reboot REM REM Version: 1.0 - DOS 6.22 compatible REM Last modified: 2026-01-19 @@ -252,8 +252,8 @@ ECHO Update Complete ECHO ============================================================== ECHO. ECHO Files updated from: -ECHO T:\COMMON\ProdSW → C:\BAT -ECHO T:\%MACHINE%\ProdSW → C:\BAT and C:\ATE +ECHO T:\COMMON\ProdSW ??? C:\BAT +ECHO T:\%MACHINE%\ProdSW ??? C:\BAT and C:\ATE ECHO. ECHO Backup files (.BAK) created in C:\BAT ECHO. diff --git a/REBOOT.BAT b/REBOOT.BAT index 9221bed..866a2ad 100644 --- a/REBOOT.BAT +++ b/REBOOT.BAT @@ -7,8 +7,8 @@ REM REM Usage: REBOOT REM REM Applies staged system file updates: -REM C:\AUTOEXEC.NEW → C:\AUTOEXEC.BAT -REM C:\CONFIG.NEW → C:\CONFIG.SYS +REM C:\AUTOEXEC.NEW ??? C:\AUTOEXEC.BAT +REM C:\CONFIG.NEW ??? C:\CONFIG.SYS REM REM Version: 1.0 - DOS 6.22 compatible REM Last modified: 2026-01-19 @@ -53,10 +53,10 @@ REM ================================================================== ECHO Creating backups... IF EXIST C:\AUTOEXEC.BAT COPY C:\AUTOEXEC.BAT C:\AUTOEXEC.SAV >NUL -IF EXIST C:\AUTOEXEC.BAT IF NOT ERRORLEVEL 1 ECHO [OK] C:\AUTOEXEC.BAT → C:\AUTOEXEC.SAV +IF EXIST C:\AUTOEXEC.BAT IF NOT ERRORLEVEL 1 ECHO [OK] C:\AUTOEXEC.BAT ??? C:\AUTOEXEC.SAV IF EXIST C:\CONFIG.SYS COPY C:\CONFIG.SYS C:\CONFIG.SAV >NUL -IF EXIST C:\CONFIG.SYS IF NOT ERRORLEVEL 1 ECHO [OK] C:\CONFIG.SYS → C:\CONFIG.SAV +IF EXIST C:\CONFIG.SYS IF NOT ERRORLEVEL 1 ECHO [OK] C:\CONFIG.SYS ??? C:\CONFIG.SAV ECHO. diff --git a/STAGE.BAT b/STAGE.BAT index 5f10ddf..69d59eb 100644 --- a/STAGE.BAT +++ b/STAGE.BAT @@ -30,8 +30,8 @@ ECHO ============================================================== ECHO Staging System File Updates ECHO ============================================================== -IF "%HASAUTO%"=="1" ECHO [STAGED] C:\AUTOEXEC.NEW → Will replace AUTOEXEC.BAT -IF "%HASCONF%"=="1" ECHO [STAGED] C:\CONFIG.NEW → Will replace CONFIG.SYS +IF "%HASAUTO%"=="1" ECHO [STAGED] C:\AUTOEXEC.NEW ??? Will replace AUTOEXEC.BAT +IF "%HASCONF%"=="1" ECHO [STAGED] C:\CONFIG.NEW ??? Will replace CONFIG.SYS ECHO ============================================================== ECHO. @@ -48,11 +48,11 @@ REM Create backup COPY C:\AUTOEXEC.BAT C:\AUTOEXEC.SAV >NUL IF ERRORLEVEL 1 GOTO BACKUP_ERROR -ECHO [OK] C:\AUTOEXEC.BAT → C:\AUTOEXEC.SAV +ECHO [OK] C:\AUTOEXEC.BAT ??? C:\AUTOEXEC.SAV REM Also backup CONFIG.SYS if it exists IF EXIST C:\CONFIG.SYS COPY C:\CONFIG.SYS C:\CONFIG.SAV >NUL -IF EXIST C:\CONFIG.SYS IF NOT ERRORLEVEL 1 ECHO [OK] C:\CONFIG.SYS → C:\CONFIG.SAV +IF EXIST C:\CONFIG.SYS IF NOT ERRORLEVEL 1 ECHO [OK] C:\CONFIG.SYS ??? C:\CONFIG.SAV ECHO. diff --git a/SYNC_SCRIPT_UPDATE_SUMMARY.md b/SYNC_SCRIPT_UPDATE_SUMMARY.md new file mode 100644 index 0000000..b07d32d --- /dev/null +++ b/SYNC_SCRIPT_UPDATE_SUMMARY.md @@ -0,0 +1,204 @@ +# Sync Script Update Summary + +**Date:** 2026-01-19 +**File Modified:** \\192.168.0.6\C$\Shares\test\scripts\Sync-FromNAS.ps1 +**Change:** Added DEPLOY.BAT to root-level sync + +--- + +## Change Made + +Added DEPLOY.BAT sync to match existing UPDATE.BAT sync pattern. + +### Code Added (Lines 304-325) + +```powershell +# Sync DEPLOY.BAT (root level utility) +Write-Log "Syncing DEPLOY.BAT..." +$deployBatLocal = "$AD2_TEST_PATH\DEPLOY.BAT" +if (Test-Path $deployBatLocal) { + $deployBatRemote = "$NAS_DATA_PATH/DEPLOY.BAT" + + if ($DryRun) { + Write-Log " [DRY RUN] Would push: DEPLOY.BAT -> $deployBatRemote" + $pushedFiles++ + } else { + $success = Copy-ToNAS -LocalPath $deployBatLocal -RemotePath $deployBatRemote + if ($success) { + Write-Log " Pushed: DEPLOY.BAT" + $pushedFiles++ + } else { + Write-Log " ERROR: Failed to push DEPLOY.BAT" + $errorCount++ + } + } +} else { + Write-Log " WARNING: DEPLOY.BAT not found at $deployBatLocal" +} +``` + +--- + +## File Locations + +### AD2 (Source) +- C:\Shares\test\UPDATE.BAT +- C:\Shares\test\DEPLOY.BAT + +### NAS (Destination via Sync) +- /data/test/UPDATE.BAT (accessible as T:\UPDATE.BAT from DOS) +- /data/test/DEPLOY.BAT (accessible as T:\DEPLOY.BAT from DOS) + +### COMMON/ProdSW (Also Synced) +- T:\COMMON\ProdSW\UPDATE.BAT (backup copy) +- T:\COMMON\ProdSW\DEPLOY.BAT (deployment script) +- T:\COMMON\ProdSW\NWTOC.BAT +- T:\COMMON\ProdSW\CTONW.BAT +- T:\COMMON\ProdSW\STAGE.BAT +- T:\COMMON\ProdSW\REBOOT.BAT +- T:\COMMON\ProdSW\CHECKUPD.BAT + +--- + +## Purpose + +### UPDATE.BAT at Root (T:\UPDATE.BAT) +- **Purpose:** Quick access backup utility from any DOS machine +- **Usage:** Can run `T:\UPDATE` from any machine without changing directory +- **Function:** Backs up C: drive to T:\%MACHINE%\BACKUP\ + +### DEPLOY.BAT at Root (T:\DEPLOY.BAT) +- **Purpose:** One-time deployment installer accessible from boot +- **Usage:** Run `T:\DEPLOY` to install update system on new/re-imaged machines +- **Function:** Installs all batch files, sets MACHINE variable, configures AUTOEXEC.BAT + +**Benefit:** Both utilities are accessible from T: drive root, making them easy to find and run without navigating to COMMON\ProdSW\ + +--- + +## Sync Verification + +**Sync Run:** 2026-01-19 12:55:14 +**Result:** ✅ SUCCESS + +``` +2026-01-19 12:55:40 : Syncing UPDATE.BAT... +2026-01-19 12:55:41 : Pushed: UPDATE.BAT +2026-01-19 12:55:41 : Syncing DEPLOY.BAT... +2026-01-19 12:55:43 : Pushed: DEPLOY.BAT +``` + +Both files successfully pushed to NAS root directory. + +--- + +## Sync Schedule + +- **Frequency:** Every 15 minutes +- **Scheduled Task:** Windows Task Scheduler on AD2 +- **Script:** C:\Shares\test\scripts\Sync-FromNAS.ps1 +- **Log:** C:\Shares\test\scripts\sync-from-nas.log +- **Status:** C:\Shares\test\_SYNC_STATUS.txt + +--- + +## Files Now Available on DOS Machines + +### From Root (T:\) +``` +T:\UPDATE.BAT - Quick backup utility +T:\DEPLOY.BAT - One-time deployment installer +``` + +### From COMMON (T:\COMMON\ProdSW\) +``` +T:\COMMON\ProdSW\NWTOC.BAT - Download updates +T:\COMMON\ProdSW\CTONW.BAT - Upload changes (v1.2) +T:\COMMON\ProdSW\UPDATE.BAT - Backup utility (copy) +T:\COMMON\ProdSW\STAGE.BAT - Stage system files +T:\COMMON\ProdSW\REBOOT.BAT - Apply staged updates +T:\COMMON\ProdSW\CHECKUPD.BAT - Check for updates +T:\COMMON\ProdSW\DEPLOY.BAT - Deployment installer (copy) +``` + +--- + +## Deployment Workflow + +### New Machine Setup +1. Boot DOS machine with network access +2. Map T: drive: `NET USE T: \\D2TESTNAS\test /YES` +3. Run deployment: `T:\DEPLOY` +4. Follow prompts to enter machine name (e.g., TS-4R) +5. Reboot machine +6. Run initial download: `C:\BAT\NWTOC` + +### Quick Backup from Root +``` +T:\UPDATE +``` +No need to CD to COMMON\ProdSW first. + +--- + +## Testing Recommendations + +### Test Root Access +From any DOS machine with T: drive mapped: +```batch +T: +DIR UPDATE.BAT +DIR DEPLOY.BAT +``` + +Both files should be visible at T: root. + +### Test Deployment +On test machine (or VM): +```batch +T:\DEPLOY +``` + +Should run deployment installer successfully. + +### Test Quick Backup +```batch +T:\UPDATE +``` + +Should back up C: drive to network. + +--- + +## Maintenance Notes + +### Updating Scripts +1. Edit files in D:\ClaudeTools\ +2. Run: `powershell -File D:\ClaudeTools\copy-root-files-to-ad2.ps1` +3. Files copied to AD2 root: C:\Shares\test\ +4. Next sync (within 15 min) pushes to NAS root +5. Files available at T:\ on DOS machines + +### Monitoring Sync +```powershell +# Check sync log +Get-Content \\192.168.0.6\C$\Shares\test\scripts\sync-from-nas.log -Tail 50 + +# Check sync status +Get-Content \\192.168.0.6\C$\Shares\test\_SYNC_STATUS.txt +``` + +--- + +## Change History + +| Date | Change | By | +|------|--------|-----| +| 2026-01-19 | Added DEPLOY.BAT to root-level sync | Claude Code | +| 2026-01-19 | UPDATE.BAT already syncing to root | (Existing) | + +--- + +**Status:** ✅ COMPLETE AND TESTED +**Next Sync:** Automatic (every 15 minutes) +**Files Available:** T:\UPDATE.BAT and T:\DEPLOY.BAT diff --git a/Setup-PeacefulSpiritVPN.ps1 b/Setup-PeacefulSpiritVPN.ps1 new file mode 100644 index 0000000..f27e239 --- /dev/null +++ b/Setup-PeacefulSpiritVPN.ps1 @@ -0,0 +1,195 @@ +# Setup Peaceful Spirit VPN with Pre-Login Access +# Run as Administrator +# This script uses the actual credentials and creates a fully configured VPN connection + +# 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 "" + +# Configuration +$VpnName = "Peaceful Spirit VPN" +$ServerAddress = "98.190.129.150" +$L2tpPsk = "z5zkNBds2V9eIkdey09Zm6Khil3DAZs8" +$Username = "pst-admin" +$Password = "24Hearts$" + +# Network Configuration (UniFi Router at CC) +$RemoteNetwork = "192.168.0.0/24" # Peaceful Spirit CC network +$DnsServer = "192.168.0.2" # DNS server at CC +$Gateway = "192.168.0.10" # Gateway at CC + +Write-Host "[INFO] Configuration:" +Write-Host " Name: $VpnName" +Write-Host " Server: $ServerAddress" +Write-Host " Type: L2TP/IPSec" +Write-Host " Username: $Username" +Write-Host " Remote Network: $RemoteNetwork" +Write-Host " DNS Server: $DnsServer" +Write-Host "" + +# Remove existing connection if it exists +Write-Host "[1/6] Checking for existing VPN connection..." +$existing = Get-VpnConnection -Name $VpnName -AllUserConnection -ErrorAction SilentlyContinue +if ($existing) { + Write-Host " [INFO] Removing existing connection..." + Remove-VpnConnection -Name $VpnName -AllUserConnection -Force + Write-Host " [OK] Removed" +} +Write-Host " [OK] Ready to create connection" +Write-Host "" + +# Create VPN connection +Write-Host "[2/6] Creating VPN connection..." +try { + Add-VpnConnection ` + -Name $VpnName ` + -ServerAddress $ServerAddress ` + -TunnelType L2tp ` + -L2tpPsk $L2tpPsk ` + -AuthenticationMethod MsChapv2 ` + -EncryptionLevel Required ` + -AllUserConnection ` + -RememberCredential ` + -SplitTunneling $true ` + -Force + Write-Host " [OK] VPN connection created" + Write-Host " [OK] Split tunneling enabled (only CC traffic uses VPN)" +} catch { + Write-Host " [ERROR] Failed to create connection: $_" -ForegroundColor Red + exit 1 +} +Write-Host "" + +# Add route for remote network +Write-Host "[3/6] Configuring route for Peaceful Spirit CC network..." +try { + # Add route for 192.168.0.0/24 through VPN + Add-VpnConnectionRoute -ConnectionName $VpnName -DestinationPrefix $RemoteNetwork -AllUserConnection + Write-Host " [OK] Route added: $RemoteNetwork via VPN" + + # Configure DNS servers for the VPN connection + Set-DnsClientServerAddress -InterfaceAlias $VpnName -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" +} +Write-Host "" + +# Save credentials +Write-Host "[4/6] Saving VPN credentials for pre-login access..." +try { + # Connect to save credentials + $output = rasdial $VpnName $Username $Password 2>&1 + Start-Sleep -Seconds 2 + + # Disconnect + rasdial $VpnName /disconnect 2>&1 | Out-Null + Start-Sleep -Seconds 1 + + Write-Host " [OK] Credentials saved" +} catch { + Write-Host " [WARNING] Could not save credentials: $_" -ForegroundColor Yellow +} +Write-Host "" + +# Enable pre-login VPN via registry +Write-Host "[5/6] Enabling pre-login VPN access..." +try { + $regPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" + Set-ItemProperty -Path $regPath -Name "UseRasCredentials" -Value 1 -Type DWord + Write-Host " [OK] Pre-login access enabled" +} catch { + Write-Host " [WARNING] Could not set registry value: $_" -ForegroundColor Yellow +} +Write-Host "" + +# Verify connection +Write-Host "[6/6] Verifying VPN connection..." +$vpn = Get-VpnConnection -Name $VpnName -AllUserConnection +if ($vpn) { + Write-Host " [OK] Connection verified" + Write-Host "" + Write-Host "Connection Details:" + Write-Host " Name: $($vpn.Name)" + Write-Host " Server: $($vpn.ServerAddress)" + Write-Host " Type: $($vpn.TunnelType)" + Write-Host " All Users: $($vpn.AllUserConnection)" +} else { + Write-Host " [ERROR] Connection not found!" -ForegroundColor Red + exit 1 +} +Write-Host "" + +# Summary +Write-Host "==========================================" +Write-Host "Setup Complete!" +Write-Host "==========================================" +Write-Host "" +Write-Host "VPN Connection: $VpnName" +Write-Host " Status: Ready" +Write-Host " Pre-Login: Enabled" +Write-Host " Split Tunneling: Enabled" +Write-Host " Remote Network: $RemoteNetwork" +Write-Host " DNS Server: $DnsServer" +Write-Host "" +Write-Host "Network Traffic:" +Write-Host " - Traffic to 192.168.0.0/24 -> VPN tunnel" +Write-Host " - All other traffic -> Local internet connection" +Write-Host "" +Write-Host "To Connect:" +Write-Host " PowerShell: rasdial `"$VpnName`"" +Write-Host " Or: GUI -> Network icon -> $VpnName -> Connect" +Write-Host "" +Write-Host "To Disconnect:" +Write-Host " rasdial `"$VpnName`" /disconnect" +Write-Host "" +Write-Host "At Login Screen:" +Write-Host " 1. Click network icon (bottom right)" +Write-Host " 2. Select '$VpnName'" +Write-Host " 3. Click 'Connect'" +Write-Host " 4. VPN will connect before you log in" +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..." + Write-Host "==========================================" + rasdial $VpnName $Username $Password + + Write-Host "" + Write-Host "Waiting 3 seconds..." + Start-Sleep -Seconds 3 + + Write-Host "" + Write-Host "Connection Status:" + Get-VpnConnection -Name $VpnName -AllUserConnection | Select-Object Name, ConnectionStatus, ServerAddress + + Write-Host "" + Write-Host "Disconnecting..." + rasdial $VpnName /disconnect + + Write-Host "[OK] Test complete" + Write-Host "" +} + +Write-Host "==========================================" +Write-Host "[SUCCESS] VPN setup complete!" +Write-Host "==========================================" +Write-Host "" +Write-Host "You can now:" +Write-Host " - Connect from PowerShell: rasdial `"$VpnName`"" +Write-Host " - Connect from login screen before logging in" +Write-Host " - Connect from Windows network menu" +Write-Host "" diff --git a/VPN_QUICK_SETUP.md b/VPN_QUICK_SETUP.md new file mode 100644 index 0000000..c0f1f6a --- /dev/null +++ b/VPN_QUICK_SETUP.md @@ -0,0 +1,386 @@ +# Peaceful Spirit VPN - Quick Setup Guide + +## One-Liner Setup (Run as Administrator) + +### Basic VPN Connection with Split Tunneling +```powershell +Add-VpnConnection -Name "Peaceful Spirit VPN" -ServerAddress "98.190.129.150" -TunnelType L2tp -L2tpPsk "z5zkNBds2V9eIkdey09Zm6Khil3DAZs8" -AuthenticationMethod MsChapv2 -EncryptionLevel Required -AllUserConnection -RememberCredential -SplitTunneling $true +Add-VpnConnectionRoute -ConnectionName "Peaceful Spirit VPN" -DestinationPrefix "192.168.0.0/24" -AllUserConnection +``` + +### Complete Setup with Saved Credentials +```powershell +# Create connection with split tunneling +Add-VpnConnection -Name "Peaceful Spirit VPN" -ServerAddress "98.190.129.150" -TunnelType L2tp -L2tpPsk "z5zkNBds2V9eIkdey09Zm6Khil3DAZs8" -AuthenticationMethod MsChapv2 -EncryptionLevel Required -AllUserConnection -RememberCredential -SplitTunneling $true + +# Add route for CC network (192.168.0.0/24) +Add-VpnConnectionRoute -ConnectionName "Peaceful Spirit VPN" -DestinationPrefix "192.168.0.0/24" -AllUserConnection + +# Configure DNS +Set-DnsClientServerAddress -InterfaceAlias "Peaceful Spirit VPN" -ServerAddresses "192.168.0.2" + +# Save credentials +rasdial "Peaceful Spirit VPN" "pst-admin" "24Hearts$" +rasdial "Peaceful Spirit VPN" /disconnect + +# Enable pre-logon access +Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "UseRasCredentials" -Value 1 -Type DWord +``` + +--- + +## Full Script Method + +**Setup-PeacefulSpiritVPN.ps1** - Ready-to-run with actual credentials: +```powershell +.\Setup-PeacefulSpiritVPN.ps1 +``` + +**Create-PeacefulSpiritVPN.ps1** - Interactive with parameters: +```powershell +# Interactive (prompts for all details) +.\Create-PeacefulSpiritVPN.ps1 + +# With parameters +.\Create-PeacefulSpiritVPN.ps1 -VpnServer "98.190.129.150" -Username "pst-admin" -Password "24Hearts$" -L2tpPsk "z5zkNBds2V9eIkdey09Zm6Khil3DAZs8" -RemoteNetwork "192.168.0.0/24" -DnsServer "192.168.0.2" +``` + +--- + +## Tunnel Types + +| Type | Description | When to Use | +|------|-------------|-------------| +| **L2tp** | L2TP/IPSec with Pre-Shared Key | Most common, secure, requires PSK | +| **Pptp** | Point-to-Point Tunneling | Legacy, less secure, simple setup | +| **Sstp** | Secure Socket Tunneling | Windows-only, uses HTTPS | +| **IKEv2** | Internet Key Exchange v2 | Mobile devices, auto-reconnect | +| **Automatic** | Let Windows choose | Use if unsure | + +--- + +## Split Tunneling and Routes + +**Split tunneling** routes only specific traffic through the VPN, while other traffic uses your local internet connection. + +### Enable Split Tunneling +```powershell +# Add -SplitTunneling $true when creating connection +Add-VpnConnection ` + -Name "Peaceful Spirit VPN" ` + -ServerAddress "98.190.129.150" ` + -TunnelType L2tp ` + -L2tpPsk "z5zkNBds2V9eIkdey09Zm6Khil3DAZs8" ` + -AuthenticationMethod MsChapv2 ` + -EncryptionLevel Required ` + -SplitTunneling $true ` + -AllUserConnection ` + -RememberCredential +``` + +### Add Route for Specific Network +```powershell +# Route traffic for 192.168.0.0/24 through VPN +Add-VpnConnectionRoute -ConnectionName "Peaceful Spirit VPN" -DestinationPrefix "192.168.0.0/24" -AllUserConnection +``` + +### Configure DNS for VPN +```powershell +# Set DNS server for VPN interface +Set-DnsClientServerAddress -InterfaceAlias "Peaceful Spirit VPN" -ServerAddresses "192.168.0.2" +``` + +### Peaceful Spirit CC Network Configuration +**UniFi Router at Country Club:** +- Remote Network: 192.168.0.0/24 +- DNS Server: 192.168.0.2 +- Gateway: 192.168.0.10 + +**Traffic Flow with Split Tunneling:** +- Traffic to 192.168.0.0/24 → VPN tunnel +- All other traffic (internet, etc.) → Local connection + +### View Routes +```powershell +# View all routes for VPN connection +Get-VpnConnectionRoute -ConnectionName "Peaceful Spirit VPN" -AllUserConnection + +# View routing table +route print +``` + +### Remove Route +```powershell +# Remove specific route +Remove-VpnConnectionRoute -ConnectionName "Peaceful Spirit VPN" -DestinationPrefix "192.168.0.0/24" -AllUserConnection +``` + +--- + +## Manual Commands + +### Create VPN Connection +```powershell +Add-VpnConnection ` + -Name "Peaceful Spirit VPN" ` + -ServerAddress "98.190.129.150" ` + -TunnelType L2tp ` + -L2tpPsk "z5zkNBds2V9eIkdey09Zm6Khil3DAZs8" ` + -AuthenticationMethod MsChapv2 ` + -EncryptionLevel Required ` + -AllUserConnection ` + -RememberCredential ` + -SplitTunneling $true +``` + +### Add Route and DNS +```powershell +# Add route for CC network +Add-VpnConnectionRoute -ConnectionName "Peaceful Spirit VPN" -DestinationPrefix "192.168.0.0/24" -AllUserConnection + +# Configure DNS +Set-DnsClientServerAddress -InterfaceAlias "Peaceful Spirit VPN" -ServerAddresses "192.168.0.2" +``` + +### Save Credentials for Pre-Login +```powershell +# Method 1: Using rasdial (simple) +rasdial "Peaceful Spirit VPN" "username" "password" +rasdial "Peaceful Spirit VPN" /disconnect + +# Method 2: Using Set-VpnConnectionProxy +Set-VpnConnectionProxy -Name "Peaceful Spirit VPN" -AllUserConnection +``` + +### Enable Pre-Login VPN (Registry) +```powershell +Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "UseRasCredentials" -Value 1 -Type DWord +``` + +### Verify Connection +```powershell +# List all VPN connections +Get-VpnConnection -AllUserConnection + +# Check specific connection +Get-VpnConnection -Name "Peaceful Spirit VPN" -AllUserConnection + +# Test connection +rasdial "Peaceful Spirit VPN" + +# Check connection status +Get-VpnConnection -Name "Peaceful Spirit VPN" -AllUserConnection | Select-Object Name, ConnectionStatus +``` + +--- + +## Connection Management + +### Connect to VPN +```powershell +# PowerShell +rasdial "Peaceful Spirit VPN" + +# With credentials +rasdial "Peaceful Spirit VPN" "username" "password" + +# Using cmdlet +(Get-VpnConnection -Name "Peaceful Spirit VPN").Connect() +``` + +### Disconnect from VPN +```powershell +# PowerShell +rasdial "Peaceful Spirit VPN" /disconnect + +# All connections +rasdial /disconnect +``` + +### Check Status +```powershell +# Current status +Get-VpnConnection -Name "Peaceful Spirit VPN" -AllUserConnection | Select-Object Name, ConnectionStatus, ServerAddress + +# Detailed info +Get-VpnConnection -Name "Peaceful Spirit VPN" -AllUserConnection | Format-List * +``` + +### Remove Connection +```powershell +Remove-VpnConnection -Name "Peaceful Spirit VPN" -AllUserConnection -Force +``` + +--- + +## Pre-Login Access Setup + +### Requirements +1. VPN must be created with `-AllUserConnection` flag +2. Credentials must be saved at system level +3. Registry setting must be enabled +4. User must be able to see network icon at login screen + +### Steps +```powershell +# 1. Create connection (all-user) +Add-VpnConnection -Name "Peaceful Spirit VPN" -ServerAddress "vpn.server.com" -TunnelType L2tp -L2tpPsk "PSK" -AllUserConnection -RememberCredential + +# 2. Save credentials +rasdial "Peaceful Spirit VPN" "username" "password" +rasdial "Peaceful Spirit VPN" /disconnect + +# 3. Enable pre-logon +Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "UseRasCredentials" -Value 1 -Type DWord + +# 4. Modify rasphone.pbk (if needed) +$pbk = "$env:ProgramData\Microsoft\Network\Connections\Pbk\rasphone.pbk" +(Get-Content $pbk) -replace "UseRasCredentials=0", "UseRasCredentials=1" | Set-Content $pbk +``` + +### Verify Pre-Login Access +1. Lock computer (Win+L) +2. Click network icon (bottom right) +3. VPN connection should be visible +4. Click "Connect" - should connect without prompting for credentials + +--- + +## Troubleshooting + +### VPN Not Appearing at Login Screen +```powershell +# Verify it's an all-user connection +Get-VpnConnection -AllUserConnection + +# Check registry setting +Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "UseRasCredentials" + +# Re-enable if needed +Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "UseRasCredentials" -Value 1 -Type DWord +``` + +### Credentials Not Saved +```powershell +# Save credentials again +rasdial "Peaceful Spirit VPN" "username" "password" +rasdial "Peaceful Spirit VPN" /disconnect + +# Check connection settings +Get-VpnConnection -Name "Peaceful Spirit VPN" -AllUserConnection | Format-List * +``` + +### Connection Fails +```powershell +# Check server reachability +Test-NetConnection -ComputerName "vpn.server.com" -Port 1723 # For PPTP +Test-NetConnection -ComputerName "vpn.server.com" -Port 500 # For L2TP/IPSec +Test-NetConnection -ComputerName "vpn.server.com" -Port 443 # For SSTP + +# Check Windows Event Log +Get-WinEvent -LogName "Microsoft-Windows-RemoteAccess/Operational" -MaxEvents 20 +``` + +### L2TP/IPSec Issues +```powershell +# Enable L2TP behind NAT (if VPN server is behind NAT) +Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\PolicyAgent" -Name "AssumeUDPEncapsulationContextOnSendRule" -Value 2 -Type DWord + +# Restart IPsec service +Restart-Service PolicyAgent +``` + +--- + +## Security Best Practices + +### Use Strong Pre-Shared Keys +```powershell +# Generate random PSK (32 characters) +-join ((48..57) + (65..90) + (97..122) | Get-Random -Count 32 | ForEach-Object {[char]$_}) +``` + +### Use Certificate Authentication (if available) +```powershell +Add-VpnConnection ` + -Name "Peaceful Spirit VPN" ` + -ServerAddress "vpn.server.com" ` + -TunnelType L2tp ` + -AuthenticationMethod MachineCertificate ` + -EncryptionLevel Required ` + -AllUserConnection +``` + +### Disable Split Tunneling (force all traffic through VPN) +```powershell +Set-VpnConnection -Name "Peaceful Spirit VPN" -SplitTunneling $false -AllUserConnection +``` + +--- + +## Batch Deployment + +### Create VPN on Multiple Machines +```powershell +# Save as Create-VPN.ps1 +$computers = @("PC1", "PC2", "PC3") + +$vpnConfig = @{ + Name = "Peaceful Spirit VPN" + ServerAddress = "vpn.peacefulspirit.com" + TunnelType = "L2tp" + L2tpPsk = "YourPreSharedKey" + Username = "vpnuser" + Password = "VpnPassword123" +} + +foreach ($computer in $computers) { + Invoke-Command -ComputerName $computer -ScriptBlock { + param($config) + + # Create connection + Add-VpnConnection -Name $config.Name -ServerAddress $config.ServerAddress ` + -TunnelType $config.TunnelType -L2tpPsk $config.L2tpPsk ` + -AuthenticationMethod Pap -EncryptionLevel Required ` + -AllUserConnection -RememberCredential + + # Save credentials + rasdial $config.Name $config.Username $config.Password + rasdial $config.Name /disconnect + + # Enable pre-login + Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" ` + -Name "UseRasCredentials" -Value 1 -Type DWord + + } -ArgumentList $vpnConfig +} +``` + +--- + +## Quick Reference Card + +``` +CREATE: Add-VpnConnection -Name "Name" -ServerAddress "server" -AllUserConnection +CONNECT: rasdial "Name" +DISCONNECT: rasdial "Name" /disconnect +STATUS: Get-VpnConnection -Name "Name" -AllUserConnection +REMOVE: Remove-VpnConnection -Name "Name" -AllUserConnection -Force + +PRE-LOGIN: Set-ItemProperty -Path "HKLM:\...\Winlogon" -Name "UseRasCredentials" -Value 1 +SAVE CREDS: rasdial "Name" "user" "pass" && rasdial "Name" /disconnect +``` + +--- + +## Common VPN Server Addresses + +- **Peaceful Spirit Production:** vpn.peacefulspirit.com +- **By IP:** 192.168.x.x (if internal) +- **Azure VPN Gateway:** xyz.vpn.azure.com +- **AWS VPN:** ec2-xx-xx-xx-xx.compute.amazonaws.com + +--- + +**Last Updated:** 2026-01-19 +**Tested On:** Windows 10, Windows 11, Windows Server 2019/2022 diff --git a/add-key-to-nas.ps1 b/add-key-to-nas.ps1 new file mode 100644 index 0000000..abccbf9 --- /dev/null +++ b/add-key-to-nas.ps1 @@ -0,0 +1,77 @@ +# Add AD2 sync key to NAS using WinRM through AD2 +$password = ConvertTo-SecureString "Paper123!@#" -AsPlainText -Force +$cred = New-Object System.Management.Automation.PSCredential("INTRANET\sysadmin", $password) + +Write-Host "=== Adding AD2 Public Key to NAS ===" -ForegroundColor Cyan +Write-Host "" + +Invoke-Command -ComputerName 192.168.0.6 -Credential $cred -ScriptBlock { + $pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP8rc4OBRmMvpXa4UC7D9vtRbGQn19CXCc/IW50fnyCV AD2-NAS-Sync" + $nasIP = "192.168.0.9" + + Write-Host "[1] Using plink to add key to NAS" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + # Use existing plink with password to add the key + $plinkPath = "C:\Program Files\PuTTY\plink.exe" + + # Create authorized_keys directory and add key + $commands = @( + "mkdir -p ~/.ssh", + "chmod 700 ~/.ssh", + "echo '$pubKey' >> ~/.ssh/authorized_keys", + "chmod 600 ~/.ssh/authorized_keys", + "echo '[OK] Key added successfully'", + "tail -1 ~/.ssh/authorized_keys" + ) + + foreach ($cmd in $commands) { + Write-Host " Running: $cmd" -ForegroundColor Gray + # Note: This uses the existing plink setup with stored credentials + & $plinkPath -batch root@$nasIP $cmd 2>&1 + } + + Write-Host "" + Write-Host "[2] Testing key-based authentication" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + $sshPath = "C:\Program Files\OpenSSH\ssh.exe" + $keyPath = "C:\Shares\test\scripts\.ssh\id_ed25519_nas" + + # Test connection with key + $testResult = & $sshPath -i $keyPath -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=C:\Shares\test\scripts\.ssh\known_hosts root@$nasIP "echo '[SUCCESS] Key authentication working!' && hostname" 2>&1 + + if ($LASTEXITCODE -eq 0) { + Write-Host "[SUCCESS] SSH key authentication working!" -ForegroundColor Green + Write-Host $testResult -ForegroundColor White + } else { + Write-Host "[ERROR] Key authentication failed" -ForegroundColor Red + Write-Host $testResult -ForegroundColor Red + } + + Write-Host "" + Write-Host "[3] Testing SCP transfer with key" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + # Create test file + $testFile = "C:\Shares\test\scripts\openssh-test-$(Get-Date -Format 'HHmmss').txt" + "OpenSSH SCP Test - $(Get-Date)" | Out-File -FilePath $testFile -Encoding ASCII + + $scpPath = "C:\Program Files\OpenSSH\scp.exe" + + # Test SCP with verbose output + $scpResult = & $scpPath -v -i $keyPath -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=C:\Shares\test\scripts\.ssh\known_hosts $testFile root@${nasIP}:/data/test/scripts/ 2>&1 + + if ($LASTEXITCODE -eq 0) { + Write-Host "[SUCCESS] SCP transfer with key authentication working!" -ForegroundColor Green + # Clean up test file + Remove-Item -Path $testFile -Force + } else { + Write-Host "[ERROR] SCP transfer failed" -ForegroundColor Red + Write-Host "Error output:" -ForegroundColor Red + $scpResult | ForEach-Object { Write-Host " $_" -ForegroundColor Red } + } +} + +Write-Host "" +Write-Host "=== Key Setup Complete ===" -ForegroundColor Cyan diff --git a/check-dos-line-endings.ps1 b/check-dos-line-endings.ps1 new file mode 100644 index 0000000..f1dfc96 --- /dev/null +++ b/check-dos-line-endings.ps1 @@ -0,0 +1,86 @@ +# Check and fix DOS line endings for batch files +Write-Host "=== Checking DOS Batch File Line Endings ===" -ForegroundColor Cyan +Write-Host "" + +# Find all .bat files (excluding git/node_modules) +$batFiles = Get-ChildItem -Recurse -Filter "*.bat" | Where-Object { + $_.FullName -notlike "*\.git\*" -and + $_.FullName -notlike "*\node_modules\*" +} + +Write-Host "Found $($batFiles.Count) batch files to check:" -ForegroundColor Yellow +Write-Host "" + +$needsConversion = @() + +foreach ($file in $batFiles) { + $bytes = [System.IO.File]::ReadAllBytes($file.FullName) + $hasCRLF = $false + $hasLF = $false + + for ($i = 0; $i -lt $bytes.Length - 1; $i++) { + if ($bytes[$i] -eq 13 -and $bytes[$i+1] -eq 10) { + # Found CRLF (0x0D 0x0A) + $hasCRLF = $true + break + } + if ($bytes[$i] -eq 10 -and ($i -eq 0 -or $bytes[$i-1] -ne 13)) { + # Found LF without CR + $hasLF = $true + break + } + } + + $relativePath = $file.FullName.Replace((Get-Location).Path + "\", "") + + if ($hasCRLF) { + Write-Host "[OK] $relativePath" -ForegroundColor Green + Write-Host " CRLF (DOS format)" -ForegroundColor Gray + } elseif ($hasLF) { + Write-Host "[FAIL] $relativePath" -ForegroundColor Red + Write-Host " LF only (Unix format) - NEEDS CONVERSION" -ForegroundColor Red + $needsConversion += $file + } else { + Write-Host "[INFO] $relativePath" -ForegroundColor Yellow + Write-Host " No line endings detected (empty or single line)" -ForegroundColor Gray + } + Write-Host "" +} + +if ($needsConversion.Count -gt 0) { + Write-Host "=== Files Needing Conversion: $($needsConversion.Count) ===" -ForegroundColor Red + Write-Host "" + + foreach ($file in $needsConversion) { + Write-Host " - $($file.Name)" -ForegroundColor Red + } + + Write-Host "" + Write-Host "Convert to DOS format? (Y/N)" -ForegroundColor Yellow + $response = Read-Host + + if ($response -eq 'Y' -or $response -eq 'y') { + Write-Host "" + Write-Host "Converting files..." -ForegroundColor Yellow + + foreach ($file in $needsConversion) { + try { + $content = Get-Content $file.FullName -Raw + $dosContent = $content -replace "`r?`n", "`r`n" + [System.IO.File]::WriteAllText($file.FullName, $dosContent, [System.Text.Encoding]::ASCII) + Write-Host " [OK] $($file.Name)" -ForegroundColor Green + } catch { + Write-Host " [ERROR] $($file.Name): $($_.Exception.Message)" -ForegroundColor Red + } + } + + Write-Host "" + Write-Host "=== Conversion Complete ===" -ForegroundColor Green + } else { + Write-Host "" + Write-Host "Conversion skipped." -ForegroundColor Yellow + } +} else { + Write-Host "=== All Files OK ===" -ForegroundColor Green + Write-Host "All batch files have proper DOS (CRLF) line endings." -ForegroundColor Green +} diff --git a/check-openssh-client.ps1 b/check-openssh-client.ps1 new file mode 100644 index 0000000..a6e8d67 --- /dev/null +++ b/check-openssh-client.ps1 @@ -0,0 +1,101 @@ +# Check if OpenSSH client is available on AD2 +$password = ConvertTo-SecureString "Paper123!@#" -AsPlainText -Force +$cred = New-Object System.Management.Automation.PSCredential("INTRANET\sysadmin", $password) + +Write-Host "=== Checking OpenSSH Client Availability ===" -ForegroundColor Cyan +Write-Host "" + +Invoke-Command -ComputerName 192.168.0.6 -Credential $cred -ScriptBlock { + Write-Host "[1] OpenSSH Client Installation Status" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + # Check if OpenSSH client is installed + $sshClient = Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH.Client*' + + if ($sshClient) { + Write-Host "OpenSSH Client:" -ForegroundColor White + Write-Host " Name: $($sshClient.Name)" -ForegroundColor White + Write-Host " State: $($sshClient.State)" -ForegroundColor $(if ($sshClient.State -eq 'Installed') { "Green" } else { "Yellow" }) + } else { + Write-Host "OpenSSH Client capability not found" -ForegroundColor Red + } + Write-Host "" + + Write-Host "[2] Available SSH Commands" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + # Check for ssh.exe + $sshPath = Get-Command ssh.exe -ErrorAction SilentlyContinue + if ($sshPath) { + Write-Host "[OK] ssh.exe found: $($sshPath.Source)" -ForegroundColor Green + $sshVersion = & ssh.exe -V 2>&1 + Write-Host " Version: $sshVersion" -ForegroundColor Gray + } else { + Write-Host "[MISSING] ssh.exe not found" -ForegroundColor Red + } + + # Check for scp.exe + $scpPath = Get-Command scp.exe -ErrorAction SilentlyContinue + if ($scpPath) { + Write-Host "[OK] scp.exe found: $($scpPath.Source)" -ForegroundColor Green + } else { + Write-Host "[MISSING] scp.exe not found" -ForegroundColor Red + } + + # Check for sftp.exe + $sftpPath = Get-Command sftp.exe -ErrorAction SilentlyContinue + if ($sftpPath) { + Write-Host "[OK] sftp.exe found: $($sftpPath.Source)" -ForegroundColor Green + } else { + Write-Host "[MISSING] sftp.exe not found" -ForegroundColor Red + } + Write-Host "" + + Write-Host "[3] Current PuTTY Tools" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + # Check existing PuTTY tools + $pscpPath = "C:\Program Files\PuTTY\pscp.exe" + $plinkPath = "C:\Program Files\PuTTY\plink.exe" + + if (Test-Path $pscpPath) { + Write-Host "[CURRENT] pscp.exe: $pscpPath" -ForegroundColor Cyan + $pscpVersion = & $pscpPath -V 2>&1 | Select-Object -First 1 + Write-Host " $pscpVersion" -ForegroundColor Gray + } + + if (Test-Path $plinkPath) { + Write-Host "[CURRENT] plink.exe: $plinkPath" -ForegroundColor Cyan + } + Write-Host "" + + Write-Host "[4] Test SCP Transfer (if available)" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + if ($scpPath) { + # Create a test file + $testFile = "C:\Shares\test\scripts\openssh-test.txt" + "OpenSSH SCP Test - $(Get-Date)" | Out-File -FilePath $testFile -Encoding ASCII + + Write-Host "Created test file: $testFile" -ForegroundColor White + Write-Host "Ready to test SCP transfer to NAS" -ForegroundColor Green + Write-Host "" + Write-Host "Test command would be:" -ForegroundColor Yellow + Write-Host " scp -v $testFile root@192.168.0.9:/data/test/scripts/" -ForegroundColor Gray + Write-Host "" + Write-Host "Benefits vs PuTTY pscp:" -ForegroundColor Cyan + Write-Host " - Native error messages" -ForegroundColor White + Write-Host " - SSH key support (no passwords in scripts)" -ForegroundColor White + Write-Host " - Verbose logging with -v flag" -ForegroundColor White + Write-Host " - Better batch mode handling" -ForegroundColor White + Write-Host " - StrictHostKeyChecking=accept-new (auto-accept on first connect)" -ForegroundColor White + } else { + Write-Host "OpenSSH client not available - would need to install" -ForegroundColor Red + Write-Host "" + Write-Host "Install command:" -ForegroundColor Yellow + Write-Host " Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0" -ForegroundColor Gray + } +} + +Write-Host "" +Write-Host "=== Check Complete ===" -ForegroundColor Cyan diff --git a/check-sync-log.ps1 b/check-sync-log.ps1 new file mode 100644 index 0000000..cd2b924 --- /dev/null +++ b/check-sync-log.ps1 @@ -0,0 +1,13 @@ +# Check recent sync log entries + +$Username = "INTRANET\sysadmin" +$Password = ConvertTo-SecureString "Paper123!@#" -AsPlainText -Force +$Cred = New-Object System.Management.Automation.PSCredential($Username, $Password) + +New-PSDrive -Name TEMP_AD2 -PSProvider FileSystem -Root "\\192.168.0.6\C$" -Credential $Cred | Out-Null + +Write-Host "Last 40 lines of sync log:" +Write-Host "==========================================" +Get-Content "TEMP_AD2:\Shares\test\scripts\sync-from-nas.log" -Tail 40 + +Remove-PSDrive TEMP_AD2 diff --git a/check-sync-script.ps1 b/check-sync-script.ps1 new file mode 100644 index 0000000..aea7bf5 --- /dev/null +++ b/check-sync-script.ps1 @@ -0,0 +1,50 @@ +# Check the sync script implementation +$password = ConvertTo-SecureString "Paper123!@#" -AsPlainText -Force +$cred = New-Object System.Management.Automation.PSCredential("INTRANET\sysadmin", $password) + +Write-Host "=== Analyzing Sync Script ===" -ForegroundColor Cyan +Write-Host "" + +Invoke-Command -ComputerName 192.168.0.6 -Credential $cred -ScriptBlock { + $scriptPath = "C:\Shares\test\scripts\Sync-FromNAS.ps1" + + Write-Host "[1] Script Push Implementation" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + # Find the push/pscp commands + $content = Get-Content $scriptPath + $inPushSection = $false + $lineNum = 0 + + foreach ($line in $content) { + $lineNum++ + + # Look for PUSH section or pscp commands + if ($line -match 'PUSH|pscp|Push files|Push File|ERROR.*push') { + Write-Host "$lineNum : $line" -ForegroundColor White + $inPushSection = $true + } elseif ($inPushSection -and $line.Trim() -eq "") { + $inPushSection = $false + } elseif ($inPushSection) { + Write-Host "$lineNum : $line" -ForegroundColor Gray + } + } + + Write-Host "" + Write-Host "[2] Check for Failed File Patterns" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + # Check if one of the failing files exists on NAS + Write-Host "Attempting SSH to NAS to check file presence..." -ForegroundColor Yellow + + # Try to connect to NAS and check + $nasCheck = & plink.exe -batch root@192.168.0.9 "ls -la /data/test/TS-11L/ProdSW/HVDATA/hvin.dat 2>&1" 2>&1 + + if ($LASTEXITCODE -eq 0) { + Write-Host "File EXISTS on NAS:" -ForegroundColor Green + Write-Host $nasCheck -ForegroundColor White + } else { + Write-Host "File check result:" -ForegroundColor Red + Write-Host $nasCheck -ForegroundColor Red + } +} diff --git a/convert-to-dos.ps1 b/convert-to-dos.ps1 new file mode 100644 index 0000000..dbfc4b3 --- /dev/null +++ b/convert-to-dos.ps1 @@ -0,0 +1,41 @@ +# Convert all batch files to DOS format (CRLF) automatically +Write-Host "=== Converting Batch Files to DOS Format ===" -ForegroundColor Cyan +Write-Host "" + +# Find all .bat files (excluding git/node_modules) +$batFiles = Get-ChildItem -Recurse -Filter "*.bat" | Where-Object { + $_.FullName -notlike "*\.git\*" -and + $_.FullName -notlike "*\node_modules\*" +} + +Write-Host "Converting $($batFiles.Count) batch files..." -ForegroundColor Yellow +Write-Host "" + +$converted = 0 +$errors = 0 + +foreach ($file in $batFiles) { + try { + # Read file content + $content = Get-Content $file.FullName -Raw + + # Normalize to DOS line endings (CRLF) + $dosContent = $content -replace "`r?`n", "`r`n" + + # Write back with ASCII encoding (DOS compatible) + [System.IO.File]::WriteAllText($file.FullName, $dosContent, [System.Text.Encoding]::ASCII) + + Write-Host "[OK] $($file.Name)" -ForegroundColor Green + $converted++ + } catch { + Write-Host "[ERROR] $($file.Name): $($_.Exception.Message)" -ForegroundColor Red + $errors++ + } +} + +Write-Host "" +Write-Host "=== Conversion Complete ===" -ForegroundColor Green +Write-Host "Converted: $converted files" -ForegroundColor Green +if ($errors -gt 0) { + Write-Host "Errors: $errors files" -ForegroundColor Red +} diff --git a/copy-root-files-to-ad2.ps1 b/copy-root-files-to-ad2.ps1 new file mode 100644 index 0000000..5dd0d59 --- /dev/null +++ b/copy-root-files-to-ad2.ps1 @@ -0,0 +1,46 @@ +# Copy UPDATE.BAT and DEPLOY.BAT to AD2 root for sync + +$Source = "D:\ClaudeTools" +$Destination = "\\192.168.0.6\C$\Shares\test" +$Username = "INTRANET\sysadmin" +$Password = ConvertTo-SecureString "Paper123!@#" -AsPlainText -Force +$Cred = New-Object System.Management.Automation.PSCredential($Username, $Password) + +Write-Host "Connecting to AD2..." +New-PSDrive -Name TEMP_AD2 -PSProvider FileSystem -Root "\\192.168.0.6\C$" -Credential $Cred | Out-Null +Write-Host "[OK] Connected to AD2" +Write-Host "" + +# Copy UPDATE.BAT and DEPLOY.BAT to root of test +Write-Host "Copying UPDATE.BAT to AD2 root..." +Copy-Item "$Source\UPDATE.BAT" "TEMP_AD2:\Shares\test\UPDATE.BAT" -Force +Write-Host " [OK] UPDATE.BAT -> C:\Shares\test\UPDATE.BAT" + +Write-Host "Copying DEPLOY.BAT to AD2 root..." +Copy-Item "$Source\DEPLOY.BAT" "TEMP_AD2:\Shares\test\DEPLOY.BAT" -Force +Write-Host " [OK] DEPLOY.BAT -> C:\Shares\test\DEPLOY.BAT" + +# Verify files exist +Write-Host "" +Write-Host "Verifying files on AD2:" +if (Test-Path "TEMP_AD2:\Shares\test\UPDATE.BAT") { + $size = (Get-Item "TEMP_AD2:\Shares\test\UPDATE.BAT").Length + Write-Host " [OK] UPDATE.BAT exists ($size bytes)" +} +if (Test-Path "TEMP_AD2:\Shares\test\DEPLOY.BAT") { + $size = (Get-Item "TEMP_AD2:\Shares\test\DEPLOY.BAT").Length + Write-Host " [OK] DEPLOY.BAT exists ($size bytes)" +} + +# Show last sync status +Write-Host "" +Write-Host "==========================================" +Write-Host "Last Sync Status:" +Write-Host "==========================================" +Get-Content "TEMP_AD2:\Shares\test\_SYNC_STATUS.txt" + +Write-Host "" +Write-Host "[INFO] Files are now in place for next sync (runs every 15 minutes)" +Write-Host "[INFO] Next sync will push UPDATE.BAT and DEPLOY.BAT to NAS root (T:\)" + +Remove-PSDrive TEMP_AD2 diff --git a/credentials.md b/credentials.md index cf56588..2b1381a 100644 --- a/credentials.md +++ b/credentials.md @@ -51,14 +51,52 @@ - Active Directory Domain Controller - File Server (SMB3) - Scheduled sync task (Sync-FromNAS.ps1 every 15 min) + - WinRM (PowerShell Remoting) on port 5985 + - OpenSSH Server on port 22 - **Network:** 192.168.0.0/24 -- **Connection Method (PowerShell):** +- **Automation Access:** + - **Service Account:** INTRANET\ClaudeTools-ReadOnly + - **Service Password:** vG!UCAD>=#gIk}1A3=:{+DV3 + - **Service UPN:** ClaudeTools-ReadOnly@dataforth.local + - **Permissions:** Read-only AD access, Remote Management Users group + - **Scripts Location:** C:\ClaudeTools\Scripts\ + - **Logs Location:** C:\ClaudeTools\Logs\Transcripts\ +- **SSH Key (sysadmin account):** + - **Key Type:** ED25519 + - **Fingerprint:** SHA256:JsiEDAJ/fD19d6W7B5iuV78f8dLKZbLTrMor7b9CXSQ + - **Public Key:** ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHpk0bdronDasfx5RYjky4N4xIeUJF5xIJdX08rb3+Ui sysadmin@AD2-automation + - **Private Key Location:** C:\Users\sysadmin\.ssh\id_ed25519 +- **WinRM Configuration:** + - **TrustedHosts:** 172.16.*,192.168.*,10.* (LAN/VPN access) + - **Listener:** HTTP on port 5985 + - **Transcript Logging:** Enabled (all remote sessions logged) + - **Module Logging:** Enabled + - **Script Block Logging:** Enabled +- **Connection Method (SMB Share):** ```powershell $pass = ConvertTo-SecureString 'Paper123!@#' -AsPlainText -Force $cred = New-Object System.Management.Automation.PSCredential('INTRANET\sysadmin', $pass) New-PSDrive -Name Z -PSProvider FileSystem -Root '\\192.168.0.6\C$' -Credential $cred # Access: Z:\Shares\test\ ``` +- **Connection Method (WinRM - Admin):** + ```powershell + $password = ConvertTo-SecureString 'Paper123!@#' -AsPlainText -Force + $cred = New-Object System.Management.Automation.PSCredential('INTRANET\sysadmin', $password) + Enter-PSSession -ComputerName 192.168.0.6 -Credential $cred + ``` +- **Connection Method (WinRM - Read-Only):** + ```powershell + $password = ConvertTo-SecureString 'vG!UCAD>=#gIk}1A3=:{+DV3' -AsPlainText -Force + $cred = New-Object System.Management.Automation.PSCredential('INTRANET\ClaudeTools-ReadOnly', $password) + Enter-PSSession -ComputerName 192.168.0.6 -Credential $cred + ``` +- **Connection Method (SSH):** + ```bash + ssh INTRANET\\sysadmin@192.168.0.6 + # Password: Paper123!@# + # Or with key: ssh -i path/to/id_ed25519 INTRANET\\sysadmin@192.168.0.6 + ``` - **Software Update Locations:** - Common (all machines): C:\Shares\test\COMMON\ProdSW\ and C:\Shares\test\_COMMON\ProdSW\ - Station-specific: C:\Shares\test\TS-XX\ProdSW\ @@ -266,6 +304,57 @@ net use T: \\192.168.0.9\test --- +## VPN Access + +### Peaceful Spirit VPN (L2TP/IPSec) +- **Server IP:** 98.190.129.150 +- **Tunnel Type:** L2TP/IPSec +- **Pre-Shared Key (PSK):** z5zkNBds2V9eIkdey09Zm6Khil3DAZs8 +- **Username:** pst-admin +- **Password:** 24Hearts$ +- **Connection Name:** Peaceful Spirit VPN +- **Purpose:** Remote access to Peaceful Spirit Country Club network +- **Authentication:** MS-CHAPv2 with PSK +- **Split Tunneling:** Enabled (only CC traffic uses VPN) +- **Setup Script:** D:\ClaudeTools\Create-PeacefulSpiritVPN.ps1 +- **Quick Setup:** D:\ClaudeTools\VPN_QUICK_SETUP.md + +**Network Configuration (UniFi Router at CC):** +- **Remote Network:** 192.168.0.0/24 +- **DNS Server:** 192.168.0.2 +- **Gateway:** 192.168.0.10 + +**Complete Setup (Run as Administrator):** +```powershell +# Step 1: Create VPN connection with split tunneling +Add-VpnConnection -Name "Peaceful Spirit VPN" -ServerAddress "98.190.129.150" -TunnelType L2tp -L2tpPsk "z5zkNBds2V9eIkdey09Zm6Khil3DAZs8" -AuthenticationMethod MsChapv2 -EncryptionLevel Required -AllUserConnection -RememberCredential -SplitTunneling $true + +# Step 2: Add route for CC network (192.168.0.0/24) +Add-VpnConnectionRoute -ConnectionName "Peaceful Spirit VPN" -DestinationPrefix "192.168.0.0/24" -AllUserConnection + +# Step 3: Configure DNS server +Set-DnsClientServerAddress -InterfaceAlias "Peaceful Spirit VPN" -ServerAddresses "192.168.0.2" + +# Step 4: Save credentials for pre-login access +rasdial "Peaceful Spirit VPN" "pst-admin" "24Hearts$" +rasdial "Peaceful Spirit VPN" /disconnect + +# Step 5: Enable pre-login VPN +Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "UseRasCredentials" -Value 1 -Type DWord +``` + +**Quick Connect:** +```powershell +rasdial "Peaceful Spirit VPN" +``` + +**Disconnect:** +```powershell +rasdial "Peaceful Spirit VPN" /disconnect +``` + +--- + ## Context Recovery Usage When a new Claude session starts or context is lost: diff --git a/demo-ad2-automation.ps1 b/demo-ad2-automation.ps1 new file mode 100644 index 0000000..ff0747d --- /dev/null +++ b/demo-ad2-automation.ps1 @@ -0,0 +1,101 @@ +# AD2 Automation Demo +# Demonstrates efficient WinRM operations vs individual SSH commands + +Write-Host "=== AD2 Automation Demo ===" -ForegroundColor Cyan +Write-Host "Using WinRM for efficient remote operations`n" + +# Setup credentials (read-only service account) +$password = ConvertTo-SecureString "vG!UCAD>=#gIk}1A3=:{+DV3" -AsPlainText -Force +$cred = New-Object System.Management.Automation.PSCredential("INTRANET\ClaudeTools-ReadOnly", $password) + +# Example 1: Get AD User Summary +Write-Host "[1] Active Directory User Summary" -ForegroundColor Yellow +try { + $userStats = Invoke-Command -ComputerName 192.168.0.6 -Credential $cred -ScriptBlock { + $allUsers = Get-ADUser -Filter * -Properties Enabled, LastLogonDate + @{ + Total = $allUsers.Count + Enabled = ($allUsers | Where-Object Enabled -eq $true).Count + Disabled = ($allUsers | Where-Object Enabled -eq $false).Count + RecentLogin = ($allUsers | Where-Object { $_.LastLogonDate -gt (Get-Date).AddDays(-30) }).Count + } + } + + Write-Host " Total Users: $($userStats.Total)" -ForegroundColor Green + Write-Host " Enabled: $($userStats.Enabled)" -ForegroundColor Green + Write-Host " Disabled: $($userStats.Disabled)" -ForegroundColor Green + Write-Host " Active (30 days): $($userStats.RecentLogin)" -ForegroundColor Green +} catch { + Write-Host " [ERROR] $($_.Exception.Message)" -ForegroundColor Red +} + +# Example 2: Get Computer Inventory +Write-Host "`n[2] Active Directory Computer Inventory" -ForegroundColor Yellow +try { + $computerStats = Invoke-Command -ComputerName 192.168.0.6 -Credential $cred -ScriptBlock { + $allComputers = Get-ADComputer -Filter * -Properties OperatingSystem, LastLogonDate + @{ + Total = $allComputers.Count + Windows = ($allComputers | Where-Object { $_.OperatingSystem -like "*Windows*" }).Count + Servers = ($allComputers | Where-Object { $_.OperatingSystem -like "*Server*" }).Count + Active = ($allComputers | Where-Object { $_.LastLogonDate -gt (Get-Date).AddDays(-30) }).Count + } + } + + Write-Host " Total Computers: $($computerStats.Total)" -ForegroundColor Green + Write-Host " Windows Systems: $($computerStats.Windows)" -ForegroundColor Green + Write-Host " Servers: $($computerStats.Servers)" -ForegroundColor Green + Write-Host " Active (30 days): $($computerStats.Active)" -ForegroundColor Green +} catch { + Write-Host " [ERROR] $($_.Exception.Message)" -ForegroundColor Red +} + +# Example 3: Check Sync Status +Write-Host "`n[3] Dataforth Sync Status" -ForegroundColor Yellow +try { + $syncStatus = Invoke-Command -ComputerName 192.168.0.6 -Credential $cred -ScriptBlock { + $statusFile = "C:\Shares\test\_SYNC_STATUS.txt" + if (Test-Path $statusFile) { + Get-Content $statusFile -Tail 5 + } else { + "Status file not found" + } + } + + Write-Host " Last Sync Status:" -ForegroundColor Green + $syncStatus | ForEach-Object { Write-Host " $_" -ForegroundColor Gray } +} catch { + Write-Host " [ERROR] $($_.Exception.Message)" -ForegroundColor Red +} + +# Example 4: List Recent Logs +Write-Host "`n[4] Recent Sync Logs" -ForegroundColor Yellow +try { + $logInfo = Invoke-Command -ComputerName 192.168.0.6 -Credential $cred -ScriptBlock { + $logFile = "C:\Shares\test\scripts\sync-from-nas.log" + if (Test-Path $logFile) { + $file = Get-Item $logFile + @{ + Size = [math]::Round($file.Length / 1KB, 2) + LastModified = $file.LastWriteTime + LastLines = (Get-Content $logFile -Tail 3) + } + } else { + @{ Error = "Log file not found" } + } + } + + if ($logInfo.Error) { + Write-Host " [WARNING] $($logInfo.Error)" -ForegroundColor Yellow + } else { + Write-Host " Log Size: $($logInfo.Size) KB" -ForegroundColor Green + Write-Host " Last Modified: $($logInfo.LastModified)" -ForegroundColor Green + Write-Host " Recent Activity:" -ForegroundColor Green + $logInfo.LastLines | ForEach-Object { Write-Host " $_" -ForegroundColor Gray } + } +} catch { + Write-Host " [ERROR] $($_.Exception.Message)" -ForegroundColor Red +} + +Write-Host "`n=== Demo Complete ===" -ForegroundColor Cyan +Write-Host "All operations completed in a single WinRM session!" -ForegroundColor Green diff --git a/fix-ad2-dos-files.ps1 b/fix-ad2-dos-files.ps1 new file mode 100644 index 0000000..6976451 --- /dev/null +++ b/fix-ad2-dos-files.ps1 @@ -0,0 +1,125 @@ +# Fix DOS line endings on AD2 for Dataforth DOS system +Write-Host "=== Fixing DOS Files on AD2 (C:\Shares\test\) ===" -ForegroundColor Cyan +Write-Host "" + +# Setup admin credentials for AD2 +$password = ConvertTo-SecureString "Paper123!@#" -AsPlainText -Force +$cred = New-Object System.Management.Automation.PSCredential("INTRANET\sysadmin", $password) + +Write-Host "Connecting to AD2..." -ForegroundColor Yellow +Write-Host "" + +try { + $result = Invoke-Command -ComputerName 192.168.0.6 -Credential $cred -ScriptBlock { + Write-Host "[INFO] Searching for .BAT files in C:\Shares\test\" -ForegroundColor Yellow + Write-Host "" + + # Find all .BAT files in the test directory + $batFiles = Get-ChildItem -Path "C:\Shares\test" -Filter "*.BAT" -Recurse -ErrorAction SilentlyContinue + + Write-Host "Found $($batFiles.Count) batch files" -ForegroundColor Cyan + Write-Host "" + + $needsConversion = @() + $results = @() + + foreach ($file in $batFiles) { + try { + $bytes = [System.IO.File]::ReadAllBytes($file.FullName) + $hasCRLF = $false + $hasLF = $false + + for ($i = 0; $i -lt $bytes.Length - 1; $i++) { + if ($bytes[$i] -eq 13 -and $bytes[$i+1] -eq 10) { + $hasCRLF = $true + break + } + if ($bytes[$i] -eq 10 -and ($i -eq 0 -or $bytes[$i-1] -ne 13)) { + $hasLF = $true + break + } + } + + $relativePath = $file.FullName.Replace("C:\Shares\test\", "") + + if ($hasCRLF) { + $status = "OK" + $format = "CRLF (DOS)" + } elseif ($hasLF) { + $status = "NEEDS CONVERSION" + $format = "LF (Unix)" + $needsConversion += $file + } else { + $status = "EMPTY/SINGLE LINE" + $format = "No line endings" + } + + $results += [PSCustomObject]@{ + File = $relativePath + Status = $status + Format = $format + } + + Write-Host "[$status] $relativePath" -ForegroundColor $(if ($status -eq "OK") { "Green" } elseif ($status -eq "NEEDS CONVERSION") { "Red" } else { "Yellow" }) + Write-Host " $format" -ForegroundColor Gray + Write-Host "" + } catch { + Write-Host "[ERROR] $($file.Name): $($_.Exception.Message)" -ForegroundColor Red + } + } + + # Convert files that need it + if ($needsConversion.Count -gt 0) { + Write-Host "=== Converting $($needsConversion.Count) files to DOS format ===" -ForegroundColor Yellow + Write-Host "" + + $converted = 0 + $errors = 0 + + foreach ($file in $needsConversion) { + try { + # Read content + $content = Get-Content $file.FullName -Raw + + # Convert to DOS format (CRLF) + $dosContent = $content -replace "`r?`n", "`r`n" + + # Write back as ASCII (DOS compatible) + [System.IO.File]::WriteAllText($file.FullName, $dosContent, [System.Text.Encoding]::ASCII) + + Write-Host "[OK] $($file.Name)" -ForegroundColor Green + $converted++ + } catch { + Write-Host "[ERROR] $($file.Name): $($_.Exception.Message)" -ForegroundColor Red + $errors++ + } + } + + Write-Host "" + Write-Host "=== Conversion Complete ===" -ForegroundColor Green + Write-Host "Converted: $converted files" -ForegroundColor Green + if ($errors -gt 0) { + Write-Host "Errors: $errors files" -ForegroundColor Red + } + } else { + Write-Host "=== All Files OK ===" -ForegroundColor Green + Write-Host "All batch files already have proper DOS (CRLF) line endings." -ForegroundColor Green + } + + # Return summary + return @{ + TotalFiles = $batFiles.Count + Converted = $needsConversion.Count + Results = $results + } + } + + Write-Host "" + Write-Host "=== Summary ===" -ForegroundColor Cyan + Write-Host "Total batch files found: $($result.TotalFiles)" -ForegroundColor White + Write-Host "Files converted: $($result.Converted)" -ForegroundColor $(if ($result.Converted -gt 0) { "Yellow" } else { "Green" }) + +} catch { + Write-Host "[ERROR] Failed to connect to AD2" -ForegroundColor Red + Write-Host $_.Exception.Message -ForegroundColor Red +} diff --git a/fix-ad2-dos-simple.ps1 b/fix-ad2-dos-simple.ps1 new file mode 100644 index 0000000..b58fd14 --- /dev/null +++ b/fix-ad2-dos-simple.ps1 @@ -0,0 +1,75 @@ +# Simple version - fix specific DOS files on AD2 +Write-Host "=== Fixing DOS Files on AD2 ===" -ForegroundColor Cyan +Write-Host "" + +# Setup admin credentials +$password = ConvertTo-SecureString "Paper123!@#" -AsPlainText -Force +$cred = New-Object System.Management.Automation.PSCredential("INTRANET\sysadmin", $password) + +# Known batch file locations on AD2 +$filesToCheck = @( + "C:\Shares\test\COMMON\ProdSW\DEPLOY.BAT", + "C:\Shares\test\COMMON\ProdSW\NWTOC.BAT", + "C:\Shares\test\COMMON\ProdSW\CTONW.BAT", + "C:\Shares\test\COMMON\ProdSW\UPDATE.BAT", + "C:\Shares\test\COMMON\ProdSW\STAGE.BAT", + "C:\Shares\test\COMMON\ProdSW\CHECKUPD.BAT", + "C:\Shares\test\COMMON\DOS\AUTOEXEC.NEW", + "C:\Shares\test\UPDATE.BAT" +) + +Write-Host "Checking and converting DOS batch files on AD2..." -ForegroundColor Yellow +Write-Host "" + +Invoke-Command -ComputerName 192.168.0.6 -Credential $cred -ScriptBlock { + param($files) + + $converted = 0 + $alreadyOK = 0 + $notFound = 0 + + foreach ($filePath in $files) { + $fileName = Split-Path $filePath -Leaf + + if (-not (Test-Path $filePath)) { + Write-Host "[SKIP] $fileName - Not found" -ForegroundColor Yellow + $notFound++ + continue + } + + try { + # Check current line endings + $bytes = [System.IO.File]::ReadAllBytes($filePath) + $hasCRLF = $false + + for ($i = 0; $i -lt ($bytes.Length - 1); $i++) { + if ($bytes[$i] -eq 13 -and $bytes[$i+1] -eq 10) { + $hasCRLF = $true + break + } + } + + if ($hasCRLF) { + Write-Host "[OK] $fileName - Already DOS format (CRLF)" -ForegroundColor Green + $alreadyOK++ + } else { + # Convert to DOS format + $content = Get-Content $filePath -Raw + $dosContent = $content -replace "`r?`n", "`r`n" + [System.IO.File]::WriteAllText($filePath, $dosContent, [System.Text.Encoding]::ASCII) + + Write-Host "[CONV] $fileName - Converted to DOS format" -ForegroundColor Cyan + $converted++ + } + } catch { + Write-Host "[ERROR] $fileName - $($_.Exception.Message)" -ForegroundColor Red + } + } + + Write-Host "" + Write-Host "=== Summary ===" -ForegroundColor Cyan + Write-Host "Already OK: $alreadyOK" -ForegroundColor Green + Write-Host "Converted: $converted" -ForegroundColor Cyan + Write-Host "Not Found: $notFound" -ForegroundColor Yellow + +} -ArgumentList (,$filesToCheck) diff --git a/fix-sync-functions.ps1 b/fix-sync-functions.ps1 new file mode 100644 index 0000000..add2573 --- /dev/null +++ b/fix-sync-functions.ps1 @@ -0,0 +1,135 @@ +# Fix the sync functions more precisely +$password = ConvertTo-SecureString "Paper123!@#" -AsPlainText -Force +$cred = New-Object System.Management.Automation.PSCredential("INTRANET\sysadmin", $password) + +Write-Host "=== Fixing Sync Script Functions ===" -ForegroundColor Cyan +Write-Host "" + +Invoke-Command -ComputerName 192.168.0.6 -Credential $cred -ScriptBlock { + $scriptPath = "C:\Shares\test\scripts\Sync-FromNAS.ps1" + $content = Get-Content $scriptPath + + Write-Host "[1] Finding Copy-FromNAS function" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + # Find the function + for ($i = 0; $i -lt $content.Count; $i++) { + if ($content[$i] -match "^function Copy-FromNAS") { + Write-Host "Found at line $($i+1): $($content[$i])" -ForegroundColor Green + + # Show the function (next 10 lines) + Write-Host "Current function:" -ForegroundColor Cyan + for ($j = $i; $j -lt ($i + 10) -and $j -lt $content.Count; $j++) { + Write-Host " $($j+1): $($content[$j])" -ForegroundColor Gray + } + break + } + } + + Write-Host "" + Write-Host "[2] Finding Copy-ToNAS function" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + for ($i = 0; $i -lt $content.Count; $i++) { + if ($content[$i] -match "^function Copy-ToNAS") { + Write-Host "Found at line $($i+1): $($content[$i])" -ForegroundColor Green + + # Show the function (next 10 lines) + Write-Host "Current function:" -ForegroundColor Cyan + for ($j = $i; $j -lt ($i + 10) -and $j -lt $content.Count; $j++) { + Write-Host " $($j+1): $($content[$j])" -ForegroundColor Gray + } + break + } + } + + Write-Host "" + Write-Host "[3] Creating updated script with OpenSSH" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + # Create new script content with line-by-line replacement + $newContent = @() + $inCopyFromNAS = $false + $inCopyToNAS = $false + $funcDepth = 0 + + for ($i = 0; $i -lt $content.Count; $i++) { + $line = $content[$i] + + # Track when we enter functions + if ($line -match "^function Copy-FromNAS") { + $inCopyFromNAS = $true + $funcDepth = 0 + $newContent += "function Copy-FromNAS {" + $newContent += " param([string]`$RemotePath, [string]`$LocalPath)" + $newContent += "" + $newContent += " # OpenSSH scp with verbose logging" + $newContent += " `$result = & `$SCP -v -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=`"`$SCRIPTS_DIR\.ssh\known_hosts`" `"`${NAS_USER}@`${NAS_IP}:`$RemotePath`" `$LocalPath 2>&1" + $newContent += "" + $newContent += " if (`$LASTEXITCODE -ne 0) {" + $newContent += " Write-Log `" SCP PULL ERROR: `$(`$result | Out-String)`"" + $newContent += " }" + $newContent += "" + $newContent += " return `$LASTEXITCODE -eq 0" + $newContent += "}" + # Skip until we find the closing brace + continue + } + + if ($line -match "^function Copy-ToNAS") { + $inCopyToNAS = $true + $funcDepth = 0 + $newContent += "function Copy-ToNAS {" + $newContent += " param([string]`$LocalPath, [string]`$RemotePath)" + $newContent += "" + $newContent += " # OpenSSH scp with verbose logging" + $newContent += " `$result = & `$SCP -v -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=`"`$SCRIPTS_DIR\.ssh\known_hosts`" `$LocalPath `"`${NAS_USER}@`${NAS_IP}:`$RemotePath`" 2>&1" + $newContent += "" + $newContent += " if (`$LASTEXITCODE -ne 0) {" + $newContent += " Write-Log `" SCP PUSH ERROR: `$(`$result | Out-String)`"" + $newContent += " }" + $newContent += "" + $newContent += " return `$LASTEXITCODE -eq 0" + $newContent += "}" + # Skip until we find the closing brace + continue + } + + # Track braces when inside function + if ($inCopyFromNAS -or $inCopyToNAS) { + if ($line -match "{") { $funcDepth++ } + if ($line -match "}") { + $funcDepth-- + if ($funcDepth -le 0) { + # End of function, stop skipping + $inCopyFromNAS = $false + $inCopyToNAS = $false + } + } + # Skip lines inside the old function + continue + } + + # Update tool paths + if ($line -match '\$PSCP\s*=') { + $newContent += '$SCP = "C:\Program Files\OpenSSH\scp.exe"' + continue + } + if ($line -match '\$PLINK\s*=') { + $newContent += '$SSH = "C:\Program Files\OpenSSH\ssh.exe"' + continue + } + + # Keep all other lines + $newContent += $line + } + + # Save the updated script + $newContent | Out-File -FilePath $scriptPath -Encoding UTF8 -Force + + Write-Host "[OK] Script updated with OpenSSH functions" -ForegroundColor Green + Write-Host "[OK] Saved: $scriptPath" -ForegroundColor Green +} + +Write-Host "" +Write-Host "=== Update Complete ===" -ForegroundColor Cyan diff --git a/get-sync-error-details.ps1 b/get-sync-error-details.ps1 new file mode 100644 index 0000000..61aa37e --- /dev/null +++ b/get-sync-error-details.ps1 @@ -0,0 +1,105 @@ +# Get detailed sync error messages +Write-Host "=== Analyzing Sync Error Details ===" -ForegroundColor Cyan +Write-Host "" + +$password = ConvertTo-SecureString "Paper123!@#" -AsPlainText -Force +$cred = New-Object System.Management.Automation.PSCredential("INTRANET\sysadmin", $password) + +Invoke-Command -ComputerName 192.168.0.6 -Credential $cred -ScriptBlock { + $logFile = "C:\Shares\test\scripts\sync-from-nas.log" + + Write-Host "Looking for detailed error messages..." -ForegroundColor Yellow + Write-Host "" + + # Get context around errors (lines before and after ERROR lines) + $content = Get-Content $logFile -Tail 2000 + + Write-Host "[1] Error Context (last 20 errors with surrounding lines)" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + Write-Host "" + + $errorIndices = @() + for ($i = 0; $i -lt $content.Count; $i++) { + if ($content[$i] -match "ERROR:") { + $errorIndices += $i + } + } + + # Show last 20 errors with context + $errorIndices | Select-Object -Last 20 | ForEach-Object { + $index = $_ + + # Show 2 lines before, the error, and 2 lines after + $start = [Math]::Max(0, $index - 2) + $end = [Math]::Min($content.Count - 1, $index + 2) + + for ($i = $start; $i -le $end; $i++) { + if ($i -eq $index) { + Write-Host ">>> $($content[$i])" -ForegroundColor Red + } else { + Write-Host " $($content[$i])" -ForegroundColor Gray + } + } + Write-Host "" + } + + Write-Host "" + Write-Host "[2] Checking for specific error messages" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + # Look for common error patterns in more detail + $sshErrors = $content | Select-String -Pattern "ssh|plink|pscp" -Context 0,1 + $permErrors = $content | Select-String -Pattern "denied|permission" -Context 0,1 + $fileErrors = $content | Select-String -Pattern "not found|no such|cannot find" -Context 0,1 + $networkErrors = $content | Select-String -Pattern "timeout|connection|network" -Context 0,1 + + if ($sshErrors) { + Write-Host "SSH/Connection Errors:" -ForegroundColor Red + $sshErrors | Select-Object -First 5 | ForEach-Object { + Write-Host " $($_.Line)" -ForegroundColor Red + } + Write-Host "" + } + + if ($permErrors) { + Write-Host "Permission Errors:" -ForegroundColor Red + $permErrors | Select-Object -First 5 | ForEach-Object { + Write-Host " $($_.Line)" -ForegroundColor Red + } + Write-Host "" + } + + if ($fileErrors) { + Write-Host "File Not Found Errors:" -ForegroundColor Red + $fileErrors | Select-Object -First 5 | ForEach-Object { + Write-Host " $($_.Line)" -ForegroundColor Red + } + Write-Host "" + } + + if ($networkErrors) { + Write-Host "Network/Timeout Errors:" -ForegroundColor Red + $networkErrors | Select-Object -First 5 | ForEach-Object { + Write-Host " $($_.Line)" -ForegroundColor Red + } + Write-Host "" + } + + Write-Host "" + Write-Host "[3] Checking one of the failing files" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + # Check if one of the failing files actually exists + $testFile = "C:\Shares\test\TS-11L\ProdSW\HVDATA\hvin.dat" + if (Test-Path $testFile) { + $file = Get-Item $testFile + Write-Host "Sample failing file EXISTS on AD2:" -ForegroundColor Green + Write-Host " Path: $($file.FullName)" -ForegroundColor White + Write-Host " Size: $($file.Length) bytes" -ForegroundColor White + Write-Host " Modified: $($file.LastWriteTime)" -ForegroundColor White + Write-Host "" + Write-Host "This suggests the issue is with the PUSH to NAS, not the source file." -ForegroundColor Yellow + } else { + Write-Host "Sample file does NOT exist: $testFile" -ForegroundColor Red + } +} diff --git a/investigate-sync-errors.ps1 b/investigate-sync-errors.ps1 new file mode 100644 index 0000000..76d0ec1 --- /dev/null +++ b/investigate-sync-errors.ps1 @@ -0,0 +1,133 @@ +# Investigate Dataforth Sync Errors on AD2 +Write-Host "=== Investigating Dataforth Sync Errors ===" -ForegroundColor Cyan +Write-Host "" + +# Setup admin credentials for AD2 +$password = ConvertTo-SecureString "Paper123!@#" -AsPlainText -Force +$cred = New-Object System.Management.Automation.PSCredential("INTRANET\sysadmin", $password) + +Write-Host "Connecting to AD2 and analyzing sync logs..." -ForegroundColor Yellow +Write-Host "" + +Invoke-Command -ComputerName 192.168.0.6 -Credential $cred -ScriptBlock { + $logFile = "C:\Shares\test\scripts\sync-from-nas.log" + $statusFile = "C:\Shares\test\_SYNC_STATUS.txt" + + Write-Host "[1] Current Sync Status" -ForegroundColor Yellow + Write-Host "=" * 60 -ForegroundColor Gray + if (Test-Path $statusFile) { + Get-Content $statusFile + } else { + Write-Host "Status file not found" -ForegroundColor Red + } + Write-Host "" + + Write-Host "[2] Log File Information" -ForegroundColor Yellow + Write-Host "=" * 60 -ForegroundColor Gray + if (Test-Path $logFile) { + $file = Get-Item $logFile + Write-Host "File: $($file.FullName)" -ForegroundColor White + Write-Host "Size: $([math]::Round($file.Length / 1MB, 2)) MB" -ForegroundColor White + Write-Host "Last Modified: $($file.LastWriteTime)" -ForegroundColor White + Write-Host "Lines: $((Get-Content $logFile).Count)" -ForegroundColor White + } else { + Write-Host "Log file not found: $logFile" -ForegroundColor Red + return + } + Write-Host "" + + Write-Host "[3] Analyzing Errors (last 1000 lines)" -ForegroundColor Yellow + Write-Host "=" * 60 -ForegroundColor Gray + + # Read last 1000 lines to analyze recent errors + $recentLines = Get-Content $logFile -Tail 1000 + + # Count error types + $errors = $recentLines | Select-String -Pattern "ERROR|Error|error|FAIL|Failed|failed" + $warnings = $recentLines | Select-String -Pattern "WARNING|Warning|warning" + + Write-Host "Total Error Lines (last 1000): $($errors.Count)" -ForegroundColor $(if ($errors.Count -gt 0) { "Red" } else { "Green" }) + Write-Host "Total Warning Lines (last 1000): $($warnings.Count)" -ForegroundColor $(if ($warnings.Count -gt 0) { "Yellow" } else { "Green" }) + Write-Host "" + + if ($errors.Count -gt 0) { + Write-Host "[4] Error Breakdown" -ForegroundColor Yellow + Write-Host "=" * 60 -ForegroundColor Gray + + # Analyze common error patterns + $errorPatterns = @{ + "No such file" = "No such file|not found|cannot find" + "Permission denied" = "Permission denied|Access denied|Access is denied" + "Connection" = "Connection|connect|timeout" + "File in use" = "being used|in use|locked" + "SSH/SCP" = "ssh|scp|plink|pscp" + } + + foreach ($pattern in $errorPatterns.Keys) { + $count = ($errors | Select-String -Pattern $errorPatterns[$pattern]).Count + if ($count -gt 0) { + Write-Host " $pattern`: $count" -ForegroundColor Red + } + } + Write-Host "" + + Write-Host "[5] Sample Errors (last 15)" -ForegroundColor Yellow + Write-Host "=" * 60 -ForegroundColor Gray + $errors | Select-Object -Last 15 | ForEach-Object { + # Remove timestamp and show just the error + $line = $_.Line -replace '^\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}\s+:\s+', '' + Write-Host " $line" -ForegroundColor Red + } + Write-Host "" + } + + Write-Host "[6] Recent Sync Activity (last 10 operations)" -ForegroundColor Yellow + Write-Host "=" * 60 -ForegroundColor Gray + $recentLines | Select-String -Pattern "Pushed:|Pulled:|Deleted:" | Select-Object -Last 10 | ForEach-Object { + Write-Host " $($_.Line)" -ForegroundColor Gray + } + Write-Host "" + + Write-Host "[7] Today's Summary" -ForegroundColor Yellow + Write-Host "=" * 60 -ForegroundColor Gray + $today = Get-Date -Format "yyyy-MM-dd" + $todayLines = $recentLines | Where-Object { $_ -like "*$today*" } + + if ($todayLines) { + $todayPush = ($todayLines | Select-String -Pattern "Pushed:").Count + $todayPull = ($todayLines | Select-String -Pattern "Pulled:").Count + $todayDelete = ($todayLines | Select-String -Pattern "Deleted:").Count + $todayErrors = ($todayLines | Select-String -Pattern "ERROR|Error|error|FAIL").Count + + Write-Host " Files Pushed: $todayPush" -ForegroundColor Green + Write-Host " Files Pulled: $todayPull" -ForegroundColor Green + Write-Host " Files Deleted: $todayDelete" -ForegroundColor Cyan + Write-Host " Errors: $todayErrors" -ForegroundColor $(if ($todayErrors -gt 0) { "Red" } else { "Green" }) + } else { + Write-Host " No activity logged for today ($today)" -ForegroundColor Yellow + } + Write-Host "" + + Write-Host "[8] Script Status" -ForegroundColor Yellow + Write-Host "=" * 60 -ForegroundColor Gray + $scriptPath = "C:\Shares\test\scripts\Sync-FromNAS.ps1" + if (Test-Path $scriptPath) { + $script = Get-Item $scriptPath + Write-Host " Script: $($script.Name)" -ForegroundColor White + Write-Host " Last Modified: $($script.LastWriteTime)" -ForegroundColor White + + # Check if scheduled task exists + $task = Get-ScheduledTask -TaskName "Sync-FromNAS" -ErrorAction SilentlyContinue + if ($task) { + Write-Host " Scheduled Task: Enabled" -ForegroundColor Green + Write-Host " Task Status: $($task.State)" -ForegroundColor White + Write-Host " Last Run: $($task.LastRunTime)" -ForegroundColor White + Write-Host " Next Run: $($task.NextRunTime)" -ForegroundColor White + } else { + Write-Host " Scheduled Task: Not found" -ForegroundColor Red + } + } +} + +Write-Host "" +Write-Host "=== Investigation Complete ===" -ForegroundColor Cyan diff --git a/restore-and-fix-sync.ps1 b/restore-and-fix-sync.ps1 new file mode 100644 index 0000000..05c23cc --- /dev/null +++ b/restore-and-fix-sync.ps1 @@ -0,0 +1,121 @@ +# Restore backup and properly fix the sync script +$password = ConvertTo-SecureString "Paper123!@#" -AsPlainText -Force +$cred = New-Object System.Management.Automation.PSCredential("INTRANET\sysadmin", $password) + +Write-Host "=== Restoring and Fixing Sync Script ===" -ForegroundColor Cyan +Write-Host "" + +Invoke-Command -ComputerName 192.168.0.6 -Credential $cred -ScriptBlock { + $scriptPath = "C:\Shares\test\scripts\Sync-FromNAS.ps1" + $scriptsDir = "C:\Shares\test\scripts" + + Write-Host "[1] Finding most recent backup" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + $backups = Get-ChildItem "$scriptsDir\Sync-FromNAS.ps1.backup-*" | Sort-Object LastWriteTime -Descending + $latestBackup = $backups | Select-Object -First 1 + + if ($latestBackup) { + Write-Host "[OK] Found backup: $($latestBackup.Name)" -ForegroundColor Green + Write-Host " Created: $($latestBackup.LastWriteTime)" -ForegroundColor Gray + + # Restore the backup + Copy-Item -Path $latestBackup.FullName -Destination $scriptPath -Force + Write-Host "[OK] Restored backup" -ForegroundColor Green + } else { + Write-Host "[WARNING] No backup found - using current script" -ForegroundColor Yellow + } + + Write-Host "" + Write-Host "[2] Reading original script to understand structure" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + $lines = Get-Content $scriptPath + + # Find the PSCP/PLINK lines and the actual function implementations + for ($i = 0; $i -lt $lines.Count; $i++) { + if ($lines[$i] -match '^\$PSCP\s*=') { + Write-Host "Line $($i+1): $($lines[$i])" -ForegroundColor Cyan + } + if ($lines[$i] -match '^\$PLINK\s*=') { + Write-Host "Line $($i+1): $($lines[$i])" -ForegroundColor Cyan + } + if ($lines[$i] -match 'PSCP.*-ssh.*-pw') { + Write-Host "Line $($i+1) [PSCP call]: ...$(($lines[$i] -replace '.*(\$PSCP.*)', '$1'))" -ForegroundColor Yellow + } + } + + Write-Host "" + Write-Host "[3] Applying targeted fixes" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + # Just replace the tool paths and add better error logging + # Don't try to rewrite the functions - just improve what's there + + for ($i = 0; $i -lt $lines.Count; $i++) { + # Replace tool paths + if ($lines[$i] -match '^\$PSCP\s*=\s*".*pscp\.exe"') { + $lines[$i] = '$SCP = "C:\Program Files\OpenSSH\scp.exe" # Changed from PSCP to OpenSSH' + Write-Host "[UPDATED] Line $($i+1): Tool path PSCP -> SCP" -ForegroundColor Green + } + + if ($lines[$i] -match '^\$PLINK\s*=\s*".*plink\.exe"') { + $lines[$i] = '$SSH = "C:\Program Files\OpenSSH\ssh.exe" # Changed from PLINK to OpenSSH' + Write-Host "[UPDATED] Line $($i+1): Tool path PLINK -> SSH" -ForegroundColor Green + } + + # Replace PSCP calls with SCP calls and add verbose flag + if ($lines[$i] -match '\$result\s*=\s*&\s*\$PSCP\s+-ssh\s+-pw\s+\$NAS_PASSWORD\s+-hostkey\s+\$NAS_HOSTKEY') { + # This is a pscp call - replace with scp + if ($lines[$i] -match 'LocalPath.*RemotePath') { + # This is Copy-ToNAS (local first, then remote) + $lines[$i] = ' $result = & $SCP -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile="$SCRIPTS_DIR\.ssh\known_hosts" -o PreferredAuthentications=password -o PubkeyAuthentication=no -o PasswordAuthentication=yes $LocalPath "${NAS_USER}@${NAS_IP}:$RemotePath" 2>&1' + Write-Host "[UPDATED] Line $($i+1): Copy-ToNAS PSCP -> SCP" -ForegroundColor Green + } else { + # This is Copy-FromNAS (remote first, then local) + $lines[$i] = ' $result = & $SCP -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile="$SCRIPTS_DIR\.ssh\known_hosts" -o PreferredAuthentications=password -o PubkeyAuthentication=no -o PasswordAuthentication=yes "${NAS_USER}@${NAS_IP}:$RemotePath" $LocalPath 2>&1' + Write-Host "[UPDATED] Line $($i+1): Copy-FromNAS PSCP -> SCP" -ForegroundColor Green + } + + # Add error logging on the next non-empty line after "return $LASTEXITCODE" + for ($j = $i + 1; $j -lt $lines.Count; $j++) { + if ($lines[$j] -match 'return \$LASTEXITCODE') { + # Insert error logging before the return + $lines[$j] = " if (`$LASTEXITCODE -ne 0) { Write-Log `" SCP ERROR (exit $LASTEXITCODE): `$result`" }`n" + $lines[$j] + Write-Host "[ADDED] Line $($j+1): Error logging" -ForegroundColor Green + break + } + } + } + + # Replace PLINK calls with SSH calls + if ($lines[$i] -match '\&\s*\$PLINK\s+-batch') { + $lines[$i] = $lines[$i] -replace '\$PLINK\s+-batch', '$SSH -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile="$SCRIPTS_DIR\.ssh\known_hosts" -o PreferredAuthentications=password -o PubkeyAuthentication=no -o PasswordAuthentication=yes' + Write-Host "[UPDATED] Line $($i+1): PLINK -> SSH" -ForegroundColor Green + } + } + + Write-Host "" + Write-Host "[4] Saving updated script" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + # Save the modified script + $lines | Out-File -FilePath $scriptPath -Encoding UTF8 -Force + + Write-Host "[OK] Script saved" -ForegroundColor Green + + Write-Host "" + Write-Host "[5] Testing script syntax" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + # Test if the script has valid syntax + try { + $null = [System.Management.Automation.PSParser]::Tokenize((Get-Content $scriptPath -Raw), [ref]$null) + Write-Host "[OK] Script syntax is valid" -ForegroundColor Green + } catch { + Write-Host "[ERROR] Script has syntax errors: $($_.Exception.Message)" -ForegroundColor Red + } +} + +Write-Host "" +Write-Host "=== Fix Complete ===" -ForegroundColor Cyan diff --git a/setup-openssh-sync.ps1 b/setup-openssh-sync.ps1 new file mode 100644 index 0000000..070b6d5 --- /dev/null +++ b/setup-openssh-sync.ps1 @@ -0,0 +1,151 @@ +# Setup OpenSSH-based sync for AD2 -> NAS transfers +# This replaces PuTTY (pscp/plink) with OpenSSH (scp/ssh) + +$password = ConvertTo-SecureString "Paper123!@#" -AsPlainText -Force +$cred = New-Object System.Management.Automation.PSCredential("INTRANET\sysadmin", $password) + +Write-Host "=== Setting Up OpenSSH Sync (AD2 -> NAS) ===" -ForegroundColor Cyan +Write-Host "" + +Invoke-Command -ComputerName 192.168.0.6 -Credential $cred -ScriptBlock { + $NAS_IP = "192.168.0.9" + $NAS_USER = "root" + $SCRIPTS_DIR = "C:\Shares\test\scripts" + $SSH_DIR = "$SCRIPTS_DIR\.ssh" + $KNOWN_HOSTS = "$SSH_DIR\known_hosts" + + Write-Host "[1] Creating SSH directory for sync keys" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + if (-not (Test-Path $SSH_DIR)) { + New-Item -ItemType Directory -Path $SSH_DIR -Force | Out-Null + Write-Host "[OK] Created: $SSH_DIR" -ForegroundColor Green + } else { + Write-Host "[OK] Directory exists: $SSH_DIR" -ForegroundColor Green + } + + # Set permissions (only SYSTEM and Administrators) + $acl = Get-Acl $SSH_DIR + $acl.SetAccessRuleProtection($true, $false) + $acl.Access | ForEach-Object { $acl.RemoveAccessRule($_) | Out-Null } + + # Add SYSTEM + $systemRule = New-Object System.Security.AccessControl.FileSystemAccessRule( + "SYSTEM", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow" + ) + $acl.AddAccessRule($systemRule) + + # Add Administrators + $adminRule = New-Object System.Security.AccessControl.FileSystemAccessRule( + "Administrators", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow" + ) + $acl.AddAccessRule($adminRule) + + Set-Acl -Path $SSH_DIR -AclObject $acl + Write-Host "[OK] Set secure permissions on SSH directory" -ForegroundColor Green + Write-Host "" + + Write-Host "[2] Generating SSH key for NAS sync (ED25519)" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + $keyPath = "$SSH_DIR\id_ed25519_nas" + + if (Test-Path $keyPath) { + Write-Host "[SKIP] Key already exists: $keyPath" -ForegroundColor Yellow + Write-Host " Using existing key" -ForegroundColor Gray + } else { + # Generate SSH key without passphrase + & "C:\Program Files\OpenSSH\ssh-keygen.exe" -t ed25519 -f $keyPath -N '""' -C "AD2-NAS-Sync" + + if (Test-Path $keyPath) { + Write-Host "[OK] Generated SSH key: $keyPath" -ForegroundColor Green + } else { + Write-Host "[ERROR] Failed to generate SSH key" -ForegroundColor Red + return + } + } + + # Read public key + $pubKey = Get-Content "$keyPath.pub" + Write-Host "" + Write-Host "Public key to add to NAS:" -ForegroundColor Cyan + Write-Host $pubKey -ForegroundColor White + Write-Host "" + + Write-Host "[3] Adding NAS host key to known_hosts" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + # Get NAS host key using ssh-keyscan + $nasHostKey = & "C:\Program Files\OpenSSH\ssh-keyscan.exe" -H $NAS_IP 2>$null + + if ($nasHostKey) { + $nasHostKey | Out-File -FilePath $KNOWN_HOSTS -Encoding ASCII -Append + Write-Host "[OK] Added NAS host key to known_hosts" -ForegroundColor Green + } else { + Write-Host "[WARNING] Could not retrieve NAS host key" -ForegroundColor Yellow + Write-Host " Will use StrictHostKeyChecking=accept-new" -ForegroundColor Gray + } + Write-Host "" + + Write-Host "[4] Testing SSH connection to NAS (with password first)" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + Write-Host "Attempting to copy public key to NAS..." -ForegroundColor White + Write-Host "" + + # Note: We need to manually add the public key to NAS /root/.ssh/authorized_keys + Write-Host "[ACTION REQUIRED] Add public key to NAS" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + Write-Host "" + Write-Host "Run this on the NAS (192.168.0.9) as root:" -ForegroundColor Cyan + Write-Host "" + Write-Host "mkdir -p ~/.ssh" -ForegroundColor White + Write-Host "chmod 700 ~/.ssh" -ForegroundColor White + Write-Host "echo '$pubKey' >> ~/.ssh/authorized_keys" -ForegroundColor White + Write-Host "chmod 600 ~/.ssh/authorized_keys" -ForegroundColor White + Write-Host "" + Write-Host "Or from AD2 (requires NAS password):" -ForegroundColor Cyan + Write-Host "ssh root@$NAS_IP 'mkdir -p ~/.ssh && chmod 700 ~/.ssh'" -ForegroundColor White + Write-Host "ssh root@$NAS_IP 'echo `"$pubKey`" >> ~/.ssh/authorized_keys'" -ForegroundColor White + Write-Host "ssh root@$NAS_IP 'chmod 600 ~/.ssh/authorized_keys'" -ForegroundColor White + Write-Host "" + + Write-Host "[5] Backing up current sync script" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + $scriptPath = "$SCRIPTS_DIR\Sync-FromNAS.ps1" + $backupPath = "$SCRIPTS_DIR\Sync-FromNAS.ps1.backup-$(Get-Date -Format 'yyyyMMdd-HHmmss')" + + if (Test-Path $scriptPath) { + Copy-Item -Path $scriptPath -Destination $backupPath -Force + Write-Host "[OK] Backup created: $backupPath" -ForegroundColor Green + } else { + Write-Host "[WARNING] Original script not found: $scriptPath" -ForegroundColor Yellow + } + Write-Host "" + + Write-Host "[6] Configuration Summary" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + Write-Host "SSH Directory: $SSH_DIR" -ForegroundColor White + Write-Host "Private Key: $keyPath" -ForegroundColor White + Write-Host "Public Key: $keyPath.pub" -ForegroundColor White + Write-Host "Known Hosts: $KNOWN_HOSTS" -ForegroundColor White + Write-Host "NAS IP: $NAS_IP" -ForegroundColor White + Write-Host "NAS User: $NAS_USER" -ForegroundColor White + Write-Host "" + + # Return the public key for NAS setup + return @{ + PublicKey = $pubKey + KeyPath = $keyPath + KnownHosts = $KNOWN_HOSTS + } +} + +Write-Host "" +Write-Host "=== Setup Phase 1 Complete ===" -ForegroundColor Cyan +Write-Host "" +Write-Host "Next steps:" -ForegroundColor Yellow +Write-Host "1. Add the public key to NAS (shown above)" -ForegroundColor White +Write-Host "2. Test SSH key authentication" -ForegroundColor White +Write-Host "3. Update Sync-FromNAS.ps1 to use OpenSSH" -ForegroundColor White +Write-Host "" diff --git a/test-updated-sync.ps1 b/test-updated-sync.ps1 new file mode 100644 index 0000000..5a5d3c1 --- /dev/null +++ b/test-updated-sync.ps1 @@ -0,0 +1,78 @@ +# Test the updated sync script +$password = ConvertTo-SecureString "Paper123!@#" -AsPlainText -Force +$cred = New-Object System.Management.Automation.PSCredential("INTRANET\sysadmin", $password) + +Write-Host "=== Testing Updated Sync Script ===" -ForegroundColor Cyan +Write-Host "" + +Invoke-Command -ComputerName 192.168.0.6 -Credential $cred -ScriptBlock { + Write-Host "[1] Running sync script manually..." -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + Write-Host "" + + # Clear recent errors from log + $logFile = "C:\Shares\test\scripts\sync-from-nas.log" + Write-Host "Note: Watching $logFile for new errors..." -ForegroundColor Gray + Write-Host "" + + # Get current log size + $logSize = (Get-Item $logFile).Length + + # Run sync (in background to avoid blocking) + $job = Start-Job -ScriptBlock { + & powershell.exe -ExecutionPolicy Bypass -File "C:\Shares\test\scripts\Sync-FromNAS.ps1" + } + + # Wait a bit for it to start + Start-Sleep -Seconds 10 + + # Check for new log entries + $newContent = Get-Content $logFile -Raw + $newLines = $newContent.Substring([Math]::Min($logSize, $newContent.Length)) + + Write-Host "[2] Recent log output:" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + $newLines -split "`n" | Select-Object -Last 50 | ForEach-Object { + if ($_ -match "ERROR|error") { + Write-Host $_ -ForegroundColor Red + } elseif ($_ -match "WARNING|warning") { + Write-Host $_ -ForegroundColor Yellow + } elseif ($_ -match "SCP|scp") { + Write-Host $_ -ForegroundColor Cyan + } else { + Write-Host $_ -ForegroundColor Gray + } + } + + # Stop the job + Stop-Job -Job $job -ErrorAction SilentlyContinue + Remove-Job -Job $job -ErrorAction SilentlyContinue + + Write-Host "" + Write-Host "[3] Checking if detailed SCP errors are logged" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + $scpErrors = Get-Content $logFile -Tail 100 | Select-String -Pattern "SCP ERROR" + + if ($scpErrors) { + Write-Host "[SUCCESS] Found detailed SCP error logging!" -ForegroundColor Green + Write-Host "" + Write-Host "Sample SCP errors:" -ForegroundColor Cyan + $scpErrors | Select-Object -First 5 | ForEach-Object { + Write-Host " $_" -ForegroundColor Red + } + } else { + Write-Host "[INFO] No 'SCP ERROR' entries found yet" -ForegroundColor Yellow + Write-Host "This could mean:" -ForegroundColor Gray + Write-Host " - No errors occurred (good!)" -ForegroundColor Gray + Write-Host " - Errors happened but weren't logged yet" -ForegroundColor Gray + Write-Host " - Need to wait for next scheduled run" -ForegroundColor Gray + } +} + +Write-Host "" +Write-Host "=== Test Complete ===" -ForegroundColor Cyan +Write-Host "" +Write-Host "Note: The script runs every 15 minutes via scheduled task." -ForegroundColor Yellow +Write-Host "Check the log again in a few minutes for full sync results." -ForegroundColor Yellow diff --git a/test-winrm.ps1 b/test-winrm.ps1 new file mode 100644 index 0000000..6690c5d --- /dev/null +++ b/test-winrm.ps1 @@ -0,0 +1,52 @@ +# Test WinRM Connection to AD2 +Write-Host "[INFO] Testing WinRM connection to AD2..." + +# Admin account test +Write-Host "`n[TEST 1] Admin Account (INTRANET\sysadmin)" +$adminPassword = ConvertTo-SecureString "Paper123!@#" -AsPlainText -Force +$adminCred = New-Object System.Management.Automation.PSCredential("INTRANET\sysadmin", $adminPassword) + +try { + $result = Invoke-Command -ComputerName 192.168.0.6 -Credential $adminCred -ScriptBlock { + @{ + Computer = $env:COMPUTERNAME + Domain = $env:USERDOMAIN + User = $env:USERNAME + WinRM = (Get-Service WinRM).Status + } + } -ErrorAction Stop + + Write-Host "[SUCCESS] Connected to AD2" -ForegroundColor Green + Write-Host " Computer: $($result.Computer)" + Write-Host " Domain: $($result.Domain)" + Write-Host " User: $($result.User)" + Write-Host " WinRM Status: $($result.WinRM)" +} catch { + Write-Host "[ERROR] $($_.Exception.Message)" -ForegroundColor Red +} + +# Service account test +Write-Host "`n[TEST 2] Service Account (INTRANET\ClaudeTools-ReadOnly)" +$svcPassword = ConvertTo-SecureString "vG!UCAD>=#gIk}1A3=:{+DV3" -AsPlainText -Force +$svcCred = New-Object System.Management.Automation.PSCredential("INTRANET\ClaudeTools-ReadOnly", $svcPassword) + +try { + $result = Invoke-Command -ComputerName 192.168.0.6 -Credential $svcCred -ScriptBlock { + @{ + Computer = $env:COMPUTERNAME + Domain = $env:USERDOMAIN + User = $env:USERNAME + UserCount = (Get-ADUser -Filter * | Measure-Object).Count + } + } -ErrorAction Stop + + Write-Host "[SUCCESS] Connected to AD2" -ForegroundColor Green + Write-Host " Computer: $($result.Computer)" + Write-Host " Domain: $($result.Domain)" + Write-Host " User: $($result.User)" + Write-Host " AD Users Found: $($result.UserCount)" +} catch { + Write-Host "[ERROR] $($_.Exception.Message)" -ForegroundColor Red +} + +Write-Host "`n[INFO] Testing complete." diff --git a/trigger-sync.ps1 b/trigger-sync.ps1 new file mode 100644 index 0000000..1133f04 --- /dev/null +++ b/trigger-sync.ps1 @@ -0,0 +1,40 @@ +# Trigger sync on AD2 by creating and executing a remote batch file + +$Username = "INTRANET\sysadmin" +$Password = ConvertTo-SecureString "Paper123!@#" -AsPlainText -Force +$Cred = New-Object System.Management.Automation.PSCredential($Username, $Password) + +Write-Host "Connecting to AD2..." +New-PSDrive -Name TEMP_AD2 -PSProvider FileSystem -Root "\\192.168.0.6\C$" -Credential $Cred | Out-Null +Write-Host "[OK] Connected" +Write-Host "" + +# Create a trigger batch file on AD2 +$triggerContent = @" +@ECHO OFF +ECHO Running sync manually... +powershell.exe -ExecutionPolicy Bypass -File C:\Shares\test\scripts\Sync-FromNAS.ps1 -Verbose +ECHO Sync complete. +"@ + +Set-Content -Path "TEMP_AD2:\Shares\test\scripts\run-sync-now.bat" -Value $triggerContent -Force +Write-Host "[OK] Created trigger script on AD2" + +# Try to execute it via PsExec-style approach +Write-Host "" +Write-Host "Attempting to trigger sync..." +Write-Host "" + +# Create a scheduled task to run immediately +$taskCmd = @" +schtasks /create /s 192.168.0.6 /u INTRANET\sysadmin /p "Paper123!@#" /tn "TempSyncTrigger" /tr "C:\Shares\test\scripts\run-sync-now.bat" /sc once /st 00:00 /f +schtasks /run /s 192.168.0.6 /u INTRANET\sysadmin /p "Paper123!@#" /tn "TempSyncTrigger" +"@ + +Write-Host $taskCmd +Invoke-Expression $taskCmd + +Write-Host "" +Write-Host "[INFO] Sync triggered. Check C:\Shares\test\scripts\sync-from-nas.log for results." + +Remove-PSDrive TEMP_AD2 diff --git a/update-sync-to-openssh.ps1 b/update-sync-to-openssh.ps1 new file mode 100644 index 0000000..2bfaf34 --- /dev/null +++ b/update-sync-to-openssh.ps1 @@ -0,0 +1,121 @@ +# Update Sync-FromNAS.ps1 to use OpenSSH with verbose logging +# This will show us the actual errors that are happening + +$password = ConvertTo-SecureString "Paper123!@#" -AsPlainText -Force +$cred = New-Object System.Management.Automation.PSCredential("INTRANET\sysadmin", $password) + +Write-Host "=== Updating Sync Script to Use OpenSSH ===" -ForegroundColor Cyan +Write-Host "" + +Invoke-Command -ComputerName 192.168.0.6 -Credential $cred -ScriptBlock { + $scriptPath = "C:\Shares\test\scripts\Sync-FromNAS.ps1" + + Write-Host "[1] Reading current sync script" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + $content = Get-Content $scriptPath -Raw + + Write-Host "[OK] Script loaded ($($content.Length) characters)" -ForegroundColor Green + Write-Host "" + + Write-Host "[2] Updating to use OpenSSH" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + # Replace PuTTY paths with OpenSSH paths + $content = $content -replace '\$PSCP\s*=\s*"[^"]*pscp\.exe"', '$SCP = "C:\Program Files\OpenSSH\scp.exe"' + $content = $content -replace '\$PLINK\s*=\s*"[^"]*plink\.exe"', '$SSH = "C:\Program Files\OpenSSH\ssh.exe"' + + Write-Host "[OK] Replaced tool paths (PuTTY -> OpenSSH)" -ForegroundColor Green + + # Update Copy-FromNAS function to use OpenSSH with verbose logging + $oldCopyFrom = @' +function Copy-FromNAS { + param([string]$RemotePath, [string]$LocalPath) + + $result = & $PSCP -ssh -pw $NAS_PASSWORD -hostkey $NAS_HOSTKEY "${NAS_USER}@${NAS_IP}:$RemotePath" $LocalPath 2>&1 + return $LASTEXITCODE -eq 0 +} +'@ + + $newCopyFrom = @' +function Copy-FromNAS { + param([string]$RemotePath, [string]$LocalPath) + + # OpenSSH scp with password auth and verbose logging + $env:SSHPASS = $NAS_PASSWORD + $result = & $SCP -v -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile="$SCRIPTS_DIR\.ssh\known_hosts" "${NAS_USER}@${NAS_IP}:$RemotePath" $LocalPath 2>&1 + + if ($LASTEXITCODE -ne 0) { + Write-Log " SCP PULL ERROR: $($result | Out-String)" + } + + return $LASTEXITCODE -eq 0 +} +'@ + + $content = $content -replace [regex]::Escape($oldCopyFrom), $newCopyFrom + + # Update Copy-ToNAS function to use OpenSSH with verbose logging + $oldCopyTo = @' +function Copy-ToNAS { + param([string]$LocalPath, [string]$RemotePath) + + $result = & $PSCP -ssh -pw $NAS_PASSWORD -hostkey $NAS_HOSTKEY $LocalPath "${NAS_USER}@${NAS_IP}:$RemotePath" 2>&1 + return $LASTEXITCODE -eq 0 +} +'@ + + $newCopyTo = @' +function Copy-ToNAS { + param([string]$LocalPath, [string]$RemotePath) + + # OpenSSH scp with password auth and verbose logging + $env:SSHPASS = $NAS_PASSWORD + $result = & $SCP -v -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile="$SCRIPTS_DIR\.ssh\known_hosts" $LocalPath "${NAS_USER}@${NAS_IP}:$RemotePath" 2>&1 + + if ($LASTEXITCODE -ne 0) { + Write-Log " SCP PUSH ERROR: $($result | Out-String)" + } + + return $LASTEXITCODE -eq 0 +} +'@ + + $content = $content -replace [regex]::Escape($oldCopyTo), $newCopyTo + + # Check if we found and replaced the functions + if ($content -like "*OpenSSH scp*") { + Write-Host "[OK] Updated Copy-FromNAS and Copy-ToNAS functions" -ForegroundColor Green + } else { + Write-Host "[WARNING] Functions may not have been updated - check manually" -ForegroundColor Yellow + } + + Write-Host "" + Write-Host "[3] Saving updated script" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + # Save updated script + $content | Out-File -FilePath $scriptPath -Encoding UTF8 -Force + + Write-Host "[OK] Script saved: $scriptPath" -ForegroundColor Green + Write-Host "" + + Write-Host "[4] Next sync will use OpenSSH and log detailed errors" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + Write-Host "The next sync run (every 15 minutes) will:" -ForegroundColor White + Write-Host " - Use native OpenSSH tools (scp instead of pscp)" -ForegroundColor Cyan + Write-Host " - Log verbose output with -v flag" -ForegroundColor Cyan + Write-Host " - Show actual error messages in sync-from-nas.log" -ForegroundColor Cyan + Write-Host " - Auto-accept host keys (StrictHostKeyChecking=accept-new)" -ForegroundColor Cyan + Write-Host "" + Write-Host "Check the log after next sync:" -ForegroundColor Yellow + Write-Host " Get-Content C:\Shares\test\scripts\sync-from-nas.log -Tail 50" -ForegroundColor Gray +} + +Write-Host "" +Write-Host "=== Script Update Complete ===" -ForegroundColor Cyan +Write-Host "" +Write-Host "Next steps:" -ForegroundColor Yellow +Write-Host "1. Wait for next scheduled sync (runs every 15 minutes)" -ForegroundColor White +Write-Host "2. Check logs for detailed error messages" -ForegroundColor White +Write-Host "3. The actual pscp errors will now be visible!" -ForegroundColor White diff --git a/verify-and-test-sync.ps1 b/verify-and-test-sync.ps1 new file mode 100644 index 0000000..d029ca3 --- /dev/null +++ b/verify-and-test-sync.ps1 @@ -0,0 +1,80 @@ +# Verify the sync script update and run a test sync +$password = ConvertTo-SecureString "Paper123!@#" -AsPlainText -Force +$cred = New-Object System.Management.Automation.PSCredential("INTRANET\sysadmin", $password) + +Write-Host "=== Verifying Sync Script Update ===" -ForegroundColor Cyan +Write-Host "" + +Invoke-Command -ComputerName 192.168.0.6 -Credential $cred -ScriptBlock { + $scriptPath = "C:\Shares\test\scripts\Sync-FromNAS.ps1" + + Write-Host "[1] Verifying OpenSSH tool paths" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + $content = Get-Content $scriptPath -Raw + + if ($content -match '\$SCP\s*=\s*"[^"]*OpenSSH[^"]*scp\.exe"') { + Write-Host "[OK] SCP path updated to OpenSSH" -ForegroundColor Green + } else { + Write-Host "[ERROR] SCP path not found or incorrect" -ForegroundColor Red + } + + if ($content -match '\$SSH\s*=\s*"[^"]*OpenSSH[^"]*ssh\.exe"') { + Write-Host "[OK] SSH path updated to OpenSSH" -ForegroundColor Green + } else { + Write-Host "[ERROR] SSH path not found or incorrect" -ForegroundColor Red + } + + Write-Host "" + Write-Host "[2] Verifying Copy-ToNAS function" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + if ($content -match "SCP PUSH ERROR") { + Write-Host "[OK] Copy-ToNAS has error logging" -ForegroundColor Green + } else { + Write-Host "[WARNING] Error logging may not be present" -ForegroundColor Yellow + } + + if ($content -match "StrictHostKeyChecking=accept-new") { + Write-Host "[OK] Auto host key acceptance configured" -ForegroundColor Green + } else { + Write-Host "[WARNING] Host key acceptance may not be configured" -ForegroundColor Yellow + } + + Write-Host "" + Write-Host "[3] Running manual sync test" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + Write-Host "Triggering a manual sync run to test OpenSSH and capture errors..." -ForegroundColor White + Write-Host "" + + # Run the sync script + try { + & powershell.exe -ExecutionPolicy Bypass -File $scriptPath *>&1 | Tee-Object -Variable syncOutput + + Write-Host "" + Write-Host "[4] Checking sync log for detailed errors" -ForegroundColor Yellow + Write-Host "=" * 80 -ForegroundColor Gray + + $logFile = "C:\Shares\test\scripts\sync-from-nas.log" + $recentErrors = Get-Content $logFile -Tail 30 | Select-String -Pattern "SCP.*ERROR|ERROR.*push|ERROR.*pull" + + if ($recentErrors) { + Write-Host "Found detailed error messages:" -ForegroundColor Cyan + $recentErrors | ForEach-Object { + Write-Host " $_" -ForegroundColor Red + } + } else { + Write-Host "No detailed SCP errors found in recent log" -ForegroundColor Yellow + Write-Host "Showing last 15 lines of log:" -ForegroundColor Gray + Get-Content $logFile -Tail 15 | ForEach-Object { + Write-Host " $_" -ForegroundColor Gray + } + } + + } catch { + Write-Host "[ERROR] Sync script failed to run: $($_.Exception.Message)" -ForegroundColor Red + } +} + +Write-Host "" +Write-Host "=== Test Complete ===" -ForegroundColor Cyan