Microsoft Intune Graph API gebruiken met Visual Studio Code en een Entra Registered App
- Pascal

- 19 feb
- 13 minuten om te lezen
Bijgewerkt op: 12 mrt

Introductie
In deze blog leg ik uit hoe je met Microsoft Visual Studio Code toegang kunt krijgen tot Microsoft Intune via Graph API en daarmee, een back-up kunt maken en configuraties kunt uploaden. Daarbij maak ik gebruik van een Entra Registered App, waarbij ik geen gebruik maak van een client secret, maar een veiliger alternatief: een self-signed certificate.
Stap 1: Het creëren van een self-signed certificate
Een self-signed certificate maakt het mogelijk om veilig verbinding te maken met een Entra Registered App vanaf een specifiek werkstation. Dit biedt een veiliger alternatief voor het gebruik van een client secret, omdat:
Een client secret eenvoudig in scripts als plain text kan worden opgeslagen, wat een beveiligingsrisico vormt.
Een self-signed certificate beperkt de toegang tot één specifieke werkplek, in tegenstelling tot een client secret dat overal kan worden gebruikt.
Het certificaat niet exporteer baar is met private keys, waardoor het moeilijker wordt om het op een andere werkplek te gebruiken.
PowerShell-script voor het genereren van een self-signed certificate
Onderstaand PowerShell-script maakt een self-signed certificate aan en slaat het op in C:\temp\certs\{subjectnaam}. Pas de SubjectName (PowerShell script) aan zodat het certificaat een duidelijke omschrijving krijgt.
### PowerShell Script: Secure Self-Signed Certificate for Azure App Registration
# This script creates a secure self-signed certificate for Azure App Registration.
# It uses a strong cryptographic algorithm and ensures that the private key is non-exportable.
# - Uses RSA with a key length of 4096 bits.
# - Marks the private key as non-exportable to enhance security.
# - Specifies KeySpec as Signature to avoid key duplication.
# - Sets a reasonable validity period (24 months by default).
# - Run this script with administrative privileges.
# - The certificate will be stored in the Local Machine's Personal store.
# - Use the certificate thumbprint in Azure App Registration.
#
param (
[string]$subjectName = "{Name of cert}",
[string]$certStore = "LocalMachine",
[int]$validityPeriod = 24
)
$certParams = @{
Subject = "CN=$subjectName"
CertStoreLocation = "Cert:\CurrentUser\My"
KeyAlgorithm = "RSA"
KeyLength = 4096
KeyExportPolicy = "NonExportable"
KeySpec = "Signature"
NotAfter = (Get-Date).AddMonths($validityPeriod)
Provider = "Microsoft Enhanced RSA and AES Cryptographic Provider"
}
$Cert = New-SelfSignedCertificate @certParams
Write-Output "Certificate Created Successfully: $($Cert.Thumbprint)"
# Ask user if they want to export the certificate
$exportChoice = Read-Host "Do you want to export the certificate? (Yes/No)"
if ($exportChoice -eq "Yes") {
$certFolder = "C:\temp\certs"
if (!(Test-Path -Path $certFolder)) {
New-Item -ItemType Directory -Path $certFolder -Force | Out-Null
}
$certExport = @{
Cert = $Cert
FilePath = "$($certFolder)\$($subjectName).cer"
}
Export-Certificate @certExport
Write-Output "Certificate exported successfully to $($certExport.FilePath)"
} else {
Write-Output "Certificate export skipped."
}Gebruik Visual Studio Code als Administrator

