如何通过脚本获取所有Teams/SharePoint文件列表及路径?
解决方案:自动遍历Teams群组文件并生成索引
核心依赖:Microsoft Graph API
Teams的文件实际存储在对应Microsoft 365群组的SharePoint站点文档库中,通过Graph API可统一获取所有Teams的文件资源。
1. 权限配置(必须管理员操作)
在Azure AD中注册应用,添加以下应用权限(需管理员同意):
Group.Read.All:读取所有Microsoft 365群组(对应Teams)Sites.Read.All:读取所有SharePoint站点及文件
2. 实现步骤(Python示例)
安装依赖
pip install azure-identity msgraph-core pandas
核心代码逻辑
from azure.identity import ClientSecretCredential from msgraph.core import GraphClient import pandas as pd from datetime import datetime # 从Azure AD注册页面获取以下配置 TENANT_ID = "你的租户ID" CLIENT_ID = "你的应用ID" CLIENT_SECRET = "你的应用密钥" # 初始化Graph客户端 credential = ClientSecretCredential(tenant_id=TENANT_ID, client_id=CLIENT_ID, client_secret=CLIENT_SECRET) client = GraphClient(credential=credential) def get_all_teams(): """获取所有Teams对应的Microsoft 365群组""" teams = [] next_link = "https://graph.microsoft.com/v1.0/groups?$filter=resourceProvisioningOptions/Any(x:x eq 'Team')" while next_link: response = client.get(next_link) data = response.json() teams.extend(data.get('value', [])) next_link = data.get('@odata.nextLink') return teams def get_team_sharepoint_site(group_id): """获取Teams对应的SharePoint站点信息""" response = client.get(f"https://graph.microsoft.com/v1.0/groups/{group_id}/sites/root") return response.json() if response.status_code == 200 else None def list_files_in_site(site_id, drive_id="documents"): """递归遍历站点文档库中的所有文件""" files = [] # 初始请求链接,展开修改人信息并选择所需字段 base_url = f"https://graph.microsoft.com/v1.0/sites/{site_id}/drives/{drive_id}/root/children?$expand=lastModifiedByUser&select=name,webUrl,lastModifiedDateTime,lastModifiedByUser,parentReference,size" def traverse_folder(folder_url): nonlocal files resp = client.get(folder_url) data = resp.json() for item in data.get('value', []): if item.get('folder'): # 递归遍历子文件夹 child_url = item.get('@odata.nextLink') or f"{folder_url.split('?')[0]}/{item['id']}/children?{folder_url.split('?')[1]}" traverse_folder(child_url) elif item.get('file'): # 提取文件信息 file_info = { "群组名": get_group_name_by_id(item['parentReference']['siteId']), "文件路径": item['parentReference']['path'].replace("/drives/documents/root:", ""), "文件名": item['name'], "文件大小(KB)": round(item['size']/1024, 2), "修改时间": item['lastModifiedDateTime'], "最后修改人": item['lastModifiedByUser']['displayName'], "文件链接": item['webUrl'] } files.append(file_info) traverse_folder(base_url) return files def get_group_name_by_id(group_id): """缓存群组ID与名称的映射,避免重复调用API""" if not hasattr(get_group_name_by_id, 'cache'): get_group_name_by_id.cache = {g['id']: g['displayName'] for g in get_all_teams()} return get_group_name_by_id.cache.get(group_id, "未知群组") def generate_index(output_format="csv"): """生成文件索引文件""" all_files = [] teams = get_all_teams() for team in teams: site = get_team_sharepoint_site(team['id']) if not site: continue files = list_files_in_site(site['id']) all_files.extend(files) # 整理数据并排序 df = pd.DataFrame(all_files) df['修改时间'] = pd.to_datetime(df['修改时间']) df = df.sort_values(by='修改时间', ascending=False) # 生成带时间戳的输出文件 timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") if output_format == "csv": filename = f"teams_files_index_{timestamp}.csv" df.to_csv(filename, index=False, encoding='utf-8-sig') elif output_format == "html": filename = f"teams_files_index_{timestamp}.html" df.to_html(filename, index=False, encoding='utf-8') print(f"索引文件已生成:{filename}") if __name__ == "__main__": generate_index(output_format="csv") # 可切换为"html"
3. 定时执行配置
Linux/macOS(Cron)
编辑crontab:
crontab -e
添加以下规则(每30分钟执行一次脚本):
*/30 * * * * /usr/bin/python3 /绝对路径/你的脚本文件名.py
Windows(任务计划程序)
- 创建基本任务,触发频率设置为"每30分钟"
- 操作选择"启动程序",路径指向Python.exe,参数填写脚本的绝对路径
关键注意事项
- 分页处理:Graph API返回结果超过100条时会分页,代码已通过
@odata.nextLink自动处理 - 重复文件识别:可基于
文件名+文件大小(KB)+修改时间字段在生成的索引中筛选重复项 - 性能优化:针对未来数千级文件量,可添加异步请求逻辑,减少单线程请求耗时
- 权限验证:必须使用应用权限而非委派权限,否则无法遍历所有群组的文件
内容的提问来源于stack exchange,提问作者user3696153
相关产品推荐
相关产品推荐

