forked from MSEndpointMgr/IntuneWin32App
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Add-IntuneWin32AppAssignmentGroup.ps1
351 lines (295 loc) · 18.4 KB
/
Add-IntuneWin32AppAssignmentGroup.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
function Add-IntuneWin32AppAssignmentGroup {
<#
.SYNOPSIS
Add a group based assignment to a Win32 app.
.DESCRIPTION
Add a group based assignment to a Win32 app.
.PARAMETER Include
Specify the Group Mode of the assignment to be Include for the Win32 app.
.PARAMETER Exclude
Specify the Group Mode of the assignment to be Exclude for the Win32 app.
.PARAMETER ID
Specify the ID for a Win32 application.
.PARAMETER GroupID
Specify the ID for an Azure AD group.
.PARAMETER Intent
Specify the intent of the assignment, either required, available or uninstall.
.PARAMETER Notification
Specify the notification setting for the assignment of the Win32 app.
.PARAMETER AvailableTime
Specify a date time object for the availability of the assignment.
.PARAMETER DeadlineTime
Specify a date time object for the deadline of the assignment.
.PARAMETER AutoUpdateSupersededApps
Specify to automatically update superseded app using default value of 'notConfigured'.
.PARAMETER UseLocalTime
Specify to use either UTC of device local time for the assignment, set to 'True' for device local time and 'False' for UTC.
.PARAMETER DeliveryOptimizationPriority
Specify to download content in the background using default value of 'notConfigured', or set to download in foreground using 'foreground'.
.PARAMETER EnableRestartGracePeriod
Specify whether Restart Grace Period functionality for this assignment should be configured, additional parameter input using at least RestartGracePeriod and RestartCountDownDisplay is required.
.PARAMETER RestartGracePeriod
Specify the device restart grace period in minutes.
.PARAMETER RestartCountDownDisplay
Specify a count in minutes when the restart count down display box is shown.
.PARAMETER RestartNotificationSnooze
Specify a count in minutes for snoozing the restart notification, if not specified the snooze functionality is now allowed.
.PARAMETER FilterName
Specify the name of an existing Filter.
.PARAMETER FilterMode
Specify the filter mode of the specified Filter, e.g. Include or Exclude.
.NOTES
Author: Nickolaj Andersen
Contact: @NickolajA
Created: 2020-09-20
Updated: 2024-09-03
Version history:
1.0.0 - (2020-09-20) Function created
1.0.1 - (2021-04-01) Fixed a warning message text that was referencing an incorrect variable
1.0.2 - (2021-04-01) Updated token expired message to a warning instead of verbose output
1.0.3 - (2021-08-31) Updated to use new authentication header
1.0.4 - (2023-09-04) Updated with Test-AccessToken function
1.0.5 - (2023-09-20) Updated with FilterName and FilterMode parameters
1.0.6 - (2024-09-03) Updated with autoUpdateSettings parameters
1.0.7 - (2024-09-03) Deleted AvailableTime validation
#>
[CmdletBinding(SupportsShouldProcess = $true)]
param(
[parameter(Mandatory = $true, ParameterSetName = "GroupInclude", HelpMessage = "Specify the Group Mode of the assignment to be Include for the Win32 app.")]
[switch]$Include,
[parameter(Mandatory = $true, ParameterSetName = "GroupExclude", HelpMessage = "Specify the Group Mode of the assignment to be Exclude for the Win32 app..")]
[switch]$Exclude,
[parameter(Mandatory = $true, ParameterSetName = "GroupInclude", HelpMessage = "Specify the ID for a Win32 application.")]
[parameter(Mandatory = $true, ParameterSetName = "GroupExclude")]
[ValidateNotNullOrEmpty()]
[string]$ID,
[parameter(Mandatory = $true, ParameterSetName = "GroupInclude", HelpMessage = "Specify the ID for an Azure AD group.")]
[parameter(Mandatory = $true, ParameterSetName = "GroupExclude")]
[ValidateNotNullOrEmpty()]
[string]$GroupID,
[parameter(Mandatory = $true, ParameterSetName = "GroupInclude", HelpMessage = "Specify the intent of the assignment, either required, available or uninstall.")]
[parameter(Mandatory = $true, ParameterSetName = "GroupExclude")]
[ValidateNotNullOrEmpty()]
[ValidateSet("required", "available", "uninstall")]
[string]$Intent,
[parameter(Mandatory = $false, ParameterSetName = "GroupInclude", HelpMessage = "Specify the notification setting for the assignment of the Win32 app.")]
[ValidateNotNullOrEmpty()]
[ValidateSet("showAll", "showReboot", "hideAll")]
[string]$Notification = "showAll",
[parameter(Mandatory = $false, ParameterSetName = "GroupInclude", HelpMessage = "Specify a date time object for the availability of the assignment.")]
[ValidateNotNullOrEmpty()]
[datetime]$AvailableTime,
[parameter(Mandatory = $false, ParameterSetName = "GroupInclude", HelpMessage = "Specify a date time object for the deadline of the assignment.")]
[ValidateNotNullOrEmpty()]
[datetime]$DeadlineTime,
[parameter(Mandatory = $false, ParameterSetName = "GroupInclude", HelpMessage = "Specify to use either UTC of device local time for the assignment, set to 'True' for device local time and 'False' for UTC.")]
[ValidateNotNullOrEmpty()]
[bool]$UseLocalTime = $false,
[parameter(Mandatory = $false, ParameterSetName = "GroupInclude", HelpMessage = "Specify to download content in the background using default value of 'notConfigured', or set to download in foreground using 'foreground'.")]
[ValidateNotNullOrEmpty()]
[ValidateSet("notConfigured", "foreground")]
[string]$DeliveryOptimizationPriority = "notConfigured",
[parameter(Mandatory = $false, HelpMessage = "Specify to automatically update superseded app using default value of 'notConfigured'.")]
[ValidateNotNullOrEmpty()]
[ValidateSet("notConfigured", "enabled", "unknownFutureValue")]
[string]$AutoUpdateSupersededApps = "notConfigured",
[parameter(Mandatory = $false, ParameterSetName = "GroupInclude", HelpMessage = "Specify whether Restart Grace Period functionality for this assignment should be configured, additional parameter input using at least RestartGracePeriod and RestartCountDownDisplay is required.")]
[ValidateNotNullOrEmpty()]
[bool]$EnableRestartGracePeriod = $false,
[parameter(Mandatory = $false, ParameterSetName = "GroupInclude", HelpMessage = "Specify the device restart grace period in minutes.")]
[ValidateNotNullOrEmpty()]
[ValidateRange(1, 20160)]
[int]$RestartGracePeriod = 1440,
[parameter(Mandatory = $false, ParameterSetName = "GroupInclude", HelpMessage = "Specify a count in minutes when the restart count down display box is shown.")]
[ValidateNotNullOrEmpty()]
[ValidateRange(1, 240)]
[int]$RestartCountDownDisplay = 15,
[parameter(Mandatory = $false, ParameterSetName = "GroupInclude", HelpMessage = "Specify a count in minutes for snoozing the restart notification, if not specified the snooze functionality is now allowed.")]
[ValidateNotNullOrEmpty()]
[ValidateRange(1, 712)]
[int]$RestartNotificationSnooze = 240,
[parameter(Mandatory = $false, ParameterSetName = "GroupInclude", HelpMessage = "Specify the name of an existing Filter.")]
[ValidateNotNullOrEmpty()]
[string]$FilterName,
[parameter(Mandatory = $false, ParameterSetName = "GroupInclude", HelpMessage = "Specify the filter mode of the specified Filter, e.g. Include or Exclude.")]
[ValidateSet("Include", "Exclude")]
[string]$FilterMode
)
Begin {
# Ensure required authentication header variable exists
if ($null -eq $Global:AuthenticationHeader) {
Write-Warning -Message "Authentication token was not found, use Connect-MSIntuneGraph before using this function"; break
}
else {
if ((Test-AccessToken) -eq $false) {
Write-Warning -Message "Existing token found but has expired, use Connect-MSIntuneGraph to request a new authentication token"; break
}
}
# Set script variable for error action preference
$ErrorActionPreference = "Stop"
# Validate that Deadline parameter input datetime object is in the future if the Available parameter is not passed on the command line
if ($PSBoundParameters["AutoUpdateSupersededApps"]) {
if ($PSBoundParameters["Intent"] -ne "available") {
Write-Warning -Message "Validation failed for parameter input, AutoUpdateSupersededApps is only allowed with Intent equals available."; break
}
}
# Validate that Deadline parameter input datetime object is in the future if the Available parameter is not passed on the command line
if ($PSBoundParameters["DeadlineTime"]) {
if (-not($PSBoundParameters["AvailableTime"])) {
if ($DeadlineTime -lt (Get-Date)) {
Write-Warning -Message "Validation failed for parameter input, deadline date time needs to be after the current used 'as soon as possible' available date and time"; break
}
}
}
# Output warning message that additional required parameters for restart grace period was not specified and default values will be used
if ($PSBoundParameters["EnableRestartGracePeriod"]) {
if (-not($PSBoundParameters["RestartGracePeriod"])) {
Write-Warning -Message "EnableRestartGracePeriod parameter was specified but required parameter RestartGracePeriod was not, using default value of: $($RestartGracePeriod)"
}
if (-not($PSBoundParameters["RestartCountDownDisplay"])) {
Write-Warning -Message "EnableRestartGracePeriod parameter was specified but required parameter RestartCountDownDisplay was not, using default value of: $($RestartCountDownDisplay)"
}
}
# Disable RestartNotificationSnooze functionality and set object to null if not passed on command line
if (-not($PSBoundParameters["RestartNotificationSnooze"])) {
[System.Object]$RestartNotificationSnooze = $null
Write-Verbose -Message "RestartNotificationSnooze parameter was not specified, which means 'Allow user to snooze the restart notification' functionality will be disabled for this assignment"
}
# Output warning message that additional required parameters for filter assignment configuration is required
if ($PSBoundParameters["FilterMode"]) {
if (-not($PSBoundParameters["FilterName"])) {
Write-Warning -Message "FilterMode parameter was specified but required parameter FilterName was not, please specify a Filter name to use for this assignment"
}
}
# Output verbose message that default value for FilterMode will be used if FilterName is passed on the command line, but FilterMode is not
if ($PSBoundParameters["FilterName"]) {
if (-not($PSBoundParameters["FilterMode"])) {
Write-Verbose -Message "FilterMode parameter was not specified, using default value of: Include"
$FilterMode = "Include"
}
}
}
Process {
# Get Filter object if parameter is passed on command line
if ($PSBoundParameters["FilterName"]) {
# Ensure Filter mode is lowercase
$FilterMode = $FilterMode.ToLower()
# Ensure a Filter exist by given name from parameter input
Write-Verbose -Message "Querying for specified Filter: $($FilterName)"
$AssignmentFilters = Invoke-MSGraphOperation -Get -APIVersion "Beta" -Resource "deviceManagement/assignmentFilters" -Verbose
if ($null -ne $AssignmentFilters) {
$AssignmentFilter = $AssignmentFilters | Where-Object { $PSItem.displayName -eq $FilterName }
if ($null -ne $AssignmentFilter) {
Write-Verbose -Message "Found Filter with display name '$($AssignmentFilter.displayName)' and id: $($AssignmentFilter.id)"
}
else {
Write-Warning -Message "Could not find Filter with display name: '$($FilterName)'"
}
}
}
# Retrieve Win32 app by ID from parameter input
Write-Verbose -Message "Querying for Win32 app using ID: $($ID)"
$Win32App = Invoke-IntuneGraphRequest -APIVersion "Beta" -Resource "mobileApps/$($ID)" -Method "GET"
if ($null -ne $Win32App) {
$Win32AppID = $Win32App.id
# Construct target assignment body
switch ($PSCmdlet.ParameterSetName) {
"GroupInclude" {
$DataType = "#microsoft.graph.groupAssignmentTarget"
}
"GroupExclude" {
$DataType = "#microsoft.graph.exclusionGroupAssignmentTarget"
}
}
$TargetAssignment = @{
"@odata.type" = $DataType
"deviceAndAppManagementAssignmentFilterId" = if ($null -ne $AssignmentFilter) { $AssignmentFilter.id } else { $null }
"deviceAndAppManagementAssignmentFilterType" = if ($null -ne $AssignmentFilter) { $FilterMode } else { "none" }
"groupId" = $GroupID
}
# Construct table for Win32 app assignment body
$Win32AppAssignmentBody = [ordered]@{
"@odata.type" = "#microsoft.graph.mobileAppAssignment"
"intent" = $Intent
"source" = "direct"
"target" = $TargetAssignment
}
switch ($PSCmdlet.ParameterSetName) {
"GroupInclude" {
$SettingsTable = @{
"@odata.type" = "#microsoft.graph.win32LobAppAssignmentSettings"
"notifications" = $Notification
"restartSettings" = $null
"deliveryOptimizationPriority" = $DeliveryOptimizationPriority
"installTimeSettings" = $null
}
$Win32AppAssignmentBody.Add("settings", $SettingsTable)
}
"GroupExclude" {
$Win32AppAssignmentBody.Add("settings", $null)
}
}
# Amend AutoUpdateSupersededApps property if Intent equals available and the app superseeds an other app
if (($Intent -eq "available") -and ($Win32App.supersededAppCount -gt 0)) {
$Win32AppAssignmentBody.settings.autoUpdateSettings = @{
"autoUpdateSupersededAppsState" = $AutoUpdateSupersededApps
}
}
# Amend installTimeSettings property if Available parameter is specified
if (($PSBoundParameters["AvailableTime"]) -and (-not($PSBoundParameters["DeadlineTime"]))) {
$Win32AppAssignmentBody.settings.installTimeSettings = @{
"useLocalTime" = $UseLocalTime
"startDateTime" = (ConvertTo-JSONDate -InputObject $AvailableTime)
"deadlineDateTime" = $null
}
}
# Amend installTimeSettings property if Deadline parameter is specified
if (($PSBoundParameters["DeadlineTime"]) -and (-not($PSBoundParameters["AvailableTime"]))) {
$Win32AppAssignmentBody.settings.installTimeSettings = @{
"useLocalTime" = $UseLocalTime
"startDateTime" = $null
"deadlineDateTime" = (ConvertTo-JSONDate -InputObject $DeadlineTime)
}
}
# Amend installTimeSettings property if Available and Deadline parameter is specified
if (($PSBoundParameters["AvailableTime"]) -and ($PSBoundParameters["DeadlineTime"])) {
$Win32AppAssignmentBody.settings.installTimeSettings = @{
"useLocalTime" = $UseLocalTime
"startDateTime" = (ConvertTo-JSONDate -InputObject $AvailableTime)
"deadlineDateTime" = (ConvertTo-JSONDate -InputObject $DeadlineTime)
}
}
# Amend restartSettings if app restart behavior is set to baseOnReturnCode and EnableRestartGracePeriod is set to True
if ($EnableRestartGracePeriod -eq $true) {
if ($Win32App.installExperience.deviceRestartBehavior -like "basedOnReturnCode") {
Write-Verbose -Message "Detected that Win32 app was configured for restart settings, adding parameter inputs to request"
$Win32AppAssignmentBody.settings.restartSettings = @{
"gracePeriodInMinutes" = $RestartGracePeriod
"countdownDisplayBeforeRestartInMinutes" = $RestartCountDownDisplay
"restartNotificationSnoozeDurationInMinutes" = $RestartNotificationSnooze
}
}
else {
Write-Warning -Message "Win32 app was not configured for restart settings, ensure restart behavior is configured with 'Based on return code'"
}
}
$DuplicateAssignment = Test-IntuneWin32AppAssignment -ID $Win32AppID -Target "Group"
if ($DuplicateAssignment -eq $false) {
try {
# Attempt to call Graph and create new assignment for Win32 app
$Win32AppAssignmentResponse = Invoke-IntuneGraphRequest -APIVersion "Beta" -Resource "mobileApps/$($Win32AppID)/assignments" -Method "POST" -Body ($Win32AppAssignmentBody | ConvertTo-Json) -ContentType "application/json" -ErrorAction Stop
if ($Win32AppAssignmentResponse.id) {
Write-Verbose -Message "Successfully created Win32 app assignment with ID: $($Win32AppAssignmentResponse.id)"
Write-Output -InputObject $Win32AppAssignmentResponse
}
}
catch [System.Exception] {
Write-Warning -Message "An error occurred while creating a Win32 app assignment. Error message: $($_.Exception.Message)"
}
}
}
else {
Write-Warning -Message "Query for Win32 app returned an empty result, no apps matching the specified search criteria with ID '$($ID)' was found"
}
}
}