# PowerShell: "iwr -useb https://raw.githubusercontent.com/sky22333/shell/main/dev/cf-setup.ps1 | iex" # Path: "C:\ProgramData\cloudflared\" $ProgressPreference = 'SilentlyContinue' $ErrorActionPreference = 'Stop' function Write-ColorMessage { param ( [Parameter(Mandatory=$true)] [string]$Message, [ValidateSet('Black','DarkBlue','DarkGreen','DarkCyan','DarkRed','DarkMagenta','DarkYellow','Gray','DarkGray','Blue','Green','Cyan','Red','Magenta','Yellow','White')] [string]$Color = 'White' ) try { $originalColor = $null if ($Host.UI -and $Host.UI.RawUI -and $Host.UI.RawUI.ForegroundColor) { $originalColor = $Host.UI.RawUI.ForegroundColor $Host.UI.RawUI.ForegroundColor = $Color } Write-Host $Message if ($originalColor -ne $null) { $Host.UI.RawUI.ForegroundColor = $originalColor } } catch { try { Write-Host $Message -ForegroundColor $Color } catch { Write-Host $Message } } } function Download-File { param ( [string]$Url, [string]$OutputPath ) try { if ($PSVersionTable.PSVersion.Major -ge 3) { $webClient = New-Object System.Net.WebClient $webClient.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36") $webClient.DownloadFile($Url, $OutputPath) $webClient.Dispose() } else { $webClient = New-Object System.Net.WebClient $webClient.DownloadFile($Url, $OutputPath) $webClient.Dispose() } return $true } catch { Write-ColorMessage "Download failed: $($_.Exception.Message)" Red return $false } } function Test-AdminRights { try { $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object Security.Principal.WindowsPrincipal($currentUser) return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) } catch { return $false } } Write-Host "====== CloudFlared Tunnel Setup Tool ======" -ForegroundColor Cyan Write-Host "Initializing..." -ForegroundColor Yellow $cloudflaredUrl = "https://github.com/cloudflare/cloudflared/releases/download/2025.6.1/cloudflared-windows-amd64.exe" $installDir = "$env:ProgramData\cloudflared" $cloudflaredBin = Join-Path $installDir "cloudflared.exe" $logPath = Join-Path $installDir "cloudflared.log" $serviceName = "CloudflaredTunnel" $psVersion = $PSVersionTable.PSVersion.Major Write-Host "Detected PowerShell version: $psVersion" -ForegroundColor Green try { if (-not (Test-Path $installDir)) { New-Item -ItemType Directory -Path $installDir -Force | Out-Null Write-ColorMessage "Created installation directory: $installDir" Green } } catch { Write-ColorMessage "Cannot create installation directory, may need administrator privileges" Red Write-ColorMessage "Error: $($_.Exception.Message)" Red exit 1 } Write-ColorMessage "`nChecking cloudflared..." Yellow if (Test-Path $cloudflaredBin) { Write-ColorMessage "cloudflared.exe already exists: $cloudflaredBin" Green try { $fileInfo = Get-Item $cloudflaredBin $fileSize = [math]::Round($fileInfo.Length / 1MB, 2) Write-ColorMessage "File size: ${fileSize} MB" Cyan } catch { } } else { Write-ColorMessage "Starting download of cloudflared..." Cyan Write-ColorMessage "Download URL: $cloudflaredUrl" Gray Write-ColorMessage "Save location: $cloudflaredBin" Gray $downloadSuccess = Download-File -Url $cloudflaredUrl -OutputPath $cloudflaredBin if ($downloadSuccess) { Write-ColorMessage "Download complete!" Green try { $fileInfo = Get-Item $cloudflaredBin $fileSize = [math]::Round($fileInfo.Length / 1MB, 2) Write-ColorMessage "File size: ${fileSize} MB" Cyan } catch { } } else { Write-ColorMessage "Download failed, please check your network connection or download manually" Red Write-ColorMessage "Manual download URL: $cloudflaredUrl" Yellow exit 1 } } Write-ColorMessage "`nChecking existing services..." Yellow try { $serviceExists = Get-Service -Name $serviceName -ErrorAction SilentlyContinue if ($serviceExists) { Write-ColorMessage "Detected existing cloudflared service: $serviceName" Yellow Write-ColorMessage "Service status: $($serviceExists.Status)" Cyan do { $uninstall = Read-Host "Do you want to uninstall the old service? (y/n)" } while ($uninstall -notin @('y','Y','n','N','yes','no')) if ($uninstall -in @('y','Y','yes')) { Write-ColorMessage "Uninstalling old service..." Cyan try { Stop-Service -Name $serviceName -Force -ErrorAction SilentlyContinue Start-Sleep -Seconds 2 $scResult = & "$env:SystemRoot\System32\sc.exe" delete $serviceName if (Test-Path $logPath) { Remove-Item -Path $logPath -Force -ErrorAction SilentlyContinue } Write-ColorMessage "Service uninstallation complete" Green } catch { Write-ColorMessage "Error uninstalling service: $($_.Exception.Message)" Red } } else { Write-ColorMessage "Keeping existing service, only updating run address" Yellow } } } catch { Write-ColorMessage "Error checking service: $($_.Exception.Message)" Red } Write-ColorMessage "`nPlease select run mode:" Yellow Write-Host "1) Temporary run (foreground with trycloudflare domain display)" Write-Host "2) Background run (register as system service)" do { $mode = Read-Host "Please enter 1 or 2 ?" } while ($mode -notin @('1','2')) do { $localAddr = Read-Host "Please enter local service address (e.g.: 127.0.0.1:8080)" } while ([string]::IsNullOrWhiteSpace($localAddr)) if ($mode -eq "1") { Write-ColorMessage "`nRunning cloudflared in temporary mode..." Cyan Write-ColorMessage "Starting cloudflared process..." Yellow Write-ColorMessage "Local service address: $localAddr" Green try { Write-ColorMessage "Running cloudflared directly with output to console..." Yellow Write-ColorMessage "Press Ctrl+C to stop the tunnel" Yellow & $cloudflaredBin tunnel --url $localAddr } catch { Write-ColorMessage "Error starting process: $($_.Exception.Message)" Red } } elseif ($mode -eq "2") { Write-ColorMessage "`nRegistering as system service and running in background..." Cyan if (-not (Test-AdminRights)) { Write-ColorMessage "Warning: Administrator privileges may be required to create system services" Yellow Write-ColorMessage "If this fails, please run this script as administrator" Yellow } try { $serviceCommand = "`"$cloudflaredBin`" tunnel --url $localAddr --logfile `"$logPath`"" $scResult = & "$env:SystemRoot\System32\sc.exe" create $serviceName binPath= $serviceCommand start= auto if ($LASTEXITCODE -eq 0) { Write-ColorMessage "Service created successfully" Green } else { Write-ColorMessage "Service creation may have failed, exit code: $LASTEXITCODE" Yellow } Start-Sleep -Seconds 2 Write-ColorMessage "Starting service..." Yellow Start-Service -Name $serviceName -ErrorAction Stop Write-ColorMessage "Service started successfully, waiting for log output..." Green $domain = $null for ($i = 0; $i -lt 30; $i++) { Start-Sleep -Seconds 1 if (Test-Path $logPath) { try { $logContent = Get-Content $logPath -Raw -ErrorAction SilentlyContinue if ($logContent -and $logContent -match 'https://[a-zA-Z0-9-]+\.trycloudflare\.com') { $domain = $matches[0] Write-ColorMessage "`n=== Service Running Successfully ===" Green Write-ColorMessage "Public access URL: $domain" Green Write-ColorMessage "Local service address: $localAddr" Cyan Write-ColorMessage "Log file location: $logPath" Gray break } } catch { } } if ($i % 3 -eq 0) { Write-Host "." -NoNewline } } Write-Host "" if (-not $domain) { Write-ColorMessage "No access domain detected, please check the log manually: $logPath" Yellow Write-ColorMessage "The service may need more time to establish connection" Cyan try { $serviceStatus = Get-Service -Name $serviceName Write-ColorMessage "Service status: $($serviceStatus.Status)" Cyan } catch { Write-ColorMessage "Unable to get service status" Red } } Write-ColorMessage "`nService management commands:" Yellow Write-ColorMessage "Stop service: Stop-Service -Name $serviceName" Gray Write-ColorMessage "Start service: Start-Service -Name $serviceName" Gray Write-ColorMessage "Delete service: sc.exe delete $serviceName" Gray } catch { Write-ColorMessage "Failed to create or start service" Red Write-ColorMessage "Error: $($_.Exception.Message)" Red Write-ColorMessage "Please make sure you have administrator privileges" Yellow try { & "$env:SystemRoot\System32\sc.exe" delete $serviceName 2>$null } catch { } } } else { Write-ColorMessage "Invalid option, please enter 1 or 2" Red exit 1 } Write-ColorMessage "`nScript execution complete" Green