Skip to content

Import Script #110

Description

@anthonyonazure

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions