Skip to content

Commit

Permalink
feat: Enable auto update
Browse files Browse the repository at this point in the history
  • Loading branch information
svrooij committed Apr 24, 2024
1 parent 7f6d8ec commit ebd9d87
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 33 deletions.
12 changes: 11 additions & 1 deletion src/Svrooij.WinTuner.CmdLets/Commands/DeployWtWin32App.cs
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,19 @@ await batch.AddBatchRequestStepAsync(graphServiceClient.DeviceAppManagement.Mobi
// Copy assignments from old app to new app
if (oldWin32App.Assignments is not null && oldWin32App.Assignments.Count > 0)
{
// This part is to enable auto update for the new app, if that was not set on the old app
var assignments = oldWin32App.Assignments;
foreach (var assignment in assignments)
{
if (assignment.Intent == GraphModels.InstallIntent.Available && assignment.Settings is null)
{
assignment.Settings = new GraphModels.Win32LobAppAssignmentSettings { AutoUpdateSettings = new GraphModels.Win32LobAppAutoUpdateSettings { AutoUpdateSupersededApps = GraphModels.Win32LobAppAutoUpdateSupersededApps.Enabled } };
}
}

await batch.AddBatchRequestStepAsync(graphServiceClient.DeviceAppManagement.MobileApps[newAppId].Assign.ToPostRequestInformation(new Microsoft.Graph.Beta.DeviceAppManagement.MobileApps.Item.Assign.AssignPostRequestBody
{
MobileAppAssignments = oldWin32App.Assignments
MobileAppAssignments = assignments, //oldWin32App.Assignments
}));

// Remove assignments from old app
Expand Down
11 changes: 9 additions & 2 deletions src/Svrooij.WinTuner.CmdLets/Commands/Update-WtIntuneApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Svrooij.WinTuner.CmdLets.Commands;
/// </summary>
/// <example>
/// <para type="description">Update the categories of an app and make it available for all users</para>
/// <code>Update-WtIntuneApp -AppId "1450c17d-aee5-4bef-acf9-9e0107d340f2" -UseDefaultCredentials -Categories "Productivity","Business" -AvailableFor "AllUsers"</code>
/// <code>Update-WtIntuneApp -AppId "1450c17d-aee5-4bef-acf9-9e0107d340f2" -UseDefaultCredentials -Categories "Productivity","Business" -AvailableFor "AllUsers" -EnableAutoUpdate $true</code>
/// </example>
[Cmdlet(VerbsData.Update, "WtIntuneApp")]
[OutputType(typeof(MobileApp))]
Expand Down Expand Up @@ -58,6 +58,13 @@ public class UpdateWtIntuneApp : BaseIntuneCmdlet
HelpMessage = "Groups that the app should be uninstalled for, Group Object ID or 'AllUsers'/'AllDevices'")]
public string[]? UninstallFor { get; set; }

/// <summary>
/// <para type="description">Enable auto update for the app</para>
/// </summary>
[Parameter(Mandatory = false,
HelpMessage = "Enable auto update for the app")]
public bool EnableAutoUpdate { get; set; } = false;

[ServiceDependency]
private ILogger<UpdateWtIntuneApp>? logger;

Expand All @@ -83,7 +90,7 @@ public override async Task ProcessRecordAsync(CancellationToken cancellationToke
(UninstallFor is not null && UninstallFor.Any()))
{
logger?.LogInformation("Assigning app {appId} to groups", AppId);
await graphServiceClient.AssignAppAsync(AppId!, RequiredFor, AvailableFor, UninstallFor, cancellationToken);
await graphServiceClient.AssignAppAsync(AppId!, RequiredFor, AvailableFor, UninstallFor, EnableAutoUpdate, cancellationToken);
}

// Load the app to get the relationships
Expand Down
24 changes: 24 additions & 0 deletions src/Svrooij.WinTuner.CmdLets/Svrooij.WinTuner.CmdLets.dll-Help.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1961,6 +1961,18 @@
</dev:type>
<dev:defaultValue>None</dev:defaultValue>
</command:parameter>
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="named" aliases="none">
<maml:name>EnableAutoUpdate</maml:name>
<maml:description>
<maml:para>Enable auto update for the app</maml:para>
</maml:description>
<command:parameterValue required="true" variableLength="false">Boolean</command:parameterValue>
<dev:type>
<maml:name>Boolean</maml:name>
<maml:uri />
</dev:type>
<dev:defaultValue>None</dev:defaultValue>
</command:parameter>
</command:syntaxItem>
</command:syntax>
<command:parameters>
Expand Down Expand Up @@ -2120,6 +2132,18 @@
</dev:type>
<dev:defaultValue>None</dev:defaultValue>
</command:parameter>
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="named" aliases="none">
<maml:name>EnableAutoUpdate</maml:name>
<maml:description>
<maml:para>Enable auto update for the app</maml:para>
</maml:description>
<command:parameterValue required="true" variableLength="false">Boolean</command:parameterValue>
<dev:type>
<maml:name>Boolean</maml:name>
<maml:uri />
</dev:type>
<dev:defaultValue>None</dev:defaultValue>
</command:parameter>
</command:parameters>
<command:inputTypes>
<command:inputType>
Expand Down
2 changes: 1 addition & 1 deletion src/Svrooij.WinTuner.CmdLets/WinTuner.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"New-WtWingetPackage",
"Remove-WtWin32App",
"Unprotect-IntuneWinPackage"
"Update-WtWin32App"
"Update-WtIntuneApp"
)

# Variables to export from this module.
Expand Down
22 changes: 19 additions & 3 deletions src/Svrooij.WinTuner.CmdLets/docs/Update-WtIntuneApp.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ Update an app in Intune

```
Update-WtIntuneApp -AppId <String> [-Categories <String[]>] [-AvailableFor <String[]>]
[-RequiredFor <String[]>] [-UninstallFor <String[]>] [[-UseManagedIdentity] <Boolean>]
[[-UseDefaultAzureCredential] <Boolean>] [[-Token] <String>] [[-Username] <String>] [[-TenantId] <String>]
[[-ClientId] <String>] [[-ClientSecret] <String>] [-ProgressAction <ActionPreference>] [<CommonParameters>]
[-RequiredFor <String[]>] [-UninstallFor <String[]>] [-EnableAutoUpdate <Boolean>]
[[-UseManagedIdentity] <Boolean>] [[-UseDefaultAzureCredential] <Boolean>] [[-Token] <String>]
[[-Username] <String>] [[-TenantId] <String>] [[-ClientId] <String>] [[-ClientSecret] <String>]
[-ProgressAction <ActionPreference>] [<CommonParameters>]
```

## DESCRIPTION
Expand Down Expand Up @@ -231,6 +232,21 @@ Accept pipeline input: False
Accept wildcard characters: False
```
### -EnableAutoUpdate
Enable auto update for the app
```yaml
Type: Boolean
Parameter Sets: (All)
Aliases:

Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### CommonParameters
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
Expand Down
5 changes: 4 additions & 1 deletion src/WingetIntune.Cli/Commands/PublishCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public PublishCommand() : base(name, description)
AddOption(RequiredForOption);
AddOption(UninstallForOption);
AddOption(new Option<bool>("--auto-package", "Automatically package the app if it's not found in the package folder") { IsHidden = true });
AddOption(new Option<bool>("--auto-update", "Turn on auto update, if assigned as available") { IsHidden = true });
AddOption(PackageCommand.GetArchitectureOption(isHidden: true));
AddOption(PackageCommand.GetInstallerContextOption(isHidden: true));
this.Handler = CommandHandler.Create(HandleCommand);
Expand Down Expand Up @@ -99,7 +100,8 @@ await intuneManager.GenerateInstallerPackage(options.TempFolder,
Categories = options.Category,
AvailableFor = options.Available,
RequiredFor = options.Required,
UninstallFor = options.Uninstall
UninstallFor = options.Uninstall,
AddAutoUpdateSetting = options.AutoUpdate
};

var app = packageInfo.Source == PackageSource.Store
Expand All @@ -124,6 +126,7 @@ internal class PublishCommandOptions : WinGetRootCommand.DefaultOptions
public string[] Uninstall { get; set; } = Array.Empty<string>();

public bool AutoPackage { get; set; }
public bool AutoUpdate { get; set; }
public string TempFolder { get; set; }
public InstallerContext InstallerContext { get; set; }
public Architecture Architecture { get; set; }
Expand Down
47 changes: 26 additions & 21 deletions src/WingetIntune/Graph/GraphWorkflows.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.Graph.Beta;
using Microsoft.Graph.Beta.DeviceManagement.Monitoring.AlertRecords.MicrosoftGraphDeviceManagementGetPortalNotifications;
using Microsoft.Graph.Beta.Models;
using WingetIntune.Extensions;
using WingetIntune.Intune;
Expand Down Expand Up @@ -27,7 +28,7 @@ public static async Task AddIntuneCategoriesToApp(this GraphServiceClient graphS
await graphServiceClient.Batch.PostAsync(batch, cancellationToken);
}

public static async Task<int> AssignAppAsync(this GraphServiceClient graphServiceClient, string appId, string[]? requiredFor, string[]? availableFor, string[]? uninstallFor, CancellationToken cancellationToken)
public static async Task<int> AssignAppAsync(this GraphServiceClient graphServiceClient, string appId, string[]? requiredFor, string[]? availableFor, string[]? uninstallFor, bool addAutoUpdateSetting, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(graphServiceClient);
ArgumentException.ThrowIfNullOrEmpty(appId);
Expand All @@ -41,7 +42,7 @@ public static async Task<int> AssignAppAsync(this GraphServiceClient graphServic

if (availableFor is not null && availableFor.Any())
{
assignments.AddRange(GenerateAssignments(availableFor, InstallIntent.Available));
assignments.AddRange(GenerateAssignments(availableFor, InstallIntent.Available, addAutoUpdateSetting));
}

if (uninstallFor is not null && uninstallFor.Any())
Expand All @@ -61,40 +62,44 @@ await graphServiceClient.DeviceAppManagement.MobileApps[appId].Assign.PostAsync(
return assignments.Count;
}

private static List<MobileAppAssignment> GenerateAssignments(string[] groups, InstallIntent intent)
private static List<MobileAppAssignment> GenerateAssignments(string[] groups, InstallIntent intent, bool addSetting = false)
{
List<MobileAppAssignment> assignments = new List<MobileAppAssignment>();
MobileAppAssignmentSettings? settings = null;
if (intent == InstallIntent.Available && addSetting)
{
settings = new Win32LobAppAssignmentSettings { AutoUpdateSettings = new Win32LobAppAutoUpdateSettings { AutoUpdateSupersededApps = Win32LobAppAutoUpdateSupersededApps.Enabled } };
}
if (groups is not null && groups.Any())
{
var groupsGuids = groups.Where(x => Guid.TryParse(x, out _));
if (groupsGuids.Count() > 0)
{
assignments.AddRange(groupsGuids.Select(x => new MobileAppAssignment
{
Intent = intent,
Target = new GroupAssignmentTarget
{
GroupId = x
}
}));
assignments.AddRange(groupsGuids.Select(x => CreateAssignment(intent, new GroupAssignmentTarget { GroupId = x }, settings)));
}
if (groups.ContainsIgnoreCase(IntuneManagerConstants.AllUsers))
{
assignments.Add(new MobileAppAssignment
{
Intent = intent,
Target = new AllLicensedUsersAssignmentTarget()
});
assignments.Add(CreateAssignment(intent, new AllLicensedUsersAssignmentTarget(), settings));
}
if (groups.ContainsIgnoreCase(IntuneManagerConstants.AllDevices))
{
assignments.Add(new MobileAppAssignment
{
Intent = intent,
Target = new AllDevicesAssignmentTarget()
});
assignments.Add(CreateAssignment(intent, new AllDevicesAssignmentTarget(), settings));
}
}
return assignments;
}

private static MobileAppAssignment CreateAssignment(InstallIntent intent, DeviceAndAppManagementAssignmentTarget target, MobileAppAssignmentSettings? settings = null)
{
var a = new MobileAppAssignment
{
Intent = intent,
Target = target,
};
if (settings is not null)
{
a.AdditionalData.Add("settings", settings);
}
return a;
}
}
8 changes: 4 additions & 4 deletions src/WingetIntune/Intune/IntuneManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ public async Task<MobileApp> PublishAppAsync(string packagesFolder, PackageInfo

if (options.AvailableFor.Any() || options.RequiredFor.Any() || options.UninstallFor.Any())
{
await AssignAppAsync(graphServiceClient, app!.Id!, options.RequiredFor, options.AvailableFor, options.UninstallFor, cancellationToken);
await AssignAppAsync(graphServiceClient, app!.Id!, options.RequiredFor, options.AvailableFor, options.UninstallFor, options.AddAutoUpdateSetting, cancellationToken);
}
return app!;
}
Expand Down Expand Up @@ -359,7 +359,7 @@ public async Task<WinGetApp> PublishStoreAppAsync(IntunePublishOptions options,
}
if (options.AvailableFor.Any() || options.RequiredFor.Any() || options.UninstallFor.Any())
{
await AssignAppAsync(graphServiceClient, appCreated.Id!, options.RequiredFor, options.AvailableFor, options.UninstallFor, cancellationToken);
await AssignAppAsync(graphServiceClient, appCreated.Id!, options.RequiredFor, options.AvailableFor, options.UninstallFor, false, cancellationToken);
}
return appCreated;
}
Expand Down Expand Up @@ -404,15 +404,15 @@ private async Task AddCategoriesToApp(GraphServiceClient graphServiceClient, str
}
}

private async Task AssignAppAsync(GraphServiceClient graphServiceClient, string appId, string[]? requiredFor, string[]? availableFor, string[]? uninstallFor, CancellationToken cancellationToken)
private async Task AssignAppAsync(GraphServiceClient graphServiceClient, string appId, string[]? requiredFor, string[]? availableFor, string[]? uninstallFor, bool addAutoUpdateSetting, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(graphServiceClient);
ArgumentException.ThrowIfNullOrEmpty(appId);
ArgumentNullException.ThrowIfNull(cancellationToken);

try
{
var assignments = await GraphWorkflows.AssignAppAsync(graphServiceClient, appId, requiredFor, availableFor, uninstallFor, cancellationToken);
var assignments = await GraphWorkflows.AssignAppAsync(graphServiceClient, appId, requiredFor, availableFor, uninstallFor, addAutoUpdateSetting, cancellationToken);
logger.LogInformation("Assigned app {appId} to {assignmentCount} assignments", appId, assignments);
}
catch (Exception ex)
Expand Down
2 changes: 2 additions & 0 deletions src/WingetIntune/Intune/IntunePublishOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ public class IntunePublishOptions
public string[] AvailableFor { get; set; } = Array.Empty<string>();
public string[] RequiredFor { get; set; } = Array.Empty<string>();
public string[] UninstallFor { get; set; } = Array.Empty<string>();

public bool AddAutoUpdateSetting { get; set; }
}

0 comments on commit ebd9d87

Please sign in to comment.