Last active
September 10, 2024 13:35
-
-
Save MrWyss-MSFT/c063ab39cf0bcab868e31503b27fe1d8 to your computer and use it in GitHub Desktop.
Lists not assigned apps Intune Win32Apps for the user to delete.
This file contains hidden or 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
| <# | |
| .SYNOPSIS | |
| Lists not assigned apps Intune Win32Apps for the user to delete. | |
| .DESCRIPTION | |
| Lists all apps that are not assigned and are Win32 Apps. | |
| The user can select the apps to delete. There is standard output as well as a | |
| CMTrace compatible Logfile (Delete-UnusedIntuneApps-yyyy-m-dd.log) | |
| which will be created in the ScriptRoot. | |
| Requires | |
| - Modules Microsoft.Graph.Intune and Microsoft.Graph.Authentication | |
| - Install-Module Microsoft.Graph.Authentication -Force | |
| - Access to MSGraph with Consent (DeviceManagementApps.ReadWrite.All) | |
| - Tested with PowerShell 7.4 | |
| .EXAMPLE | |
| PS> .\Delete-UnusedIntuneAppss.ps1 | |
| DryRun Mode | |
| .EXAMPLE | |
| PS> .\Delete-UnusedIntuneApps.ps1 -Force | |
| With Force Mode devices will get wiped | |
| .NOTES | |
| Author: Marius Wyss ([email protected]) | |
| Date: 2024-09-10 | |
| Version: 1.1 | |
| .LINK | |
| https://gist.github.com/MrWyss-MSFT/c063ab39cf0bcab868e31503b27fe1d8 | |
| #> | |
| #Requires -Modules @{ ModuleName="Microsoft.Graph.Authentication"; ModuleVersion="2.20.0" } | |
| [CmdletBinding()] | |
| Param( | |
| [Parameter(Mandatory = $false)] | |
| [Switch] | |
| $Force | |
| ) | |
| #region Variables | |
| $ScriptName = "Delete-UnusedIntuneApps" | |
| $ScriptDirectory = Split-Path $MyInvocation.MyCommand.Path | |
| $LogFilePath = Join-Path $ScriptDirectory "$ScriptName-$(Get-Date -Format yyyy-M-dd).log" | |
| $PSDefaultParameterValues = @{ | |
| "Write-Log:Path" = $LogFilePath | |
| "Write-Log:Component" = $ScriptName | |
| "Write-Log:Type" = "Info" | |
| "Write-Log:ConsoleOutput" = $True | |
| } | |
| #endregion | |
| #region Functions | |
| Function Write-Log { | |
| <# | |
| .SYNOPSIS | |
| Writes CMTrace log file, customized version of https://janikvonrotz.ch/2017/10/26/powershell-logging-in-cmtrace-format/ | |
| #> | |
| [CmdletBinding()] | |
| Param( | |
| [parameter(Mandatory = $true)] | |
| [String]$Path, | |
| [parameter(Mandatory = $true, ValueFromPipeline)] | |
| [String]$Message, | |
| [parameter(Mandatory = $true)] | |
| [String]$Component, | |
| [Parameter(Mandatory = $true)] | |
| [ValidateSet("Info", "Warning", "Error")] | |
| [String]$Type, | |
| [Parameter(Mandatory = $false)] | |
| [Switch]$ConsoleOutput | |
| ) | |
| switch ($Type) { | |
| "Info" { [int]$Type = 1 } | |
| "Warning" { [int]$Type = 2 } | |
| "Error" { [int]$Type = 3 } | |
| } | |
| if ($ConsoleOutput.IsPresent) { | |
| switch ($Type) { | |
| 1 { $ForgroundColor = "White" } | |
| 2 { $ForgroundColor = "Yellow" } | |
| 3 { $ForgroundColor = "Red" } | |
| } | |
| $OutPut = "{0} : {1}" -f $(Get-Date -Format "MM-d-yyyy HH:mm:ss.ffffff"), $Message | |
| write-host $OutPut -ForegroundColor $ForgroundColor | |
| } | |
| # Create a log entry | |
| $Content = "<![LOG[$Message]LOG]!>" + ` | |
| "<time=`"$(Get-Date -Format "HH:mm:ss.ffffff")`" " + ` | |
| "date=`"$(Get-Date -Format "M-d-yyyy")`" " + ` | |
| "component=`"$Component`" " + ` | |
| "context=`"$([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)`" " + ` | |
| "type=`"$Type`" " + ` | |
| "thread=`"$([Threading.Thread]::CurrentThread.ManagedThreadId)`" " + ` | |
| "file=`"`">" | |
| # Write the line to the log file | |
| $Content | Out-File -FilePath $Path -Append -Encoding UTF8 | |
| } | |
| #endregion | |
| #region Prerequisites Check | |
| if (-not (Get-Module -Name "Microsoft.Graph.Authentication" -ListAvailable)) { | |
| Write-Host "Missing Modules, please run:" -ForegroundColor Yellow | |
| Write-Host @" | |
| Install-Module "Microsoft.Graph.Authentication" -Force | |
| Import-Module "Microsoft.Graph.Authentication" | |
| "@ -ForegroundColor Green | |
| break | |
| } | |
| #endregion | |
| #region Main Code | |
| Write-Log -Message "--- Start $ScriptName ---" | |
| # region Connect to Microsoft Graph | |
| Connect-MgGraph -Scopes "DeviceManagementApps.ReadWrite.All" -NoWelcome | |
| #endregion | |
| # Discovered with the browser developer tools (F12) in https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/AppsMenu/~/allApps | |
| $url = "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps?" + | |
| "`$filter=((isof('microsoft.graph.win32LobApp') and not(isof('microsoft.graph.win32CatalogApp')))) " + | |
| "and (microsoft.graph.managedApp/appAvailability eq null or microsoft.graph.managedApp/appAvailability eq 'lineOfBusiness' or isAssigned eq true) " + | |
| "and isAssigned eq false" + | |
| "&`$orderby=displayName" | |
| $UnusedApps = Invoke-MgGraphRequest -uri $url | |
| $SelectedApps = $UnusedApps.Value | Select-Object displayName, displayVersion, lastModifiedDateTime, description,id | Out-GridView -OutputMode Multiple -Title "$ScriptName" | |
| Write-Log -Message "Selected Apps: $($SelectedApps.Count), json=$($SelectedApps | ConvertTo-Json)" -Type Info -ConsoleOutput:$false | |
| Write-Output "Selected Apps: $($SelectedApps.Count)" | |
| # Delete the selected apps | |
| ForEach ($App in $SelectedApps) { | |
| $AppId = $App.id | |
| Write-Log -Message "Deleting App: $($App.displayName), id=$AppId, version=$($App.displayVersion)" -Type Warning | |
| try { | |
| if ($Force) { | |
| Invoke-MgRestMethod -Method DELETE -Uri "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps/$AppId" | |
| Write-Log -Message "Deleted App: $($App.displayName), id=$App, version=$($App.displayVersion)" -Type Info | |
| } else { | |
| Write-Log -Message "DryRun: Deleted App: $($App.displayName), id=$App, version=$($App.displayVersion)" -Type Info | |
| } | |
| } | |
| catch { | |
| Write-Log -Message "Failed to delete App: $($App.displayName), id=$App, version=$($App.displayVersion)" -Type Error | |
| Write-Log -Message $_.ErrorDetails.Message -Type Error | |
| } | |
| } | |
| Write-Log -Message "--- End $ScriptName ---" | |
| #endregion |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment