; Script for GE Aerospace Mapped Drive Reconnection Utility
; Helps users update credentials and reconnect mapped drives

[Setup]
AppId={{C7D8E9F0-A1B2-3C4D-5E6F-7A8B9C0D1E2F}
AppName=WJDT GE Aerospace Mapped Drive Reconnection
AppVersion=1.1
AppPublisher=WJDT
AppPublisherURL=http://tsgwp00524.logon.ds.ge.com
AppSupportURL=http://tsgwp00524.logon.ds.ge.com
AppUpdatesURL=http://tsgwp00524.logon.ds.ge.com
CreateAppDir=no
ChangesAssociations=no
PrivilegesRequired=admin
OutputDir=C:\Users\570005354\Downloads\Output
OutputBaseFilename=MappedDriveReconnect
SolidCompression=yes
WizardStyle=modern
SetupIconFile=gea-logo.ico
WizardImageFile=patrick.bmp
WizardSmallImageFile=patrick-sm.bmp
CreateUninstallRegKey=no
DisableWelcomePage=no

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"

[Messages]
WelcomeLabel2=This utility will help you reconnect your mapped network drives with updated credentials.%n%nYou will be prompted to enter your password for the logon domain. Your Windows username will be detected automatically.%n%nThis is useful when:%n- Your password has changed (90-day policy)%n- Drives have disconnected%n- Credentials need to be updated

[Code]
function SetEnvironmentVariable(lpName: String; lpValue: String): Boolean;
external 'SetEnvironmentVariableW@kernel32.dll stdcall';

var
  PasswordPage: TInputQueryWizardPage;
  ServerSelectionPage: TInputOptionWizardPage;
  CurrentUsername: String;
  UserPassword: String;
  
procedure InitializeWizard();
begin
  CurrentUsername := GetUserNameString;
  
  ServerSelectionPage := CreateInputOptionPage(wpWelcome,
    'Select Servers to Reconnect',
    'Choose which network drives you need to reconnect',
    'Select the servers below. You can choose one or both depending on your needs.',
    False, False);
  
  ServerSelectionPage.Add('tsgwp00525.rd.ds.ge.com (Shared Drive)');
  ServerSelectionPage.Add('win.cighpeifep036.logon.ds.ge.com (Engineering Server)');
  
  ServerSelectionPage.Values[0] := True;
  ServerSelectionPage.Values[1] := False;
  
  PasswordPage := CreateInputQueryPage(ServerSelectionPage.ID,
    'Enter Network Credentials',
    'Please enter your password for the logon domain',
    'Your username will be: logon\' + CurrentUsername + #13#10#13#10 +
    'Enter your password below:');
  
  PasswordPage.Add('Password:', True);
end;

function NextButtonClick(CurPageID: Integer): Boolean;
var
  ResultCode: Integer;
  ScriptPath: String;
  PowerShellScript: String;
  Server1Selected: Boolean;
  Server2Selected: Boolean;
  SelectedServers: String;
begin
  Result := True;
  
  if CurPageID = ServerSelectionPage.ID then
  begin
    if not (ServerSelectionPage.Values[0] or ServerSelectionPage.Values[1]) then
    begin
      MsgBox('Please select at least one server to reconnect.', mbError, MB_OK);
      Result := False;
      Exit;
    end;
  end;
  
  if CurPageID = PasswordPage.ID then
  begin
    UserPassword := PasswordPage.Values[0];
    
    if Trim(UserPassword) = '' then
    begin
      MsgBox('Password cannot be empty. Please enter your password.', mbError, MB_OK);
      Result := False;
      Exit;
    end;
    
    SelectedServers := '';
    if ServerSelectionPage.Values[0] then
      SelectedServers := SelectedServers + '- tsgwp00525.rd.ds.ge.com' + #13#10;
    if ServerSelectionPage.Values[1] then
      SelectedServers := SelectedServers + '- win.cighpeifep036.logon.ds.ge.com' + #13#10;
    
    if MsgBox('Username: logon\' + CurrentUsername + #13#10#13#10 +
              'Selected servers:' + #13#10 + SelectedServers + #13#10 +
              'Are you ready to reconnect your mapped drives?', 
              mbConfirmation, MB_YESNO) = IDNO then
    begin
      Result := False;
      Exit;
    end;
  end;
  
  if CurPageID = wpReady then
  begin
    Server1Selected := ServerSelectionPage.Values[0];
    Server2Selected := ServerSelectionPage.Values[1];
    
    PowerShellScript := 
      '$username = "logon\' + CurrentUsername + '"' + #13#10 +
      '$password = [System.Environment]::GetEnvironmentVariable("TEMP_GE_PASSWORD","Process")' + #13#10 +
      '[System.Environment]::SetEnvironmentVariable("TEMP_GE_PASSWORD",$null,"Process")' + #13#10 +
      '$allSuccess = $true' + #13#10 +
      '$mappingsFile = "$env:APPDATA\GEDriveMappings.json"' + #13#10 +
      '' + #13#10 +
      'Write-Host "========================================" -ForegroundColor Cyan' + #13#10 +
      'Write-Host "  GE Aerospace Drive Reconnection Tool" -ForegroundColor Cyan' + #13#10 +
      'Write-Host "========================================" -ForegroundColor Cyan' + #13#10 +
      'Write-Host ""' + #13#10 +
      'Write-Host "Backing up current network mappings..." -ForegroundColor Yellow' + #13#10 +
      '$currentMappings = @()' + #13#10 +
      '$netUseOutput = net use | Select-String ":"' + #13#10 +
      'foreach ($line in $netUseOutput) {' + #13#10 +
      '    if ($line -match "^[^\s]+\s+([A-Z]:)\s+(\\\\[^\s]+)\s+") {' + #13#10 +
      '        $driveLetter = $matches[1]' + #13#10 +
      '        $drivePath = $matches[2]' + #13#10 +
      '        if (-not ($currentMappings | Where-Object { $_.Drive -eq $driveLetter })) {' + #13#10 +
      '            $currentMappings += @{Drive=$driveLetter; Path=$drivePath}' + #13#10 +
      '            Write-Host "  ${driveLetter} -> ${drivePath}" -ForegroundColor Gray' + #13#10 +
      '        }' + #13#10 +
      '    }' + #13#10 +
      '}' + #13#10 +
      '' + #13#10 +
      '$existingBackup = @()' + #13#10 +
      'if (Test-Path $mappingsFile) {' + #13#10 +
      '    try {' + #13#10 +
      '        $loaded = Get-Content $mappingsFile -Raw | ConvertFrom-Json' + #13#10 +
      '        if ($loaded) {' + #13#10 +
      '            if ($loaded -is [System.Array]) {' + #13#10 +
      '                $existingBackup = $loaded' + #13#10 +
      '            } else {' + #13#10 +
      '                $existingBackup = @($loaded)' + #13#10 +
      '            }' + #13#10 +
      '        }' + #13#10 +
      '        if ($existingBackup.Count -gt 26) {' + #13#10 +
      '            Write-Host "  Warning: Backup file corrupted, starting fresh" -ForegroundColor Yellow' + #13#10 +
      '            $existingBackup = @()' + #13#10 +
      '        }' + #13#10 +
      '    } catch {' + #13#10 +
      '        $existingBackup = @()' + #13#10 +
      '    }' + #13#10 +
      '}' + #13#10 +
      '' + #13#10 +
      '$mergedMappings = @{}' + #13#10 +
      'foreach ($current in $currentMappings) {' + #13#10 +
      '    $mergedMappings[$current.Drive] = $current.Path' + #13#10 +
      '}' + #13#10 +
      'foreach ($existing in $existingBackup) {' + #13#10 +
      '    if (-not $mergedMappings.ContainsKey($existing.Drive)) {' + #13#10 +
      '        $mergedMappings[$existing.Drive] = $existing.Path' + #13#10 +
      '    }' + #13#10 +
      '}' + #13#10 +
      '' + #13#10 +
      '$mappingsToSave = @()' + #13#10 +
      'foreach ($key in $mergedMappings.Keys) {' + #13#10 +
      '    $mappingsToSave += @{Drive=$key; Path=$mergedMappings[$key]}' + #13#10 +
      '}' + #13#10 +
      '' + #13#10 +
      'if ($mappingsToSave.Count -gt 0) {' + #13#10 +
      '    $mappingsToSave | ConvertTo-Json -Depth 10 | Out-File -FilePath $mappingsFile -Encoding UTF8 -Force' + #13#10 +
      '    Write-Host "  Saved $($mappingsToSave.Count) mappings" -ForegroundColor Green' + #13#10 +
      '    if ($existingBackup.Count -gt 0 -and $mappingsToSave.Count -gt $currentMappings.Count) {' + #13#10 +
      '        $preserved = $mappingsToSave.Count - $currentMappings.Count' + #13#10 +
      '        Write-Host "  Preserved $preserved disconnected drive(s)" -ForegroundColor Yellow' + #13#10 +
      '    }' + #13#10 +
      '}' + #13#10 +
      'Write-Host ""' + #13#10 +
      'Write-Host "Step 1: Checking for ghost drives..." -ForegroundColor Yellow' + #13#10;
    
    if Server1Selected then
      PowerShellScript := PowerShellScript +
        '$job = Start-Job -ScriptBlock { net use S: 2>&1 }' + #13#10 +
        'Wait-Job $job -Timeout 3 | Out-Null' + #13#10 +
        'Remove-Job $job -Force 2>$null | Out-Null' + #13#10;
    
    if Server2Selected then
      PowerShellScript := PowerShellScript +
        '$job = Start-Job -ScriptBlock { net use Y: 2>&1 }' + #13#10 +
        'Wait-Job $job -Timeout 3 | Out-Null' + #13#10 +
        'Remove-Job $job -Force 2>$null | Out-Null' + #13#10;
    
    PowerShellScript := PowerShellScript +
      'Write-Host "  Done" -ForegroundColor Gray' + #13#10 +
      'Write-Host ""' + #13#10 +
      'Write-Host "Step 2: Disconnecting drives..." -ForegroundColor Yellow' + #13#10;
    
    if Server1Selected then
      PowerShellScript := PowerShellScript +
        '$tsgwpConnections = Get-WmiObject Win32_NetworkConnection -ErrorAction SilentlyContinue | Where-Object { $_.RemoteName -like "*tsgwp00525*" }' + #13#10 +
        'if ($tsgwpConnections) {' + #13#10 +
        '    $tsgwpConnections | ForEach-Object {' + #13#10 +
        '        Write-Host "  $($_.LocalName)" -ForegroundColor Gray' + #13#10 +
        '        net use $_.LocalName /delete /yes 2>$null | Out-Null' + #13#10 +
        '    }' + #13#10 +
        '}' + #13#10;
    
    if Server2Selected then
      PowerShellScript := PowerShellScript +
        'net use Y: /delete /yes 2>$null | Out-Null' + #13#10 +
        'Write-Host "  Y:" -ForegroundColor Gray' + #13#10;
    
    PowerShellScript := PowerShellScript +
      'Write-Host ""' + #13#10 +
      'Write-Host "Step 3: Updating credentials..." -ForegroundColor Yellow' + #13#10;
    
    if Server1Selected then
      PowerShellScript := PowerShellScript +
        'cmdkey /delete:tsgwp00525.rd.ds.ge.com 2>$null | Out-Null' + #13#10 +
        'cmdkey /add:tsgwp00525.rd.ds.ge.com /user:$username /pass:$password | Out-Null' + #13#10 +
        'Write-Host "  tsgwp00525" -ForegroundColor Green' + #13#10;
    
    if Server2Selected then
      PowerShellScript := PowerShellScript +
        'cmdkey /delete:win.cighpeifep036.logon.ds.ge.com 2>$null | Out-Null' + #13#10 +
        'cmdkey /add:win.cighpeifep036.logon.ds.ge.com /user:$username /pass:$password | Out-Null' + #13#10 +
        'Write-Host "  win.cighpeifep036" -ForegroundColor Green' + #13#10;
    
    PowerShellScript := PowerShellScript +
      'Start-Sleep -Seconds 1' + #13#10 +
      'Write-Host ""' + #13#10;
    
    if Server1Selected then
      PowerShellScript := PowerShellScript +
        'Write-Host "Step 4: Restoring tsgwp00525 drives..." -ForegroundColor Yellow' + #13#10 +
        '$otherDrives = @()' + #13#10 +
        'if (Test-Path $mappingsFile) {' + #13#10 +
        '    try {' + #13#10 +
        '        $allMappings = Get-Content $mappingsFile -Raw | ConvertFrom-Json' + #13#10 +
        '        if ($allMappings -is [System.Array]) {' + #13#10 +
        '            $otherDrives = @($allMappings | Where-Object { $_.Path -like "*tsgwp00525*" -and $_.Drive -ne "S:" })' + #13#10 +
        '        } else {' + #13#10 +
        '            if ($allMappings.Path -like "*tsgwp00525*" -and $allMappings.Drive -ne "S:") {' + #13#10 +
        '                $otherDrives = @($allMappings)' + #13#10 +
        '            }' + #13#10 +
        '        }' + #13#10 +
        '    } catch { }' + #13#10 +
        '}' + #13#10 +
        'if ($otherDrives.Count -gt 0) {' + #13#10 +
        '    foreach ($drive in $otherDrives) {' + #13#10 +
        '        $driveLetter = $drive.Drive' + #13#10 +
        '        $drivePath = $drive.Path' + #13#10 +
        '        Write-Host "  Restoring ${driveLetter}..." -ForegroundColor Gray' + #13#10 +
        '        $result = net use $driveLetter $drivePath /user:$username $password /persistent:yes 2>&1' + #13#10 +
        '        if ($LASTEXITCODE -eq 0) {' + #13#10 +
        '            Write-Host "    Success" -ForegroundColor Green' + #13#10 +
        '        } else {' + #13#10 +
        '            Write-Host "    Failed: $result" -ForegroundColor Red' + #13#10 +
        '        }' + #13#10 +
        '    }' + #13#10 +
        '} else {' + #13#10 +
        '    Write-Host "  No additional drives to restore" -ForegroundColor Gray' + #13#10 +
        '}' + #13#10 +
        'Write-Host ""' + #13#10;
    
    PowerShellScript := PowerShellScript +
      'Write-Host "Step 5: Mapping primary drives..." -ForegroundColor Yellow' + #13#10 +
      'Write-Host ""' + #13#10;
    
    if Server1Selected then
      PowerShellScript := PowerShellScript +
        'Write-Host "  Mapping S:..." -ForegroundColor Cyan' + #13#10 +
        '$maxRetries = 3' + #13#10 +
        '$retryCount = 0' + #13#10 +
        '$mapped = $false' + #13#10 +
        '$authFailed = $false' + #13#10 +
        '' + #13#10 +
        'while (-not $mapped -and $retryCount -lt $maxRetries) {' + #13#10 +
        '    $retryCount++' + #13#10 +
        '    Write-Host "    Attempt $retryCount..." -ForegroundColor Gray' + #13#10 +
        '    $mapResult = net use S: \\tsgwp00525.rd.ds.ge.com\shared /user:$username $password /persistent:yes 2>&1' + #13#10 +
        '    if ($LASTEXITCODE -eq 0) {' + #13#10 +
        '        Write-Host "    Success!" -ForegroundColor Green' + #13#10 +
        '        $mapped = $true' + #13#10 +
        '    } elseif ($mapResult -like "*85*" -or $mapResult -like "*already in use*") {' + #13#10 +
        '        Write-Host "    Ghost drive detected - cleaning up..." -ForegroundColor Yellow' + #13#10 +
        '        for ($i=1; $i -le 5; $i++) { net use S: /delete /yes 2>$null | Out-Null; Start-Sleep -Milliseconds 300 }' + #13#10 +
        '        if (Test-Path "HKCU:\Network\S") { Remove-Item "HKCU:\Network\S" -Recurse -Force -ErrorAction SilentlyContinue }' + #13#10 +
        '        Get-WmiObject Win32_NetworkConnection -ErrorAction SilentlyContinue | Where-Object { $_.LocalName -eq "S:" } | ForEach-Object { $_.Delete() }' + #13#10 +
        '        if (Get-PSDrive S -ErrorAction SilentlyContinue) { Remove-PSDrive S -Force -ErrorAction SilentlyContinue }' + #13#10 +
        '        if ($retryCount -eq 2) {' + #13#10 +
        '            Write-Host "    Restarting Explorer..." -ForegroundColor Yellow' + #13#10 +
        '            Stop-Process -Name explorer -Force -ErrorAction SilentlyContinue' + #13#10 +
        '            Start-Sleep -Seconds 2' + #13#10 +
        '            Start-Process explorer' + #13#10 +
        '            Start-Sleep -Seconds 2' + #13#10 +
        '        }' + #13#10 +
        '        Start-Sleep -Seconds 3' + #13#10 +
        '    } elseif ($mapResult -like "*1219*") {' + #13#10 +
        '        Write-Host "    Resolving credential conflict..." -ForegroundColor Yellow' + #13#10 +
        '        $savedDrives = @()' + #13#10 +
        '        if (Test-Path $mappingsFile) {' + #13#10 +
        '            $allMappings = @(Get-Content $mappingsFile -Raw | ConvertFrom-Json)' + #13#10 +
        '            $savedDrives = @($allMappings | Where-Object { $_.Path -like "*tsgwp00525*" -and $_.Drive -ne "S:" })' + #13#10 +
        '        }' + #13#10 +
        '        Get-WmiObject Win32_NetworkConnection -ErrorAction SilentlyContinue | Where-Object { $_.RemoteName -like "*tsgwp00525*" } | ForEach-Object { net use $_.LocalName /delete /yes 2>$null | Out-Null }' + #13#10 +
        '        cmdkey /delete:tsgwp00525.rd.ds.ge.com 2>$null | Out-Null' + #13#10 +
        '        cmdkey /add:tsgwp00525.rd.ds.ge.com /user:$username /pass:$password | Out-Null' + #13#10 +
        '        Start-Sleep -Seconds 1' + #13#10 +
        '        foreach ($drive in $savedDrives) {' + #13#10 +
        '            net use $drive.Drive $drive.Path /user:$username $password /persistent:yes 2>$null | Out-Null' + #13#10 +
        '        }' + #13#10 +
        '    } else {' + #13#10 +
        '        if ($mapResult -like "*1326*" -or $mapResult -like "*1244*" -or $mapResult -like "*86*" -or $mapResult -like "*logon failure*" -or $mapResult -like "*password*" -or $mapResult -like "*access*denied*") {' + #13#10 +
        '            $Host.UI.RawUI.BackgroundColor = "DarkRed"' + #13#10 +
        '            Clear-Host' + #13#10 +
        '            Write-Host ""' + #13#10 +
        '            Write-Host "  ========================================" -ForegroundColor Red' + #13#10 +
        '            Write-Host "  AUTHENTICATION FAILED" -ForegroundColor Red' + #13#10 +
        '            Write-Host "  ========================================" -ForegroundColor Red' + #13#10 +
        '            Write-Host ""' + #13#10 +
        '            Write-Host "  The password is incorrect or your" -ForegroundColor Yellow' + #13#10 +
        '            Write-Host "  account may need attention." -ForegroundColor Yellow' + #13#10 +
        '            Write-Host ""' + #13#10 +
        '            Write-Host "  Visit: https://oneidm.ge.com" -ForegroundColor Cyan' + #13#10 +
        '            Write-Host "  to verify or change your password." -ForegroundColor Cyan' + #13#10 +
        '            Write-Host ""' + #13#10 +
        '            $authFailed = $true' + #13#10 +
        '        } else {' + #13#10 +
        '            Write-Host "    Error: $mapResult" -ForegroundColor Red' + #13#10 +
        '            $authFailed = $true' + #13#10 +
        '        }' + #13#10 +
        '        $allSuccess = $false' + #13#10 +
        '        $password = $null' + #13#10 +
        '        Write-Host "  Press any key to exit..." -ForegroundColor Gray' + #13#10 +
        '        $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")' + #13#10 +
        '        $Host.UI.RawUI.BackgroundColor = "Black"' + #13#10 +
        '        break' + #13#10 +
        '    }' + #13#10 +
        '}' + #13#10 +
        'if (-not $mapped -and -not $authFailed) {' + #13#10 +
        '    $Host.UI.RawUI.BackgroundColor = "DarkRed"' + #13#10 +
        '    Clear-Host' + #13#10 +
        '    $allSuccess = $false' + #13#10 +
        '    Write-Host ""' + #13#10 +
        '    Write-Host "  ========================================" -ForegroundColor Red' + #13#10 +
        '    Write-Host "  GHOST DRIVE DETECTED" -ForegroundColor Red' + #13#10 +
        '    Write-Host "  ========================================" -ForegroundColor Red' + #13#10 +
        '    Write-Host ""' + #13#10 +
        '    Write-Host "  Could not map S: after $retryCount attempts." -ForegroundColor Yellow' + #13#10 +
        '    Write-Host ""' + #13#10 +
        '    Write-Host "  To fix:" -ForegroundColor Yellow' + #13#10 +
        '    Write-Host "    1. Save your work" -ForegroundColor White' + #13#10 +
        '    Write-Host "    2. Restart your computer" -ForegroundColor White' + #13#10 +
        '    Write-Host "    3. Run this tool again" -ForegroundColor White' + #13#10 +
        '    Write-Host ""' + #13#10 +
        '    $password = $null' + #13#10 +
        '    Write-Host "  Press any key to exit..." -ForegroundColor Gray' + #13#10 +
        '    $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")' + #13#10 +
        '    $Host.UI.RawUI.BackgroundColor = "Black"' + #13#10 +
        '}' + #13#10 +
        'Write-Host ""' + #13#10;
    
    if Server2Selected then
      PowerShellScript := PowerShellScript +
        'Write-Host "  Checking Y: configuration..." -ForegroundColor Cyan' + #13#10 +
        '$yWasOnTsgwp = $false' + #13#10 +
        'if (Test-Path $mappingsFile) {' + #13#10 +
        '    $savedMappings = @(Get-Content $mappingsFile -Raw | ConvertFrom-Json)' + #13#10 +
        '    $yMapping = $savedMappings | Where-Object { $_.Drive -eq "Y:" }' + #13#10 +
        '    if ($yMapping -and $yMapping.Path -like "*tsgwp00525*") {' + #13#10 +
        '        $yWasOnTsgwp = $true' + #13#10 +
        '        Write-Host "    Y: already configured for tsgwp00525" -ForegroundColor Yellow' + #13#10 +
        '    }' + #13#10 +
        '}' + #13#10 +
        'if (-not $yWasOnTsgwp) {' + #13#10 +
        '    Write-Host "  Mapping Y:..." -ForegroundColor Cyan' + #13#10 +
        '    $mapResult = net use Y: \\win.cighpeifep036.logon.ds.ge.com\ugcam_res_lib\library\database /user:$username $password /persistent:yes 2>&1' + #13#10 +
        '    if ($LASTEXITCODE -eq 0) {' + #13#10 +
        '        Write-Host "    Success!" -ForegroundColor Green' + #13#10 +
        '    } else {' + #13#10 +
        '        Write-Host "    Failed: $mapResult" -ForegroundColor Red' + #13#10 +
        '        $allSuccess = $false' + #13#10 +
        '    }' + #13#10 +
        '}' + #13#10 +
        'Write-Host ""' + #13#10;
    
    PowerShellScript := PowerShellScript +
      'if ($allSuccess) {' + #13#10 +
      '    $Host.UI.RawUI.BackgroundColor = "DarkGreen"' + #13#10 +
      '    Clear-Host' + #13#10 +
      '    Write-Host ""' + #13#10 +
      '    Write-Host "  ========================================" -ForegroundColor Cyan' + #13#10 +
      '    Write-Host "  SUCCESS!" -ForegroundColor Cyan' + #13#10 +
      '    Write-Host "  ========================================" -ForegroundColor Cyan' + #13#10 +
      '    Write-Host ""' + #13#10 +
      '    Write-Host "  Connected drives:" -ForegroundColor White' + #13#10 +
      '    net use | Select-String ":" | ForEach-Object {' + #13#10 +
      '        if ($_ -match "([A-Z]:)\s+(\\\\[^\s]+)") {' + #13#10 +
      '            Write-Host "    $($matches[1]) -> $($matches[2])" -ForegroundColor Gray' + #13#10 +
      '        }' + #13#10 +
      '    }' + #13#10 +
      '    Write-Host ""' + #13#10 +
      '    Write-Host "  Updating backup..." -ForegroundColor Yellow' + #13#10 +
      '    $finalMappings = @()' + #13#10 +
      '    $existingBackup = @()' + #13#10 +
      '    if (Test-Path $mappingsFile) {' + #13#10 +
      '        $existingBackup = @(Get-Content $mappingsFile -Raw | ConvertFrom-Json)' + #13#10 +
      '    }' + #13#10 +
      '    $netUseOutput = net use | Select-String ":"' + #13#10 +
      '    foreach ($line in $netUseOutput) {' + #13#10 +
      '        if ($line -match "([A-Z]:)\s+(\\\\[^\s]+)") {' + #13#10 +
      '            $finalMappings += @{Drive=$matches[1]; Path=$matches[2]}' + #13#10 +
      '        }' + #13#10 +
      '    }' + #13#10 +
      '    foreach ($existing in $existingBackup) {' + #13#10 +
      '        if (-not ($finalMappings | Where-Object { $_.Drive -eq $existing.Drive })) {' + #13#10 +
      '            $finalMappings += $existing' + #13#10 +
      '        }' + #13#10 +
      '    }' + #13#10 +
      '    if ($finalMappings.Count -gt 0) {' + #13#10 +
      '        $finalMappings | ConvertTo-Json -Depth 10 | Out-File -FilePath $mappingsFile -Encoding UTF8 -Force' + #13#10 +
      '        Write-Host "  Backup updated" -ForegroundColor Green' + #13#10 +
      '    }' + #13#10 +
      '    Write-Host ""' + #13#10 +
      '    $password = $null' + #13#10 +
      '    Write-Host "  Press any key to close..." -ForegroundColor Gray' + #13#10 +
      '    $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")' + #13#10 +
      '    $Host.UI.RawUI.BackgroundColor = "Black"' + #13#10 +
      '}';
    
    ScriptPath := ExpandConstant('{tmp}\MapDrives.ps1');
    SaveStringToFile(ScriptPath, PowerShellScript, False);
    
    SetEnvironmentVariable('TEMP_GE_PASSWORD', UserPassword);
    
    if not Exec('powershell.exe', 
                '-NoProfile -ExecutionPolicy Bypass -File "' + ScriptPath + '"',
                '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
    begin
      MsgBox('Failed to execute script.', mbError, MB_OK);
      Result := False;
    end;
    
    SetEnvironmentVariable('TEMP_GE_PASSWORD', '');
    DeleteFile(ScriptPath);
  end;
end;

function ShouldSkipPage(PageID: Integer): Boolean;
begin
  Result := False;
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssPostInstall then
  begin
  end;
end;