Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Verwenden Sie das Grant-DefenderConsent.ps1 PowerShell-Skript, um Microsoft Defender Code bereitzustellen und eine tenant-weite Administratorzustimmung für einen Azure DevOps-Connector zu erteilen.
Kopiere das folgende Skript in eine Datei namens Grant-DefenderConsent.ps1.
Führen Sie das Skript aus.
Führe das Skript in einem der folgenden Modi aus.
Nur Bereitstellung
Melden Sie sich an und erstellen oder lösen Sie die beiden Dienstprinzipalen, ohne Zustimmung zu geben oder ein Token zu validieren:
.\Grant-DefenderConsent.ps1 -TenantId <tenant-guid> -ProvisionOnly
Versorgung und Zustimmung
Melden Sie sich an, stellen Sie die Dienstleistungsverantwortlichen bereit und erteilen Sie Ihre Zustimmung. Das ist das Standardverhalten:
.\Grant-DefenderConsent.ps1 -TenantId <tenant-guid>
Bereitstellung, Zustimmung und Tokenvalidierung
Führen Sie alle drei Stufen durch, einschließlich der Token-Validierung:
.\Grant-DefenderConsent.ps1 -TenantId <tenant-guid> -VerifyToken
PowerShell-Skript
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, Position = 0)]
[ValidatePattern('^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$')]
[string]$TenantId,
# Run only the provisioning stage (login + service principal resolve/create),
# then stop. Consent grant and token verification are skipped.
[switch]$ProvisionOnly,
[switch]$VerifyToken
)
$ErrorActionPreference = 'Stop'
if ($ProvisionOnly -and $VerifyToken) {
Write-Warning "-VerifyToken is ignored when -ProvisionOnly is specified."
}
# Constants
$FpaAppId = 'c2fd607e-fe6e-41bd-ae58-08e2f24014aa' # Microsoft Defender Code
$CliAppId = '04b07795-8ddb-461a-bbee-02f9e1bf7b46'
$ScopeValue = 'Defender.InteractiveLogin'
function Invoke-AzCli {
param([Parameter(Mandatory)][string[]]$Arguments)
$out = & az @Arguments 2>&1
if ($LASTEXITCODE -ne 0) {
throw "az $($Arguments -join ' ') failed:`n$out"
}
return $out
}
function Get-OrCreateServicePrincipal {
param([Parameter(Mandatory)][string]$AppId)
$filter = "appId eq '$AppId'"
$url = "https://graph.microsoft.com/v1.0/servicePrincipals?`$filter=$filter&`$select=id,appId,displayName"
$resp = Invoke-AzCli -Arguments @('rest','--method','GET','--url',$url) | Out-String | ConvertFrom-Json
if ($resp.value -and $resp.value.Count -gt 0) {
return $resp.value[0]
}
Write-Host "Service principal for appId $AppId not found in tenant -- creating..." -ForegroundColor Yellow
$bodyFile = New-TemporaryFile
try {
Set-Content -Path $bodyFile -Value ('{"appId":"' + $AppId + '"}') -NoNewline -Encoding utf8
$created = Invoke-AzCli -Arguments @(
'rest','--method','POST',
'--url','https://graph.microsoft.com/v1.0/servicePrincipals',
'--headers','Content-Type=application/json',
'--body',"@$bodyFile"
) | Out-String | ConvertFrom-Json
return $created
}
finally {
Remove-Item $bodyFile -ErrorAction SilentlyContinue
}
}
Write-Host "==> az login to tenant $TenantId" -ForegroundColor Cyan
& az login --tenant $TenantId --use-device-code --allow-no-subscriptions | Out-Host
if ($LASTEXITCODE -ne 0) { throw "az login failed (exit $LASTEXITCODE)" }
Write-Host "==> Resolving service principals" -ForegroundColor Cyan
$fpaSp = Get-OrCreateServicePrincipal -AppId $FpaAppId
$cliSp = Get-OrCreateServicePrincipal -AppId $CliAppId
Write-Host " FPA SP: $($fpaSp.id) ($($fpaSp.displayName))"
Write-Host " CLI SP: $($cliSp.id) ($($cliSp.displayName))"
if ($ProvisionOnly) {
Write-Host "==> -ProvisionOnly specified: skipping consent grant and token verification." -ForegroundColor Yellow
Write-Host "`nDone (provisioning only)." -ForegroundColor Green
return
}
Write-Host "==> Checking for existing oauth2PermissionGrant" -ForegroundColor Cyan
$existing = Invoke-AzCli -Arguments @(
'rest','--method','GET',
'--url',"https://graph.microsoft.com/v1.0/oauth2PermissionGrants?`$filter=clientId eq '$($cliSp.id)' and resourceId eq '$($fpaSp.id)' and consentType eq 'AllPrincipals'"
) | Out-String | ConvertFrom-Json
$match = $existing.value | Where-Object { ($_.scope -split '\s+') -contains $ScopeValue }
if ($match) {
Write-Host " Grant already exists (id $($match.id)). Skipping create." -ForegroundColor Green
$grant = $match
}
else {
Write-Host "==> Creating tenant-wide admin consent grant ($ScopeValue)" -ForegroundColor Cyan
$bodyFile = New-TemporaryFile
try {
$body = @{
clientId = $cliSp.id
consentType = 'AllPrincipals'
resourceId = $fpaSp.id
scope = $ScopeValue
} | ConvertTo-Json -Compress
Set-Content -Path $bodyFile -Value $body -NoNewline -Encoding utf8
$grant = Invoke-AzCli -Arguments @(
'rest','--method','POST',
'--url','https://graph.microsoft.com/v1.0/oauth2PermissionGrants',
'--headers','Content-Type=application/json',
'--body',"@$bodyFile"
) | Out-String | ConvertFrom-Json
}
finally {
Remove-Item $bodyFile -ErrorAction SilentlyContinue
}
Write-Host " Grant id: $($grant.id)" -ForegroundColor Green
}
if ($VerifyToken) {
Write-Host "==> Acquiring verification token" -ForegroundColor Cyan
$tok = Invoke-AzCli -Arguments @(
'account','get-access-token',
'--tenant',$TenantId,
'--scope',"$FpaAppId/$ScopeValue",
'--query','accessToken','-o','tsv'
) | Out-String
$tok = $tok.Trim()
Write-Host " Token acquired." -ForegroundColor Green
}
Write-Host "`nDone." -ForegroundColor Green