Files
CmiiDeploy/998-常用脚本/b-镜像同步/windows镜像下载/windows从MINIO下载文件.ps1
2026-05-19 14:28:56 +08:00

134 lines
5.5 KiB
PowerShell

<#
.SYNOPSIS
MinIO 免 Alias 批量下载脚本 (强力兼容特殊字符版)。
.DESCRIPTION
1. 采用临时配置目录 (--config-dir),彻底解决密码中 #、@、$ 等符号导致的 URL 解析错误。
2. 自动清理:脚本结束或异常退出时,会自动销毁临时生成的凭证文件。
3. 路径追踪:支持递归下载、进度显示及失败文件自动清理。
#>
# =====================================================================
# 1. 解决中文编码问题
# =====================================================================
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
[Console]::InputEncoding = [System.Text.Encoding]::UTF8
$OutputEncoding = [System.Text.Encoding]::UTF8
# =====================================================================
# 2. 变量配置区 (请按实际情况修改)
# =====================================================================
# MinIO 客户端 (mc.exe) 的全路径
$McExePath = "C:\Users\zzy\Desktop\cmii\mc.exe"
# 远端服务器信息
$MinioEndpoint = "https://oss.demo.uavcmlc.com"
$MinioUsername = "cmii"
# 注意:密码务必使用单引号 '' 包裹,防止 PowerShell 误解析其中的特殊符号
$MinioPassword = 'B#923fC7mk'
# 远端桶及目录 (需以 / 结尾)
$TargetBucketPath = "cmlc-installation/rke13014/"
# 本地保存全路径 (需以 \ 结尾)
$LocalSavePath = "C:\Users\zzy\Desktop\cmii\rke13014\"
# =====================================================================
# 3. 初始化临时环境 (避开环境变量 URL 解析 Bug)
# =====================================================================
Clear-Host
Write-Host "正在初始化安全传输环境..." -ForegroundColor Cyan
# 在系统临时目录下创建一个独立的 mc 配置文件夹
$TempConfigDir = Join-Path -Path $env:TEMP -ChildPath ("mc_tmp_" + [Guid]::NewGuid().ToString().Substring(0,8))
if (-not (Test-Path $TempConfigDir)) { New-Item -ItemType Directory -Path $TempConfigDir | Out-Null }
# 定义一个内部使用的临时 Alias 名称
$TmpAlias = "InternalTmp"
# =====================================================================
# 4. 建立连接 (使用 --config-dir 隔离配置)
# =====================================================================
Write-Host "正在建立与远端服务器的验证连接..." -ForegroundColor DarkGray
# 使用 alias set 命令,这种方式对密码中的 # 号等字符支持最稳健
& $McExePath --config-dir $TempConfigDir alias set $TmpAlias $MinioEndpoint $MinioUsername $MinioPassword --insecure | Out-Null
if ($LASTEXITCODE -ne 0) {
Write-Error "验证失败!请检查账密(特别是特殊字符)或网络地址。"
Remove-Item -Path $TempConfigDir -Recurse -Force -ErrorAction SilentlyContinue
exit
}
# 拼接 mc 识别路径
$RemoteDir = "$TmpAlias/$TargetBucketPath"
# 检查本地目录
if (-not (Test-Path $LocalSavePath)) {
New-Item -ItemType Directory -Path $LocalSavePath -Force | Out-Null
}
# =====================================================================
# 5. 安全获取文件列表
# =====================================================================
Write-Host "正在扫描远端文件..." -ForegroundColor Cyan
$jsonOutput = & $McExePath --config-dir $TempConfigDir ls --recursive --json --insecure $RemoteDir 2>&1
$fileList = @()
foreach ($line in $jsonOutput) {
if ([string]::IsNullOrWhiteSpace($line) -or $line -match "mc: ") { continue }
try {
$obj = $line | ConvertFrom-Json -ErrorAction Stop
if ($obj.type -eq "file") { $fileList += $obj }
} catch {
# 忽略非 JSON 的提示信息
}
}
$totalFiles = $fileList.Count
if ($totalFiles -eq 0) {
Write-Host "未发现可下载文件,请检查桶路径是否正确: $TargetBucketPath" -ForegroundColor Yellow
Remove-Item -Path $TempConfigDir -Recurse -Force -ErrorAction SilentlyContinue
exit
}
# =====================================================================
# 6. 循环下载与断点清理
# =====================================================================
Write-Host "共扫描到 $totalFiles 个文件,开始下载任务..." -ForegroundColor Green
$currentIndex = 0
foreach ($file in $fileList) {
$currentIndex++
$relPath = $file.key
$remoteFile = "$RemoteDir$relPath"
# 路径转换
$winRelPath = $relPath -replace '/', '\'
$localFile = Join-Path -Path $LocalSavePath -ChildPath $winRelPath
# 创建子目录
$parentDir = Split-Path $localFile -Parent
if (-not (Test-Path $parentDir)) { New-Item -ItemType Directory -Path $parentDir -Force | Out-Null }
Write-Host "[$currentIndex/$totalFiles] 正在下载: $relPath" -ForegroundColor Yellow
# 执行下载
& $McExePath --config-dir $TempConfigDir cp --insecure $remoteFile $localFile
if ($LASTEXITCODE -ne 0) {
Write-Host " [失败] 下载被中断。" -ForegroundColor Red
if (Test-Path $localFile) {
Write-Host " [清理] 删除不完整的临时文件: $localFile" -ForegroundColor DarkYellow
Remove-Item $localFile -Force
}
} else {
Write-Host " [完成]" -ForegroundColor Green
}
}
# =====================================================================
# 7. 彻底清理临时凭证
# =====================================================================
Write-Host "`n任务结束,正在销毁临时安全凭证..." -ForegroundColor Cyan
Remove-Item -Path $TempConfigDir -Recurse -Force -ErrorAction SilentlyContinue
Write-Host "脚本执行完毕。" -ForegroundColor White