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

如何用MSGraph PowerShell按UPN/显示名下载Azure用户照片

解决方案:用MS Graph PowerShell按UPN/显示名下载Azure AD用户照片

核心问题分析

你之前用Get-MgGroupMember时出现文件名空值,是因为该命令默认返回DirectoryObject类型对象,不会自动包含UserPrincipalName和DisplayName属性,必须显式指定或直接获取完整用户对象。以下是可直接复用的解决方案:

完整脚本示例

# 连接MS Graph(需User.Read.All和GroupMember.Read.All权限)
Connect-MgGraph -Scopes "User.Read.All", "GroupMember.Read.All"

# 获取Staff组ID
$staffGroup = Get-MgGroup -Filter "displayName eq 'Staff'" -Select Id
if (-not $staffGroup) {
    Write-Error "未找到名为Staff的组"
    exit
}
$groupId = $staffGroup.Id

# 获取Staff组内有照片的用户,同时提取UPN、显示名和用户ID
$usersWithPhoto = Get-MgGroupMember -GroupId $groupId -All `
    -Select "Id", "UserPrincipalName", "DisplayName" `
    | Where-Object { $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.user' } `
    | ForEach-Object {
        # 提前验证用户是否有照片,避免下载报错
        $hasPhoto = $null
        try {
            Get-MgUserPhoto -UserId $_.Id -ErrorAction Stop
            $hasPhoto = $true
        } catch {
            $hasPhoto = $false
        }
        if ($hasPhoto) { $_ }
    }

# 设置照片下载路径
$downloadPath = "C:\ADPhotos"
if (-not (Test-Path $downloadPath)) { New-Item -Path $downloadPath -ItemType Directory | Out-Null }

# 遍历下载照片,按UPN命名(可替换为DisplayName)
foreach ($user in $usersWithPhoto) {
    # 替换文件名中的非法字符,防止保存失败
    $safeFileName = $user.UserPrincipalName -replace '[\\/:*?"<>|]', '_'
    $filePath = Join-Path $downloadPath "$safeFileName.jpg"

    try {
        Get-MgUserPhotoContent -UserId $user.Id -OutFile $filePath -ErrorAction Stop
        Write-Host "成功下载:$filePath"
    } catch {
        Write-Error "下载$($user.UserPrincipalName)照片失败:$_"
    }
}

# 断开MS Graph连接
Disconnect-MgGraph

关键细节说明

  1. 属性显式指定:通过-Select参数明确要求返回UserPrincipalName和DisplayName,确保不会出现空值;同时用Where-Object筛选出纯用户类型的组成员(排除组、设备等非用户对象)。
  2. 照片存在性校验:提前用Get-MgUserPhoto验证用户是否有照片,避免无照片用户触发下载报错。
  3. 文件名合法性处理:用-replace替换UPN/显示名中的非法字符(如\ / : * ? " < > |),防止系统拒绝保存文件。
  4. 权限要求:连接Graph时必须申请User.Read.All(读取用户信息)和GroupMember.Read.All(读取组成员)权限,否则会触发访问拒绝错误。

简化写法(直接筛选目标用户)

如果不需要分步处理组成员,也可以直接通过用户筛选器一步获取符合条件的用户:

$usersWithPhoto = Get-MgUser -Filter "memberOf/any(g:g/displayName eq 'Staff') and photo ne null" `
    -Select "Id", "UserPrincipalName", "DisplayName" -All

这种方式更高效,直接从用户层面完成组归属+有照片的双重筛选,无需额外校验照片存在性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 21:53:25