diff --git a/Main.ps1 b/Main.ps1 index 460c28d..98bf780 100644 --- a/Main.ps1 +++ b/Main.ps1 @@ -9,13 +9,15 @@ and logging are implemented to catch and log errors during these processes. .NOTES Author: Maxime Guillemin | CloudFlow -Date: 21/06/2024 +Date: 09/07/2024 + .EXAMPLE Show-Window Displays the main window of the application. #> +$currentVersion = "v0.2.0-alpha" # Define the log file path $logFile = ".\IntuneToolkit.log" @@ -88,13 +90,16 @@ function Show-Window { $BackupButton = $Window.FindName("BackupButton") $RestoreButton = $Window.FindName("RestoreButton") $ExportToCSVButton = $Window.FindName("ExportToCSVButton") + $ExportToMDButton = $Window.FindName("ExportToMDButton") $ConfigurationPoliciesButton = $Window.FindName("ConfigurationPoliciesButton") $DeviceConfigurationButton = $Window.FindName("DeviceConfigurationButton") $ComplianceButton = $Window.FindName("ComplianceButton") $AdminTemplatesButton = $Window.FindName("AdminTemplatesButton") $ApplicationsButton = $Window.FindName("ApplicationsButton") + $AppConfigButton = $Window.FindName("AppConfigButton") $RemediationScriptsButton = $Window.FindName("RemediationScriptsButton") $PlatformScriptsButton = $Window.FindName("PlatformScriptsButton") + $MacosScriptsButton = $Window.FindName("MacosScriptsButton") $SearchBox = $Window.FindName("SearchBox") $SearchButton = $Window.FindName("SearchButton") $SearchFieldComboBox = $Window.FindName("SearchFieldComboBox") @@ -116,10 +121,17 @@ function Show-Window { . .\Scripts\BackupButton.ps1 . .\Scripts\RestoreButton.ps1 . .\Scripts\ExportToCSVButton.ps1 + . .\Scripts\ExportToMDButton.ps1 . .\Scripts\Show-SelectionDialog.ps1 . .\Scripts\SearchButton.ps1 . .\Scripts\RemediationScriptsButton.ps1 . .\Scripts\PlatformScriptsButton.ps1 + . .\Scripts\AppConfigButton.ps1 + . .\Scripts\MacosScriptsButton.ps1 + # Check for the latest version + . .\Scripts\CheckVersion.ps1 + + Check-LatestVersion -currentVersion $currentVersion Write-IntuneToolkitLog "Successfully imported external scripts" diff --git a/README.md b/README.md index ada712f..e8302f3 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,11 @@ The Intune Toolkit is a PowerShell-based solution designed to simplify the manag - Device Configuration Policies - Device Compliance Policies - Mobile Applications + - App Configuration Policies - Administrative Templates - Platform Scripts + + - Mac OS Scripts - **Assignment Management:** - Add and delete assignments for selected policies. - Search Security Groups. @@ -26,6 +29,25 @@ The Intune Toolkit is a PowerShell-based solution designed to simplify the manag - Back up and restore assignments to policies and apps. - **Export Assignments:** - Export assignments to CSV + + - Document Assignments to Markdown File + - Selected Policies / applications + - Bulk Export of Policy Type +- **Logging:** Detailed logging for all major actions and error handling. + +## Release Notes +# v0.2.0-alpha +- **Features** + - Mac OS Scripts + - App Configuration Policies + - Document To markdown + - Selected Policies / applications + - Bulk Export of Policy Type + - Basic Version Check to latest Release Version on Github +- **Bug Fixes** + - Build in safety when no filters Exists ( Second Attempt ;-) ) +# v0.1.1-alpha +======= - **Logging:** Detailed logging for all major actions and error handling. ## Release Notes diff --git a/Scripts/AddAssignmentButton.ps1 b/Scripts/AddAssignmentButton.ps1 index 45f5284..fec430f 100644 --- a/Scripts/AddAssignmentButton.ps1 +++ b/Scripts/AddAssignmentButton.ps1 @@ -49,13 +49,14 @@ $AddAssignmentButton.Add_Click({ Write-IntuneToolkitLog "Processing selected policy: $($selectedPolicy.PolicyId)" -component "AddAssignment-Button" -file "AddAssignmentButton.ps1" # Get current assignments - if ($global:CurrentPolicyType -eq "mobileApps") { - $urlGetAssignments = "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps('$($selectedPolicy.PolicyId)')/assignments" + if ($global:CurrentPolicyType -eq "mobileApps" -or $global:CurrentPolicyType -eq "mobileAppConfigurations") { + $urlGetAssignments = "https://graph.microsoft.com/beta/deviceAppManagement/$($global:CurrentPolicyType)('$($selectedPolicy.PolicyId)')/assignments" + $assignments = (Invoke-MgGraphRequest -Uri $urlGetAssignments -Method GET).value } else { - $urlGetAssignments = "https://graph.microsoft.com/beta/deviceManagement/$($global:CurrentPolicyType)('$($selectedPolicy.PolicyId)')/assignments" + $urlGetAssignments = "https://graph.microsoft.com/beta/deviceManagement/$($global:CurrentPolicyType)('$($selectedPolicy.PolicyId)')?`$expand=assignments" + $assignments = (Invoke-MgGraphRequest -Uri $urlGetAssignments -Method GET).assignments } Write-IntuneToolkitLog "Fetching current assignments from: $urlGetAssignments" -component "AddAssignment-Button" -file "AddAssignmentButton.ps1" - $assignments = (Invoke-MgGraphRequest -Uri $urlGetAssignments -Method GET).value Write-IntuneToolkitLog "Fetched assignments: $($assignments.Count)" -component "AddAssignment-Button" -file "AddAssignmentButton.ps1" # Determine the target type based on the assignment type @@ -97,7 +98,7 @@ $AddAssignmentButton.Add_Click({ $bodyObject = @{ mobileAppAssignments = $assignments } - } elseif ($global:CurrentPolicyType -eq "deviceManagementScripts") { + } elseif ($global:CurrentPolicyType -eq "deviceManagementScripts" -or $global:CurrentPolicyType -eq "deviceShellScripts") { $newAssignment = @{ target = @{ '@odata.type' = $targetType @@ -114,7 +115,7 @@ $AddAssignmentButton.Add_Click({ $bodyObject = @{ deviceManagementScriptAssignments = $assignments } - }else { + } else { $newAssignment = @{ target = @{ '@odata.type' = $targetType @@ -138,8 +139,8 @@ $AddAssignmentButton.Add_Click({ Write-IntuneToolkitLog "Body for update: $body" -component "AddAssignment-Button" -file "AddAssignmentButton.ps1" # Update the assignments - if ($global:CurrentPolicyType -eq "mobileApps") { - $urlUpdateAssignments = "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps('$($selectedPolicy.PolicyId)')/assign" + if ($global:CurrentPolicyType -eq "mobileApps" -or $global:CurrentPolicyType -eq "mobileAppConfigurations") { + $urlUpdateAssignments = "https://graph.microsoft.com/beta/deviceAppManagement/$($global:CurrentPolicyType)('$($selectedPolicy.PolicyId)')/assign" } else { $urlUpdateAssignments = "https://graph.microsoft.com/beta/deviceManagement/$($global:CurrentPolicyType)('$($selectedPolicy.PolicyId)')/assign" } diff --git a/Scripts/AppConfigButton.ps1 b/Scripts/AppConfigButton.ps1 new file mode 100644 index 0000000..2e25337 --- /dev/null +++ b/Scripts/AppConfigButton.ps1 @@ -0,0 +1,32 @@ +<# +.SYNOPSIS +Handles the click event for the AppConfigButton to load application configuration policies. + +.DESCRIPTION +This script is triggered when the AppConfigButton is clicked. It sets the global policy type to mobileAppConfigurations and calls the Load-PolicyData function to load application configuration policies. It includes logging for each major step and error handling. + +.NOTES +Author: Maxime Guillemin | CloudFlow +Date: 09/07/2024 + +.EXAMPLE +$AppConfigButton.Add_Click({ + # Code to handle click event +}) +#> + +$AppConfigButton.Add_Click({ + Write-IntuneToolkitLog "AppConfigButton clicked" -component "AppConfig-Button" -file "AppConfigButton.ps1" + + try { + $global:CurrentPolicyType = "mobileAppConfigurations" + Write-IntuneToolkitLog "Set CurrentPolicyType to mobileAppConfigurations" -component "AppConfig-Button" -file "AppConfigButton.ps1" + + Load-PolicyData -policyType "mobileAppConfigurations" -loadingMessage "Loading application configurations..." -loadedMessage "Application configurations loaded." + Write-IntuneToolkitLog "Called Load-PolicyData for mobileAppConfigurations" -component "AppConfig-Button" -file "AppConfigButton.ps1" + } catch { + $errorMessage = "Failed to load application configurations. Error: $($_.Exception.Message)" + Write-Error $errorMessage + Write-IntuneToolkitLog $errorMessage -component "AppConfig-Button" -file "AppConfigButton.ps1" + } +}) diff --git a/Scripts/BackupButton.ps1 b/Scripts/BackupButton.ps1 index ffeafae..3598cbc 100644 --- a/Scripts/BackupButton.ps1 +++ b/Scripts/BackupButton.ps1 @@ -24,7 +24,9 @@ $BackupButton.Add_Click({ # Determine the policy type from the global variable if ($global:CurrentPolicyType -eq "mobileApps") { $url = "https://graph.microsoft.com/beta/deviceAppManagement/$($global:CurrentPolicyType)?`$filter=(microsoft.graph.managedApp/appAvailability%20eq%20null%20or%20microsoft.graph.managedApp/appAvailability%20eq%20%27lineOfBusiness%27%20or%20isAssigned%20eq%20true)&`$orderby=displayName&`$expand=assignments" - } else { + } elseif ($global:CurrentPolicyType -eq "mobileAppConfigurations") { + $url = "https://graph.microsoft.com/beta/deviceAppManagement/$($global:CurrentPolicyType)?`$expand=assignments" + }else { $url = "https://graph.microsoft.com/beta/deviceManagement/$($global:CurrentPolicyType)?`$expand=assignments" } Write-IntuneToolkitLog "Determined policy type: $($global:CurrentPolicyType)" -component "Backup-Button" -file "BackupButton.ps1" diff --git a/Scripts/CheckVersion.ps1 b/Scripts/CheckVersion.ps1 new file mode 100644 index 0000000..e10f154 --- /dev/null +++ b/Scripts/CheckVersion.ps1 @@ -0,0 +1,36 @@ +<# +.SYNOPSIS +Checks the current running version against the latest release version on GitHub. + +.DESCRIPTION +This script retrieves the latest release version from GitHub and compares it with the current running version. If a newer version is available, it notifies the user. + +.NOTES +Author: Maxime Guillemin | CloudFlow +Date: 09/07/2024 +#> + +function Check-LatestVersion { + param ( + [string]$currentVersion, + [string]$repoUrl = "https://api.github.com/repos/MG-Cloudflow/Intune-Toolkit/releases/latest" + ) + + try { + Write-IntuneToolkitLog "Checking for latest version at $repoUrl" -component "Check-LatestVersion" -file "CheckVersion.ps1" + $response = Invoke-RestMethod -Uri $repoUrl -Method Get + $latestVersion = $response.tag_name + + if ($latestVersion -ne $currentVersion) { + $message = "A new version ($latestVersion) is available. You are currently running version $currentVersion. Download the latest Version from github https://github.com/MG-Cloudflow/Intune-Toolkit" + [System.Windows.Forms.MessageBox]::Show($message, "Update Available", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Information) | Out-Null + Write-IntuneToolkitLog $message -component "Check-LatestVersion" -file "CheckVersion.ps1" + } else { + Write-IntuneToolkitLog "You are running the latest version ($currentVersion)" -component "Check-LatestVersion" -file "CheckVersion.ps1" + } + } catch { + $errorMessage = "Failed to check for the latest version. Error: $($_.Exception.Message)" + Write-Error $errorMessage + Write-IntuneToolkitLog $errorMessage -component "Check-LatestVersion" -file "CheckVersion.ps1" + } +} diff --git a/Scripts/ConnectButton.ps1 b/Scripts/ConnectButton.ps1 index 5152c54..f296474 100644 --- a/Scripts/ConnectButton.ps1 +++ b/Scripts/ConnectButton.ps1 @@ -45,6 +45,8 @@ $ConnectButton.Add_Click({ $ComplianceButton.IsEnabled = $true $AdminTemplatesButton.IsEnabled = $true $ApplicationsButton.IsEnabled = $true + $AppConfigButton.IsEnabled = $true + $MacosScriptsButton.IsEnabled = $true #$RemediationScriptsButton.IsEnabled = $true $PlatformScriptsButton.IsEnabled = $true $ConnectButton.IsEnabled = $false @@ -53,6 +55,7 @@ $ConnectButton.Add_Click({ $SearchBox.IsEnabled = $true $SearchButton.IsEnabled = $true $ExportToCSVButton.IsEnabled = $true + $ExportToMDButton.IsEnabled = $true Write-IntuneToolkitLog "UI elements updated successfully" -component "Connect-Button" -file "ConnectButton.ps1" diff --git a/Scripts/DeleteAssignmentButton.ps1 b/Scripts/DeleteAssignmentButton.ps1 index f147bb8..e9d45d1 100644 --- a/Scripts/DeleteAssignmentButton.ps1 +++ b/Scripts/DeleteAssignmentButton.ps1 @@ -8,7 +8,8 @@ It retrieves the current assignments, filters out the selected assignment, and u .NOTES Author: Maxime Guillemin | CloudFlow -Date: 21/06/2024 +Date: 09/07/2024 + .EXAMPLE $DeleteAssignmentButton.Add_Click({ # Code to handle click event @@ -27,13 +28,14 @@ $DeleteAssignmentButton.Add_Click({ Write-IntuneToolkitLog "Processing selected policy: $($selectedPolicy.PolicyId)" -component "DeleteAssignment-Button" -file "DeleteAssignmentButton.ps1" # Get current assignments - if ($global:CurrentPolicyType -eq "mobileApps") { - $urlGetAssignments = "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps/$($selectedPolicy.PolicyId)/assignments" + if ($global:CurrentPolicyType -eq "mobileApps" -or $global:CurrentPolicyType -eq "mobileAppConfigurations") { + $urlGetAssignments = "https://graph.microsoft.com/beta/deviceAppManagement/$($global:CurrentPolicyType)('$($selectedPolicy.PolicyId)')/assignments" + $assignments = (Invoke-MgGraphRequest -Uri $urlGetAssignments -Method GET).value } else { - $urlGetAssignments = "https://graph.microsoft.com/beta/deviceManagement/$($global:CurrentPolicyType)/$($selectedPolicy.PolicyId)/assignments" + $urlGetAssignments = "https://graph.microsoft.com/beta/deviceManagement/$($global:CurrentPolicyType)('$($selectedPolicy.PolicyId)')?`$expand=assignments" + $assignments = (Invoke-MgGraphRequest -Uri $urlGetAssignments -Method GET).assignments } Write-IntuneToolkitLog "Fetching current assignments from: $urlGetAssignments" -component "DeleteAssignment-Button" -file "DeleteAssignmentButton.ps1" - $assignments = (Invoke-MgGraphRequest -Uri $urlGetAssignments -Method GET).value Write-IntuneToolkitLog "Fetched assignments: $($assignments.Count)" -component "DeleteAssignment-Button" -file "DeleteAssignmentButton.ps1" # Filter out the selected group @@ -63,7 +65,7 @@ $DeleteAssignmentButton.Add_Click({ $bodyObject = @{ mobileAppAssignments = $updatedAssignments } - }elseif($global:CurrentPolicyType -eq "deviceManagementScripts") { + }elseif($global:CurrentPolicyType -eq "deviceManagementScripts" -or $global:CurrentPolicyType -eq "deviceShellScripts") { $bodyObject = @{ deviceManagementScriptAssignments = $updatedAssignments } @@ -78,10 +80,10 @@ $DeleteAssignmentButton.Add_Click({ Write-IntuneToolkitLog "Body for update: $body" -component "DeleteAssignment-Button" -file "DeleteAssignmentButton.ps1" # Update the assignments - if ($global:CurrentPolicyType -eq "mobileApps") { - $urlUpdateAssignments = "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps/$($selectedPolicy.PolicyId)/assign" + if ($global:CurrentPolicyType -eq "mobileApps" -or $global:CurrentPolicyType -eq "mobileAppConfigurations") { + $urlUpdateAssignments = "https://graph.microsoft.com/beta/deviceAppManagement/$($global:CurrentPolicyType)('$($selectedPolicy.PolicyId)')/assign" } else { - $urlUpdateAssignments = "https://graph.microsoft.com/beta/deviceManagement/$($global:CurrentPolicyType)/$($selectedPolicy.PolicyId)/assign" + $urlUpdateAssignments = "https://graph.microsoft.com/beta/deviceManagement/$($global:CurrentPolicyType)('$($selectedPolicy.PolicyId)')/assign" } Write-IntuneToolkitLog "Updating assignments at: $urlUpdateAssignments" -component "DeleteAssignment-Button" -file "DeleteAssignmentButton.ps1" Invoke-MgGraphRequest -Uri $urlUpdateAssignments -Method POST -Body $body -ContentType "application/json" diff --git a/Scripts/ExportToMDButton.ps1 b/Scripts/ExportToMDButton.ps1 new file mode 100644 index 0000000..e423e03 --- /dev/null +++ b/Scripts/ExportToMDButton.ps1 @@ -0,0 +1,194 @@ +<# +.SYNOPSIS +Exports policy data loaded in the grid to a Markdown file. + +.DESCRIPTION +This script exports the policy data from the Intune Toolkit grid to a Markdown file. +It generates the Markdown content including the policy name, description, and assignments. +If the policy type is mobileApps, it also includes the InstallIntent in the output. + +.PARAMETER MainWindow +The main window of the Intune Toolkit application. + +.PARAMETER dataGridItems +The policy data loaded in the grid that needs to be exported. + +.NOTES + +Author: Maxime Guillemin | CloudFlow +Date: 09/07/2024 + + +This script adds a button to the Intune Toolkit interface that allows users to export +policy data to a Markdown file. The export process includes handling for selected policies +or all policies if none are selected, and incorporates detailed error handling and logging. +#> + +# Event handler for the Export to Markdown button click event +$ExportToMDButton.Add_Click({ + + <# + .SYNOPSIS + Exports the provided policy data to a Markdown file. + + .DESCRIPTION + This function takes the policy data and generates a Markdown file, + organizing the data by policy name, description, and assignments. + It handles different columns for mobileApps policy type. + + .PARAMETER OutputPath + The file path where the Markdown file will be saved. + + .PARAMETER PolicyDataGrid + The collection of policy data to be exported. + + .PARAMETER CurrentPolicyType + The type of policies being exported, used to determine specific columns. + #> + function Export-ToMarkdown { + param ( + [Parameter(Mandatory=$true)] + [string]$OutputPath, + + [Parameter(Mandatory=$true)] + [PSObject]$PolicyDataGrid, + + [string]$CurrentPolicyType + ) + + try { + $tenant = Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/v1.0/organization" -Method GET + $user = Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/v1.0/me" -Method GET + $tenantinfo = "Tenant: $($tenant.value[0].displayName)" + $dateString = Get-Date -Format "dddd, MMMM dd, yyyy HH:mm:ss" + $markdownContent = "" + $markdownContent += "# $global:CurrentPolicyType`n`n" + $markdownContent += " $tenantinfo `n`n" + $markdownContent += " Documentation Date: $dateString `n`n" + + # Group policies by PolicyId and sort by PolicyName + $uniquePolicies = $PolicyDataGrid | Group-Object -Property PolicyId | Sort-Object { $_.Group[0].PolicyName } + + foreach ($policyGroup in $uniquePolicies) { + $firstPolicy = $policyGroup.Group[0] + $PolicyName = $firstPolicy.PolicyName + $PolicyDescription = $firstPolicy.PolicyDescription + + # Add policy name and description to markdown content + $markdownContent += "## $($PolicyName)`n`n" + $markdownContent += "### Description`n`n" + $markdownContent += "$($PolicyDescription)`n`n" + $markdownContent += "### Assignments`n`n" + + # Add table headers based on policy type + if ($CurrentPolicyType -eq "mobileApps") { + $markdownContent += "| GroupDisplayname | GroupId | AssignmentType | FilterDisplayname | FilterType | InstallIntent |`n" + $markdownContent += "| ---------------- | ------- | -------------- | ----------------- | ---------- | ------------- |`n" + } else { + $markdownContent += "| GroupDisplayname | GroupId | AssignmentType | FilterDisplayname | FilterType |`n" + $markdownContent += "| ---------------- | ------- | -------------- | ----------------- | ---------- |`n" + } + + # Add each assignment to the markdown table + foreach ($policy in $policyGroup.Group) { + $GroupDisplayname = $policy.GroupDisplayname + $GroupId = $policy.GroupId + $AssignmentType = $policy.AssignmentType + $FilterDisplayname = $policy.FilterDisplayname + $FilterType = $policy.FilterType + $InstallIntent = $policy.InstallIntent + + if ($CurrentPolicyType -eq "mobileApps") { + $markdownContent += "| $GroupDisplayname | $GroupId | $AssignmentType | $FilterDisplayname | $FilterType | $InstallIntent |`n" + } else { + $markdownContent += "| $GroupDisplayname | $GroupId | $AssignmentType | $FilterDisplayname | $FilterType |`n" + } + } + + $markdownContent += "`n`n" + } + + # Write the markdown content to a file + try { + $markdownContent | Out-File -FilePath $OutputPath -Encoding utf8 + Write-IntuneToolkitLog -Message "Exported policy data to Markdown file at $OutputPath" -Component "ExportToMarkdown" + } + catch { + Write-IntuneToolkitLog -Message "Failed to write to file: $_" -Component "ExportToMarkdown" -Severity "Error" + [System.Windows.MessageBox]::Show("Failed to write to file: $_", "Export Failed", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) + return + } + } + catch { + Write-IntuneToolkitLog -Message "An error occurred during Markdown export: $_" -Component "ExportToMarkdown" -Severity "Error" + [System.Windows.MessageBox]::Show("An error occurred during Markdown export: $_", "Export Failed", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) + } + } + + <# + .SYNOPSIS + Retrieves policies to be exported based on user selection. + + .DESCRIPTION + This function checks if any policies are selected in the DataGrid. + If selected policies exist, it returns those. Otherwise, it returns all policies. + + .PARAMETER AllPolicies + The collection of all policies available for export. + + .PARAMETER DataGrid + The DataGrid control containing the policies. + + .RETURNS + The policies to be exported. + #> + function Get-PoliciesToExport { + param ( + [PSObject]$AllPolicies, + [System.Windows.Controls.DataGrid]$DataGrid + ) + + try { + $selectedItems = $DataGrid.SelectedItems + if ($selectedItems.Count -gt 0) { + # Get unique policy IDs from the selected items + $selectedPolicyIds = $selectedItems | Select-Object -ExpandProperty PolicyId -Unique + # Return all assignments for the selected policies + return $AllPolicies | Where-Object { $selectedPolicyIds -contains $_.PolicyId } + } else { + return $AllPolicies + } + } + catch { + Write-IntuneToolkitLog -Message "Failed to get policies to export: $_" -Component "ExportToMarkdown" -Severity "Error" + [System.Windows.MessageBox]::Show("Failed to get policies to export: $_", "Error", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) + throw + } + } + + # Open a Save File Dialog to select the output path + $saveFileDialog = New-Object -TypeName Microsoft.Win32.SaveFileDialog + $saveFileDialog.Filter = "Markdown files (*.md)|*.md" + $saveFileDialog.DefaultExt = "md" + $saveFileDialog.AddExtension = $true + + try { + if ($saveFileDialog.ShowDialog() -eq $true) { + $outputPath = $saveFileDialog.FileName + Write-IntuneToolkitLog -Message "Initiating export to Markdown" -Component "ExportToMarkdown" + + $policiesToExport = Get-PoliciesToExport -AllPolicies $global:AllPolicyData -DataGrid $PolicyDataGrid + Export-ToMarkdown -OutputPath $outputPath -PolicyDataGrid $policiesToExport -CurrentPolicyType $global:CurrentPolicyType + + [System.Windows.MessageBox]::Show("Export to Markdown completed successfully.", "Export Completed", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information) + Write-IntuneToolkitLog -Message "Export to Markdown completed successfully." -Component "ExportToMarkdown" + } else { + [System.Windows.MessageBox]::Show("Export to Markdown was canceled.", "Export Canceled", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) + Write-IntuneToolkitLog -Message "Export to Markdown was canceled by user." -Component "ExportToMarkdown" + } + } + catch { + Write-IntuneToolkitLog -Message "An error occurred during the export process: $_" -Component "ExportToMarkdown" -Severity "Error" + [System.Windows.MessageBox]::Show("An error occurred during the export process: $_", "Export Failed", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) + } +}) diff --git a/Scripts/Functions.ps1 b/Scripts/Functions.ps1 index dd1e26c..2add85d 100644 --- a/Scripts/Functions.ps1 +++ b/Scripts/Functions.ps1 @@ -9,7 +9,8 @@ reloading grid data, and loading policy data. Error handling and logging are imp .NOTES Author: Maxime Guillemin | CloudFlow -Date: 21/06/2024 +Date: 09/07/2024 + .EXAMPLE $groups = Get-AllSecurityGroups @@ -96,6 +97,8 @@ function Reload-Grid { if ($type -eq "mobileApps") { $url = "https://graph.microsoft.com/beta/deviceAppManagement/$($type)?`$filter=(microsoft.graph.managedApp/appAvailability%20eq%20null%20or%20microsoft.graph.managedApp/appAvailability%20eq%20%27lineOfBusiness%27%20or%20isAssigned%20eq%20true)&`$orderby=displayName&`$expand=assignments" + } elseif ($type -eq "mobileAppConfigurations") { + $url = "https://graph.microsoft.com/beta/deviceAppManagement/$($type)?`$expand=assignments" } else { $url = "https://graph.microsoft.com/beta/deviceManagement/$($type)?`$expand=assignments" } @@ -120,7 +123,7 @@ function Reload-Grid { # Initialize the global variable as an array $global:AllPolicyData = @() foreach ($policy in $result) { - if ($type -eq "deviceConfigurations" -or $type -eq "configurationPolicies" -or $type -eq "deviceCompliancePolicies" -or $type -eq "groupPolicyConfigurations" -or $type -eq "deviceHealthScripts" -or $type -eq "deviceManagementScripts" -or $type -eq "managedAppPolicies") { + if ($type -eq "deviceConfigurations" -or $type -eq "configurationPolicies" -or $type -eq "deviceCompliancePolicies" -or $type -eq "groupPolicyConfigurations" -or $type -eq "deviceHealthScripts" -or $type -eq "deviceManagementScripts" -or $type -eq "managedAppPolicies" -or $type -eq "mobileAppConfigurations" -or $type -eq "deviceShellScripts") { if ($null -ne $policy.assignments -and $policy.assignments.Count -gt 0) { foreach ($assignment in $policy.assignments) { $groupDisplayName = if ($assignment.target.groupId -and $groupLookup.ContainsKey($assignment.target.groupId)) { $groupLookup[$assignment.target.groupId] } else { "" } @@ -211,8 +214,10 @@ function Load-PolicyData { $ComplianceButton.IsEnabled = $false $AdminTemplatesButton.IsEnabled = $false $ApplicationsButton.IsEnabled = $false + $AppConfigButton.IsEnabled = $false $RemediationScriptsButton.IsEnabled = $false $PlatformScriptsButton.IsEnabled = $false + $MacosScriptsButton.IsEnabled = $false $DeleteAssignmentButton.IsEnabled = $false $AddAssignmentButton.IsEnabled = $false $BackupButton.IsEnabled = $false @@ -221,6 +226,7 @@ function Load-PolicyData { $SearchBox.IsEnabled = $false $SearchButton.IsEnabled = $false $ExportToCSVButton.IsEnabled = $false + $ExportToMDButton.IsEnabled = $false # Load data synchronously $result = Reload-Grid -type $policyType @@ -240,8 +246,10 @@ function Load-PolicyData { $ComplianceButton.IsEnabled = $true $AdminTemplatesButton.IsEnabled = $true $ApplicationsButton.IsEnabled = $true + $AppConfigButton.IsEnabled = $true #$RemediationScriptsButton.IsEnabled = $true $PlatformScriptsButton.IsEnabled = $true + $MacosScriptsButton.IsEnabled = $true $DeleteAssignmentButton.IsEnabled = $true $AddAssignmentButton.IsEnabled = $true $BackupButton.IsEnabled = $true @@ -250,4 +258,5 @@ function Load-PolicyData { $SearchBox.IsEnabled = $true $SearchButton.IsEnabled = $true $ExportToCSVButton.IsEnabled = $true + $ExportToMDButton.IsEnabled = $true } \ No newline at end of file diff --git a/Scripts/LogoutButton.ps1 b/Scripts/LogoutButton.ps1 index c9ea7af..892f9c2 100644 --- a/Scripts/LogoutButton.ps1 +++ b/Scripts/LogoutButton.ps1 @@ -37,7 +37,9 @@ $LogoutButton.Add_Click({ $ComplianceButton.IsEnabled = $false $AdminTemplatesButton.IsEnabled = $false $ApplicationsButton.IsEnabled = $false + $AppConfigButton.IsEnabled = $false $RemediationScriptsButton.IsEnabled = $false + $MacosScriptsButton.IsEnabled = $false $PlatformScriptsButton.IsEnabled = $false $ConnectButton.IsEnabled = $true $LogoutButton.IsEnabled = $false @@ -45,6 +47,7 @@ $LogoutButton.Add_Click({ $SearchBox.IsEnabled = $false $SearchButton.IsEnabled = $false $ExportToCSVButton.IsEnabled = $false + $ExportToMDButton.IsEnabled = $false Write-IntuneToolkitLog "UI elements reset successfully" -component "Logout-Button" -file "LogoutButton.ps1" diff --git a/Scripts/MacosScriptsButton.ps1 b/Scripts/MacosScriptsButton.ps1 new file mode 100644 index 0000000..b73cad5 --- /dev/null +++ b/Scripts/MacosScriptsButton.ps1 @@ -0,0 +1,32 @@ +<# +.SYNOPSIS +Handles the click event for the MacosScriptsButton to load macOS shell scripts. + +.DESCRIPTION +This script is triggered when the MacosScriptsButton is clicked. It sets the global policy type to deviceShellScripts and calls the Load-PolicyData function to load macOS shell scripts. It includes logging for each major step and error handling. + +.NOTES +Author: Maxime Guillemin +Date: 09/07/2024 + +.EXAMPLE +$MacosScriptsButton.Add_Click({ + # Code to handle click event +}) +#> + +$MacosScriptsButton.Add_Click({ + Write-IntuneToolkitLog "MacosScriptsButton clicked" -component "MacosScripts-Button" -file "MacosScriptsButton.ps1" + + try { + $global:CurrentPolicyType = "deviceShellScripts" + Write-IntuneToolkitLog "Set CurrentPolicyType to deviceShellScripts" -component "MacosScripts-Button" -file "MacosScriptsButton.ps1" + + Load-PolicyData -policyType "deviceShellScripts" -loadingMessage "Loading macOS shell scripts..." -loadedMessage "macOS shell scripts loaded." + Write-IntuneToolkitLog "Called Load-PolicyData for deviceShellScripts" -component "MacosScripts-Button" -file "MacosScriptsButton.ps1" + } catch { + $errorMessage = "Failed to load macOS shell scripts. Error: $($_.Exception.Message)" + Write-Error $errorMessage + Write-IntuneToolkitLog $errorMessage -component "MacosScripts-Button" -file "MacosScriptsButton.ps1" + } +}) diff --git a/Scripts/RestoreButton.ps1 b/Scripts/RestoreButton.ps1 index a38184d..78efa85 100644 --- a/Scripts/RestoreButton.ps1 +++ b/Scripts/RestoreButton.ps1 @@ -8,9 +8,8 @@ It allows the user to select a backup file, reads and parses the file, and updat assignments for each policy in the backup. The script includes error handling and logging for all major actions. -.NOTES -Author: Author: Maxime Guillemin | CloudFlow -Date: 21/06/2024 +Author: Maxime Guillemin | CloudFlow +Date: 09/07/2024 .EXAMPLE $RestoreButton.Add_Click({ @@ -50,11 +49,11 @@ $RestoreButton.Add_Click({ $bodyObject = @{ mobileAppAssignments = $policy.assignments } - } elseif($global:CurrentPolicyType -eq "deviceManagementScripts") { + } elseif($global:CurrentPolicyType -eq "deviceManagementScripts" -or $global:CurrentPolicyType -eq "deviceShellScripts") { $bodyObject = @{ deviceManagementScriptAssignments = $policy.assignments } - } else { + }else { $bodyObject = @{ assignments = $policy.assignments } @@ -66,7 +65,7 @@ $RestoreButton.Add_Click({ # Update the assignments for the policy if ($policyType -eq "mobileApps") { - $UrlUpdateAssignments = "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps/$($policy.id)/assign" + $UrlUpdateAssignments = "https://graph.microsoft.com/beta/deviceAppManagement/$($policyType)/$($policy.id)/assign" } else { $UrlUpdateAssignments = "https://graph.microsoft.com/beta/deviceManagement/$($policyType)/$($policy.id)/assign" } diff --git a/Scripts/Show-SelectionDialog.ps1 b/Scripts/Show-SelectionDialog.ps1 index 3f32cd9..9454f10 100644 --- a/Scripts/Show-SelectionDialog.ps1 +++ b/Scripts/Show-SelectionDialog.ps1 @@ -7,7 +7,8 @@ This script is triggered when the AdminTemplatesButton is clicked. It sets the g .NOTES Author: Maxime Guillemin | CloudFlow -Date: 21/06/2024 +Date: 09/07/2024 + .EXAMPLE $AdminTemplatesButton.Add_Click({ @@ -18,7 +19,7 @@ function Show-SelectionDialog { param ( [Parameter(Mandatory = $true)] [array]$groups, - [Parameter(Mandatory = $true)] + [Parameter(Mandatory = $false)] [array]$filters, [Parameter(Mandatory = $false)] [bool]$includeIntent = $false @@ -106,6 +107,9 @@ function Show-SelectionDialog { } Write-IntuneToolkitLog "Populated filter combo box" -component "Show-SelectionDialog" -file "SelectionDialog.ps1" } else { + $comboBoxItem = New-Object Windows.Controls.ComboBoxItem + $comboBoxItem.Content = "No Filters" + $FilterComboBox.Items.Add($comboBoxItem) Write-IntuneToolkitLog "No filters available to populate filter combo box" -component "Show-SelectionDialog" -file "SelectionDialog.ps1" } diff --git a/XML/Main.xaml b/XML/Main.xaml index 2235b48..5d62dc4 100644 --- a/XML/Main.xaml +++ b/XML/Main.xaml @@ -68,8 +68,10 @@