Skip to content

Commit

Permalink
1.4.1
Browse files Browse the repository at this point in the history
  • Loading branch information
NickolajA committed Mar 18, 2023
1 parent 84b3d83 commit e2600c9
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 60 deletions.
3 changes: 2 additions & 1 deletion IntuneWin32App.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
RootModule = 'IntuneWin32App.psm1'

# Version number of this module.
ModuleVersion = '1.4.0'
ModuleVersion = '1.4.1'

# Supported PSEditions
# CompatiblePSEditions = @()
Expand Down Expand Up @@ -101,6 +101,7 @@ FunctionsToExport = @("Add-IntuneWin32App",
"Remove-IntuneWin32AppDependency",
"Remove-IntuneWin32AppSupersedence",
"Set-IntuneWin32App",
"Test-AccessToken",
"Update-IntuneWin32AppPackageFile"
)

Expand Down
16 changes: 4 additions & 12 deletions Private/Get-IntuneWin32AppRelationExistence.ps1
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
function Get-IntuneWin32AppRelationExistence {
function Get-IntuneWin32AppRelation {
<#
.SYNOPSIS
Retrieve any existing given supersedence or dependency (relations) configuration from an existing Win32 application.
Retrieve any existing supersedence and dependency (relations) configuration from an existing Win32 application.
.DESCRIPTION
Retrieve any existing given supersedence or dependency (relations) configuration from an existing Win32 application.
Retrieve any existing supersedence and dependency (relations) configuration from an existing Win32 application.
.PARAMETER ID
Specify the ID for an existing Win32 application to retrieve relation configuration from.
.PARAMETER Type
Specify the relation type, either Dependency or Supersedence.
.NOTES
Author: Nickolaj Andersen
Contact: @NickolajA
Expand All @@ -26,12 +23,7 @@ function Get-IntuneWin32AppRelationExistence {
param(
[parameter(Mandatory = $true, HelpMessage = "Specify the ID for an existing Win32 application to retrieve relation configuration from.")]
[ValidateNotNullOrEmpty()]
[string]$ID,

[parameter(Mandatory = $true, HelpMessage = "Specify the relation type, either Dependency or Supersedence.")]
[ValidateNotNullOrEmpty()]
[ValidateSet("Dependency", "Supersedence")]
[string]$Type
[string]$ID
)
Begin {
# Ensure required authentication header variable exists
Expand Down
69 changes: 46 additions & 23 deletions Private/New-IntuneWin32AppBody.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ function New-IntuneWin32AppBody {
.PARAMETER RestartBehavior
Specify the installation experience for the Win32 application body.
.PARAMETER AllowAvailableUninstall
Specify to allow the uninstall option when assigned as available of the Win32 application body.
.PARAMETER RequirementRule
Specify the requirement rules for the Win32 application body.
Expand Down Expand Up @@ -94,7 +97,7 @@ function New-IntuneWin32AppBody {
Author: Nickolaj Andersen
Contact: @NickolajA
Created: 2020-01-04
Updated: 2023-01-20
Updated: 2023-03-17
Version history:
1.0.0 - (2020-01-04) Function created
Expand All @@ -106,6 +109,7 @@ function New-IntuneWin32AppBody {
would never contain any value since they're not handled by this function (https://github.com/MSEndpointMgr/IntuneWin32App/issues/44)
1.0.4 - (2023-01-20) Added requirement rule to both MSI and EXE switch statements, now handled dynamically based on what's present in the requirement rule object.
Added ScopeTagList and CategoryList parameters.
1.0.4 - (2023-03-17) Added AllowAvailableUninstall parameter switch. Improved handling of RequirementRule when not passed on the command line.
#>
[CmdletBinding(SupportsShouldProcess = $true)]
param(
Expand Down Expand Up @@ -185,6 +189,11 @@ function New-IntuneWin32AppBody {
[ValidateSet("allow", "basedOnReturnCode", "suppress", "force")]
[string]$RestartBehavior,

[parameter(Mandatory = $false, ParameterSetName = "MSI", HelpMessage = "Specify to allow the uninstall option when assigned as available of the Win32 application body.")]
[parameter(Mandatory = $false, ParameterSetName = "EXE")]
[ValidateNotNullOrEmpty()]
[switch]$AllowAvailableUninstall,

[parameter(Mandatory = $false, ParameterSetName = "MSI", HelpMessage = "Specify the requirement rules for the Win32 application body.")]
[parameter(Mandatory = $false, ParameterSetName = "EXE")]
[ValidateNotNullOrEmpty()]
Expand Down Expand Up @@ -301,17 +310,19 @@ function New-IntuneWin32AppBody {
}

# Add requirement rule items dynamically
if ($RequirementRule["minimumFreeDiskSpaceInMB"]) {
$Win32AppBody.Add("minimumFreeDiskSpaceInMB", $RequirementRule["minimumFreeDiskSpaceInMB"])
}
if ($RequirementRule["minimumMemoryInMB"]) {
$Win32AppBody.Add("minimumMemoryInMB", $RequirementRule["minimumMemoryInMB"])
}
if ($RequirementRule["minimumNumberOfProcessors"]) {
$Win32AppBody.Add("minimumNumberOfProcessors", $RequirementRule["minimumNumberOfProcessors"])
}
if ($RequirementRule["minimumCpuSpeedInMHz"]) {
$Win32AppBody.Add("minimumCpuSpeedInMHz", $RequirementRule["minimumCpuSpeedInMHz"])
if ($PSBoundParameters["RequirementRule"]) {
if ($RequirementRule["minimumFreeDiskSpaceInMB"]) {
$Win32AppBody.Add("minimumFreeDiskSpaceInMB", $RequirementRule["minimumFreeDiskSpaceInMB"])
}
if ($RequirementRule["minimumMemoryInMB"]) {
$Win32AppBody.Add("minimumMemoryInMB", $RequirementRule["minimumMemoryInMB"])
}
if ($RequirementRule["minimumNumberOfProcessors"]) {
$Win32AppBody.Add("minimumNumberOfProcessors", $RequirementRule["minimumNumberOfProcessors"])
}
if ($RequirementRule["minimumCpuSpeedInMHz"]) {
$Win32AppBody.Add("minimumCpuSpeedInMHz", $RequirementRule["minimumCpuSpeedInMHz"])
}
}

# Add icon property if passed on command line
Expand All @@ -331,6 +342,11 @@ function New-IntuneWin32AppBody {
if ($PSBoundParameters["CategoryList"]) {
$Win32AppBody.Add("categories", @($CategoryList))
}

# Add allow available uninstall option if passed on the command line
if ($PSBoundParameters["AllowAvailableUninstall"]) {
$Win32AppBody.Add("allowAvailableUninstall", $true)
}
}
"EXE" {
$Win32AppBody = [ordered]@{
Expand Down Expand Up @@ -360,17 +376,19 @@ function New-IntuneWin32AppBody {
}

# Add requirement rule items dynamically
if ($RequirementRule["minimumFreeDiskSpaceInMB"]) {
$Win32AppBody.Add("minimumFreeDiskSpaceInMB", $RequirementRule["minimumFreeDiskSpaceInMB"])
}
if ($RequirementRule["minimumMemoryInMB"]) {
$Win32AppBody.Add("minimumMemoryInMB", $RequirementRule["minimumMemoryInMB"])
}
if ($RequirementRule["minimumNumberOfProcessors"]) {
$Win32AppBody.Add("minimumNumberOfProcessors", $RequirementRule["minimumNumberOfProcessors"])
}
if ($RequirementRule["minimumCpuSpeedInMHz"]) {
$Win32AppBody.Add("minimumCpuSpeedInMHz", $RequirementRule["minimumCpuSpeedInMHz"])
if ($PSBoundParameters["RequirementRule"]) {
if ($RequirementRule["minimumFreeDiskSpaceInMB"]) {
$Win32AppBody.Add("minimumFreeDiskSpaceInMB", $RequirementRule["minimumFreeDiskSpaceInMB"])
}
if ($RequirementRule["minimumMemoryInMB"]) {
$Win32AppBody.Add("minimumMemoryInMB", $RequirementRule["minimumMemoryInMB"])
}
if ($RequirementRule["minimumNumberOfProcessors"]) {
$Win32AppBody.Add("minimumNumberOfProcessors", $RequirementRule["minimumNumberOfProcessors"])
}
if ($RequirementRule["minimumCpuSpeedInMHz"]) {
$Win32AppBody.Add("minimumCpuSpeedInMHz", $RequirementRule["minimumCpuSpeedInMHz"])
}
}

# Add icon property if passed on command line
Expand All @@ -390,6 +408,11 @@ function New-IntuneWin32AppBody {
if ($PSBoundParameters["CategoryList"]) {
$Win32AppBody.Add("categories", @($CategoryList))
}

# Add allow available uninstall option if passed on the command line
if ($PSBoundParameters["AllowAvailableUninstall"]) {
$Win32AppBody.Add("allowAvailableUninstall", $true)
}
}
}

Expand Down
21 changes: 18 additions & 3 deletions Public/Add-IntuneWin32App.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ function Add-IntuneWin32App {
.PARAMETER RestartBehavior
Specify the restart behavior for the Win32 application. Supported values are: allow, basedOnReturnCode, suppress or force.
.PARAMETER AllowAvailableUninstall
Specify whether to allow the Win32 application to be uninstalled from the Company Portal app when assigned as available.
.PARAMETER DetectionRule
Provide an array of a single or multiple OrderedDictionary objects as detection rules that will be used for the Win32 application.
Expand Down Expand Up @@ -88,7 +91,7 @@ function Add-IntuneWin32App {
Author: Nickolaj Andersen
Contact: @NickolajA
Created: 2020-01-04
Updated: 2023-01-20
Updated: 2023-03-17
Version history:
1.0.0 - (2020-01-04) Function created
Expand All @@ -105,7 +108,8 @@ function Add-IntuneWin32App {
1.0.9 - (2023-01-20) Added parameter AzCopyWindowStyle and ScopeTagName. Updated regex pattern for .intunewin file and parameter FilePath.
Added support for specifying Scope Tags when creating the Win 32 app, using the ScopeTagName parameter. Added UnattendedInstall and
UnattendedUninstall parameters for MSI parameter set, to automatically add /quiet to the respectively generated command line.
Added CategoryName parameter. UseAzCopy parameter will now only be allowed if content size is 100MB or more.
Added CategoryName parameter. UseAzCopy parameter will now only be allowed if content size is 100MB or more.
1.1.0 - (2023-03-17) Added parameter switch AllowAvailableUninstall. Fixed issue #77 related to scope tags and custom roles.
#>
[CmdletBinding(SupportsShouldProcess=$true, DefaultParameterSetName = "MSI")]
param(
Expand Down Expand Up @@ -205,6 +209,11 @@ function Add-IntuneWin32App {
[ValidateSet("allow", "basedOnReturnCode", "suppress", "force")]
[string]$RestartBehavior,

[parameter(Mandatory = $false, ParameterSetName = "MSI", HelpMessage = "Specify whether to allow the Win32 application to be uninstalled from the Company Portal app when assigned as available.")]
[parameter(Mandatory = $false, ParameterSetName = "EXE")]
[ValidateNotNullOrEmpty()]
[switch]$AllowAvailableUninstall,

[parameter(Mandatory = $true, ParameterSetName = "MSI", HelpMessage = "Provide an array of a single or multiple OrderedDictionary objects as detection rules that will be used for the Win32 application.")]
[parameter(Mandatory = $true, ParameterSetName = "EXE")]
[ValidateNotNullOrEmpty()]
Expand Down Expand Up @@ -287,7 +296,7 @@ function Add-IntuneWin32App {
foreach ($ScopeTagItem in $ScopeTagName) {
# Ensure a Scope Tag exist by given name from parameter input
Write-Verbose -Message "Querying for specified Scope Tag: $($ScopeTagItem)"
$ScopeTag = (Invoke-IntuneGraphRequest -APIVersion "Beta" -Route "deviceManagement" -Resource "roleScopeTags?`$filter=displayName eq '$($ScopeTagItem)'" -Method "GET" -ErrorAction "Stop").value
$ScopeTag = (Invoke-IntuneGraphRequest -APIVersion "Beta" -Route "deviceManagement" -Resource "getRoleScopeTagsByResource(resource='MobileApps')?`$filter=displayName eq '$($ScopeTagItem)'" -Method "GET" -ErrorAction "Stop").value
if ($ScopeTag -ne $null) {
Write-Verbose -Message "Found Scope Tag with display name '$($ScopeTag.displayName)' and id: $($ScopeTag.id)"
$ScopeTagList.Add($ScopeTag.id) | Out-Null
Expand Down Expand Up @@ -405,6 +414,9 @@ function Add-IntuneWin32App {
if ($UnattendedUninstall) {
$AppBodySplat.Add("UnattendedUninstall", $true)
}
if ($AllowAvailableUninstall) {
$AppBodySplat.Add("AllowAvailableUninstall", $true)
}

$Win32AppBody = New-IntuneWin32AppBody @AppBodySplat
Write-Verbose -Message "Constructed the basic layout for 'MSI' Win32 app body type"
Expand Down Expand Up @@ -446,6 +458,9 @@ function Add-IntuneWin32App {
$AppBodySplat.Add("CategoryList", $CategoryList)
}
}
if ($AllowAvailableUninstall) {
$AppBodySplat.Add("AllowAvailableUninstall", $true)
}

$Win32AppBody = New-IntuneWin32AppBody @AppBodySplat
Write-Verbose -Message "Constructed the basic layout for 'EXE' Win32 app body type"
Expand Down
42 changes: 23 additions & 19 deletions Public/Add-IntuneWin32AppSupersedence.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -63,30 +63,34 @@ function Add-IntuneWin32AppSupersedence {
$Win32AppID = $Win32App.id

# Check for existing relations for Win32 app, supersedence and dependency configurations cannot co-exist currently
$Win32AppDependencyExistence = Get-IntuneWin32AppRelationExistence -ID $Win32AppID -Type "Dependency"
if ($Win32AppDependencyExistence -eq $false) {
# Validate that Win32 app where supersedence is configured, is not passed in $Supersedence variable to prevent an app superseding itself
if ($Win32AppID -notin $Supersedence.targetId) {
$Win32AppRelationships = [ordered]@{
"relationships" = @($Supersedence)
}
#$Win32AppRelations = Get-IntuneWin32AppRelation -ID $Win32AppID

try {
# Attempt to call Graph and configure supersedence for Win32 app
Invoke-IntuneGraphRequest -APIVersion "Beta" -Resource "mobileApps/$($Win32AppID)/updateRelationships" -Method "POST" -Body ($Win32AppRelationships | ConvertTo-Json) -ErrorAction Stop
}
catch [System.Exception] {
Write-Warning -Message "An error occurred while configuring supersedence for Win32 app: $($Win32AppID). Error message: $($_.Exception.Message)"
}
#
# Handle existing relation items, get all relations and combine into array with new relation(s)
#

if ($Win32AppRelations -ne $null) {

}

# Validate that the target Win32 app where supersedence is to be configured, is not passed in $Supersedence variable to prevent target app superseding itself
if ($Win32AppID -notin $Supersedence.targetId) {
$Win32AppRelationsTable = [ordered]@{
"relationships" = @($Supersedence)
}

try {
# Attempt to call Graph and configure supersedence for Win32 app
Invoke-IntuneGraphRequest -APIVersion "Beta" -Resource "mobileApps/$($Win32AppID)/updateRelationships" -Method "POST" -Body ($Win32AppRelationsTable | ConvertTo-Json) -ErrorAction Stop
}
else {
$SupersedenceItems = -join@($Supersedence.targetId, ", ")
Write-Warning -Message "A Win32 app cannot be used to supersede itself, please specify a valid array or single object for supersedence"
Write-Warning -Message "Win32 app with ID '$($Win32AppID)' is set as parent for supersedence configuration, and was also found in child items: $($SupersedenceItems)"
catch [System.Exception] {
Write-Warning -Message "An error occurred while configuring supersedence for Win32 app: $($Win32AppID). Error message: $($_.Exception.Message)"
}
}
else {
Write-Warning -Message "Existing dependency relation configuration exists for Win32 app, supersedence is not allowed to be configured at this point"
$SupersedenceItems = -join@($Supersedence.targetId, ", ")
Write-Warning -Message "A Win32 app cannot be used to supersede itself, please specify a valid array or single object for supersedence"
Write-Warning -Message "Win32 app with ID '$($Win32AppID)' is set as parent for supersedence configuration, and was also found in child items: $($SupersedenceItems)"
}
}
else {
Expand Down
11 changes: 9 additions & 2 deletions Public/Set-IntuneWin32App.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ function Set-IntuneWin32App {
Author: Nickolaj Andersen
Contact: @NickolajA
Created: 2023-01-25
Updated: 2023-01-25
Updated: 2023-03-17
Version history:
1.0.0 - (2023-01-25) Function created
1.0.1 - (2023-03-17) Added AllowAvailableUninstall parameter switch.
#>
[CmdletBinding(SupportsShouldProcess = $true)]
param(
Expand Down Expand Up @@ -91,7 +92,10 @@ function Set-IntuneWin32App {
[string]$PrivacyURL,

[parameter(Mandatory = $false, HelpMessage = "Specify whether to have the Win32 application featured in Company Portal or not.")]
[bool]$CompanyPortalFeaturedApp
[bool]$CompanyPortalFeaturedApp,

[parameter(Mandatory = $false, HelpMessage = "Specify whether to allow the Win32 application to be uninstalled from the Company Portal app when assigned as available.")]
[bool]$AllowAvailableUninstall
)
Begin {
# Ensure required authentication header variable exists
Expand Down Expand Up @@ -154,6 +158,9 @@ function Set-IntuneWin32App {
if ($PSBoundParameters["CompanyPortalFeaturedApp"]) {
$Win32AppBody.Add("isFeatured", $CompanyPortalFeaturedApp)
}
if ($PSBoundParameters["AllowAvailableUninstall"]) {
$Win32AppBody.Add("allowAvailableUninstall", $AllowAvailableUninstall)
}

try {
# Attempt to call Graph and update Win32 app
Expand Down
43 changes: 43 additions & 0 deletions Public/Test-AccessToken.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
function Test-AccessToken {
<#
.SYNOPSIS
Use to check if the existing access token is about to expire.
.DESCRIPTION
Use to check if the existing access token is about to expire.
.PARAMETER RenewalThresholdMinutes
Specify the renewal threshold for access token age in minutes.
.NOTES
Author: Nickolaj Andersen
Contact: @NickolajA
Created: 2021-04-08
Updated: 2021-04-08
Version history:
1.0.0 - (2021-04-08) Script created
#>
param(
[parameter(Mandatory = $false, HelpMessage = "Specify the renewal threshold for access token age in minutes.")]
[ValidateNotNullOrEmpty()]
[int]$RenewalThresholdMinutes = 10
)
Process {
# Determine the current time in UTC
$UTCDateTime = (Get-Date).ToUniversalTime()

# Determine the token expiration count as minutes
$TokenExpireMinutes = ([datetime]$Global:AccessToken.ExpiresOn.ToUniversalTime().UtcDateTime - $UTCDateTime).Minutes

# Determine if refresh of access token is required when expiration count is less than or equal to minimum age
if ($TokenExpireMinutes -le $RenewalThresholdMinutes) {
Write-Verbose -Message "Access token refresh is required, current token expires in (minutes): $($TokenExpireMinutes)"
return $false
}
else {
Write-Verbose -Message "Access token refresh is not required, remaining minutes until expiration: $($TokenExpireMinutes)"
return $true
}
}
}
Loading

0 comments on commit e2600c9

Please sign in to comment.