Last active
July 13, 2023 20:56
-
-
Save SMSAgentSoftware/2d1cc4fa9718b1a8d1452b842ef34a7d to your computer and use it in GitHub Desktop.
Invokes an Intune remediations script on demand against one or more devices
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Invoke-IntuneRemediationOnDemand { | |
[CmdletBinding()] | |
Param | |
( | |
[Parameter(Mandatory=$true)] | |
[ValidateNotNull()] | |
[ValidateNotNullOrEmpty()] | |
[string[]] | |
$Computername | |
) | |
# Requires the Intune PowerShell SDK (Microsoft.Graph.Intune) | |
# MS Graph required permissions (delegated): | |
# DeviceManagementManagedDevices.Read.All | |
# DeviceManagementConfiguration.Read.All | |
# DeviceManagementManagedDevices.PrivilegedOperations.All | |
Begin | |
{ | |
$script:GraphToken = Connect-MSGraph -PassThru | |
$ProgressPreference = 'SilentlyContinue' | |
Function script:Invoke-LocalGraphRequest { | |
Param ($URL,$Headers,$Method,$Body) | |
try | |
{ | |
If ($Method -eq "POST") | |
{ | |
$WebRequest = Invoke-WebRequest -Uri $URL -Method $Method -Headers $Headers -Body $Body -ContentType "application/json" -UseBasicParsing | |
} | |
else | |
{ | |
$WebRequest = Invoke-WebRequest -Uri $URL -Method $Method -Headers $Headers -UseBasicParsing | |
} | |
} | |
catch | |
{ | |
$Response = $_ | |
$WebRequest = [PSCustomObject]@{ | |
Message = $response.Exception.Message | |
StatusCode = $response.Exception.Response.StatusCode | |
StatusDescription = $response.Exception.Response.StatusDescription | |
} | |
} | |
Return $WebRequest | |
} | |
Function Get-IntuneManagedDevices { | |
param($DeviceName) | |
$URL = "https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?`$filter=deviceName eq '$DeviceName'" | |
$headers = @{'Authorization'="Bearer " + $GraphToken} | |
$GraphRequest = Invoke-LocalGraphRequest -URL $URL -Headers $headers -Method GET | |
return $GraphRequest | |
} | |
Function Get-IntuneDeviceHealthScripts { | |
param($URL) | |
If ($null -eq $URL) | |
{ | |
$URL = "https://graph.microsoft.com/beta/deviceManagement/deviceHealthScripts" | |
} | |
$headers = @{'Authorization'="Bearer " + $GraphToken} | |
$GraphRequest = Invoke-LocalGraphRequest -URL $URL -Headers $headers -Method GET | |
return $GraphRequest | |
} | |
Function Invoke-IntuneOnDemandRemediation { | |
param($DeviceId,$RemediationId,$DeviceType) | |
if ($DeviceType -eq "CoManaged") | |
{ | |
$URL = "https://graph.microsoft.com/beta/deviceManagement/comanagedDevices('$DeviceID')/initiateOnDemandProactiveRemediation" | |
} | |
else | |
{ | |
$URL = "https://graph.microsoft.com/beta/deviceManagement/managedDevices('$DeviceID')/initiateOnDemandProactiveRemediation" | |
} | |
$headers = @{'Authorization'="Bearer " + $GraphToken} | |
$body = @{ | |
"scriptPolicyId"="$RemediationID" | |
} | ConvertTo-Json | |
$GraphRequest = Invoke-LocalGraphRequest -URL $URL -Headers $headers -Body $Body -Method POST | |
return $GraphRequest | |
} | |
# Get list of remediations | |
$result = Get-IntuneDeviceHealthScripts | |
if ($result.StatusCode -ne 200) | |
{ | |
Write-Error $result | |
break | |
} | |
# Do paging | |
$Content = $result.Content | ConvertFrom-Json | |
$ScriptList = [System.Collections.Generic.List[Object]]::new() | |
$ScriptList.AddRange($Content.value) | |
If ($null -ne $Content.'@odata.nextLink') | |
{ | |
do | |
{ | |
$result = Get-IntuneDeviceHealthScripts -URL $Content.'@odata.nextLink' | |
if ($result.StatusCode -ne 200) | |
{ | |
Write-Error $result | |
continue | |
} | |
$Content = $result.Content | ConvertFrom-Json | |
$ScriptList.AddRange($Content.value) | |
} | |
until ($null -eq $Content.'@odata.nextLink') | |
} | |
# Check we have an actual list | |
$Scripts = $ScriptList | Select -Property displayName,version,description,publisher,id | |
if ($Scripts.Count -lt 1) | |
{ | |
Write-Warning "No remediation scripts found" | |
break | |
} | |
# Prompt user to select a script | |
$script:SelectedScript = $Scripts | Sort -Property displayName | Out-GridView -Title "Select a remediation" -OutputMode Single | |
if ($null -eq $SelectedScript) | |
{ | |
Write-Error "No remediation script selected" | |
break | |
} | |
} | |
Process | |
{ | |
foreach ($Computer in $Computername) | |
{ | |
# Find managed device in Graph | |
$result = Get-IntuneManagedDevices -DeviceName "$Computer" | |
if ($result.StatusCode -ne 200) | |
{ | |
Write-Error $result | |
continue | |
} | |
# Make sure only 1 result returned | |
$Device = $result.Content | ConvertFrom-Json | Select -ExpandProperty value | |
if ($null -eq $Device) | |
{ | |
Write-Error "Device not found" | |
continue | |
} | |
if ($Device.Count -gt 1) | |
{ | |
Write-Error "Multiple devices found with the name '$Computer'. Device names must be unique." | |
continue | |
} | |
# Invoke the remediation | |
if ($Device.managementAgent -match "configurationManager") | |
{ | |
$result = Invoke-IntuneOnDemandRemediation -DeviceID $Device.id -RemediationID $SelectedScript.id -DeviceType "CoManaged" | |
} | |
else | |
{ | |
$result = Invoke-IntuneOnDemandRemediation -DeviceID $Device.id -RemediationID $SelectedScript.id | |
} | |
If ($result.StatusCode -ne 204) | |
{ | |
# Try the other managament agent option | |
if ($Device.managementAgent -match "configurationManager") | |
{ | |
$result = Invoke-IntuneOnDemandRemediation -DeviceID $Device.id -RemediationID $SelectedScript.id | |
} | |
else | |
{ | |
$result = Invoke-IntuneOnDemandRemediation -DeviceID $Device.id -RemediationID $SelectedScript.id -DeviceType "CoManaged" | |
} | |
If ($result.StatusCode -ne 204) | |
{ | |
Write-Error $result | |
continue | |
} | |
} | |
} | |
} | |
End | |
{ | |
} | |
} | |
# Example usage | |
Invoke-IntuneRemediationOnDemand -Computername "PC001","PC002" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment