零成本25TB OneDrive白养虾「转」 发表于 2026-08-28 更新于 2026-08-28
阅读量: 广州
零成本25TB OneDrive白养虾「转」 宁一二 2026-08-28 2026-08-28 微软 E3 开发者订阅白给 25TB OneDrive。不花钱。我让我的 Agent 每天凌晨自动打包、自动上传、自动接管这 25TB。已经跑了两个月,零故障。这篇把完整方案拆给你——从拿 Token 到 Agent 全自动备份,每一步都能直接抄。
为什么 Agent 需要一块自己的硬盘 Agent 跑久了,数据比你想象的多:cron 日志、会话快照、状态备份、脚本、配置文件。VPS 那几十 GB 的 SSD 塞满只是时间问题。
E3 开发者订阅你可能早就拿过了——注册微软开发者计划(Microsoft 365 Developer Program),送 25 个 E3 席位。每个账号 OneDrive 默认 1TB,管理员能调到 5TB。还不够?联系微软支持直接拉到 25TB。
25TB ≈ 300 个 80GB 的 VPS 系统盘。白给的。
关键问题是:怎么让 Agent 自动用起来?不能用那种需要浏览器弹窗的 OAuth——Agent 没人给它在浏览器里点“同意”。
这时候就需要 Client Credentials Flow。它是 Microsoft Graph API 专门给后台服务设计的鉴权方式:不需要用户交互,不需要浏览器登录,纯靠 Client ID + Client Secret 直接拿 Token。对 Agent 来说就是两个字符串的事。
第一步:注册一个后台应用(App-only) 登录 Azure Portal(E3 订阅附带的),进 Azure Active Directory → 应用注册 → 新注册。
名称随便填,比如 AgentBackup
账户类型选“仅此组织目录”
不需要重定向URI
注册完后记下两个东西:
Application (Client) ID:应用的身份证
Directory (Tenant) ID:你 E3 组织的租户 ID
然后点“证书和密码” → 新建客户端密码 → 记下密码值(只显示一次)。这就是 Client Secret。
最后给权限:API 权限 → 添加权限 → Microsoft Graph → 应用程序权限 → 勾选 Files.ReadWrite.All → 管理员同意。
Files.ReadWrite.All 是应用级权限,不是用户委托。这意味着这个应用能读写整个组织所有人的 OneDrive——但既然是自己的 E3 组织,读写自己的完全没问题。
第二步:Client Credentials Flow 拿 Token 三个参数发一个 POST,Token 就到手了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import requests def get_graph_token(tenant_id, client_id, client_secret): resp = requests.post( f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token", data={ "client_id": client_id, "client_secret": client_secret, "scope": "https://graph.microsoft.com/.default", "grant_type": "client_credentials" }, timeout=20 ) return resp.json()["access_token"]
全程没有任何弹窗、没有浏览器、不需要点“同意”。Agent 自己就能调。
拿到 Token 后,Graph API 直接访问 OneDrive。完整路径是:
1 2 3 https://graph.microsoft.com/v1.0/users/{user_id}/drive/root:/
其中 user_id 是你 E3 账号的邮箱(如 admin@yourdomain.onmicrosoft.com ),也可以用 /me 简化。
第三步:Agent 自动备份脚本(抄作业) 下面是生产环境在用的完整逻辑——打包 + 瘦身 + 分片上传:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 import os import time import tarfile import requests CHUNK_SIZE = 5 * 1024 * 1024 # 5MB 黄金分片 TENANT_ID = "你的租户ID" CLIENT_ID = "你的应用ID" CLIENT_SECRET = "你的ClientSecret" USER_ID = "你的E3邮箱" # 直连 Session(不走中转,OneDrive 能直连) direct = requests.Session() direct.trust_env = False # 不读系统中转环境变量 def get_token(): resp = direct.post( f"https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token", data={ "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, "scope": "https://graph.microsoft.com/.default", "grant_type": "client_credentials" }, timeout=20 ) return resp.json()["access_token"] def agent_backup_to_onedrive(): """Agent cron 调用的备份入口""" # 1. 打包 ← 精准排除垃圾 tar_path = "/tmp/agent_backup.tar.gz" excludes = [ "*venv*", "*node_modules*", ".hermes/node", ".hermes/lsp", ".hermes/checkpoints", ".hermes/state-snapshots", ".hermes/trash" ] with tarfile.open(tar_path, "w:gz") as tar: for path in ["/root/.hermes", "/root/scripts"]: tar.add(path, arcname=os.path.basename(path), exclude=lambda n: any(ex in n for ex in excludes)) size_mb = os.path.getsize(tar_path) / 1024 / 1024 print(f"📦 打包完成: {size_mb:.1f} MB") # 2. 拿 Token token = get_token() # 3. 创建上传会话 file_name = f"backup_{time.strftime('%Y%m%d_%H%M%S')}.tar.gz" session_url = f"https://graph.microsoft.com/v1.0/users/{USER_ID}/drive/root:/backups/{file_name}:/createUploadSession" resp = direct.post(session_url, headers={"Authorization": f"Bearer {token}"}, timeout=20) upload_url = resp.json()["uploadUrl"] # 4. 分片上传(5MB 分片 + 5 次重试 + 递增退避) file_size = os.path.getsize(tar_path) with open(tar_path, "rb") as f: offset = 0 while offset < file_size: chunk = f.read(CHUNK_SIZE) end = offset + len(chunk) - 1 headers = {"Content-Range": f"bytes {offset}-{end}/{file_size}"} for attempt in range(5): try: r = direct.put(upload_url, headers=headers, data=chunk, timeout=60) if r.status_code in (200, 201, 202): break except requests.exceptions.RequestException: pass time.sleep(3 + attempt) else: raise Exception(f"分片 {offset}-{end} 上传失败") offset = end + 1 print(f" ⬆ {offset}/{file_size} ({100*offset//file_size}%)") print(f"✅ OneDrive 备份完成: {file_name}") return file_name
把这个脚本挂到 Agent 的 cron 里,每天凌晨 4 点自动触发。Agent 自己打包、自己瘦身、自己上传。全程零人工。
效果:从 2.5GB 到 312MB,从频繁超时到零重试 排除规则生效前,打包文件 2.5GB,跨国上传经常在 60% 左右被网关掐断。排除后体积打了一折,传输从超时变秒传。
指标 优化前 优化后 打包体积 2.5 GB 312 MB 打包时间 ~30 秒 < 5 秒 上传耗时 超时失败 ~8 分钟 单次重试次数 50+ 0 成功率 60% 100%
三个关键设计让这成为可能:
Client Credentials Flow:不要浏览器、不要用户交互——Agent 拿两个字符串就能读写 OneDrive 上的任何文件。这是整个自动化的基石。
trust_env = False:强制物理直连,绕开系统的中转通道。OneDrive 本来就对直连友好,走中转反而慢。
5MB 分片 + 5 次重试:小分片抖动影响小,重试成本低。10MB 分片一抖就丢半个,5MB 丢了一个秒补。
备份的精髓不是“把东西打包传上去”,而是“只备份值得备份的东西,用 Agent 能理解的方式连接”。Client Credentials Flow 是让 OneDrive 从“手动上传的网盘”变成“Agent 自带硬盘”的那把钥匙。
这东西适合你吗 适合:
手上有 E3 开发者订阅的——25TB 吃灰不如给 Agent 当私有云盘
跑 Agent / 自动化任务需要自动备份的
想要“设定一次、永久运行”的零交互方案
不适合:
只有个人版 OneDrive(5GB)的——方案依然能用,但空间扛不住 Agent 的日志量
网络环境无法直连微软服务的——Client Credentials 拿 Token 也需要连 login.microsoftonline.com
处理高度敏感数据的——虽然走直连,但数据存在微软服务器