Skip to content

Commit e116a50

Browse files
committed
feat(scripts): implement mobile app assignment script with filtering and error handling
1 parent e8752fe commit e116a50

1 file changed

Lines changed: 229 additions & 0 deletions

File tree

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
<#
2+
.SYNOPSIS
3+
Assigns all mobile apps in Intune as available to all users for testing.
4+
5+
.DESCRIPTION
6+
This script loops through all mobile apps in Microsoft Intune and assigns each one
7+
as "available" to all users. Useful for quickly testing app deployments.
8+
9+
.PARAMETER WhatIf
10+
Preview changes without making any assignments.
11+
12+
.PARAMETER AppTypes
13+
Filter to specific app types. Default includes common types.
14+
Examples: winGetApp, microsoftStoreForBusinessApp, win32LobApp
15+
16+
.EXAMPLE
17+
.\Set-MobileAppAssignments.ps1
18+
# Assigns all apps as available to all users
19+
20+
.EXAMPLE
21+
.\Set-MobileAppAssignments.ps1 -WhatIf
22+
# Preview what would be assigned without making changes
23+
24+
.EXAMPLE
25+
.\Set-MobileAppAssignments.ps1 -AppTypes @('winGetApp')
26+
# Only assign WinGet (Microsoft Store) apps
27+
28+
.NOTES
29+
Requires Microsoft.Graph.Authentication module and appropriate permissions:
30+
- DeviceManagementApps.ReadWrite.All
31+
#>
32+
33+
[CmdletBinding(SupportsShouldProcess)]
34+
param(
35+
[Parameter()]
36+
[string[]]$AppTypes = @(
37+
'#microsoft.graph.winGetApp',
38+
'#microsoft.graph.microsoftStoreForBusinessApp',
39+
'#microsoft.graph.win32LobApp',
40+
'#microsoft.graph.windowsMicrosoftEdgeApp',
41+
'#microsoft.graph.officeSuiteApp',
42+
'#microsoft.graph.macOSMicrosoftEdgeApp',
43+
'#microsoft.graph.macOSOfficeSuiteApp'
44+
)
45+
)
46+
47+
#region Functions
48+
function Connect-ToGraph {
49+
<#
50+
.SYNOPSIS
51+
Ensures connection to Microsoft Graph with required scopes
52+
#>
53+
$requiredScopes = @('DeviceManagementApps.ReadWrite.All')
54+
55+
$context = Get-MgContext
56+
if (-not $context) {
57+
Write-Host "Connecting to Microsoft Graph..." -ForegroundColor Cyan
58+
Connect-MgGraph -Scopes $requiredScopes -NoWelcome
59+
}
60+
else {
61+
# Check if we have the required scope
62+
$hasScope = $context.Scopes | Where-Object { $_ -like '*DeviceManagementApps*' }
63+
if (-not $hasScope) {
64+
Write-Host "Reconnecting with required scopes..." -ForegroundColor Yellow
65+
Disconnect-MgGraph | Out-Null
66+
Connect-MgGraph -Scopes $requiredScopes -NoWelcome
67+
}
68+
}
69+
}
70+
71+
function Get-AllMobileApps {
72+
<#
73+
.SYNOPSIS
74+
Retrieves all mobile apps from Intune with pagination support
75+
#>
76+
[CmdletBinding()]
77+
param()
78+
79+
$apps = @()
80+
$uri = "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps"
81+
82+
do {
83+
$response = Invoke-MgGraphRequest -Method GET -Uri $uri
84+
$apps += $response.value
85+
$uri = $response.'@odata.nextLink'
86+
} while ($uri)
87+
88+
return $apps
89+
}
90+
91+
function Get-AppAssignments {
92+
<#
93+
.SYNOPSIS
94+
Gets existing assignments for a mobile app
95+
#>
96+
[CmdletBinding()]
97+
param(
98+
[Parameter(Mandatory)]
99+
[string]$AppId
100+
)
101+
102+
$uri = "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps/$AppId/assignments"
103+
$response = Invoke-MgGraphRequest -Method GET -Uri $uri
104+
return $response.value
105+
}
106+
107+
function Set-AppAvailableToAllUsers {
108+
<#
109+
.SYNOPSIS
110+
Assigns an app as available to all users
111+
#>
112+
[CmdletBinding(SupportsShouldProcess)]
113+
param(
114+
[Parameter(Mandatory)]
115+
[string]$AppId,
116+
117+
[Parameter(Mandatory)]
118+
[string]$AppName
119+
)
120+
121+
# Check for existing "All Users" assignment
122+
$existingAssignments = Get-AppAssignments -AppId $AppId
123+
$hasAllUsersAssignment = $existingAssignments | Where-Object {
124+
$_.target.'@odata.type' -eq '#microsoft.graph.allLicensedUsersAssignmentTarget'
125+
}
126+
127+
if ($hasAllUsersAssignment) {
128+
Write-Host " [Skip] $AppName - Already assigned to All Users" -ForegroundColor DarkGray
129+
return @{
130+
Name = $AppName
131+
Status = 'Skipped'
132+
Reason = 'Already assigned'
133+
}
134+
}
135+
136+
if ($PSCmdlet.ShouldProcess($AppName, "Assign as Available to All Users")) {
137+
$assignmentBody = @{
138+
mobileAppAssignments = @(
139+
@{
140+
"@odata.type" = "#microsoft.graph.mobileAppAssignment"
141+
intent = "available"
142+
target = @{
143+
"@odata.type" = "#microsoft.graph.allLicensedUsersAssignmentTarget"
144+
}
145+
settings = $null
146+
}
147+
)
148+
}
149+
150+
try {
151+
$uri = "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps/$AppId/assign"
152+
Invoke-MgGraphRequest -Method POST -Uri $uri -Body $assignmentBody -ContentType "application/json" | Out-Null
153+
154+
Write-Host " [OK] $AppName" -ForegroundColor Green
155+
return @{
156+
Name = $AppName
157+
Status = 'Assigned'
158+
Reason = $null
159+
}
160+
}
161+
catch {
162+
Write-Host " [Error] $AppName - $($_.Exception.Message)" -ForegroundColor Red
163+
return @{
164+
Name = $AppName
165+
Status = 'Failed'
166+
Reason = $_.Exception.Message
167+
}
168+
}
169+
}
170+
else {
171+
Write-Host " [WhatIf] Would assign: $AppName" -ForegroundColor Yellow
172+
return @{
173+
Name = $AppName
174+
Status = 'WhatIf'
175+
Reason = $null
176+
}
177+
}
178+
}
179+
#endregion
180+
181+
#region Main
182+
Write-Host "`n=== Mobile App Assignment Script ===" -ForegroundColor Cyan
183+
Write-Host "This script assigns all mobile apps as 'Available' to All Users`n"
184+
185+
# Connect to Graph
186+
Connect-ToGraph
187+
188+
# Get all mobile apps
189+
Write-Host "Fetching mobile apps from Intune..." -ForegroundColor Cyan
190+
$allApps = Get-AllMobileApps
191+
192+
# Filter to specified app types
193+
$filteredApps = $allApps | Where-Object { $_.'@odata.type' -in $AppTypes }
194+
195+
Write-Host "Found $($filteredApps.Count) apps to process (filtered from $($allApps.Count) total)`n" -ForegroundColor Cyan
196+
197+
if ($filteredApps.Count -eq 0) {
198+
Write-Host "No apps found matching the specified types." -ForegroundColor Yellow
199+
exit 0
200+
}
201+
202+
# Process each app
203+
$results = @()
204+
Write-Host "Processing assignments:" -ForegroundColor Cyan
205+
206+
foreach ($app in $filteredApps) {
207+
$result = Set-AppAvailableToAllUsers -AppId $app.id -AppName $app.displayName
208+
$results += [PSCustomObject]$result
209+
}
210+
211+
# Summary
212+
Write-Host "`n=== Summary ===" -ForegroundColor Cyan
213+
$assigned = ($results | Where-Object { $_.Status -eq 'Assigned' }).Count
214+
$skipped = ($results | Where-Object { $_.Status -eq 'Skipped' }).Count
215+
$failed = ($results | Where-Object { $_.Status -eq 'Failed' }).Count
216+
$whatif = ($results | Where-Object { $_.Status -eq 'WhatIf' }).Count
217+
218+
Write-Host "Assigned: $assigned" -ForegroundColor Green
219+
Write-Host "Skipped: $skipped" -ForegroundColor DarkGray
220+
if ($failed -gt 0) {
221+
Write-Host "Failed: $failed" -ForegroundColor Red
222+
}
223+
if ($whatif -gt 0) {
224+
Write-Host "WhatIf: $whatif" -ForegroundColor Yellow
225+
}
226+
227+
# Return results for pipeline
228+
$results
229+
#endregion

0 commit comments

Comments
 (0)