-
-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updating previously updated apps with PowerShell (#41)
* Updating apps previously created with WinTuner * Updating categories with PowerShell * Assigning apps with PowerShell
- Loading branch information
Showing
22 changed files
with
2,234 additions
and
143 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
using Microsoft.Extensions.Logging; | ||
using Svrooij.PowerShell.DependencyInjection; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Management.Automation; | ||
using System.Net.Http; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using WingetIntune.Graph; | ||
|
||
namespace Svrooij.WinTuner.CmdLets.Commands; | ||
|
||
/// <summary> | ||
/// <para type="synopsis">Get all apps from Intune packaged by WinTuner</para> | ||
/// <para type="description">Load apps from Tenant and filter based on Update Availabe, pipe to `New-IntuneWinPackage`</para> | ||
/// <para type="link" uri="https://wintuner.app/docs/wintuner-powershell/Get-WtWin32Apps">Documentation</para> | ||
/// </summary> | ||
/// <example> | ||
/// <para type="description">Get all apps that have updates, using interactive authentication</para> | ||
/// <code>Get-WtWin32Apps -Update $true -Username [email protected]</code> | ||
/// </example> | ||
[Cmdlet(VerbsCommon.Get, "WtWin32Apps")] | ||
[OutputType(typeof(Models.WtWin32App[]))] | ||
public class GetWtWin32Apps : BaseIntuneCmdlet | ||
{ | ||
/// <summary> | ||
/// <para type="description">Filter based on UpdateAvailable</para> | ||
/// </summary> | ||
[Parameter(Mandatory = false, | ||
HelpMessage = "Filter based on UpdateAvailable")] | ||
public bool? Update { get; set; } | ||
|
||
/// <summary> | ||
/// <para type="description">Filter based on SupersedingAppCount</para> | ||
/// </summary> | ||
[Parameter(Mandatory = false, | ||
HelpMessage = "Filter based on SupersedingAppCount")] | ||
public bool? Superseded { get; set; } | ||
|
||
/// <summary> | ||
/// <para type="description">Filter based on SupersedingAppCount</para> | ||
/// </summary> | ||
[Parameter(Mandatory = false, | ||
HelpMessage = "Filter based on SupersedingAppCount")] | ||
public bool? Superseding { get; set; } | ||
|
||
[ServiceDependency] | ||
private ILogger<GetWtWin32Apps>? logger; | ||
|
||
[ServiceDependency] | ||
private HttpClient? httpClient; | ||
|
||
[ServiceDependency] | ||
private Winget.CommunityRepository.WingetRepository? repo; | ||
|
||
/// <inheritdoc/> | ||
public override async Task ProcessRecordAsync(CancellationToken cancellationToken) | ||
{ | ||
ValidateAuthenticationParameters(); | ||
logger?.LogInformation("Getting list of published apps"); | ||
|
||
var graphServiceClient = CreateGraphServiceClient(httpClient!); | ||
var apps = await graphServiceClient.DeviceAppManagement.MobileApps.GetWinTunerAppsAsync(cancellationToken); | ||
|
||
List<Models.WtWin32App> result = new(); | ||
|
||
foreach (var app in apps) | ||
{ | ||
var version = await repo!.GetLatestVersion(app.PackageId, cancellationToken); | ||
result.Add(new Models.WtWin32App | ||
{ | ||
GraphId = app.GraphId, | ||
PackageId = app.PackageId, | ||
Name = app.Name, | ||
CurrentVersion = app.CurrentVersion, | ||
SupersededAppCount = app.SupersededAppCount, | ||
SupersedingAppCount = app.SupersedingAppCount, | ||
LatestVersion = version, | ||
}); | ||
} | ||
|
||
if (Update.HasValue) | ||
{ | ||
result = result.Where(x => x.IsUpdateAvailable == Update.Value).ToList(); | ||
} | ||
|
||
if (Superseded.HasValue) | ||
{ | ||
result = result.Where(x => x.SupersedingAppCount > 0 == Superseded.Value).ToList(); | ||
} | ||
|
||
if (Superseding.HasValue) | ||
{ | ||
result = Superseding.Value ? result.Where(x => x.SupersededAppCount > 0).ToList() : result.Where(x => x.SupersededAppCount == 0).ToList(); | ||
} | ||
|
||
WriteObject(result); | ||
} | ||
} |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
using Microsoft.Extensions.Logging; | ||
using Svrooij.PowerShell.DependencyInjection; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Management.Automation; | ||
using System.Net.Http; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace Svrooij.WinTuner.CmdLets.Commands; | ||
|
||
/// <summary> | ||
/// <para type="synopsis">Remove an app from Intune</para> | ||
/// <para type="description">Will remove the relationships (if any) first and then remove the app.</para> | ||
/// <para type="link" uri="https://wintuner.app/docs/wintuner-powershell/Remove-WtWin32App">Documentation</para> | ||
/// </summary> | ||
/// <example> | ||
/// <para type="description">Delete a single app by ID with interactive authentication</para> | ||
/// <code>Remove-WtWin32App -AppId "1450c17d-aee5-4bef-acf9-9e0107d340f2" -Username [email protected]</code> | ||
/// </example> | ||
[Cmdlet(VerbsCommon.Remove, "WtWin32App")] | ||
public class RemoveWtWin32App : BaseIntuneCmdlet | ||
{ | ||
/// <summary> | ||
/// <para type="description">Id of the app in Intune</para> | ||
/// </summary> | ||
[Parameter(Mandatory = true, | ||
HelpMessage = "Id of the app in Intune")] | ||
public string? AppId { get; set; } | ||
|
||
[ServiceDependency] | ||
private ILogger<RemoveWtWin32App>? logger; | ||
|
||
[ServiceDependency] | ||
private HttpClient? httpClient; | ||
|
||
/// <inheritdoc/> | ||
public override async Task ProcessRecordAsync(CancellationToken cancellationToken) | ||
{ | ||
ValidateAuthenticationParameters(); | ||
logger?.LogInformation("Removing app {appId} from Intune", AppId); | ||
|
||
var graphServiceClient = CreateGraphServiceClient(httpClient!); | ||
|
||
// Load the app to get the relationships | ||
var app = await graphServiceClient.DeviceAppManagement.MobileApps[AppId].GetAsync(cancellationToken: cancellationToken); | ||
|
||
if (app?.SupersedingAppCount > 0) // This means deletion will fail | ||
{ | ||
// Load the relationships to see if we can remove them | ||
var relationships = await graphServiceClient.DeviceAppManagement.MobileApps[AppId].Relationships.GetAsync(cancellationToken: cancellationToken); | ||
|
||
foreach (var relationship in relationships!.Value!.Where(r => r.TargetType == Microsoft.Graph.Beta.Models.MobileAppRelationshipType.Parent)) | ||
{ | ||
logger?.LogInformation("Updating relations of app {parentAppId} to remove {appId}", relationship.TargetId, AppId); | ||
var parentRelationShips = await graphServiceClient.DeviceAppManagement.MobileApps[relationship.TargetId].Relationships.GetAsync(cancellationToken: cancellationToken); | ||
await graphServiceClient.DeviceAppManagement.MobileApps[relationship.TargetId].UpdateRelationships.PostAsync(new Microsoft.Graph.Beta.DeviceAppManagement.MobileApps.Item.UpdateRelationships.UpdateRelationshipsPostRequestBody | ||
{ | ||
Relationships = parentRelationShips?.Value?.Where(r => r.TargetId != AppId).ToList() ?? new List<Microsoft.Graph.Beta.Models.MobileAppRelationship>() | ||
}, cancellationToken: cancellationToken); | ||
} | ||
|
||
logger?.LogInformation("Relationship removed, waiting 2 seconds before removing app"); | ||
await Task.Delay(2000, cancellationToken); | ||
} | ||
|
||
await graphServiceClient.DeviceAppManagement.MobileApps[AppId].DeleteAsync(cancellationToken: cancellationToken); | ||
logger?.LogInformation("App {appId} removed from Intune", AppId); | ||
} | ||
} |
Oops, something went wrong.