使用 Microsoft Graph PowerShell 注册新应用程序


在这篇文章中,我将向您展示如何使用 Microsoft Graph PowerShell 和 Invoke-MgGraphRequest cmdlet 在 Microsoft Entra 中创建新应用程序。这使您可以创建新的应用注册,而无需额外依赖 Microsoft.Graph.Applications 模块。

要求

要在 Microsoft Graph PowerShell 中创建应用程序注册,您首先需要确保已安装 Microsoft.Graph.Authentication 模块。这允许您使用 Connect-MgGraph Invoke-MgGraphRequest cmdlet。

您还需要访问全局管理员帐户,以同意 Microsoft Graph 命令行工具应用程序所需的权限。

注册一个新的应用程序

让我们在 Microsoft Entra 中注册一个新应用程序。我们将从注册一个基本应用程序开始,然后在此基础上慢慢添加功能。首先,您必须连接到 Microsoft Graph PowerShell 并同意 Application.ReadWrite.All 权限。

Connect-MgGraph -Scope Application.ReadWrite.All

现在,我们可以定义一些基线变量,我们可以进一步构建这些变量。以下命令将使用您在 $Name 变量中定义的名称在您的租户中注册一个新应用程序。

$Name = "Application Name"
$Uri = "Beta\Applications"
$body = @{
    DisplayName = "$Name"
    signInAudience = "AzureADMyOrg"
    requiredResourceAccess = @(
    )
    servicePrincipalLockConfiguration = @{
        isEnabled = $true
        allProperties = $true
        credentialsWithUsageSign = $true
        credentialsWithUsageVerify = $true
        identifierUris = $false
        tokenEncryptionKeyId = $true
    }
}
$payload = $body | ConvertTo-Json -Depth 4
Invoke-MgGraphRequest -Method POST -Uri $Uri -ContentType "application/json" -Body $payload

如果您运行上述代码,应用程序注册将在您的租户中创建,并且仅供您的租户使用。如果您需要修改 signInAudiance 并需要额外的安全性,我还在配置中包含了 servicePrincipalLockConfiguration 属性。另请注意,我使用了 Invoke-MgGraphRequest cmdlet 而不是 New-MgApplication。这是因为我们最终会将我们的代码变成PowerShell函数,并且我想删除对除身份验证模块之外的所有模块的依赖关系。您可以在此处阅读有关该命令的更多信息:如何将 Invoke-MgGraphRequest 与 PowerShell 结合使用

在接下来的几节中,我们将通过配置进一步的应用程序设置来构建上述代码。

添加重定向 URI

重定向 URI 是用户成功授权应用程序后将发送到的位置。要在创建时向应用程序添加重定向 URI,请将以下代码添加到请求正文中:

publicClient = @{
    redirectUris = @(
        "http://localhost"
    )
}

这会将位置为 http://localhost移动和桌面应用程序重定向 URI 添加到您的应用程序。这是创建可通过 Microsoft Grah PowerShell 连接的应用程序所需的配置。

添加权限

您还可以使用以下代码块在创建时向应用程序添加权限。在本例中,00000003-0000-0000-c000-000000000000 代表 Microsoft Graph 资源,resourceAccess 数组中的每个哈希表代表一个具体许可。

requiredResourceAccess = @(
    @{
        resourceAppId = "00000003-0000-0000-c000-000000000000"
        resourceAccess = @(
        @{
          id ="ebfcd32b-babb-40f4-a14b-42706e83bd28"
          type = "Scope"
        }
        @{
          id = "e4aa47b9-9a69-4109-82ed-36ec70d85ff1"
          type = "Scope"
        }
      )
    }
  )

该类型可以是范围角色,具体取决于您要添加委派权限(范围)还是应用程序权限(角色),并且每个权限都有一个唯一的 ID。

要查看所有可用权限、ID 和范围,请使用以下命令:

Find-MgGraphPermission | Select Name, PermissionType, Id | Sort -Property Name

以编程方式添加多个权限

正如我们在上面所看到的,添加权限可能非常麻烦。正如您所看到的,它需要大量代码,特别是如果您需要一次拥有少量权限,或者需要重用脚本并每次更改权限。为了解决这个问题,我写了几行代码来为我们生成这个属性。

首先,您需要声明您需要的权限以及权限类型:

