ApplicationFactoryClient.psm1
#Region '.\Private\Get-AppFactoryClientAppDownload.ps1' 0 function Get-AppFactoryClientAppDownload{ [CmdletBinding()] [OutputType([String])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$sasTokens, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$workspace, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) $downloadFolder = Join-Path -Path $workspace -ChildPath "downloads" -AdditionalChildPath $application.IntuneAppName if(Test-Path $downloadFolder){ Remove-Item -Path $downloadFolder -Force -Recurse -ErrorAction SilentlyContinue } New-Item -Path $downloadFolder -ItemType Directory | Out-Null if($script:AppFactoryClientLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Download Folder - <c='green'>$($downloadFolder)</c>" -Level $LogLevel -Tag "Applications","$($application.IntuneAppName)" -Target "Application Factory Client" } if($application.container -eq $sasTokens.PublicContainerName){ $endpoint = "$($sasTokens.StoragePath)/$($sasTokens.PublicContainerName)/$($application.GUID)/$($application.AppVersion)" $sas = $sasTokens.public } else{ $endpoint = "$($sasTokens.StoragePath)/$($sasTokens.OrganizationContainerName)/$($application.GUID)/$($application.AppVersion)" $sas = $sasTokens.organization } if($script:AppFactoryClientLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Downloading files from $($endpoint)" -Level $LogLevel -Tag "Applications","$($application.IntuneAppName)" -Target "Application Factory Client" } $filelist = @("$($application.IntuneAppName).intunewin","App.json") foreach($file in $filelist){ if($script:AppFactoryClientLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Downloading file $($file)" -Level $LogLevel -Tag "Applications","$($application.IntuneAppName)" -Target "Application Factory Client" } try{ Invoke-WebRequest -Uri "$($endpoint)/$($file)?$($sas)" -OutFile "$($downloadFolder)\$($file)" | Out-Null } catch{ throw "[$($application.IntuneAppName)] Failed to download $($file) from $($baseURI). $($_.Exception.Message)" } } $AppData = Get-Content "$($downloadFolder)\App.json" | ConvertFrom-JSON $downloadFiles = [System.Collections.Generic.List[String]]@() $downloadFiles.Add($AppData.PackageInformation.IconFile) | Out-Null if($AppData.DetectionRule.Type -eq "Script"){ $downloadFiles.Add($AppData.DetectionRule.ScriptFile) | Out-Null } foreach($file in $downloadFiles){ try{ Invoke-WebRequest -Uri "$($endpoint)/$($file)?$($sas)" -OutFile "$($downloadFolder)\$($file)" | Out-Null } catch{ throw "[$($application.IntuneAppName)] Failed to download $($file) from $($baseURI). $($_.Exception.Message)" } } return $downloadFolder } #EndRegion '.\Private\Get-AppFactoryClientAppDownload.ps1' 57 #Region '.\Private\New-AppFactoryClientApp.ps1' 0 function New-AppFactoryClientApp { [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$tenantID, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$clientID, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$appregsecret, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) if ($script:AppFactoryClientLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Publishing Applications" -Level $LogLevel -Tag "Applications", "Intune", "$($application.IntuneAppName)" -Target "Application Factory Client" } $AppData = Get-Content -Path "$($application.filePath)\App.json" | ConvertFrom-JSON $IntuneAppPackage = Get-ChildItem "$($application.filePath)\*.intunewin" $AppIconFile = Join-Path -Path $application.filePath -ChildPath $AppData.PackageInformation.IconFile $ScriptsFolder = $application.filePath # Create default requirement rule $RequirementRule = New-IntuneWin32AppRequirementRule -Architecture $AppData.RequirementRule.Architecture -MinimumSupportedWindowsRelease $AppData.RequirementRule.MinimumSupportedWindowsRelease # Create additional custom requirement rules $CustomRequirementRuleCount = ($AppData.CustomRequirementRule | Measure-Object).Count if ($CustomRequirementRuleCount -ge 1) { $RequirementRules = New-AppFactoryClientCustomRequirements -RequirementRuleItems $AppData.CustomRequirementRule -application $application -ScriptsFolder $ScriptsFolder -loglevel $LogLevel } $DetectionRules = New-AppFactoryClientDetectionRule -DetectionRules $AppData.DetectionRule -application $application -ScriptsFolder $ScriptsFolder -loglevel $LogLevel # Icon File $Icon = New-IntuneWin32AppIcon -FilePath $AppIconFile # Construct a table of default parameters for Win32 app $Win32AppArgs = @{ "FilePath" = $IntuneAppPackage.FullName "DisplayName" = "$($application.IntuneAppName) $($application.AppVersion)" "AppVersion" = $AppData.Information.AppVersion "Description" = $AppData.Information.Description "Publisher" = $AppData.Information.Publisher "InstallExperience" = $AppData.Program.InstallExperience "RestartBehavior" = $AppData.Program.DeviceRestartBehavior "DetectionRule" = $DetectionRules "RequirementRule" = $RequirementRule "Notes" = "$($AppData.Information.Notes)`n`rSTSID:$($application.GUID)" } # Dynamically add additional parameters for Win32 app if ($null -ne $RequirementRules) { $Win32AppArgs.Add("AdditionalRequirementRule", $RequirementRules) } if (Test-Path -Path $AppIconFile) { $Win32AppArgs.Add("Icon", $Icon) } if (-not([string]::IsNullOrEmpty($AppData.Information.InformationURL))) { $Win32AppArgs.Add("InformationURL", $AppData.Information.InformationURL) } if (-not([string]::IsNullOrEmpty($AppData.Information.PrivacyURL))) { $Win32AppArgs.Add("PrivacyURL", $AppData.Information.PrivacyURL) } if (-not([string]::IsNullOrEmpty($AppData.Information.Owner))) { $Win32AppArgs.Add("Owner", $AppData.Information.Owner) } if (-not([string]::IsNullOrEmpty($AppData.Program.InstallCommand))) { if($application.InteractiveInstall){ $Win32AppArgs.Add("InstallCommandLine", $AppData.Program.InstallCommandInteractive) } else{ $Win32AppArgs.Add("InstallCommandLine", $AppData.Program.InstallCommand) } } if (-not([string]::IsNullOrEmpty($AppData.Program.UninstallCommand))) { if($application.InteractiveUninstall){ $Win32AppArgs.Add("UninstallCommandLine", $AppData.Program.UninstallCommandInteractive) } else{ $Win32AppArgs.Add("UninstallCommandLine", $AppData.Program.UninstallCommand) } } if (-not([string]::IsNullOrEmpty($AppData.Program.AllowAvailableUninstall))) { if ($AppData.Program.AllowAvailableUninstall -eq $true) { $Win32AppArgs.Add("AllowAvailableUninstall", $true) } } try { Connect-MSIntuneGraph -TenantID $tenantID -ClientID $clientID -ClientSecret $appregsecret | Out-Null Add-IntuneWin32App @Win32AppArgs -UseAzCopy -ErrorAction Stop -WarningAction Stop | Out-Null } catch { $intuneApp = Get-GraphIntuneApp -displayName $application.IntuneAppName if ($intuneApp.count -gt 1) { $intuneApp = $intuneApp | Sort-Object -Property createdDateTime -Descending | Select-Object -First 1 } Remove-GraphIntuneApp -applicationid $intuneApp.id throw $_ } } #EndRegion '.\Private\New-AppFactoryClientApp.ps1' 90 #Region '.\Private\New-AppFactoryClientCustomRequirements.ps1' 0 function New-AppFactoryClientCustomRequirements{ [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[PSCustomObject]]$RequirementRuleItems, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$ScriptsFolder, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) $RequirementRules = [System.Collections.Generic.List[PSCustomObject]]@() foreach ($RequirementRuleItem in $RequirementRuleItems) { switch ($RequirementRuleItem.Type) { "File" { switch ($RequirementRuleItem.DetectionMethod) { "Existence" { # Create a custom file based requirement rule $RequirementRuleArgs = @{ "Existence" = $true "Path" = $RequirementRuleItem.Path "FileOrFolder" = $RequirementRuleItem.FileOrFolder "DetectionType" = $RequirementRuleItem.DetectionType "Check32BitOn64System" = [System.Convert]::ToBoolean($RequirementRuleItem.Check32BitOn64System) } } "DateModified" { # Create a custom file based requirement rule $RequirementRuleArgs = @{ "DateModified" = $true "Path" = $RequirementRuleItem.Path "FileOrFolder" = $RequirementRuleItem.FileOrFolder "Operator" = $RequirementRuleItem.Operator "DateTimeValue" = $RequirementRuleItem.DateTimeValue "Check32BitOn64System" = [System.Convert]::ToBoolean($RequirementRuleItem.Check32BitOn64System) } } "DateCreated" { # Create a custom file based requirement rule $RequirementRuleArgs = @{ "DateCreated" = $true "Path" = $RequirementRuleItem.Path "FileOrFolder" = $RequirementRuleItem.FileOrFolder "Operator" = $RequirementRuleItem.Operator "DateTimeValue" = $RequirementRuleItem.DateTimeValue "Check32BitOn64System" = [System.Convert]::ToBoolean($RequirementRuleItem.Check32BitOn64System) } } "Version" { # Create a custom file based requirement rule $RequirementRuleArgs = @{ "Version" = $true "Path" = $RequirementRuleItem.Path "FileOrFolder" = $RequirementRuleItem.FileOrFolder "Operator" = $RequirementRuleItem.Operator "VersionValue" = $RequirementRuleItem.VersionValue "Check32BitOn64System" = [System.Convert]::ToBoolean($RequirementRuleItem.Check32BitOn64System) } } "Size" { # Create a custom file based requirement rule $RequirementRuleArgs = @{ "Size" = $true "Path" = $RequirementRuleItem.Path "FileOrFolder" = $RequirementRuleItem.FileOrFolder "Operator" = $RequirementRuleItem.Operator "SizeInMBValue" = $RequirementRuleItem.SizeInMBValue "Check32BitOn64System" = [System.Convert]::ToBoolean($RequirementRuleItem.Check32BitOn64System) } } } # Create file based requirement rule $CustomRequirementRule = New-IntuneWin32AppRequirementRuleFile @RequirementRuleArgs } "Registry" { switch ($RequirementRuleItem.DetectionMethod) { "Existence" { # Create a custom registry based requirement rule $RequirementRuleArgs = @{ "Existence" = $true "KeyPath" = $RequirementRuleItem.KeyPath "ValueName" = $RequirementRuleItem.ValueName "DetectionType" = $RequirementRuleItem.DetectionType "Check32BitOn64System" = [System.Convert]::ToBoolean($RequirementRuleItem.Check32BitOn64System) } } "StringComparison" { # Create a custom registry based requirement rule $RequirementRuleArgs = @{ "StringComparison" = $true "KeyPath" = $RequirementRuleItem.KeyPath "ValueName" = $RequirementRuleItem.ValueName "StringComparisonOperator" = $RequirementRuleItem.Operator "StringComparisonValue" = $RequirementRuleItem.Value "Check32BitOn64System" = [System.Convert]::ToBoolean($RequirementRuleItem.Check32BitOn64System) } } "VersionComparison" { # Create a custom registry based requirement rule $RequirementRuleArgs = @{ "VersionComparison" = $true "KeyPath" = $RequirementRuleItem.KeyPath "ValueName" = $RequirementRuleItem.ValueName "VersionComparisonOperator" = $RequirementRuleItem.Operator "VersionComparisonValue" = $RequirementRuleItem.Value "Check32BitOn64System" = [System.Convert]::ToBoolean($RequirementRuleItem.Check32BitOn64System) } } "IntegerComparison" { # Create a custom registry based requirement rule $RequirementRuleArgs = @{ "IntegerComparison" = $true "KeyPath" = $RequirementRuleItem.KeyPath "ValueName" = $RequirementRuleItem.ValueName "IntegerComparisonOperator" = $RequirementRuleItem.Operator "IntegerComparisonValue" = $RequirementRuleItem.Value "Check32BitOn64System" = [System.Convert]::ToBoolean($RequirementRuleItem.Check32BitOn64System) } } } # Create registry based requirement rule $CustomRequirementRule = New-IntuneWin32AppRequirementRuleRegistry @RequirementRuleArgs } "Script" { switch ($RequirementRuleItem.DetectionMethod) { "StringOutput" { # Create a custom script based requirement rule $RequirementRuleArgs = @{ "StringOutputDataType" = $true "ScriptFile" = (Join-Path -Path $ScriptsFolder -ChildPath $RequirementRuleItem.ScriptFile) "ScriptContext" = $RequirementRuleItem.ScriptContext "StringComparisonOperator" = $RequirementRuleItem.Operator "StringValue" = $RequirementRuleItem.Value "RunAs32BitOn64System" = [System.Convert]::ToBoolean($RequirementRuleItem.RunAs32BitOn64System) "EnforceSignatureCheck" = [System.Convert]::ToBoolean($RequirementRuleItem.EnforceSignatureCheck) } } "IntegerOutput" { # Create a custom script based requirement rule $RequirementRuleArgs = @{ "IntegerOutputDataType" = $true "ScriptFile" = $RequirementRuleItem.ScriptFile "ScriptContext" = $RequirementRuleItem.ScriptContext "IntegerComparisonOperator" = $RequirementRuleItem.Operator "IntegerValue" = $RequirementRuleItem.Value "RunAs32BitOn64System" = [System.Convert]::ToBoolean($RequirementRuleItem.RunAs32BitOn64System) "EnforceSignatureCheck" = [System.Convert]::ToBoolean($RequirementRuleItem.EnforceSignatureCheck) } } "BooleanOutput" { # Create a custom script based requirement rule $RequirementRuleArgs = @{ "BooleanOutputDataType" = $true "ScriptFile" = $RequirementRuleItem.ScriptFile "ScriptContext" = $RequirementRuleItem.ScriptContext "BooleanComparisonOperator" = $RequirementRuleItem.Operator "BooleanValue" = $RequirementRuleItem.Value "RunAs32BitOn64System" = [System.Convert]::ToBoolean($RequirementRuleItem.RunAs32BitOn64System) "EnforceSignatureCheck" = [System.Convert]::ToBoolean($RequirementRuleItem.EnforceSignatureCheck) } } "DateTimeOutput" { # Create a custom script based requirement rule $RequirementRuleArgs = @{ "DateTimeOutputDataType" = $true "ScriptFile" = $RequirementRuleItem.ScriptFile "ScriptContext" = $RequirementRuleItem.ScriptContext "DateTimeComparisonOperator" = $RequirementRuleItem.Operator "DateTimeValue" = $RequirementRuleItem.Value "RunAs32BitOn64System" = [System.Convert]::ToBoolean($RequirementRuleItem.RunAs32BitOn64System) "EnforceSignatureCheck" = [System.Convert]::ToBoolean($RequirementRuleItem.EnforceSignatureCheck) } } "FloatOutput" { # Create a custom script based requirement rule $RequirementRuleArgs = @{ "FloatOutputDataType" = $true "ScriptFile" = $RequirementRuleItem.ScriptFile "ScriptContext" = $RequirementRuleItem.ScriptContext "FloatComparisonOperator" = $RequirementRuleItem.Operator "FloatValue" = $RequirementRuleItem.Value "RunAs32BitOn64System" = [System.Convert]::ToBoolean($RequirementRuleItem.RunAs32BitOn64System) "EnforceSignatureCheck" = [System.Convert]::ToBoolean($RequirementRuleItem.EnforceSignatureCheck) } } "VersionOutput" { # Create a custom script based requirement rule $RequirementRuleArgs = @{ "VersionOutputDataType" = $true "ScriptFile" = $RequirementRuleItem.ScriptFile "ScriptContext" = $RequirementRuleItem.ScriptContext "VersionComparisonOperator" = $RequirementRuleItem.Operator "VersionValue" = $RequirementRuleItem.Value "RunAs32BitOn64System" = [System.Convert]::ToBoolean($RequirementRuleItem.RunAs32BitOn64System) "EnforceSignatureCheck" = [System.Convert]::ToBoolean($RequirementRuleItem.EnforceSignatureCheck) } } } # Create script based requirement rule $CustomRequirementRule = New-IntuneWin32AppRequirementRuleScript @RequirementRuleArgs } } # Add requirement rule to list $RequirementRules.Add($CustomRequirementRule) | Out-Null } return $RequirementRules } #EndRegion '.\Private\New-AppFactoryClientCustomRequirements.ps1' 206 #Region '.\Private\New-AppFactoryClientDetectionRule.ps1' 0 function New-AppFactoryClientDetectionRule{ [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[PSCustomObject]]$DetectionRules, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$ScriptsFolder, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) $rules = [System.Collections.Generic.List[PSCustomObject]]@() foreach ($DetectionRuleItem in $DetectionRules) { switch ($DetectionRuleItem.Type) { "MSI" { if($script:AppFactoryClientLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Adding MSI Detection Rule" -Level $LogLevel -Tag "Applications","Intune","$($application.IntuneAppName)" -Target "Application Factory Client" } # Create a MSI installation based detection rule $DetectionRuleArgs = @{ "ProductCode" = $DetectionRuleItem.ProductCode "ProductVersionOperator" = $DetectionRuleItem.ProductVersionOperator } if (-not([string]::IsNullOrEmpty($DetectionRuleItem.ProductVersion))) { $DetectionRuleArgs.Add("ProductVersion", $DetectionRuleItem.ProductVersion) } # Create MSI based detection rule $DetectionRule = New-IntuneWin32AppDetectionRuleMSI @DetectionRuleArgs } "Script" { if($script:AppFactoryClientLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Adding Script Detection Rule" -Level $LogLevel -Tag "Applications","Intune","$($application.IntuneAppName)" -Target "Application Factory Client" } # Create a PowerShell script based detection rule $DetectionRuleArgs = @{ "ScriptFile" = (Join-Path -Path $ScriptsFolder -ChildPath $DetectionRuleItem.ScriptFile) "EnforceSignatureCheck" = [System.Convert]::ToBoolean($DetectionRuleItem.EnforceSignatureCheck) "RunAs32Bit" = [System.Convert]::ToBoolean($DetectionRuleItem.RunAs32Bit) } # Create script based detection rule $DetectionRule = New-IntuneWin32AppDetectionRuleScript @DetectionRuleArgs } "Registry" { if($script:AppFactoryClientLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Adding Registry Detection Rule" -Level $LogLevel -Tag "Applications","Intune","$($application.IntuneAppName)" -Target "Application Factory Client" } switch ($DetectionRuleItem.DetectionMethod) { "Existence" { # Construct registry existence detection rule parameters $DetectionRuleArgs = @{ "Existence" = $true "KeyPath" = $DetectionRuleItem.KeyPath "DetectionType" = $DetectionRuleItem.DetectionType "Check32BitOn64System" = [System.Convert]::ToBoolean($DetectionRuleItem.Check32BitOn64System) } if (-not([string]::IsNullOrEmpty($DetectionRuleItem.ValueName))) { $DetectionRuleArgs.Add("ValueName", $DetectionRuleItem.ValueName) } } "VersionComparison" { # Construct registry version comparison detection rule parameters $DetectionRuleArgs = @{ "VersionComparison" = $true "KeyPath" = $DetectionRuleItem.KeyPath "ValueName" = $DetectionRuleItem.ValueName "VersionComparisonOperator" = $DetectionRuleItem.Operator "VersionComparisonValue" = $DetectionRuleItem.Value "Check32BitOn64System" = [System.Convert]::ToBoolean($DetectionRuleItem.Check32BitOn64System) } } "StringComparison" { # Construct registry string comparison detection rule parameters $DetectionRuleArgs = @{ "StringComparison" = $true "KeyPath" = $DetectionRuleItem.KeyPath "ValueName" = $DetectionRuleItem.ValueName "StringComparisonOperator" = $DetectionRuleItem.Operator "StringComparisonValue" = $DetectionRuleItem.Value "Check32BitOn64System" = [System.Convert]::ToBoolean($DetectionRuleItem.Check32BitOn64System) } } "IntegerComparison" { # Construct registry integer comparison detection rule parameters $DetectionRuleArgs = @{ "IntegerComparison" = $true "KeyPath" = $DetectionRuleItem.KeyPath "ValueName" = $DetectionRuleItem.ValueName "IntegerComparisonOperator" = $DetectionRuleItem.Operator "IntegerComparisonValue" = $DetectionRuleItem.Value "Check32BitOn64System" = [System.Convert]::ToBoolean($DetectionRuleItem.Check32BitOn64System) } } } # Create registry based detection rule $DetectionRule = New-IntuneWin32AppDetectionRuleRegistry @DetectionRuleArgs } "File" { if($script:AppFactoryClientLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Adding File Detection Rule" -Level $LogLevel -Tag "Applications","Intune","$($application.IntuneAppName)" -Target "Application Factory Client" } switch ($DetectionRuleItem.DetectionMethod) { "Existence" { # Create a custom file based requirement rule $DetectionRuleArgs = @{ "Existence" = $true "Path" = $DetectionRuleItem.Path "FileOrFolder" = $DetectionRuleItem.FileOrFolder "DetectionType" = $DetectionRuleItem.DetectionType "Check32BitOn64System" = [System.Convert]::ToBoolean($DetectionRuleItem.Check32BitOn64System) } } "DateModified" { # Create a custom file based requirement rule $DetectionRuleArgs = @{ "DateModified" = $true "Path" = $DetectionRuleItem.Path "FileOrFolder" = $DetectionRuleItem.FileOrFolder "Operator" = $DetectionRuleItem.Operator "DateTimeValue" = $DetectionRuleItem.DateTimeValue "Check32BitOn64System" = [System.Convert]::ToBoolean($DetectionRuleItem.Check32BitOn64System) } } "DateCreated" { # Create a custom file based requirement rule $DetectionRuleArgs = @{ "DateCreated" = $true "Path" = $DetectionRuleItem.Path "FileOrFolder" = $DetectionRuleItem.FileOrFolder "Operator" = $DetectionRuleItem.Operator "DateTimeValue" = $DetectionRuleItem.DateTimeValue "Check32BitOn64System" = [System.Convert]::ToBoolean($DetectionRuleItem.Check32BitOn64System) } } "Version" { # Create a custom file based requirement rule $DetectionRuleArgs = @{ "Version" = $true "Path" = $DetectionRuleItem.Path "FileOrFolder" = $DetectionRuleItem.FileOrFolder "Operator" = $DetectionRuleItem.Operator "VersionValue" = $DetectionRuleItem.VersionValue "Check32BitOn64System" = [System.Convert]::ToBoolean($DetectionRuleItem.Check32BitOn64System) } } "Size" { # Create a custom file based requirement rule $DetectionRuleArgs = @{ "Size" = $true "Path" = $DetectionRuleItem.Path "FileOrFolder" = $DetectionRuleItem.FileOrFolder "Operator" = $DetectionRuleItem.Operator "SizeInMBValue" = $DetectionRuleItem.SizeInMBValue "Check32BitOn64System" = [System.Convert]::ToBoolean($DetectionRuleItem.Check32BitOn64System) } } } # Create file based detection rule $DetectionRule = New-IntuneWin32AppDetectionRuleFile @DetectionRuleArgs } } # Add detection rule to list $rules.Add($DetectionRule) | Out-Null } return $rules } #EndRegion '.\Private\New-AppFactoryClientDetectionRule.ps1' 164 #Region '.\Public\Add-AppFactoryClientAppAssignments.ps1' 0 function Add-AppFactoryClientAppAssignments { [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[PSCustomObject]]$applicationList, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[PSCustomObject]]$intuneApplications, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) foreach ($application in $applicationList) { if ($script:AppFactoryClientLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Adding Application Assignments" -Level $LogLevel -Tag "Applications", "Intune", "$($application.IntuneAppName)" -Target "Application Factory Client" } $applications = $intuneApplications | Where-Object { $_.Notes -match "STSID:$($application.GUID)" } | Sort-Object -Property "createdDateTime" -Descending | Select-Object -first 1 $workingApplication = $applications[0] $commonVariables = @{ "applicationid" = $workingApplication.id "filters" = $application.filters } try { if ($application.AvailableAssignments -ne "") { Add-GraphIntuneAppAssignment @commonVariables -intent available -groups $application.AvailableAssignments -foreground $application.foreground } if ($application.AvailableExceptions -ne "") { Add-GraphIntuneAppAssignment @commonVariables -intent available -groups $application.AvailableExceptions -exclude } if ($application.RequiredAssignments -ne "") { Add-GraphIntuneAppAssignment @commonVariables -intent required -groups $application.RequiredAssignments -foreground $application.foreground } if ($application.RequiredExceptions -ne "") { Add-GraphIntuneAppAssignment @commonVariables -intent required -groups $application.RequiredExceptions -exclude } if ($application.UninstallAssignments -ne "") { Add-GraphIntuneAppAssignment @commonVariables -intent uninstall -groups $application.UninstallAssignments -foreground $application.foreground } if ($application.UninstallExceptions -ne "") { Add-GraphIntuneAppAssignment @commonVariables -intent uninstall -groups $application.UninstallExceptions -exclude } } catch { $_ } } } #EndRegion '.\Public\Add-AppFactoryClientAppAssignments.ps1' 31 #Region '.\Public\Add-AppFactoryClientESPAssignment.ps1' 0 function Add-AppFactoryClientESPAssignment{ [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[PSCustomObject]]$applicationList, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[PSCustomObject]]$intuneApplications, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) # Loop through applications foreach($application in $applicationList){ if($application.espprofiles){ $applications = $intuneApplications | Where-Object {$_.Notes -eq "STSID:$($application.guid)"} | Sort-Object -Property @{expr={[system.version]$_.DisplayVersion}},createdDateTime -Descending foreach($esp in $application.espprofiles){ if($script:AppFactoryClientLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Assigning application to ESP Porfile $($esp)" -Level $LogLevel -Tag "Applications","Intune","$($application.IntuneAppName)" -Target "Application Factory Client" } Add-GraphIntuneAppAddToESP -displayName $esp -applicationid $applications[0].id } } } } #EndRegion '.\Public\Add-AppFactoryClientESPAssignment.ps1' 23 #Region '.\Public\Compare-AppFactoryClientAppVersions.ps1' 0 function Compare-AppFactoryClientAppVersions { [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[PSCustomObject]]$applicationList, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[PSCustomObject]]$intuneApplications, [Parameter()][ValidateNotNullOrEmpty()][switch]$force, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) # Create blank list to store the applications that we will be moving forward with. $applications = [System.Collections.Generic.List[PSCustomObject]]@() # Loop through the applications foreach ($application in $applicationList) { if ($script:AppFactoryClientLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Comparing Versions between expected and latest published" -Level $LogLevel -Tag "Applications", "$($application.IntuneAppName)" -Target "Application Factory Client" } $intuneApplication = $intuneApplications | Where-Object { $_.Notes -eq "STSID:$($application.GUID)" } | Sort-Object -Property "createdDateTime" -Descending | Select-Object -first 1 if ($script:AppFactoryClientLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Current Published Version: <c='green'>$($intuneApplication.displayVersion)</c>" -Level $LogLevel -Tag "Applications", "$($application.IntuneAppName)" -Target "Application Factory Client" Write-PSFMessage -Message "[$($application.IntuneAppName)] Current Expected Version: <c='green'>$($application.AppVersion)</c>" -Level $LogLevel -Tag "Applications", "$($application.IntuneAppName)" -Target "Application Factory Client" } if (-not $intuneApplication -or $force -or [System.Version]$application.AppVersion -gt [System.Version]$intuneApplication.displayVersion) { if ($script:AppFactoryClientLogging) { if ($force) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Current Expected Version already published. But force selected." -Level $LogLevel -Tag "Applications", "$($application.IntuneAppName)" -Target "Application Factory Client" } else { Write-PSFMessage -Message "[$($application.IntuneAppName)]Application requires an update." -Level $LogLevel -Tag "Applications", "$($application.IntuneAppName)" -Target "Application Factory Client" } } $applications.Add($application) | Out-Null } else { if ($script:AppFactoryClientLogging) { Write-PSFMessage -Message "<c='yellow'>[$($application.IntuneAppName)] Current Expected Version is already present.</c>" -Level $LogLevel -Tag "Applications", "$($application.IntuneAppName)" -Target "Application Factory Client" Write-PSFMessage -Message "<c='yellow'>[$($application.IntuneAppName)] Removing from process.</c>" -Level $LogLevel -Tag "Applications", "$($application.IntuneAppName)" -Target "Application Factory Client" } } } return $applications } #EndRegion '.\Public\Compare-AppFactoryClientAppVersions.ps1' 42 #Region '.\Public\Copy-AppFactoryClientAppAssignments.ps1' 0 function Copy-AppFactoryClientAppAssignments{ [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[PSCustomObject]]$applicationList, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[PSCustomObject]]$intuneApplications, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) foreach($application in $applicationList){ if($application.CopyPrevious){ if($script:AppFactoryClientLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Copying Application Assignments" -Level $LogLevel -Tag "Applications","Intune","$($application.IntuneAppName)" -Target "Application Factory Client" } $applications = $intuneApplications | Where-Object {$_.Notes -match "STSID:$($application.guid)"} | Sort-Object -Property @{expr={[system.version]$_.DisplayVersion}},createdDateTime -Descending if($applications.count -gt 1){ Copy-GraphIntuneAppAssignments -applicationid $applications[0].id -copyapplicationid $applications[1].id } } } } #EndRegion '.\Public\Copy-AppFactoryClientAppAssignments.ps1' 20 #Region '.\Public\Get-AppFactoryClientApp.ps1' 0 function Get-AppFactoryClientApp{ [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter()][string]$GUID, [Parameter()][string]$AppName, [Parameter()][bool]$AddToIntune, [Parameter()][string]$AvailableAssignments, [Parameter()][string]$AvailableExceptions, [Parameter()][string]$RequiredAssignments, [Parameter()][string]$RequiredExceptions, [Parameter()][string]$UninstallAssignments, [Parameter()][string]$UninstallExceptions, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) # App Folders $applicationFolderPath = Join-Path -Path $script:AppFactoryClientSourceDir -ChildPath "Apps" # Get All Applications $applicationConfigFiles = Get-Childitem -Path $applicationFolderPath # Blank List for the Apps $applicationList = [System.Collections.Generic.List[PSCustomObject]]@() # Loop through the configuration and add to the list. foreach($file in $applicationConfigFiles){ $json = Get-Content $file.FullName | ConvertFrom-Json if($GUID -and $json.GUID -ne $GUID){continue} if($AppName -and $json.AppName -ne $AppName){continue} if($AddToIntune -and $json.AddToIntune -ne $AddToIntune){continue} if($AvailableAssignments -and $AvailableAssignments -notin $json.AvailableAssignments){continue} if($AvailableExceptions -and $AvailableExceptions -notin $json.AvailableExceptions){continue} if($RequiredAssignments -and $RequiredAssignments -notin $json.RequiredAssignments){continue} if($RequiredExceptions -and $RequiredExceptions -notin $json.RequiredExceptions){continue} if($UninstallAssignments -and $UninstallAssignments -notin $json.UninstallAssignments){continue} if($UninstallExceptions -and $UninstallExceptions -notin $json.UninstallExceptions){continue} $applicationList.Add($json) | Out-Null } return $applicationList } #EndRegion '.\Public\Get-AppFactoryClientApp.ps1' 38 #Region '.\Public\Get-AppFactoryClientAppFiles.ps1' 0 function Get-AppFactoryClientAppFiles { [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[PSCustomObject]]$applicationList, [Parameter()][switch]$multithread, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) # Create blank list to store the applications that we will be moving forward with. $applications = [System.Collections.Generic.List[PSCustomObject]]@() # App List Endpoint $endpoint = "$($script:AppFactoryClientApiEndpoint)/SAS" if ($script:AppFactoryClientLogging) { Write-PSFMessage -Message "Getting SAS Token fron endoiunt $($endpoint)" -Level $LogLevel -Tag "Applications", "API", "SAS" -Target "Application Factory Client" } $headers = @{ "content-type" = "application/json" "authorization" = "bearer $(ConvertFrom-SecureString $script:AppFactoryClientAPISecret -AsPlainText)" } $sasTokens = Invoke-RestMethod -Method "GET" -Uri $endpoint -Headers $headers -StatusCodeVariable "statusCode" if (-not $multithread.IsPresent) { foreach ($application in $applicationList) { try { $download = Get-AppFactoryClientAppDownload -application $application -sasTokens $sasTokens -workspace $script:AppFactoryClientWorkspace -LogLevel $LogLevel $application | Add-Member -MemberType "NoteProperty" -Name "filePath" -value $download -Force $applications.add($application) | Out-Null } catch { if ($script:AppFactoryClientLogging) { Write-PSFMessage -Message "<c='yellow'>[$($application.IntuneAppName)] failed download files.</c>" -Level Error -Tag "Applications", "$($application.IntuneAppName)" -Target "Application Factory Client" Write-PSFMessage -Message "<c='yellow'>[$($application.IntuneAppName)] Error $($_).</c>" -Level Error -Tag "Applications", "$($application.IntuneAppName)" -Target "Application Factory Client" } } } } else { $applist = [hashtable]::Synchronized(@{}) if ($script:LocalModulePath) { $modulePath = $script:LocalModulePath } else { $modulePath = (Get-module ApplicationFactoryClient).path } $applicationList | Foreach-Object -Parallel { Import-Module -Name $using:modulePath -Force $application = $_ $dict = $using:applist $script:AppFactoryClientLogging = $using:script:AppFactoryClientLogging $script:AppFactoryClientWorkspace = $using:script:AppFactoryClientWorkspace $sasTokens = $using:sasTokens $LogLevel = $using:LogLevel try { $download = Get-AppFactoryClientAppDownload -application $application -sasTokens $sasTokens -workspace $script:AppFactoryClientWorkspace -LogLevel $LogLevel $obj = [PSCustomObject]@{ "Status" = "Downloaded" "download" = $download "Error" = $null } $dict.add($application.GUID, $obj) } catch { $obj = [PSCustomObject]@{ "Status" = "Fail" "Application" = $null "Error" = $_ } $dict.add($application.GUID, $obj) } } foreach ($item in $applist.GetEnumerator()) { if ($item.Value.status -eq "Downloaded") { $index = $applicationList.guid.indexOf($item.key) $application = $applicationList[$index] $application | Add-Member -MemberType NoteProperty -Name 'filePath' -Value $item.Value.download $applications.Add($application) | Out-Null } } } return $applications } #EndRegion '.\Public\Get-AppFactoryClientAppFiles.ps1' 81 #Region '.\Public\Get-AppFactoryClientAppList.ps1' 0 function Get-AppFactoryClientAppList { [CmdletBinding()] param( [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) # Where to save file $ApplicationFolder = Join-Path -Path $script:AppFactoryClientSourceDir -ChildPath "Apps" if(-not (Test-Path -Path $ApplicationFolder)){ New-Item -Path $ApplicationFolder -ItemType Directory | Out-Null } $endpoint = "$($script:AppFactoryClientApiEndpoint)/AppList" if ($script:AppFactoryClientLogging) { Write-PSFMessage -Message "Storing application configuration files to <c='green'>$($ApplicationFolder)</c>" -Level $LogLevel -Tag "Applications" -Target "Application Factory Client" Write-PSFMessage -Message "Downloading app list file from <c='green'>$($endpoint)</c>" -Level $LogLevel -Tag "Application Factory Client" } # Retrieve Data $headers = @{ "content-type" = "application/json" "authorization" = "bearer $(ConvertFrom-SecureString $script:AppFactoryClientAPISecret -AsPlainText)" } $applicationList = Invoke-RestMethod -Method "GET" -Uri $endpoint -Headers $headers -StatusCodeVariable "statusCode" foreach($application in $applicationList){ if($script:AppFactoryClientLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Writing application configuration" -Level $LogLevel -Tag "Applications","$($application.IntuneAppName)" -Target "Application Factory Client" } if(($application.filters.psobject.properties.value)){ $filters = $application.filters -split "@@" $appfilters = @{} foreach($filter in $filters){ $temp = $filter -split ";" $appfilters.add($temp[0],@{ "filterType" = $temp[1] "filterName" = $temp[2] }) } $application.filters = $appfilters } $applicationfile = Join-Path -Path $ApplicationFolder -ChildPath "$($application.IntuneAppName).json" $application | ConvertTo-Json -Depth 5 | Out-File -Path $applicationfile } } #EndRegion '.\Public\Get-AppFactoryClientAppList.ps1' 42 #Region '.\Public\Publish-AppFactoryClientApp.ps1' 0 function Publish-AppFactoryClientApp{ [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[PSCustomObject]]$applicationList, [Parameter()][switch]$multithread, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) # Create blank list to store the applications that we will be moving forward with. $applications = [System.Collections.Generic.List[PSCustomObject]]@() if(-not $multithread.IsPresent){ foreach($application in $applicationList){ try{ New-AppFactoryClientApp -application $application -tenantID $script:AppFactoryClientTenantID -clientID $script:AppFactoryClientClientID -appregsecret $script:AppFactoryClientAppRegSecret -LogLevel $LogLevel $applications.add($application) | Out-Null } catch{ if($script:AppFactoryClientLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] failed to create intune application." -Level Error -Tag "Applications","Intune","$($application.IntuneAppName)" -Target "Application Factory Client" Write-PSFMessage -Message "[$($application.IntuneAppName)] Error $($_)." -Level Error -Tag "Applications","Intune","$($application.IntuneAppName)" -Target "Application Factory Client" } } } } else{ $applist = [hashtable]::Synchronized(@{}) if ($script:LocalModulePath) { $modulePath = $script:LocalModulePath } else { $modulePath = (Get-module ApplicationFactoryClient).path } $applicationList | Foreach-Object -Parallel { Import-Module -Name $using:modulePath -Force $application = $_ $dict = $using:applist $script:AppFactoryClientLogging = $using:script:AppFactoryClientLogging $script:AppFactoryClientTenantID = $using:script:AppFactoryClientTenantID $script:AppFactoryClientClientID = $using:script:AppFactoryClientClientID $script:AppFactoryClientAppRegSecret = $using:script:AppFactoryClientAppRegSecret $LogLevel = $using:LogLevel try{ New-AppFactoryClientApp -application $application -tenantID $script:AppFactoryClientTenantID -clientID $script:AppFactoryClientClientID -appregsecret $script:AppFactoryClientAppRegSecret -LogLevel $LogLevel $obj = [PSCustomObject]@{ "Status" = "Published" "Error" = $null } $dict.add($application.GUID,$obj) } catch{ $obj = [PSCustomObject]@{ "Status" = "Error" "Error" = $_ } $dict.add($application.GUID,$obj) } } foreach($item in $applist.GetEnumerator()){ if($item.Value.status -eq "Published"){ $index = $applicationList.guid.indexOf($item.key) $application = $applicationList[$index] $applications.Add($application) | Out-Null } } } return $applications } #EndRegion '.\Public\Publish-AppFactoryClientApp.ps1' 68 #Region '.\Public\Remove-AppFactoryClientApp.ps1' 0 function Remove-AppFactoryClientApp{ [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[PSCustomObject]]$applicationList, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[PSCustomObject]]$intuneApplications, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) # Loop through the applications and remove ones that are no longer required foreach($application in $applicationList){ if($script:AppFactoryClientLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Removing Previous Applications" -Level $LogLevel -Tag "Applications","Intune","$($application.IntuneAppName)" -Target "Application Factory Client" } $applications = $intuneApplications | Where-Object {$_.Notes -eq "STSID:$($application.guid)"} | Sort-Object -Property @{expr={[system.version]$_.DisplayVersion}},createdDateTime if($applications.count -gt $(1 + $application.KeepPrevious)){ $removalCount = $applications.count - $application.KeepPrevious - 1 if($script:AppFactoryClientLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Based on keeping $($application.KeepPrevious) previous versions there are $($removalCount) applications to remove." -Level $LogLevel -Tag "Applications","Intune","$($application.IntuneAppName)" -Target "Application Factory Client" } for($i = 0; $i -lt $removalCount; $i++){ Remove-GraphIntuneApp -applicationid $applications[$i].id } } else{ if($script:AppFactoryClientLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Based on keeping $($application.KeepPrevious) previous versions there are no applications to remove." -Level $LogLevel -Tag "Applications","Intune","$($application.IntuneAppName)" -Target "Application Factory Client" } } } } #EndRegion '.\Public\Remove-AppFactoryClientApp.ps1' 31 #Region '.\Public\Remove-AppFactoryClientFiles.ps1' 0 function Remove-AppFactoryClientFiles{ [CmdletBinding()] param( [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) if($script:AppFactoryClientLogging){ Write-PSFMessage -Message "Removing previous workspace folder located at <c='green'>$($script:AppFactoryClientWorkspace)</c>" -Level $LogLevel -Tag "Setup" -Target "Application Factory Client" } if(Test-Path $script:AppFactoryClientWorkspace){ Remove-Item -Path $script:AppFactoryClientWorkspace -Force -Recurse } } #EndRegion '.\Public\Remove-AppFactoryClientFiles.ps1' 13 #Region '.\Public\Start-AppFactoryClient.ps1' 0 function Start-AppFactoryClient { [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true, ParameterSetName = 'console')][ValidateNotNullOrEmpty()][string]$Path, [Parameter(Mandatory = $true, ParameterSetName = 'PSU')][switch]$PSU, [Parameter()][ValidateNotNullOrEmpty()][string]$configfile = "Configuration.json", [Parameter()][ValidateNotNullOrEmpty()][string]$apikeysecret, [Parameter()][string]$LocalModule = $null, [Parameter()][switch]$EnableLogging, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) # Set if we will be logging via PSFramework if ($EnableLogging) { $script:AppFactoryClientLogging = $true } else { $script:AppFactoryClientLogging = $false } # Create Global Variables if ($PSCmdlet.ParameterSetName -eq "console") { $script:AppFactoryClientSourceDir = $Path } if ($LocalModule) { $script:LocalModulePath = $LocalModule } # Where is the configuration file stored $script:AppFactoryClientConfigDir = Join-Path -Path $script:AppFactoryClientSourceDir -ChildPath "Configurations" # Other Tool Directories $script:AppFactoryClientWorkspace = Join-Path -Path $script:AppFactoryClientSourceDir -ChildPath "Workspace" if ($script:AppFactoryClientLogging) { $AppFactoryClientLogDir = Join-Path -Path $script:AppFactoryClientSourceDir -ChildPath "Logs" # Name for the log file to be used $logFile = "$($AppFactoryClientLogDir)\AppFactoryClient-%Date%.csv" $paramSetPSFLoggingProvider = @{ Name = "logfile" InstanceName = "AppFactoryClient" FilePath = $logFile Enabled = $true Wait = $true } Set-PSFLoggingProvider @paramSetPSFLoggingProvider Write-PSFMessage -Message "Logging Configured" -Level $LogLevel -Tag "Setup" -Target "Application Factory Client" Write-PSFMessage -Message "Log File: <c='green'>$($logFile)</c>" -Level $LogLevel -Tag "Setup" -Target "AppFactoryClient" Write-PSFMessage -Message "Reading Configuration File" -Level $LogLevel -Tag "Setup" -Target "AppFactoryClient" } if ($PSCmdlet.ParameterSetName -eq "console") { try { $configFilePath = Join-Path $script:AppFactoryClientConfigDir -ChildPath $configfile $configDetails = Get-Content -Path $configFilePath -ErrorAction Stop | ConvertFrom-JSON $script:AppFactoryClientClientID = $configDetails.clientID $script:AppFactoryClientTenantID = $configDetails.tenantID $script:AppFactoryClientApiEndpoint = $configDetails.apiendpoint $script:AppFactoryClientAppRegSecret = Get-Secret -Vault $configDetails.keyVault -Name $configDetails.appregistrationSecret -AsPlainText $script:AppFactoryClientAPISecret = Get-Secret -Vault $configDetails.keyVault -Name $configDetails.apisecret } catch { throw $_ } } else { $script:AppFactoryClientAppRegSecret = ConvertTo-SecureString $secret:AppFactoryClientAppRegSecret -AsPlainText -Force $script:AppFactoryClientAPISecret = ConvertTo-SecureString $secret:AppFactoryClientAPISecret -AsPlainText -Force } return [PSCustomObject]@{ AppFactoryClientClientID = $script:AppFactoryClientClientID AppFactoryClientTenantID = $script:AppFactoryClientTenantID AppFactoryClientAppRegSecret = $script:AppFactoryClientAppRegSecret } } #EndRegion '.\Public\Start-AppFactoryClient.ps1' 72 #Region '.\Public\Start-AppFactoryClientProcess.ps1' 0 function Start-AppFactoryClientProcess{ [CmdletBinding()] param( [Parameter(Mandatory = $true,ParameterSetName = 'console')][ValidateNotNullOrEmpty()][string]$Path, [Parameter()][ValidateNotNullOrEmpty()][string]$configfile = "Configuration.json", [Parameter()][string]$LocalModule = $null, [Parameter()][switch]$EnableLogging, [Parameter()][switch]$multithread, [Parameter()][switch]$force, [Parameter()][switch]$LocalConfigs, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) $processparams = @{ "Path" = $Path "configfile" = $ConfigFile "LocalModule" = $LocalModule "EnableLogging" = $EnableLogging "LogLevel" = $LogLevel } $multithreadParam = @{ "multithread" = $multithread } $forceParam = @{ "force" = $force } $graphDetails = Start-AppFactoryClient @processparams # Get the current application configurations from the cloud if(-not ($LocalConfigs.IsPresent)){ Get-AppFactoryClientAppList } for ($x = 0; $x -lt 5; $x++) { # Cleanup Previous Files Remove-AppFactoryClientFiles Write-Host "Getting list of applications configurations from service" -ForegroundColor Green $applicationList = Get-AppFactoryClientApp -AddToIntune $true -LogLevel $LogLevel Write-Host "There are $($applicationList.count) application set to be configured in intune" -ForegroundColor Green Write-Host "Getting Graph Token" -ForegroundColor Green Get-GraphAccessToken -clientID $graphDetails.AppFactoryClientClientID -tenantID $graphDetails.AppFactoryClientTenantID -clientSecret $graphDetails.AppFactoryClientAppRegSecret | Out-Null Write-Host "Getting list of applications that are in intune" -ForegroundColor Green $intuneApplications = Get-GraphIntuneApp -type "microsoft.graph.win32LobApp" Write-Host "Compare expected version of application against intune" -ForegroundColor Green $applicationList = Compare-AppFactoryClientAppVersions -applicationList $applicationList -intuneapplications $intuneApplications -LogLevel $LogLevel @forceParam Write-Host "There are $($applicationList.count) apps that require an update." -ForegroundColor Green if ($applicationList.count -eq 0) { Write-Host "No applications require an update" -ForegroundColor Green return } # Make a note of how many applications we are expecting to update $originalCount = $applicationList.count $applicationList = Get-AppFactoryClientAppFiles -applicationList $applicationList -LogLevel $LogLevel @multithreadParam Write-Host "Downloaded files for $($applicationList.count) apps that require an update." -ForegroundColor Green $applicationList = Publish-AppFactoryClientApp -applicationList $applicationList -LogLevel $LogLevel @multithreadParam Write-Host "Published files for $($applicationList.count) apps that require an update." -ForegroundColor Green Write-Host "Getting fresh list of applications that are in intune" -ForegroundColor Green Remove-Variable -Name "graphAccessToken" -Scope Global -ErrorAction "SilentlyContinue" Get-GraphAccessToken -clientID $graphDetails.AppFactoryClientClientID -tenantID $graphDetails.AppFactoryClientTenantID -clientSecret $graphDetails.AppFactoryClientAppRegSecret | Out-Null $intuneApplications = Get-GraphIntuneApp -type "microsoft.graph.win32LobApp" Write-Host "Cleanup applications that might of failed but did not cleanup in prior step" -ForegroundColor Green foreach ($app in $($intuneApplications | Where-Object { $_.UploadState -eq 0 })) { Remove-GraphIntuneApp -applicationid $app.id } Write-Host "Adding application assignments" -ForegroundColor Green Add-AppFactoryClientAppAssignments -applicationList $applicationList -intuneapplications $intuneApplications -LogLevel $LogLevel Write-Host "Copying application assignments" -ForegroundColor Green Copy-AppFactoryClientAppAssignments -applicationList $applicationList -intuneapplications $intuneApplications -LogLevel $LogLevel Write-Host "Removing previous applications if applicable" -ForegroundColor Green Remove-AppFactoryClientApp -applicationList $applicationList -intuneapplications $intuneApplications -LogLevel $LogLevel Write-Host "Adding app to ESP if configured" -ForegroundColor Green Add-AppFactoryClientESPAssignment -applicationList $applicationList -intuneapplications $intuneApplications -LogLevel $LogLevel Write-Host "Completed $($applicationList.count) of the original $($originalCount)" -ForegroundColor Green foreach ($application in $applicationList) { Write-Host "Application Published: $($application.IntuneAppName)" -ForegroundColor Yellow } if ($applicationList.count -eq $originalCount) { return } Write-Host "==========================================================================================" -ForegroundColor Red Write-Host "Some applications failed to import into intune. Waiting 5 minutes to run the process again" -ForegroundColor Red Write-Host "==========================================================================================" -ForegroundColor Red Start-Sleep -Seconds 300 Remove-Variable -Name "graphAccessToken" -Scope Global -ErrorAction "SilentlyContinue" } } #EndRegion '.\Public\Start-AppFactoryClientProcess.ps1' 84 |