-
Notifications
You must be signed in to change notification settings - Fork 124
Description
I created a script to import all of the remediation scripts into Intune.
<#
.SYNOPSIS
Bulk imports JayRHa EndpointAnalytics remediation scripts into Intune via Graph API.
.NOTES
Requires:
- App registration with DeviceManagementScripts.ReadWrite.All
- The repo cloned/downloaded locally
- MSAL.PS module (Install-Module MSAL.PS)
- Create C:\Temp\EndpointAnalyticsRemediationScripts
.HOW TO IMPORT ONLY SELECTED SCRIPTS
By default this script imports every folder in the repo. If you only want
specific scripts, you have three options:
OPTION 1 — Delete the folders you don't want before running
Simply delete any folders from C:\Temp\EndpointAnalyticsRemediationScripts
that you don't want imported. The script only reads what's there.
OPTION 2 — Point $RepoPath at a subfolder copy
Create a new folder like C:\Temp\MySelectedScripts, copy only the
script folders you want into it, then set:
$RepoPath = "C:\Temp\MySelectedScripts"
OPTION 3 — Use an allowlist in the script (uncomment the block below)
Add the exact folder names you want to $AllowList, then uncomment
the Where-Object filter line in the LOOP FOLDERS section.
$AllowList = @(
"Activate-Numlock",
"Check-DiskHealth",
"Clear-BrowserCache"
)
Then in the LOOP FOLDERS section, change the $ScriptFolders line to:
$ScriptFolders = Get-ChildItem -Path $RepoPath -Directory |
Where-Object { $_.Name -notmatch "^0 -|^\.git|^_" } |
Where-Object { $AllowList -contains $_.Name }
#>
─── CONFIG ────────────────────────────────────────────────────────────────────
$TenantId = "tenant ID" # Add you applications Tenant ID
$ClientId = "client ID" # Add you applications Client ID
$ClientSecret = "secret" # add you client secret or use cert auth
Path to the cloned repo root
$RepoPath = "C:\Temp\EndpointAnalyticsRemediationScripts"
Publisher name that will show in Intune
$Publisher = "AC"
───────────────────────────────────────────────────────────────────────────────
─── GET ACCESS TOKEN ──────────────────────────────────────────────────────────
$TokenBody = @{
grant_type = "client_credentials"
client_id = $ClientId
client_secret = $ClientSecret
scope = "https://graph.microsoft.com/.default"
}
Write-Host "Getting access token..." -ForegroundColor Cyan
$TokenResponse = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token"
-Method POST `
-Body $TokenBody
$AccessToken = $TokenResponse.access_token
$Headers = @{
Authorization = "Bearer $AccessToken"
"Content-Type" = "application/json"
}
Write-Host "Token acquired." -ForegroundColor Green
───────────────────────────────────────────────────────────────────────────────
─── LOOP FOLDERS ──────────────────────────────────────────────────────────────
$ScriptFolders = Get-ChildItem -Path $RepoPath -Directory |
Where-Object { $.Name -notmatch "^0 -|^.git|^" } # skip template/git folders
$Imported = 0
$Skipped = 0
$Failed = 0
foreach ($Folder in $ScriptFolders) {
# Find detection script — filename must contain "Detect"
$DetectFile = Get-ChildItem -Path $Folder.FullName -Filter "*.ps1" |
Where-Object { $_.Name -match "Detect" } |
Select-Object -First 1
if (-not $DetectFile) {
Write-Warning " No detection script found in: $($Folder.Name) — skipping."
$Skipped++
continue
}
# Find remediation script — filename must contain "Remediat"
$RemediateFile = Get-ChildItem -Path $Folder.FullName -Filter "*.ps1" |
Where-Object { $_.Name -match "Remediat" } |
Select-Object -First 1
# Base64 encode script content (Intune requires this)
$DetectContent = [Convert]::ToBase64String(
[System.Text.Encoding]::UTF8.GetBytes(
(Get-Content -Path $DetectFile.FullName -Raw)
)
)
$RemediateContent = if ($RemediateFile) {
[Convert]::ToBase64String(
[System.Text.Encoding]::UTF8.GetBytes(
(Get-Content -Path $RemediateFile.FullName -Raw)
)
)
} else {
$null
}
# Build the request body
$Body = @{
displayName = $Folder.Name
description = "Imported from JayRHa/EndpointAnalyticsRemediationScripts"
publisher = $Publisher
runAs32Bit = $false
runAsAccount = "system"
enforceSignatureCheck = $false
detectionScriptContent = $DetectContent
}
if ($RemediateContent) {
$Body.remediationScriptContent = $RemediateContent
}
# POST to Graph API
try {
Write-Host "Importing: $($Folder.Name)" -ForegroundColor Yellow
$Result = Invoke-RestMethod `
-Uri "https://graph.microsoft.com/beta/deviceManagement/deviceHealthScripts" `
-Method POST `
-Headers $Headers `
-Body ($Body | ConvertTo-Json -Depth 5)
Write-Host " Created: $($Result.id)" -ForegroundColor Green
$Imported++
}
catch {
Write-Warning " FAILED: $($Folder.Name) — $($_.Exception.Message)"
$Failed++
}
# Small delay to avoid throttling
Start-Sleep -Milliseconds 500
}
─── SUMMARY ───────────────────────────────────────────────────────────────────
Write-Host "`n──────────────────────────────────" -ForegroundColor Cyan
Write-Host "Done." -ForegroundColor Cyan
Write-Host " Imported : $Imported"
Write-Host " Skipped : $Skipped (no detection script found)"
Write-Host " Failed : $Failed"
Write-Host "──────────────────────────────────" -ForegroundColor Cyan