$Scope = "User.Read.All", "User.ReadWrite.All", "Group.Read.All", "Group.ReadWrite.All"
$context = "Delegated"

我已经存储了一份公开的权限列表,您需要下载该列表并将其存储在内存中:

#Download permissions list
if ($context -eq "Delegated") {
    $Permissions = Invoke-WebRequest -Method GET -Uri "https://raw.githubusercontent.com/DanielBradley1/Microsoft-Graph-PowerShell-Examples/main/Permissions/DelegatedGraphPermissions.csv" | ConvertFrom-Csv
    $Type = "Scope"
} Elseif ($context -eq "Application") {
    $Permissions = Invoke-WebRequest -Method GET -Uri "https://raw.githubusercontent.com/DanielBradley1/Microsoft-Graph-PowerShell-Examples/main/Permissions/ApplicationGraphPermissions.csv" | ConvertFrom-Csv
    $Type = "Role"
}

然后将生成一个权限集合,存储每个权限的 Id 和 Type

$resourceAccess = [System.Collections.Generic.List[Object]]::new()
Foreach ($Perm in $Scope){
    $obj = [PSCustomObject][ordered]@{
        "id" = ($Permissions | Where {$_.Name -eq $perm}).id
        "Type" = $Type
    }
    $resourceAccess.Add($obj)
}

然后,该集合被添加到临时哈希表中,该临时哈希表又被添加到请求正文的 requiredResourceAccess 属性中。

$resource = @{
    resourceAppId = "00000003-0000-0000-c000-000000000000"
    resourceAccess = $resourceAccess
}
$body.requiredResourceAccess += $resource

添加徽标

不幸的是,不支持使用 Invoke-MgGraphRequest 在创建时添加徽标。为了解决这个问题,您需要首先存储创建应用程序的输出,如下所示:

$Application = Invoke-MgGraphRequest -Method POST -Uri $Uri `
-ContentType "application/json" -Body $payload -OutputType PSObject

然后,您可以使用 PUT 方法,同时指定图像的路径和内容类型为图像。这将成功更新您的应用程序的徽标。

Invoke-MgGraphRequest -Uri "$Uri/$($Application.id)/logo" -Method PUT `
-InputFilePath "C:\Temp\images.png" -ContentType "image/png"

或者,如果您有要下载的在线托管文件,则可以使用 PowerShell 将其下载并暂时存储在本地。然后它可以用于更新应用程序,如下所示:

#Temporary image path
$imgpath = "C:\Temp\Image.png"
#Image to download
$webimage = "https://i.imgur.com/dAqRsQr.png"

#Download image
$wc = New-Object System.Net.WebClient
$wc.DownloadFile($webimage, "$imgpath")

#Update image
Invoke-MgGraphRequest -Uri "$Uri/$($Application.id)/logo" -Method PUT `
-InputFilePath $imgpath -ContentType "image/png"

#Remove temporary image
Remove-Item -path $imgpath

添加内部注释

内部注释是向其他管理员提供有关应用程序在您的环境中的原始用途、范围和使用区域的详细信息的好方法。当然,您不应该在内部注释部分中存储敏感信息,而是存储有用的信息,以帮助其他人了解您的应用程序的目的及其预期用例,这样,如果应用程序的范围偏离了其最初的意图,可以解决或更新。

要向您的应用程序添加内部注释,请将以下代码添加到您的请求正文中:

Notes = "This is a new note"

添加应用程序所有者

根据微软的文档,在 Microsoft Entra 中创建应用程序的用户自动成为该应用程序的所有者。但是,使用 Microsoft Graph PowerShell 创建应用程序时情况并非如此。相反,您必须在创建应用程序后手动定义应用程序所有者。

像我们之前看到的那样,将创建的应用程序存储在 $Application 变量中之后,使用下面的示例使用 PowerShell 添加应用程序所有者。

#Change the object Id for the user you wish to add as an owner
$owner = @{
    "@odata.id" = "https://graph.microsoft.com/v1.0/directoryObjects/387c58a2-3fea-4e8e-979d-a49469b89100"
}

Invoke-MgGraphRequest -Method POST `
-Uri "https://graph.microsoft.com/v1.0/applications/$($Application.id)/owners/`$ref" `
-ContentType "application/json" -Body $owner | ConvertTo-Json