Update to version 2.3 with MgGraph support

This commit is contained in:
Petri Paavola
2024-05-10 00:24:12 +03:00
committed by GitHub
parent 80f0bf804c
commit 42a6ce37be
+230 -116
View File
@@ -1,8 +1,8 @@
<#PSScriptInfo <#PSScriptInfo
.VERSION 2.0 .VERSION 2.3
.GUID 87ef29a6-6a9f-49af-a3ba-36ed4438814d .GUID f321e845-7139-41d7-b0dd-356ea87931e3
.AUTHOR Petri.Paavola@yodamiitti.fi .AUTHOR Petri.Paavola@yodamiitti.fi
@@ -37,6 +37,7 @@ Version 2.0: Huge new feature is to create html report
Console timeline will be available for example for OOBE troubleshooting scenarios Console timeline will be available for example for OOBE troubleshooting scenarios
Added App detection events to timeline Added App detection events to timeline
Html report entries support HoverOn ToolTips which include more information Html report entries support HoverOn ToolTips which include more information
Version 2.3: Updated script to use Microsoft.Graph.Authentication module to download data from Graph API
#> #>
<# <#
@@ -75,12 +76,13 @@ Version 2.0: Huge new feature is to create html report
Senior Modern Management Principal Senior Modern Management Principal
Microsoft MVP - Windows and Devices Microsoft MVP - Windows and Devices
2023-09-26 2024-05-09
https://github.com/petripaavola/Get-IntuneManagementExtensionDiagnostics https://github.com/petripaavola/Get-IntuneManagementExtensionDiagnostics
.PARAMETER Online .PARAMETER Online
Download Powershell, Remediation and custom Compliance policy scripts to get displayName to Timeline report Download Powershell, Remediation and custom Compliance policy scripts to get displayName to Timeline report
Install Microsoft Graph module with command: Install-Module -Name Microsoft.Graph.Authentication -Scope CurrentUser
.PARAMETER LogFile .PARAMETER LogFile
Specify log file fullpath Specify log file fullpath
@@ -269,10 +271,11 @@ Param(
) )
$ScriptVersion = "2.0" $ScriptVersion = "2.3"
$TimeOutBetweenGraphAPIRequests = 300
Write-Host "Get-IntuneManagementExtensionDiagnostics.ps1 $ScriptVersion beta" -ForegroundColor Cyan Write-Host "Get-IntuneManagementExtensionDiagnostics.ps1 $ScriptVersion" -ForegroundColor Cyan
Write-Host "Author: Petri.Paavola@yodamiitti.fi / Microsoft MVP - Windows and Devices" Write-Host "Author: Petri.Paavola@yodamiitti.fi / Microsoft MVP - Windows and Devices"
Write-Host "" Write-Host ""
@@ -311,7 +314,7 @@ if($ShowLogViewerUI -or $LogViewerUI) {
# Set variables if we are in Windows Autopilot ESP (Enrollment Status Page) # Set variables automatically if we are in Windows Autopilot ESP (Enrollment Status Page)
# Idea is that user can just run the script without checking Parameters first # Idea is that user can just run the script without checking Parameters first
if($env:UserName -eq 'defaultUser0') { if($env:UserName -eq 'defaultUser0') {
@@ -323,7 +326,7 @@ if($env:UserName -eq 'defaultUser0') {
$DoNotOpenReportAutomatically = $true $DoNotOpenReportAutomatically = $true
if((-not $LogFilesFolder) -or (-not $LOGFile)) { if((-not $LogFilesFolder) -or (-not $LOGFile)) {
Write-Host "Automatically configuring parameters" Write-Host "Configuring parameters automatically"
Write-Host "Selected: All log files from default Intune IME logs folder" Write-Host "Selected: All log files from default Intune IME logs folder"
Write-Host "Selected: Do not open HTML report automatically" Write-Host "Selected: Do not open HTML report automatically"
Write-Host Write-Host
@@ -349,8 +352,10 @@ if($env:UserName -eq 'defaultUser0') {
# This will not show time selection UI # This will not show time selection UI
$AllLogEntries=$True $AllLogEntries=$True
# Not sure if this is good or bad by default so not configured by default for now # Show all entries in Timeline
#$ShowAllTimelineEvents=$True # This especially useful if some script or application hangs for a long time
# so then you can see start entry for that script or application and you know what is current running Intune deployment
$ShowAllTimelineEvents=$True
if(-not (Test-Path 'C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\IntuneManagementExtension.log')) { if(-not (Test-Path 'C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\IntuneManagementExtension.log')) {
Write-Host "Log file does not exist yet: C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\IntuneManagementExtension.log" -ForegroundColor Yellow Write-Host "Log file does not exist yet: C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\IntuneManagementExtension.log" -ForegroundColor Yellow
@@ -651,6 +656,78 @@ $Script:observedTimeLineIndexToHTMLTable=0
} }
function Invoke-MgGraphRequestGetAllPages {
param (
[Parameter(Mandatory = $true)]
[String]$uri
)
$MgGraphRequest = $null
$AllMSGraphRequest = $null
Start-Sleep -Milliseconds $TimeOutBetweenGraphAPIRequests
try {
# Save results to this variable
$allGraphAPIData = @()
do {
$MgGraphRequest = $null
$MgGraphRequest = Invoke-MgGraphRequest -Uri $uri -Method 'Get' -OutputType PSObject -ContentType "application/json"
if($MgGraphRequest) {
# Test if object has attribute named Value (whether value is null or not)
#if((Get-Member -inputobject $MgGraphRequest -name 'Value' -Membertype Properties) -and (Get-Member -inputobject $MgGraphRequest -name '@odata.context' -Membertype Properties)) {
if(Get-Member -inputobject $MgGraphRequest -name 'Value' -Membertype Properties) {
# Value property exists
$allGraphAPIData += $MgGraphRequest.Value
# Check if we have value starting https:// in attribute @odate.nextLink
# and check that $Top= parameter was NOT used. With $Top= parameter we can limit search results
# but that almost always results .nextLink being present if there is more data than specified with top
# If we specified $Top= ourselves then we don't want to fetch nextLink values
#
# So get GraphAllPages if there is valid nextlink and $Top= was NOT used in url originally
if (($MgGraphRequest.'@odata.nextLink' -like 'https://*') -and (-not ($uri.Contains('$top=')))) {
# Save nextLink url to variable and rerun do-loop
$uri = $MgGraphRequest.'@odata.nextLink'
Start-Sleep -Milliseconds $TimeOutBetweenGraphAPIRequests
# Continue to next round in Do-loop
Continue
} else {
# We dont have nextLink value OR
# $top= exists so we return what we got from first round
#return $allGraphAPIData
$uri = $null
}
} else {
# Sometimes we get results without Value-attribute (eg. getting user details)
# We will return all we got as is
# because there should not be nextLink page in this case ???
return $MgGraphRequest
}
} else {
# Invoke-MGGraphRequest failed so we return false
return $null
}
} while ($uri) # Always run once and continue if there is nextLink value
# We should not end here but just in case
return $allGraphAPIData
} catch {
Write-Error "There was error with MGGraphRequest with url $url!"
return $null
}
}
### HTML Report helper functions ### ### HTML Report helper functions ###
@@ -928,160 +1005,196 @@ if(((-not $LogStartDateTime) -and (-not $LogEndDateTime)) -and (-not $AllLogEntr
# Download Powershell scripts, Proactive Remediation scripts and custom Compliance Policy scripts # Download Powershell scripts, Proactive Remediation scripts and custom Compliance Policy scripts
if ($Online) { if ($Online) {
$GraphAuthenticationModule = $null
$MgContext = $null
# Test if we are in Enrollment Status Page (ESP) phase # Test if we are in Enrollment Status Page (ESP) phase
# Detect defaultuser0 loggedon # Detect defaultuser0 loggedon
if($env:UserName -eq 'defaultUser0') { if($env:UserName -eq 'defaultUser0') {
# Make sure we can connect # Make sure we can connect
$module = Import-Module Microsoft.Graph.Intune -PassThru -ErrorAction Ignore $GraphAuthenticationModule = Import-Module Microsoft.Graph.Authentication -PassThru -ErrorAction Ignore
if (-not $module) { if (-not $GraphAuthenticationModule) {
Write-Host "Installing module Microsoft.Graph.Intune"
Install-Module Microsoft.Graph.Intune -Force Write-Host "Installing module Microsoft.Graph.Authentication"
Install-Module Microsoft.Graph.Authentication -Force
$Success = $?
if($Success) {
Write-Host "Success`n" -ForegroundColor Green
Write-Host "Import module Microsoft.Graph.Authentication"
$GraphAuthenticationModule = Import-Module Microsoft.Graph.Authentication -PassThru -ErrorAction Ignore
if($GraphAuthenticationModule) {
# Module imported successfully
Write-Host "Success`n" -ForegroundColor Green
} else {
# Failed to import module
Write-Host "Failed to import module! Skip downloading script names...`n" -ForegroundColor Red
}
} else {
Write-Host "Failed to install module! Skip downloading script names...`n" -ForegroundColor Red
}
} }
Import-Module Microsoft.Graph.Intune
if($GraphAuthenticationModule) {
Write-Host "Connect to Microsoft Graph API"
$scopes = "DeviceManagementConfiguration.Read.All"
$MgGraph = Connect-MgGraph -scopes $scopes
$Success = $?
$MSGraphEnvironment = Connect-MSGraph if ($Success -and $MgGraph) {
Write-Host "Connected to tenant $($graph.TenantId)" Write-Host "Success`n" -ForegroundColor Green
# Get MgGraph session details
$MgContext = Get-MgContext
if($MgContext) {
$TenantId = $MgContext.TenantId
$AdminUserUPN = $MgContext.Account
Write-Host "Connected to Intune tenant:`n$TenantId`n$AdminUserUPN`n"
} else {
Write-Host "Error getting MgContext information! Skip downloading script names..." -ForegroundColor Red
}
} else {
Write-Host "Could not connect to Graph API! Skip downloading script names..." -ForegroundColor Red
}
} else {
Write-Host "Could not connect to Graph API! Skip downloading script names..." -ForegroundColor Red
}
} else { } else {
Write-Host "Connecting to Intune using Powershell Intune-Module" Write-Host "Connecting to Intune using module Microsoft.Graph.Authentication"
Update-MSGraphEnvironment -SchemaVersion 'beta'
Write-Host "Import module Microsoft.Graph.Authentication"
Import-Module Microsoft.Graph.Authentication
$Success = $? $Success = $?
if (-not $Success) { if($Success) {
Write-Host "Failed to update MSGraph Environment schema to Beta!`n" -ForegroundColor Red # Module imported successfully
Write-Host "Make sure you have installed Intune Powershell module" Write-Host "Success`n" -ForegroundColor Green
Write-Host "`nYou can install Intune module to your user account with command:" } else {
Write-Host "Install-Module -Name Microsoft.Graph.Intune -Scope CurrentUser`n" -ForegroundColor Yellow Write-Host "Failed" -ForegroundColor Red
Write-Host "`nor you can install machine-wide Intune module with command:`nInstall-Module -Name Microsoft.Graph.Intune" Write-Host "Make sure you have installed module Microsoft.Graph.Authentication"
Write-Host "More information: https://github.com/microsoft/Intune-PowerShell-SDK" Write-Host "You can install module without admin rights to your user account with command:`n`nInstall-Module -Name Microsoft.Graph.Authentication -Scope CurrentUser" -ForegroundColor Yellow
Write-Host "`nor you can install machine-wide module with with admin rights using command:`nInstall-Module -Name Microsoft.Graph.Authentication"
Write-Host ""
Exit 1 Exit 1
} }
$MSGraphEnvironment = Connect-MSGraph
Write-Host "Connect to Microsoft Graph API"
$scopes = "DeviceManagementConfiguration.Read.All"
$MgGraph = Connect-MgGraph -scopes $scopes
$Success = $? $Success = $?
if ($Success -and $MSGraphEnvironment) { if ($Success -and $MgGraph) {
$TenantId = $MSGraphEnvironment.tenantId Write-Host "Success`n" -ForegroundColor Green
$AdminUserUPN = $MSGraphEnvironment.upn
Write-Host "Connected to tenant $TenantId as user $AdminUserUPN" # Get MgGraph session details
$MgContext = Get-MgContext
if($MgContext) {
$TenantId = $MgContext.TenantId
$AdminUserUPN = $MgContext.Account
Write-Host "Connected to Intune tenant:`n$TenantId`n$AdminUserUPN`n"
} else {
Write-Host "Error getting MgContext information!`nScript will exit!" -ForegroundColor Red
Exit 1
}
} else { } else {
Write-Host "Could not connect to MSGraph!" -ForegroundColor Red Write-Host "Could not connect to Graph API!" -ForegroundColor Red
Write-Host "Will not download information from Microsoft Intune" -ForegroundColor Yellow Exit 1
Write-Host "Script will exit."
Exit 0
} }
} }
if($MSGraphEnvironment) { # Download Intune scripts information if we have connection to Microsoft Graph API
if($MgContext) {
Write-Host "Download Intune Powershell scripts" Write-Host "Download Intune Powershell scripts"
# Get PowerShell Scripts # Get PowerShell Scripts
$url = 'https://graph.microsoft.com/beta/deviceManagement/deviceManagementScripts' $uri = 'https://graph.microsoft.com/beta/deviceManagement/deviceManagementScripts'
$MSGraphRequest = Invoke-MSGraphRequest -Url $url -HttpMethod 'GET' $AllIntunePowershellScripts = Invoke-MgGraphRequestGetAllPages -Uri $uri
$Success = $?
if (-not ($Success)) { if($AllIntunePowershellScripts) {
Write-Error "Error downloading Intune Powershell scripts" Write-Host "Done" -ForegroundColor Green
#return $null
# Add Name Property to object
$AllIntunePowershellScripts | Foreach-Object { $_ | Add-Member -MemberType noteProperty -Name name -Value $_.displayName }
# Add all PowershellScripts to Hashtable
$AllIntunePowershellScripts | Foreach-Object { $id = $_.id; $value=$_; $IdHashtable["$id"] = $value }
} else { } else {
$AllIntunePowershellScripts = Get-MSGraphAllPages -SearchResult $MSGraphRequest Write-Error "Did not find Intune Powershell scripts"
$Success = $?
if($Success) {
Write-Host "Done" -ForegroundColor Green
# Add Name Property to object
$AllIntunePowershellScripts | Foreach-Object { $_ | Add-Member -MemberType noteProperty -Name name -Value $_.displayName }
# Add all PowershellScripts to Hashtable
$AllIntunePowershellScripts | Foreach-Object { $id = $_.id; $value=$_; $IdHashtable["$id"] = $value }
} else {
Write-Error "Error downloading All Intune Powershell scripts"
}
} }
Start-Sleep 1 Start-Sleep -MilliSeconds 500
Write-Host "Download Intune Remediations Scripts" Write-Host "Download Intune Remediations Scripts"
# Get Proactive Remediations Scripts # Get Proactive Remediations Scripts
$url = 'https://graph.microsoft.com/beta/deviceManagement/deviceHealthScripts' $uri = 'https://graph.microsoft.com/beta/deviceManagement/deviceHealthScripts'
$MSGraphRequest = Invoke-MSGraphRequest -Url $url -HttpMethod 'GET' $AllIntuneProactiveRemediationsScripts = Invoke-MgGraphRequestGetAllPages -Uri $uri
$Success = $?
if (-not ($Success)) { if($AllIntuneProactiveRemediationsScripts) {
Write-Error "Error downloading Intune Proactive Remediations scripts" Write-Host "Done" -ForegroundColor Green
#return $null
# Add Name Property to object
$AllIntuneProactiveRemediationsScripts | Foreach-Object { $_ | Add-Member -MemberType noteProperty -Name name -Value $_.displayName }
# Add all PowershellScripts to Hashtable
$AllIntuneProactiveRemediationsScripts | Foreach-Object { $id = $_.id; $value=$_; $IdHashtable["$id"] = $value }
} else { } else {
$AllIntuneProactiveRemediationsScripts = Get-MSGraphAllPages -SearchResult $MSGraphRequest Write-Error "Did not find Intune Remediation scripts"
$Success = $?
if($Success) {
Write-Host "Done" -ForegroundColor Green
# Add Name Property to object
$AllIntuneProactiveRemediationsScripts | Foreach-Object { $_ | Add-Member -MemberType noteProperty -Name name -Value $_.displayName }
# Add all PowershellScripts to Hashtable
$AllIntuneProactiveRemediationsScripts | Foreach-Object { $id = $_.id; $value=$_; $IdHashtable["$id"] = $value }
} else {
Write-Error "Error downloading All Intune Proactive Remediations scripts"
}
} }
Start-Sleep 1 Start-Sleep -MilliSeconds 500
Write-Host "Download Intune Windows Device Compliance custom Scripts" Write-Host "Download Intune Windows Device Compliance custom Scripts"
# Get Windows Device Compliance custom Scripts # Get Windows Device Compliance custom Scripts
$url = 'https://graph.microsoft.com/beta/deviceManagement/deviceComplianceScripts' $uri = 'https://graph.microsoft.com/beta/deviceManagement/deviceComplianceScripts'
$MSGraphRequest = Invoke-MSGraphRequest -Url $url -HttpMethod 'GET' $AllIntuneCustomComplianceScripts = Invoke-MgGraphRequestGetAllPages -Uri $uri
$Success = $?
if (-not ($Success)) { if($AllIntuneCustomComplianceScripts) {
Write-Error "Error downloading Intune Windows custom Compliance scripts" Write-Host "Done" -ForegroundColor Green
#return $null
# Add Name Property to object
$AllIntuneCustomComplianceScripts | Foreach-Object { $_ | Add-Member -MemberType noteProperty -Name name -Value $_.displayName }
# Add all PowershellScripts to Hashtable
$AllIntuneCustomComplianceScripts | Foreach-Object { $id = $_.id; $value=$_; $IdHashtable["$id"] = $value }
} else { } else {
$AllIntuneCustomComplianceScripts = Get-MSGraphAllPages -SearchResult $MSGraphRequest Write-Error "Did not find Intune Windows custom Compliance scripts"
$Success = $?
if($Success) {
Write-Host "Done" -ForegroundColor Green
# Add Name Property to object
$AllIntuneCustomComplianceScripts | Foreach-Object { $_ | Add-Member -MemberType noteProperty -Name name -Value $_.displayName }
# Add all PowershellScripts to Hashtable
$AllIntuneCustomComplianceScripts | Foreach-Object { $id = $_.id; $value=$_; $IdHashtable["$id"] = $value }
} else {
Write-Error "Error downloading All Intune Windows custom Compliance scripts"
}
} }
Start-Sleep 1 Start-Sleep -MilliSeconds 500
Write-Host "Download Intune Filters" Write-Host "Download Intune Filters"
$url = 'https://graph.microsoft.com/beta/deviceManagement/assignmentFilters?$select=*' $uri = 'https://graph.microsoft.com/beta/deviceManagement/assignmentFilters?$select=*'
$MSGraphRequest = Invoke-MSGraphRequest -Url $url -HttpMethod 'GET' $AllIntuneFilters = Invoke-MgGraphRequestGetAllPages -Uri $uri
$Success = $?
if (-not ($Success)) { if($AllIntuneFilters) {
Write-Error "Error downloading Intune filters" Write-Host "Done" -ForegroundColor Green
#return $null
# Add all Filters to Hashtable
$AllIntuneFilters | Foreach-Object { $id = $_.id; $value=$_; $IdHashtable["$id"] = $value }
} else { } else {
$AllIntuneFilters = Get-MSGraphAllPages -SearchResult $MSGraphRequest Write-Error "Did not find Intune filters"
$Success = $?
if($Success) {
Write-Host "Done" -ForegroundColor Green
# Add all Filters to Hashtable
$AllIntuneFilters | Foreach-Object { $id = $_.id; $value=$_; $IdHashtable["$id"] = $value }
} else {
Write-Error "Error downloading All Intune filters"
}
# DEBUG Intune Filters
#$AllIntuneFilters | ConvertTo-Json -Depth 5 | Set-Clipboard
} }
} else { } else {
@@ -2228,6 +2341,7 @@ do {
$RemediationExitCode = $null $RemediationExitCode = $null
$RemediationScriptName = $null $RemediationScriptName = $null
$RemediationScriptPowershellScript = $null
# Try to find displayName # Try to find displayName
if($IdHashtable.ContainsKey($PolicyId)) { if($IdHashtable.ContainsKey($PolicyId)) {