Met dit certificaat kunnen we de volgende stap zetten: het registreren van een App Registration in Entra, en het configureren van de juiste rechten.
Stap 2: Entra App Registratie en configuratie
In deze stap gaan we een Entra App registratie aanmaken, enkele API-rechten geven en ons self-signed certificaat koppelen.
Ga naar de Azure portaal (https://portal.azure.com) en druk op Microsoft Entra ID. In Entra ID gaan we naar App Registration gevolgd door New registration. Geef een logische naam aan de app registration (in mijn voorbeeld is dat Demo_Nubes365_API_Intune) en druk op Register.
Als de app is aangemaakt gaan we naar API Permissions. Afhankelijk van wat je wilt doen, moet je rechten toevoegen. Voor deze demo heb ik de onderstaande rechten aan deze App Registration gegeven:
Application.Read.All
AuditLog.Read.All
Device.Read.All
DeviceManagementApps.ReadWrite.All
DeviceManagementConfiguration.ReadWrite.All
DeviceManagementManagedDevices.ReadWrite.All
DeviceManagementServiceConfig.ReadWrite.All
Directory.Read.All
Group.Read.All
Policy.Read.All
Policy.Read.ConditionalAccess
User.Read.All
Na het toevoegen van de rechten moet er nog wel op "Grant admin consent" worden gedrukt!

Nadat we consent hebben gegeven op de API permissions gaan we naar Certificates & secrets om de self-signed certificate toe te voegen. Onder Certificates & secrets druk op Certificates gevolgd door Upload certificate. Browse naar de locatie van het certificaat (C:\Temp\certs) en druk op het certificaat. Voeg eventueel een omschrijving eraan toe en druk op Add. Het certificaat is nu toegevoegd aan de Registered App waardoor we over kunnen gaan naar stap 3: Authenticeren met Entra App Registration en Certificaat.

Stap 3: Authentiseren met Visual Studio en Certificaat
In deze stap gaan we authentiseren via de gemaakte App Registration in combinatie met Visual Studio Code.
Voordat we dit kunnen doen, moeten er wel een aantal PowerShell-modules worden geïnstalleerd. Deze modules kunnen het best in PowerShell zelf worden geïnstalleerd en worden geïmporteerd voordat VS Code wordt gebruikt.
De modules die geïnstalleerd moeten worden zijn:
Install-Module -Name MSAL.PS -Force
Import-Module MSAL.PS
Install-Module -Name Microsoft.Graph -ForceNaast de PowerShell modules moet ook in Visual Studio Code de Extension REST Client worden toegevoegd:

Nu we alle benodigde componenten hebben ingesteld – waaronder de PowerShell-modules, app-registratie, VS Code-extensie en het certificaat – is het tijd om te testen of we succesvol kunnen authentiseren. Dit doen we met behulp van het onderstaande PowerShell-script:
<#
.SYNOPSIS
Authenticate using an AAD app registration and a certificate to obtain a token
.DESCRIPTION
After generating a self-signed certificate, use the MSAL.PS module to authenticate to Azure AD and obtain a token.
.EXAMPLE
.\Get-CBATokenMSAL.ps1 -tenantId "{tenantID" -applicationId "{clientID}x" -certStore "CurrentUser" -thumbprint "{thumbprint}"
.NOTES
Requires MSAL.PS module // Install-Module MSAL.PS -Scope CurrentUser
#>
# Define variables at the top
$certStore = "LocalMachine"
$thumbprint = "{thumbprint}"
$tenantId = "{tenantID}"
$applicationId = "{ClientID}"
function Set-Certificate {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[ValidateSet('LocalMachine', 'CurrentUser')]
[string]$certStore,
[string]$thumbprint,
[string]$tenantId,
[string]$applicationId
)
# Function body here
}
Function Get-Token {
# Connect to Graph and authenticate with the certificate
Import-Module -Name MSAL.PS -Force
$connectStringSplat = @{
TenantId = $tenantId
ClientId = $applicationId
ClientCertificate = Get-ChildItem -Path "Cert:\$($certStore)\My\$($thumbprint)"
}
$authToken = Get-MsalToken @connectStringSplat
Return $authToken
}
# Get token
Get-Token -tenantId $tenantId -applicationId $applicationId -certStore $certStore -thumbprint $thumbprint
Met het uitvoeren van dit script zou een soortgelijk resultaat zichtbaar moeten zijn:

Stap 4: Backup van Microsoft Intune
Nu we succesvol kunnen authenticeren met de Graph API, kunnen we beginnen met het uitvoeren van nuttige taken. Een daarvan is het maken van een backup van Microsoft Intune.
In dit voorbeeld leggen we de configuratie van verschillende Intune-onderdelen vast, waaronder:
Device Configuration
Compliance Policies
Apps
Scripts
Remediations
Conditional Access
Onderstaand PowerShell-script voert de backup uit en slaat alle configuraties op in C:\BackupIntune. De gegevens worden opgeslagen als RAW JSON in gestructureerde mappen, en daarnaast wordt een Markdown-bestand gegenereerd dat de datum en tijd van de backup registreert.
# 📌 **Intune Configuration Backup Script**
#
# This script backs up Microsoft Intune **Device Configurations** and **Compliance Policies**.
# It retrieves policies via **Microsoft Graph API** using certificate-based authentication.
#
# ---
# ## 🔹 **Prerequisites**
# - An **Azure AD App Registration** with **certificate-based authentication**.
# - The app must have the following **API Permissions**:
# - `DeviceManagementConfiguration.Read.All`
# - `DeviceManagementConfiguration.ReadWrite.All`
# - A valid **.PFX certificate** installed in the **Local Machine** store.
# - **Microsoft Graph PowerShell SDK** installed (`Install-Module Microsoft.Graph`).
#
# ---
# ## 🔹 **Script Overview**
# - Connects to **Microsoft Graph API** with a certificate.
# - Backs up:
# - **Device Configurations** to `C:\backupIntune\DeviceConfigurations`
# - **Compliance Policies** to `C:\backupIntune\CompliancePolicies`
# - and more...
# - Saves each configuration as a **separate JSON file**.
# - Generates a **Markdown report** with timestamps.
#
# ---
# ## 🔹 **How to Use**
# 1. Update the following variables:
# - `$tenantId`: **Azure Tenant ID**
# - `$clientId`: **Azure App Registration Client ID**
# - `$thumbprint`: **Thumbprint of your installed certificate**
# 2. Run the script in **PowerShell (Admin)**.
#
# ---
# ## 🔹 **Output**
# - JSON files for each **Device Configuration** and **Compliance Policy**.
# - A Markdown report with timestamp and backup details.
#
# 🚀 **Ready to automate your Intune backups!**
#
# ---
# Define variables
$tenantId = "{tenantID}"
$clientId = "{clientID}"
$thumbprint = "{thumbprint}"
$certStore = "LocalMachine"
$backupFolder = "C:\BackupIntune"
# Create the backup folder if it doesn't exist
if (-not (Test-Path -Path $backupFolder)) {
New-Item -Path $backupFolder -ItemType Directory
}
# Define subfolders for each Intune category
$folders = @(
"DeviceConfigurations",
"CompliancePolicies",
"Intents",
"Apps",
"Scripts",
"Remediations",
"FeatureUpdates",
"Filters",
"ConditionalAccess"
#"AuditEvents"
)
# Create each backup subfolder if it doesn't exist
foreach ($folder in $folders) {
$path = Join-Path -Path $backupFolder -ChildPath $folder
if (-not (Test-Path -Path $path)) {
New-Item -Path $path -ItemType Directory
}
}
# Define the Graph API endpoints
$apiEndpoints = @{
"DeviceConfigurations" = "https://graph.microsoft.com/v1.0/deviceManagement/deviceConfigurations"
"CompliancePolicies" = "https://graph.microsoft.com/v1.0/deviceManagement/deviceCompliancePolicies"
"Intents" = "https://graph.microsoft.com/beta/deviceManagement/Intents"
"Apps" = "https://graph.microsoft.com/v1.0/deviceAppManagement/mobileApps"
"Scripts" = "https://graph.microsoft.com/beta/deviceManagement/deviceManagementScripts"
"Remediations" = "https://graph.microsoft.com/beta/deviceManagement/deviceHealthScripts"
"FeatureUpdates" = "https://graph.microsoft.com/beta/deviceManagement/windowsFeatureUpdateProfiles"
"Filters" = "https://graph.microsoft.com/beta/deviceManagement/assignmentFilters"
"ConditionalAccess" = "https://graph.microsoft.com/beta/identity/conditionalAccess/policies"
#"AuditEvents" = "https://graph.microsoft.com/beta/deviceManagement/auditEvents"
}
# Get the certificate from the specified store
$certificate = Get-Item -Path "Cert:\$certStore\My\$thumbprint"
# Get access token using MSAL
$token = Get-MsalToken -TenantId $tenantId -ClientId $clientId -ClientCertificate $certificate
# Get the Access Token from the result
$accessToken = $token.AccessToken
# Define API headers
$headers = @{
"Authorization" = "Bearer $accessToken"
"Content-Type" = "application/json"
}
# Function to create Markdown header for each run
function New-MarkdownHeader {
$dateTime = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$markdownHeader = @"
# Intune Backup Report
- **Date and Time**: $dateTime
- **Backup Path**: $backupFolder
- **Backed Up Items**:
- Device Configurations
- Compliance Policies
- Intents
- Apps (Managed, Win32)
- Scripts (Device/User)
- Remediations (Proactive Remediations)
- Managed Updates (Update Rings)
- Filters
- Conditional Access Policies
"@
return $markdownHeader
}
# Function to retrieve and save configurations
function Get-ConfigurationBackup {
param (
[string]$url,
[string]$configType
)
# Send the request to download configurations from Intune
$response = Invoke-RestMethod -Uri $url -Headers $headers -Method GET
# Check if the response contains any configurations
if ($response.value -and $response.value.Count -gt 0) {
# Get the backup folder path for this category
$backupPath = Join-Path -Path $backupFolder -ChildPath $configType
# Iterate through each configuration and save it as a separate JSON file
foreach ($config in $response.value) {
# Ensure DisplayName is safe for filenames (replace invalid characters)
$displayName = $config.displayName -replace '[\\/:*?"<>|]', '_'
# Define the timestamp for uniqueness
$timestamp = (Get-Date).ToString("yyyyMMdd-HHmmss")
# Define the output file path
$outputFilePath = Join-Path -Path $backupPath -ChildPath "$displayName-$timestamp.json"
# Convert the configuration to JSON and save to the file
$config | ConvertTo-Json -Depth 10 | Out-File -FilePath $outputFilePath
Write-Host "$configType backup completed for DisplayName: $($config.displayName). File saved to: $outputFilePath"
}
} else {
Write-Warning "No $configType configurations found to backup. Skipping."
}
}
# Save Markdown report
$markdownHeader = New-MarkdownHeader
$markdownFilePath = Join-Path -Path $backupFolder -ChildPath "Backup_Report_$((Get-Date).ToString('yyyyMMdd-HHmmss')).md"
$markdownHeader | Out-File -FilePath $markdownFilePath
Write-Host "Markdown report saved: $markdownFilePath"
# Iterate over all API endpoints and back up configurations
foreach ($configType in $apiEndpoints.Keys) {
Get-ConfigurationBackup -url $apiEndpoints[$configType] -configType $configType
}
Write-Host "Intune backup completed successfully!"
Na het uitvoeren van het script zou een soortgelijk resultaat zichtbaar moeten zijn:

