Src/Private/Get-AbrIntuneScripts.ps1
|
function Get-AbrIntuneScripts { <# .SYNOPSIS Documents Intune PowerShell scripts and Shell scripts deployed via Intune. .DESCRIPTION Collects and reports on: - Windows PowerShell scripts (name, run as, enforcement, assignments) - macOS Shell scripts (name, run as, frequency, assignments) - Proactive Remediations (detection + remediation script pairs) .NOTES Version: 0.1.0 Author: Pai Wei Sing #> [CmdletBinding()] param ( [Parameter(Position = 0, Mandatory)] [string]$TenantId ) begin { Write-PScriboMessage -Message "Collecting Intune Scripts for $TenantId." Show-AbrDebugExecutionTime -Start -TitleMessage 'Scripts' } process { Section -Style Heading2 'Scripts' { $TotalRemediations = 0 $UnsignedScripts = 0 Paragraph "The following section documents scripts deployed via Microsoft Intune in tenant $TenantId." BlankLine #region Windows PowerShell Scripts # Licence gate: deviceManagementScripts requires Intune Plan 1 if ($script:TenantHasIntuneP1 -eq $false) { Write-Host ' - Skipping Windows PowerShell Scripts (Intune Plan 1 not detected).' -ForegroundColor Yellow Write-AbrDebugLog 'Windows PowerShell Scripts skipped -- no Intune P1 licence' 'WARN' 'SCRIPTS' } else { try { Write-Host " - Retrieving Windows PowerShell scripts..." # /beta required -- deviceManagementScripts is not available in v1.0 $PSScriptsResp = Invoke-MgGraphRequest -Method GET ` -Uri "$($script:GraphEndpoint)/beta/deviceManagement/deviceManagementScripts?$expand=assignments" ` -ErrorAction SilentlyContinue $PSScripts = $PSScriptsResp.value if ($PSScripts -and @($PSScripts).Count -gt 0) { Section -Style Heading3 'Windows PowerShell Scripts' { BlankLine $PSObj = [System.Collections.ArrayList]::new() foreach ($Script in ($PSScripts | Sort-Object displayName)) { $assignResolved = Resolve-IntuneAssignments -Assignments $Script.assignments $AssignedTo = $assignResolved.AssignmentSummary $psInObj = [ordered] @{ 'Script Name' = $Script.displayName 'Run As Account' = if ($Script.runAsAccount) { $Script.runAsAccount } else { '--' } 'Run As 32-bit' = $Script.runAs32Bit 'Enforce Sig. Check' = $Script.enforceSignatureCheck 'Retry Count' = if ($null -ne $Script.retryCount) { $Script.retryCount } else { '--' } 'Assignments' = $AssignedTo 'Last Modified' = if ($Script.lastModifiedDateTime) { ([datetime]$Script.lastModifiedDateTime).ToString('yyyy-MM-dd') } else { '--' } } $PSObj.Add([pscustomobject](ConvertTo-HashToYN $psInObj)) | Out-Null } $PSTableParams = @{ Name = "Windows PowerShell Scripts - $TenantId"; ColumnWidths = 24, 14, 11, 12, 10, 17, 12 } if ($Report.ShowTableCaptions) { $PSTableParams['Caption'] = "- $($PSTableParams.Name)" } # Count scripts without signature enforcement $UnsignedScripts += @($PSScripts | Where-Object { -not $_.enforceSignatureCheck }).Count $PSObj | Table @PSTableParams if (Get-IntuneExcelSheetEnabled -SheetKey 'PowerShellScripts') { $script:ExcelSheets['PowerShell Scripts'] = $PSObj } if (Get-IntuneBackupSectionEnabled -SectionKey 'Scripts') { $script:BackupData['PowerShellScripts'] = $PSScripts } } } } catch { if (Test-AbrGraphForbidden -ErrorRecord $_) { Write-AbrPermissionError -Section 'Windows PowerShell Scripts' -RequiredRole 'Intune Service Administrator or Global Administrator' } else { Write-AbrSectionError -Section 'Windows PowerShell Scripts' -Message "$($_.Exception.Message)" } } } # end licence gate #endregion #region macOS Shell Scripts # Licence gate: deviceShellScripts requires Intune Plan 1 if ($script:TenantHasIntuneP1 -eq $false) { Write-Host ' - Skipping macOS Shell Scripts (Intune Plan 1 not detected).' -ForegroundColor Yellow Write-AbrDebugLog 'macOS Shell Scripts skipped -- no Intune P1 licence' 'WARN' 'SCRIPTS' } else { try { Write-Host " - Retrieving macOS Shell scripts..." # /beta required -- deviceShellScripts is not available in v1.0 $ShellScriptsResp = Invoke-MgGraphRequest -Method GET ` -Uri "$($script:GraphEndpoint)/beta/deviceManagement/deviceShellScripts?$expand=assignments" ` -ErrorAction SilentlyContinue $ShellScripts = $ShellScriptsResp.value if ($ShellScripts -and @($ShellScripts).Count -gt 0) { Section -Style Heading3 'macOS Shell Scripts' { BlankLine $ShellObj = [System.Collections.ArrayList]::new() foreach ($Script in ($ShellScripts | Sort-Object displayName)) { $AssignedTo = if ($Script.assignments -and @($Script.assignments).Count -gt 0) { "$(@($Script.assignments).Count) assignment(s)" } else { 'Not assigned' } $shellInObj = [ordered] @{ 'Script Name' = $Script.displayName 'Run As Account' = if ($Script.runAsAccount) { $Script.runAsAccount } else { '--' } 'Execution Frequency'= if ($Script.executionFrequency) { $Script.executionFrequency } else { '--' } 'Retry Count' = if ($null -ne $Script.retryCount) { $Script.retryCount } else { '--' } 'Assignments' = $AssignedTo 'Last Modified' = if ($Script.lastModifiedDateTime) { ([datetime]$Script.lastModifiedDateTime).ToString('yyyy-MM-dd') } else { '--' } } $ShellObj.Add([pscustomobject]$shellInObj) | Out-Null } $ShellTableParams = @{ Name = "macOS Shell Scripts - $TenantId"; ColumnWidths = 26, 16, 18, 10, 18, 12 } if ($Report.ShowTableCaptions) { $ShellTableParams['Caption'] = "- $($ShellTableParams.Name)" } $ShellObj | Table @ShellTableParams if (Get-IntuneExcelSheetEnabled -SheetKey 'ShellScripts') { $script:ExcelSheets['Shell Scripts'] = $ShellObj } if (Get-IntuneBackupSectionEnabled -SectionKey 'Scripts') { if ($script:BackupData['ShellScripts']) { $script:BackupData['ShellScripts'] += $ShellScripts } else { $script:BackupData['ShellScripts'] = $ShellScripts } } } } } catch { if (Test-AbrGraphForbidden -ErrorRecord $_) { Write-AbrPermissionError -Section 'macOS Shell Scripts' -RequiredRole 'Intune Service Administrator or Global Administrator' } else { Write-AbrSectionError -Section 'macOS Shell Scripts' -Message "$($_.Exception.Message)" } } } # end licence gate #endregion #region Proactive Remediations # Licence gate: deviceHealthScripts (Proactive Remediations) requires Intune Plan 2 / Suite if ($script:TenantHasIntuneP2 -eq $false) { Write-Host ' - Skipping Proactive Remediations (Intune Plan 2 / Suite not detected).' -ForegroundColor Yellow Write-AbrDebugLog 'Proactive Remediations skipped -- no Intune P2/Suite licence' 'WARN' 'SCRIPTS' } else { try { Write-Host " - Retrieving Proactive Remediations..." # /beta required -- deviceHealthScripts (Proactive Remediations) is not available in v1.0 $RemediationsResp = Invoke-MgGraphRequest -Method GET ` -Uri "$($script:GraphEndpoint)/beta/deviceManagement/deviceHealthScripts?$expand=assignments" ` -ErrorAction SilentlyContinue $Remediations = $RemediationsResp.value $null = ($TotalRemediations = @($Remediations).Count) if ($TotalRemediations -gt 0) { Section -Style Heading3 'Proactive Remediations' { BlankLine $RemObj = [System.Collections.ArrayList]::new() foreach ($Rem in ($Remediations | Sort-Object displayName)) { $AssignedTo = if ($Rem.assignments -and @($Rem.assignments).Count -gt 0) { "$(@($Rem.assignments).Count) assignment(s)" } else { 'Not assigned' } $remInObj = [ordered] @{ 'Remediation Name' = $Rem.displayName 'Publisher' = if ($Rem.publisher) { $Rem.publisher } else { '--' } 'Run As Account' = if ($Rem.runAsAccount) { $Rem.runAsAccount } else { '--' } 'Run As 32-bit' = $Rem.runAs32Bit 'Enforce Sig. Check' = $Rem.enforceSignatureCheck 'Assignments' = $AssignedTo 'Last Modified' = if ($Rem.lastModifiedDateTime) { ([datetime]$Rem.lastModifiedDateTime).ToString('yyyy-MM-dd') } else { '--' } } $RemObj.Add([pscustomobject](ConvertTo-HashToYN $remInObj)) | Out-Null } $RemTableParams = @{ Name = "Proactive Remediations - $TenantId"; ColumnWidths = 22, 16, 14, 11, 12, 15, 10 } if ($Report.ShowTableCaptions) { $RemTableParams['Caption'] = "- $($RemTableParams.Name)" } $RemObj | Table @RemTableParams if (Get-IntuneExcelSheetEnabled -SheetKey 'ProactiveRemediations') { $script:ExcelSheets['Proactive Remediations'] = $RemObj } if (Get-IntuneBackupSectionEnabled -SectionKey 'Scripts') { $script:BackupData['ProactiveRemediations'] = $Remediations } } } } catch { if (Test-AbrGraphForbidden -ErrorRecord $_) { Write-AbrPermissionError -Section 'Proactive Remediations' -RequiredRole 'Intune Service Administrator or Global Administrator' } else { Write-AbrSectionError -Section 'Proactive Remediations' -Message "$($_.Exception.Message)" } } } # end licence gate #endregion #region ACSC E8 Assessment if ($script:IncludeACSCe8) { BlankLine Paragraph "ACSC Essential Eight Maturity Level Assessment -- Scripts and Remediations:" BlankLine try { $_v = @{ TotalRemediations = $TotalRemediations; UnsignedScripts = $UnsignedScripts } $E8Checks = Build-AbrIntuneComplianceChecks -Definitions (Get-AbrIntuneE8Checks -Section 'Scripts') -Framework E8 -CallerVariables $_v New-AbrIntuneE8AssessmentTable -Checks $E8Checks -Name 'Scripts' -TenantId $TenantId if ($E8Checks) { $null = $script:E8AllChecks.AddRange([object[]](@($E8Checks | Select-Object @{N='Section';E={'Scripts'}}, ML, Control, Status, Detail))) } } catch { Write-AbrSectionError -Section 'E8 Scripts Assessment' -Message "$($_.Exception.Message)" } } #endregion #region CIS Assessment if ($script:IncludeCISBaseline) { BlankLine Paragraph "CIS Microsoft 365 Foundations Benchmark Assessment -- Scripts:" BlankLine try { $_v = @{ UnsignedScripts = $UnsignedScripts } $CISChecks = Build-AbrIntuneComplianceChecks -Definitions (Get-AbrIntuneCISChecks -Section 'Scripts') -Framework CIS -CallerVariables $_v New-AbrIntuneCISAssessmentTable -Checks $CISChecks -Name 'Scripts' -TenantId $TenantId if ($CISChecks) { $null = $script:CISAllChecks.AddRange([object[]](@($CISChecks | Select-Object @{N='Section';E={'Scripts'}}, CISControl, Level, Status, Detail))) } } catch { Write-AbrSectionError -Section 'CIS Scripts Assessment' -Message "$($_.Exception.Message)" } } #endregion } } end { Show-AbrDebugExecutionTime -End -TitleMessage 'Scripts' } } |