You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过脚本获取所有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(任务计划程序)

  1. 创建基本任务,触发频率设置为"每30分钟"
  2. 操作选择"启动程序",路径指向Python.exe,参数填写脚本的绝对路径

关键注意事项

  • 分页处理:Graph API返回结果超过100条时会分页,代码已通过@odata.nextLink自动处理
  • 重复文件识别:可基于文件名+文件大小(KB)+修改时间字段在生成的索引中筛选重复项
  • 性能优化:针对未来数千级文件量,可添加异步请求逻辑,减少单线程请求耗时
  • 权限验证:必须使用应用权限而非委派权限,否则无法遍历所有群组的文件

内容的提问来源于stack exchange,提问作者user3696153

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 04:08:21