Ja, na het succesvol uitvoeren van het script zouden de backup-bestanden opgeslagen moeten zijn in de map C:\BackupIntune. De bestanden worden per categorie gestructureerd in submappen en opgeslagen als RAW JSON-bestanden. Daarnaast wordt er een Markdown-bestand gegenereerd dat de datum en tijd van de backup bevat.

Nu we de basis onder de knie hebben, kunnen we nog veel meer interessante en krachtige dingen doen. Een goed voorbeeld hiervan is het ophalen van auditlogs.Dit kan handig zijn voor monitoring, beveiliging of compliance-doeleinden.
Met onderstaand script haal je moeiteloos alle auditlogs op:
# Script to List Changes Made to Microsoft Intune Using App Registration with Self-Signed Certificate
## Prerequisites
#1. **App Registration in Azure AD**: Create an app registration and upload the self-signed certificate.
#2. **Permissions**: Ensure the app has the following required permissions to read Intune audit logs:
# - `AuditLog.Read.All`
#3. **Install the MSAL.PS Module**: This module is required to handle authentication using a certificate. It can be installed via PowerShell.
## Description
#This PowerShell script authenticates to Microsoft Graph using an app registration with a self-signed certificate and lists changes made to Microsoft Intune. The script uses the `directoryAudits` API to fetch audit logs and displays key information about each change, such as the change ID, activity date, user, and activity details.
## How to Use
#1. Replace the placeholders for your **tenant ID**, **client ID**, and **certificate thumbprint**.
#2. Ensure the app registration has the necessary permissions to access the audit logs.
#3. Run the script in PowerShell or Visual Studio Code (VS Code). If using VS Code, ensure the PowerShell extension is installed for enhanced syntax highlighting and linting.
## Outputs
#- Displays the details of changes made to Intune, such as:
# - **Change ID**
# - **Activity Date**
# - **User**
# - **Activity**
# - **Target Resource**
#- Optionally exports the data to a CSV file (`IntuneChanges.csv`) for further analysis.
#---
#```powershell
# Step 1: Define variables for certificate and authentication
$certStore = "LocalMachine"
$thumbprint = "<tumbprint>"
$tenantId = "<tenantID>"
$applicationId = "<ClientID>"
$graphApiEndpoint = "https://graph.microsoft.com/v1.0/auditLogs/directoryAudits"
# Step 2: Define the Set-Certificate function to handle certificate-based authentication
function Set-Certificate {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[ValidateSet('LocalMachine', 'CurrentUser')]
[string]$certStore,
[string]$thumbprint,
[string]$tenantId,
[string]$applicationId
)
# Import MSAL.PS module
Import-Module -Name MSAL.PS -Force
# Define the connection string for MSAL token retrieval
$connectStringSplat = @{
TenantId = $tenantId
ClientId = $applicationId
ClientCertificate = Get-Item -Path "Cert:\$($certStore)\My\$($thumbprint)"
}
# Get the authentication token using MSAL.PS
$authToken = Get-MsalToken @connectStringSplat
Return $authToken
}
# Step 3: Define the Get-Token function to retrieve the token
Function Get-Token {
param (
[string]$tenantId,
[string]$applicationId,
[string]$certStore,
[string]$thumbprint
)
# Get token using Set-Certificate function
$authToken = Set-Certificate -tenantId $tenantId -applicationId $applicationId -certStore $certStore -thumbprint $thumbprint
Return $authToken
}
# Step 4: Get the token
$token = Get-Token -tenantId $tenantId -applicationId $applicationId -certStore $certStore -thumbprint $thumbprint
# Step 5: Use the token to make a GET request to the Microsoft Graph API to list the changes
$headers = @{
"Authorization" = "Bearer $($token.AccessToken)"
"Content-Type" = "application/json"
}
# Step 6: Get the audit logs for Intune changes
$response = Invoke-RestMethod -Uri $graphApiEndpoint -Headers $headers -Method Get
# Step 7: Display the changes
$response.value | ForEach-Object {
Write-Host "Change ID: $($_.id)"
Write-Host "Activity Date: $($_.activityDateTime)"
Write-Host "User: $($_.initiatedBy.user.displayName)"
Write-Host "Activity: $($_.activityDisplayName)"
Write-Host "Target: $($_.targetResources.displayName)"
Write-Host "-------------------------------------"
}
# Step 8: Optional: Output the data to a file
$response.value | Export-Csv -Path "IntuneChanges.csv" -NoTypeInformationEen functie die ik zelf enorm handig vind, is het ophalen van alle Entra ID App Registraties. Hiermee krijg je in één overzicht alle certificaten en details in een CSV-bestand, waardoor je eenvoudig inzicht hebt in de status en geldigheid van je applicaties.
# Script to List Azure AD App Registrations and Certificate Expiration Dates
## Prerequisites
#1. **App Registration in Azure AD**: The app registration used for authentication must have the required permissions, such as `Application.Read.All` to read application and certificate details.
#2. **Install the MSAL.PS Module**: This module is required to handle authentication using a certificate. It can be installed via PowerShell.
## Description
#This PowerShell script authenticates to Microsoft Graph using an app registration with a self-signed certificate. It retrieves a list of all app registrations in your Azure AD tenant and displays the expiration dates of their associated certificates.
## Outputs
#- A list of Azure AD app registrations.
#- The certificate thumbprint and expiration date for each app registration.
#- Optionally, export the data to a CSV file (`AppRegistrationsWithCerts.csv`) for further analysis.
#---
#```powershell
# Step 1: Define variables for certificate and authentication
$certStore = "LocalMachine"
$thumbprint = "<thumbprint>"
$tenantId = "<tenantID>"
$applicationId = "<ClientID>"
$graphApiEndpoint = "https://graph.microsoft.com/v1.0/applications"
# Step 2: Define the Set-Certificate function to handle certificate-based authentication
function Set-Certificate {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[ValidateSet('LocalMachine', 'CurrentUser')]
[string]$certStore,
[string]$thumbprint,
[string]$tenantId,
[string]$applicationId
)
# Import MSAL.PS module
Import-Module -Name MSAL.PS -Force
# Define the connection string for MSAL token retrieval
$connectStringSplat = @{
TenantId = $tenantId
ClientId = $applicationId
ClientCertificate = Get-Item -Path "Cert:\$($certStore)\My\$($thumbprint)"
}
# Get the authentication token using MSAL.PS
$authToken = Get-MsalToken @connectStringSplat
Return $authToken
}
# Step 3: Define the Get-Token function to retrieve the token
Function Get-Token {
param (
[string]$tenantId,
[string]$applicationId,
[string]$certStore,
[string]$thumbprint
)
# Get token using Set-Certificate function
$authToken = Set-Certificate -tenantId $tenantId -applicationId $applicationId -certStore $certStore -thumbprint $thumbprint
Return $authToken
}
# Step 4: Get the token
$token = Get-Token -tenantId $tenantId -applicationId $applicationId -certStore $certStore -thumbprint $thumbprint
# Step 5: Use the token to make a GET request to the Microsoft Graph API to list all app registrations
$headers = @{
"Authorization" = "Bearer $($token.AccessToken)"
"Content-Type" = "application/json"
}
# Step 6: Get the app registrations
$response = Invoke-RestMethod -Uri $graphApiEndpoint -Headers $headers -Method Get
# Step 7: Process each app registration and fetch certificate details
$applicationsWithCerts = @()
foreach ($app in $response.value) {
$appName = $app.displayName
$appId = $app.appId
$certificates = $app.keyCredentials
foreach ($cert in $certificates) {
$thumbprint = $cert.keyId
$expirationDate = $cert.endDate
# Store the certificate info
$applicationsWithCerts += [PSCustomObject]@{
ApplicationName = $appName
ApplicationId = $appId
CertificateThumbprint = $thumbprint
CertificateExpirationDate = $expirationDate
}
}
}
# Step 8: Display the results
$applicationsWithCerts | Format-Table -Property ApplicationName, ApplicationId, CertificateThumbprint, CertificateExpirationDate
# Step 9: Optional: Output the data to a CSV file
$applicationsWithCerts | Export-Csv -Path "AppRegistrationsWithCerts.csv" -NoTypeInformation
Stap 4: Upload JSON naar Intune
Naast het ophalen van informatie via Microsoft Graph, kunnen we ook configuraties naar Intune pushen met een POST-request. Net zoals we configuraties kunnen back-uppen in JSON-formaat, kunnen we deze JSON-bestanden ook direct naar Intune uploaden. Hoewel er verschillende kant-en-klare oplossingen beschikbaar zijn, is het interessant en waardevol om te begrijpen hoe je dit zelf kunt doen.
Werken met JSON-configuraties
Bij het uploaden van configuraties maken we gebruik van JSON-bestanden, die verchillende API Endpoints (URI) hebben. Als voorbeeld gebruik ik de Intune Baselines die zijn samengesteld door James Robinson. Deze baselines bevatten zorgvuldig geconfigureerde JSON-bestanden en kunnen worden gedownload via zijn GitHub-pagina:
In dit voorbeeld werk ik met de baseline "iOS - Baseline - BYOD - App Protection.json". Dit bestand download ik van GitHub en pas het vervolgens toe met het onderstaande script:
# 📌 **Upload JSON Configurations to Microsoft Intune via Graph API**
#
# This script uploads JSON configuration policies to Intune using
# Microsoft Graph API with certificate-based authentication.
#
# ## 🔹 **Prerequisites**
# - An **Azure AD App Registration** with **certificate-based authentication**.
# - The app must have the following **API Permissions**:
# - `DeviceManagementConfiguration.ReadWrite.All`
# - A valid **.PFX certificate** installed in the **Local Machine** store.
# - The JSON configuration files to be uploaded.
#
# ## 🔹 **How to Use**
# 1. Modify the script to set:
# - `$clientId` (Azure AD App Registration Client ID)
# - `$tenantId` (Azure Tenant ID)
# - `$certThumbprint` (Thumbprint of your installed certificate)
# 2. Save your JSON file locally and set its path in `$jsonFilePath`
# 3. Run the script in **PowerShell (Admin)**
#
# ---
param (
[string]$clientId = "<ClientID>",
[string]$tenantId = "<tenantID>",
[string]$certThumbprint = "<Thumbprint>",
[string]$jsonFilePath = "C:\Software\Blog\iOS - Baseline - BYOD - App Protection.json"
)
# Load the certificate from the Local Machine store
$cert = Get-Item "Cert:\LocalMachine\My\$certThumbprint"
if (-not $cert) {
Write-Host "❌ Certificate not found. Check the thumbprint and try again." -ForegroundColor Red
exit 1
}
# Generate JWT Client Assertion
$now = [DateTimeOffset]::Now.ToUnixTimeSeconds()
$exp = $now + (60 * 10) # Token valid for 10 minutes
$header = @{
alg = "RS256"
typ = "JWT"
x5t = [System.Convert]::ToBase64String($cert.GetCertHash())
}
$payload = @{
aud = "https://login.microsoftonline.com/$tenantId/oauth2/token"
iss = $clientId
sub = $clientId
jti = [Guid]::NewGuid().ToString()
iat = $now
exp = $exp
}
$jwtHeader = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json -Compress $header)))
$jwtPayload = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json -Compress $payload)))
$jwt = "$jwtHeader.$jwtPayload"
$signature = [System.Convert]::ToBase64String(
$cert.PrivateKey.SignData(
[System.Text.Encoding]::UTF8.GetBytes($jwt),
[Security.Cryptography.HashAlgorithmName]::SHA256,
[Security.Cryptography.RSASignaturePadding]::Pkcs1
)
)
$assertion = "$jwt.$signature"
# Get Access Token from Microsoft Identity Platform
$tokenRequest = @{
grant_type = "client_credentials"
client_id = $clientId
client_assertion = $assertion
client_assertion_type = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
scope = "https://graph.microsoft.com/.default"
}
$tokenResponse = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" -Method Post -Body $tokenRequest
$accessToken = $tokenResponse.access_token
if (-not $accessToken) {
Write-Host "❌ Failed to obtain access token. Check authentication settings." -ForegroundColor Red
exit 1
}
# Read JSON Configuration
$jsonContent = Get-Content -Raw -Path $jsonFilePath
if (-not $jsonContent) {
Write-Host "❌ JSON file is empty or could not be read. Check the file path." -ForegroundColor Red
exit 1
}
# Set API endpoint for iOS Managed App Protection
$uri = "https://graph.microsoft.com/beta/deviceAppManagement/iosManagedAppProtections"
# Upload Configuration
$headers = @{
Authorization = "Bearer $accessToken"
"Content-Type" = "application/json"
}
try {
$response = Invoke-RestMethod -Uri $uri -Headers $headers -Method Post -Body $jsonContent
Write-Host "✅ Configuration uploaded successfully: $($response.id)" -ForegroundColor Green
}
catch {
Write-Host "❌ Error uploading configuration: $_" -ForegroundColor Red
}Dit is misschien een wat langere blog, maar ik hoop dat het je waardevolle inzichten heeft gegeven en je verder helpt in je werk met Visual Studio Code, Intune en Graph API.




Opmerkingen