ApplicationFactoryServicePSU.psm1
#Region '.\Public\GUI_Private\Get-PSUApplicationDetection.ps1' 0 function Get-PSUApplicationDetection{ [cmdletbinding()] param( [Parameter()][PSCustomObject]$ApplicationInformation ) Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $variables = @("detection_DetectionOption") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } } if(-not ($eventdata.Context.PSobject.Properties.name -match "detection_DetectionOption")){ $rule = $ApplicationInformation.Config.DetectionRule if($rule.Type -eq "Registry" -and $rule.DetectionMethod -eq "Existence"){ $values.Add("detection_DetectionOption", "RegistryExistance") } elseif($rule.Type -eq "Registry" -and $rule.DetectionMethod -eq "VersionComparison"){ $values.Add("detection_DetectionOption", "RegistryVersion") } else{ $values.Add("detection_DetectionOption", $rule.Type) } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Detection Type*:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDSelect -Id "detection_DetectionOption" -ClassName "inputrequired" -DefaultValue $values.detection_DetectionOption -FullWidth -Option { New-UDSelectOption -Name "MSI" -Value "MSI" New-UDSelectOption -Name "Registry Version" -Value "RegistryVersion" New-UDSelectOption -Name "Registry Existance" -Value "RegistryExistance" New-UDSelectOption -Name "Script" -Value "Script" } -OnChange { Set-UDElement -Id 'sourceOptions' -Content { switch ($EventData) { "MSI" { Get-PSUApplicationDetectionMSI -ApplicationInformation $ApplicationInformation } "RegistryVersion" { Get-PSUApplicationDetectionRegistryVersion -ApplicationInformation $ApplicationInformation } "RegistryExistance" { Get-PSUApplicationDetectionRegistryExistance -ApplicationInformation $ApplicationInformation } "Script" { Get-PSUApplicationDetectionCustom -ApplicationInformation $ApplicationInformation } } } } } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } New-UDElement -Tag "br" New-UDElement -Tag 'div' -Id 'sourceOptions' -Content { switch ($values.detection_DetectionOption) { "MSI" { Get-PSUApplicationDetectionMSI -ApplicationInformation $ApplicationInformation } "RegistryVersion" { Get-PSUApplicationDetectionRegistryVersion -ApplicationInformation $ApplicationInformation } "RegistryExistance" { Get-PSUApplicationDetectionRegistryExistance -ApplicationInformation $ApplicationInformation } "Script" { Get-PSUApplicationDetectionCustom -ApplicationInformation $ApplicationInformation } } } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationDetection.ps1' 82 #Region '.\Public\GUI_Private\Get-PSUApplicationDetectionCustom.ps1' 0 function Get-PSUApplicationDetectionCustom{ Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $variables = @("detection_script","detection_RunAs32Bit") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } if(-not ($eventdata.Context.PSobject.Properties.name -match $var)){ $key = $var -replace "detection_", "" $value = $ApplicationInformation.Config.DetectionRule.$($key) if($null -ne $value -and $value -ne ""){ $values.Add($var, $value) } } } if(-not ($eventdata.Context.PSobject.Properties.name -match "detection_script")){ $path = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Apps" -AdditionalChildPath ($ApplicationInformation.Information.IntuneAppName -replace "STS-"),$ApplicationInformation.Config.DetectionRule.ScriptFile if((Test-Path $path) -and $null -ne $ApplicationInformation.Config.DetectionRule.ScriptFile){ $values.Add("detection_script", (Get-Content -Path $path -Raw)) } else{ $values.Add("detection_script", "") } } $32bit_Checked = $false if($values.detection_RunAs32Bit -eq "true"){ $32bit_Checked = $true } New-UDElement -Tag "span" -Content { New-UDTextbox -id "variables_detection" -Value "$($variables -join ",")" } -Attributes @{"style" = @{"display" = "none" } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Script:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "top" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "detection_script" -Type "Text" -FullWidth -ClassName "inputrequired" -Value $values.detection_script -Multiline -Rows 10 } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Run as 32bit:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDSwitch -Id "detection_RunAs32Bit" -Checked $32bit_Checked } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationDetectionCustom.ps1' 55 #Region '.\Public\GUI_Private\Get-PSUApplicationDetectionMSI.ps1' 0 function Get-PSUApplicationDetectionMSI{ [cmdletbinding()] param( [Parameter()][PSCustomObject]$ApplicationInformation ) Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $variables = @("detection_ProductVersionOperator") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } if(-not ($eventdata.Context.PSobject.Properties.name -match $var)){ $key = $var -replace "detection_", "" $value = $ApplicationInformation.Config.DetectionRule.$($key) if($null -ne $value -and $value -ne ""){ $values.Add($var, $value) } } } New-UDElement -Tag "span" -Content { New-UDTextbox -id "variables_detection" -Value "$($variables -join ",")" } -Attributes @{"style" = @{"display" = "none" } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Version Comparison*:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDSelect -Id "detection_ProductVersionOperator" -ClassName "inputoptional" -DefaultValue $values.detection_ProductVersionOperator -FullWidth -Option { New-UDSelectOption -Name "equal" -Value "equal" New-UDSelectOption -Name "notEqual" -Value "notEqual" New-UDSelectOption -Name "greaterThanOrEqual" -Value "greaterThanOrEqual" New-UDSelectOption -Name "greaterThan" -Value "greaterThan" New-UDSelectOption -Name "lessThanOrEqual" -Value "lessThanOrEqual" New-UDSelectOption -Name "lessThan" -Value "lessThan" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationDetectionMSI.ps1' 45 #Region '.\Public\GUI_Private\Get-PSUApplicationDetectionRegistryExistance.ps1' 0 function Get-PSUApplicationDetectionRegistryExistance{ Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $variables = @("detection_KeyPath","detection_Check32BitOn64System","detection_ValueName","detection_DetectionMethod") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } if(-not ($eventdata.Context.PSobject.Properties.name -match $var)){ $key = $var -replace "detection_", "" $value = $ApplicationInformation.Config.DetectionRule.$($key) if($var -eq "detection_KeyPath"){ $value = $value -replace "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\","" } if($value -eq "###PRODUCTCODE###"){$value = ""} if($null -ne $value -and $value -ne ""){ $values.Add($var, $value) } } } $32bit_Checked = $false if($values.detection_Check32BitOn64System -eq $true){ $32bit_Checked = $true } New-UDElement -Tag "span" -Content { New-UDTextbox -id "variables_detection" -Value "$($variables -join ",")" } -Attributes @{"style" = @{"display" = "none" } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Registry Key:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "detection_KeyPath" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.detection_KeyPath } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Registry Item:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "detection_ValueName" -Type "Text" -FullWidth -ClassName "inputrequired" -Value $values.detection_ValueName } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Detection Type:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDSelect -Id "detection_DetectionMethod" -ClassName "inputrequired" -DefaultValue $values.detection_DetectionMethod -FullWidth -Option { New-UDSelectOption -Name "exists" -Value "exists" New-UDSelectOption -Name "notexists" -Value "notexists" } } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "32bit Registry:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDSwitch -Id "detection_Check32BitOn64System" -Checked $32bit_Checked } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationDetectionRegistryExistance.ps1' 65 #Region '.\Public\GUI_Private\Get-PSUApplicationDetectionRegistryVersion.ps1' 0 function Get-PSUApplicationDetectionRegistryVersion{ Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $variables = @("detection_KeyPath","detection_Check32BitOn64System") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } if(-not ($eventdata.Context.PSobject.Properties.name -match $var)){ $key = $var -replace "detection_", "" $value = $ApplicationInformation.Config.DetectionRule.$($key) if($var -eq "detection_KeyPath"){ $value = $value -replace "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\","" } if($value -eq "###PRODUCTCODE###"){$value = ""} if($null -ne $value -and $value -ne ""){ $values.Add($var, $value) } } } $32bit_Checked = $false if($values.detection_Check32BitOn64System -eq $true){ $32bit_Checked = $true } New-UDElement -Tag "span" -Content { New-UDTextbox -id "variables_detection" -Value "$($variables -join ",")" } -Attributes @{"style" = @{"display" = "none" } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Registry Key:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "detection_KeyPath" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.detection_KeyPath } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "32bit Registry:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDSwitch -Id "detection_Check32BitOn64System" -Checked $32bit_Checked } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationDetectionRegistryVersion.ps1' 48 #Region '.\Public\GUI_Private\Get-PSUApplicationInfo.ps1' 0 function Get-PSUApplicationInfo { [cmdletbinding()] param( [Parameter()][Hashtable]$ApplicationInformation ) Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $variables = @("information_IntuneAppName", "information_AppPublisher", "information_InformationURL", "information_PrivacyURL", "information_Description", "information_publishTo", "information_IconFile") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } if (-not ($eventdata.Context.PSobject.Properties.name -match $var)) { $key = $var -replace "information_", "" if ($var -ne "information_Description") { $value = $ApplicationInformation.Information.$($key) } else { $value = $ApplicationInformation.Config.Information.$($key) } if ($null -ne $value -and $value -ne "") { $values.Add($var, $value) } } } if ($null -eq $values.information_publishTo) { $values.information_publishTo = "Public" } if (-not ($eventdata.Context.PSobject.Properties.name -match "information_IconFile") -and $null -ne $ApplicationInformation) { $values.information_IconFile = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Apps" -AdditionalChildPath ($ApplicationInformation.Information.IntuneAppName -replace "STS-"), "Icon.png" } if ($null -eq $values.information_IconFile) { $values.information_IconFile = Join-Path -Path $global:AppFactorySupportTemplateFolder -ChildPath "Framework" -AdditionalChildPath "Icon.png" } $organzations = Get-AppFactoryOrganizationPSU New-UDElement -Tag "span" -Content { New-UDTextbox -id "variables_information" -Value "$($variables -join ",")" } -Attributes @{"style" = @{"display" = "none" } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Name*:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "information_IntuneAppName" -Type "Text" -FullWidth -ClassName "inputrequired" -Value $values.information_IntuneAppName } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Publisher*:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "information_AppPublisher" -Type "Text" -FullWidth -ClassName "inputrequired" -Value $values.information_AppPublisher } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Information URL:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "information_InformationURL" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.information_InformationURL } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Privacy URL:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "information_PrivacyURL" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.information_PrivacyURL } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Description:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "top" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "information_Description" -Type "Text" -FullWidth -ClassName "inputrequired" -Value $values.information_Description -Multiline -Rows 5 } -Attributes @{"style" = @{"vertical-align" = "bottom" }; "colspan" = "3" } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Organization:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDSelect -Id "information_publishTo" -ClassName "inputrequired" -DefaultValue $values.information_publishTo -FullWidth -Multiple -Option { New-UDSelectOption -Name "Public" -Value "Public" foreach ($org in $organzations) { New-UDSelectOption -Name $org.Name -Value $org.GUID } } } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Icon:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -id "information_IconFile" -value $values.information_IconFile -Disabled } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content {} New-UDElement -Tag "td" -Content {} New-UDElement -Tag "td" -Content { New-UDUpload -Id "IconFile" -Text "Upload new image" -OnUpload { $Data = $Body | ConvertFrom-Json $bytes = [System.Convert]::FromBase64String($Data.Data) [System.IO.File]::WriteAllBytes("$($env:TEMP)\PSUApp_Icon.png", $bytes) Set-UDElement -id "information_IconFile" -Properties @{value = "$($env:TEMP)\PSUApp_Icon.png" } Set-UDElement -Id "imgdiv" -Content {} Set-UDElement -Id "imgdiv" -Content { New-UDImage -Id "appimage" -Path "$($env:TEMP)\PSUApp_Icon.png" -Width 50 -Height 50 } } New-UDElement -Tag "div" -Id "imgdiv" -Content { New-UDImage -Id "appimage" -Path $values.information_IconFile -Width 50 -Height 50 } } -Attributes @{"style" = @{"vertical-align" = "top" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationInfo.ps1' 120 #Region '.\Public\GUI_Private\Get-PSUApplicationInstall.ps1' 0 function Get-PSUApplicationInstall{ [cmdletbinding()] param( [Parameter()][PSCustomObject]$ApplicationInformation ) Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $variables = @("install_InstallType") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } } if(-not ($eventdata.Context.PSobject.Properties.name -match "install_InstallType")){ $value = $ApplicationInformation.Install.Type if($null -ne $value -and $value -ne ""){ $values.Add("install_InstallType", $value) } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Install Type*:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDSelect -Id "install_InstallType" -ClassName "inputrequired" -DefaultValue $values.install_InstallType -FullWidth -Option { New-UDSelectOption -Name "MSI" -Value "MSI" New-UDSelectOption -Name "EXE" -Value "EXE" New-UDSelectOption -Name "ECNO" -Value "ECNO" New-UDSelectOption -Name "Custom" -Value "CUSTOM" } -OnChange { Set-UDElement -Id 'installOptions' -Content { switch ($EventData) { "MSI" { Get-PSUApplicationInstallMSI -ApplicationInformation $ApplicationInformation } "EXE" { Get-PSUApplicationInstallEXE -ApplicationInformation $ApplicationInformation } "Custom" { Get-PSUApplicationInstallCustom -ApplicationInformation $ApplicationInformation } "ECNO" { $applicationDetails.variables_install = "" } } } } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } New-UDElement -Tag "br" New-UDElement -Tag 'div' -Id 'installOptions' -Content { switch ($values.install_InstallType) { "MSI" { Get-PSUApplicationInstallMSI -ApplicationInformation $ApplicationInformation } "EXE" { Get-PSUApplicationInstallEXE -ApplicationInformation $ApplicationInformation } "Custom" { Get-PSUApplicationInstallCustom -ApplicationInformation $ApplicationInformation } } } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationInstall.ps1' 73 #Region '.\Public\GUI_Private\Get-PSUApplicationInstallCustom.ps1' 0 function Get-PSUApplicationInstallCustom{ Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $variables = @("install_script") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } if(-not ($eventdata.Context.PSobject.Properties.name -match $var)){ $key = $var -replace "install_", "" $value = $ApplicationInformation.Install.script -join "`n" if($null -ne $value -and $value -ne ""){ $values.Add($var, $value) } } } New-UDElement -Tag "span" -Content { New-UDTextbox -id "variables_install" -Value "$($variables -join ",")" } -Attributes @{"style" = @{"display" = "none" } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Script:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "top" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "install_script" -Type "Text" -FullWidth -ClassName "inputrequired" -Value $values.install_script -Multiline -Rows 6 } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationInstallCustom.ps1' 34 #Region '.\Public\GUI_Private\Get-PSUApplicationInstallEXE.ps1' 0 function Get-PSUApplicationInstallEXE { Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $variables = @("install_installer","install_Parameters", "install_ignoreExit", "install_beginstopProcess", "install_afterstopProcess","install_WIM") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } if(-not ($eventdata.Context.PSobject.Properties.name -match $var)){ $key = $var -replace "install_", "" $value = $ApplicationInformation.Install.$($key) if($null -ne $value -and $value -ne ""){ if($value -notmatch "###SETUPFILENAME###"){ $values.Add($var, $value) } } } } $wim_Checked = $false if($values.install_WIM -eq "true"){ $wim_Checked = $true } New-UDElement -Tag "span" -Content { New-UDTextbox -id "variables_install" -Value "$($variables -join ",")" } -Attributes @{"style" = @{"display" = "none" } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Installer:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "install_installer" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.install_installer } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Parameters:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "install_Parameters" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.install_Parameters } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Ignore Exit Codes:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "install_ignoreExit" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.install_ignoreExit } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Stop Process (Start):" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "install_beginstopProcess" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.install_beginstopProcess } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Stop Process (End):" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "install_afterstopProcess" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.install_afterstopProcess } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "WIM:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDSwitch -Id "install_WIM" -Checked $wim_Checked } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationInstallEXE.ps1' 74 #Region '.\Public\GUI_Private\Get-PSUApplicationInstallMSI.ps1' 0 function Get-PSUApplicationInstallMSI{ [cmdletbinding()] param( [Parameter()][PSCustomObject]$ApplicationInformation ) Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $variables = @("install_installer","install_Parameters","install_MST","install_beginstopProcess","install_afterstopProcess","install_WIM") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } if(-not ($eventdata.Context.PSobject.Properties.name -match $var)){ $key = $var -replace "install_", "" $value = $ApplicationInformation.Install.$($key) if($null -ne $value -and $value -ne ""){ if($value -notmatch "###SETUPFILENAME###"){ $values.Add($var, $value) } } } } $wim_Checked = $false if($values.install_WIM -eq "true"){ $wim_Checked = $true } New-UDElement -Tag "span" -Content { New-UDTextbox -id "variables_install" -Value "$($variables -join ",")" } -Attributes @{"style" = @{"display" = "none" } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Installer:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "install_installer" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.install_installer } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Parameters:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "install_Parameters" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.install_Parameters } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "MST:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "install_MST" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.install_MST } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Stop Process (Start):" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "install_beginstopProcess" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.install_beginstopProcess } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Stop Process (End):" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "install_afterstopProcess" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.install_afterstopProcess } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "WIM:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDSwitch -Id "install_WIM" -Checked $wim_Checked } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationInstallMSI.ps1' 79 #Region '.\Public\GUI_Private\Get-PSUApplicationSource.ps1' 0 function Get-PSUApplicationSource { [cmdletbinding()] param( [Parameter()][PSCustomObject]$ApplicationInformation ) Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $variables = @("source_AppSource") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } } if(-not ($eventdata.Context.PSobject.Properties.name -match "source_AppSource")){ $value = $ApplicationInformation.Information.AppSource if($null -ne $value -and $value -ne ""){ $values.Add("source_AppSource", $value) } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Name*:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDSelect -Id "source_AppSource" -ClassName "inputrequired" -DefaultValue $values.source_AppSource -FullWidth -Option { New-UDSelectOption -Name "Azure Storage" -Value "StorageAccount" New-UDSelectOption -Name "ECNO" -Value "ECNO" New-UDSelectOption -Name "Evergreen" -Value "Evergreen" New-UDSelectOption -Name "PowerShell" -Value "PSADT" New-UDSelectOption -Name "Sharepoint" -Value "Sharepoint" New-UDSelectOption -Name "Winget" -Value "Winget" } -OnChange { Set-UDElement -Id 'sourceOptions' -Content { switch ($EventData) { "StorageAccount" { Get-PSUApplicationSourceStorageAccount -ApplicationInformation $ApplicationInformation } "ECNO" { Get-PSUApplicationSourceECNO -ApplicationInformation $ApplicationInformation } "Evergreen" { Get-PSUApplicationSourceEvergreen -ApplicationInformation $ApplicationInformation } "Sharepoint" { Get-PSUApplicationSourceSharepoint -ApplicationInformation $ApplicationInformation } "Winget" { Get-PSUApplicationSourceWinget -ApplicationInformation $ApplicationInformation } } } } } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } New-UDElement -Tag "br" New-UDElement -Tag 'div' -Id 'sourceOptions' -Content { switch ($values.source_AppSource) { "StorageAccount" { Get-PSUApplicationSourceStorageAccount -ApplicationInformation $ApplicationInformation } "ECNO" { Get-PSUApplicationSourceECNO -ApplicationInformation $ApplicationInformation } "Evergreen" { Get-PSUApplicationSourceEvergreen -ApplicationInformation $ApplicationInformation } "Sharepoint" { Get-PSUApplicationSourceSharepoint -ApplicationInformation $ApplicationInformation } "Winget" { Get-PSUApplicationSourceWinget -ApplicationInformation $ApplicationInformation } } } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationSource.ps1' 83 #Region '.\Public\GUI_Private\Get-PSUApplicationSourceECNO.ps1' 0 function Get-PSUApplicationSourceECNO{ [cmdletbinding()] param( [Parameter()][PSCustomObject]$ApplicationInformation ) $variables = @("source_StorageAccountContainerName") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } if(-not ($eventdata.Context.PSobject.Properties.name -match $var)){ $key = $var -replace "source_", "" $value = $ApplicationInformation.Information.$($key) if($null -ne $value -and $value -ne ""){ $values.Add($var, $value) } } } New-UDElement -Tag "span" -Content { New-UDTextbox -id "variables_source" -Value "$($variables -join ",")" } -Attributes @{"style" = @{"display" = "none" } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Application Folder*:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "source_StorageAccountContainerName" -Type "Text" -FullWidth -ClassName "inputrequired" -Value $values.source_StorageAccountContainerName } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationSourceECNO.ps1' 38 #Region '.\Public\GUI_Private\Get-PSUApplicationSourceEvergreen.ps1' 0 function Get-PSUApplicationSourceEvergreen{ [cmdletbinding()] param( [Parameter()][PSCustomObject]$ApplicationInformation ) $variables = @("source_AppSetupFileName","source_AppID","source_filter_Architecture","source_filter_Platform","source_filter_Channel","source_filter_Type","source_filter_InstallerType","source_filter_Release","source_filter_Language","source_filter_ImageType") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } if(-not ($eventdata.Context.PSobject.Properties.name -match $var)){ $value = $null if(-not ($var -match "source_filter_")){ $key = $var -replace "source_", "" $value = $ApplicationInformation.Information.$($key) } else{ $key = $var -replace "source_filter_", "" $value = $ApplicationInformation.Information.FilterOptions.$($key) } if($null -ne $value -and $value -ne ""){ $values.Add($var, $value) } } } New-UDElement -Tag "span" -Content { New-UDTextbox -id "variables_source" -Value "$($variables -join ",")" } -Attributes @{"style" = @{"display" = "none" } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Installer:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "source_AppSetupFileName" -Type "Text" -FullWidth -ClassName "inputrequired" -Value $values.source_AppSetupFileName } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Application ID:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "source_AppID" -Type "Text" -FullWidth -ClassName "inputrequired" -Value $values.source_AppID } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDElement -Tag "br" New-UDElement -Tag "div" -ClassName "card-body rounded" -Content { New-UDTypography -Text "Filter Options" -Variant "h6" -ClassName "card-title rounded x-card-title-2" -Style @{"font-weight" = "bold" } } New-UDElement -Tag "br" } -Attributes @{"style" = @{"vertical-align" = "bottom" }; "colspan" = "4" } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Architecture:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "source_filter_Architecture" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.source_filter_Architecture } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Platform:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "source_filter_Platform" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.source_filter_Platform } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Channel:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "source_filter_Channel" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.source_filter_Channel } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Type:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "source_filter_Type" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.source_filter_Type } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Installer Type:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "source_filter_InstallerType" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.source_filter_InstallerType } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Release:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "source_filter_Release" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.source_filter_Release } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Language:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "source_filter_Language" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.source_filter_Language } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "ImageType:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "source_filter_ImageType" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.source_filter_ImageType } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationSourceEvergreen.ps1' 115 #Region '.\Public\GUI_Private\Get-PSUApplicationSourceSharepoint.ps1' 0 function Get-PSUApplicationSourceSharepoint{ [cmdletbinding()] param( [Parameter()][PSCustomObject]$ApplicationInformation ) $variables = @("source_AppSetupFileName","source_archiveType") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } if(-not ($eventdata.Context.PSobject.Properties.name -match $var)){ $key = $var -replace "source_", "" $value = $ApplicationInformation.Information.$($key) if($null -ne $value -and $value -ne ""){ $values.Add($var, $value) } } } New-UDElement -Tag "span" -Content { New-UDTextbox -id "variables_source" -Value "$($variables -join ",")" } -Attributes @{"style" = @{"display" = "none" } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Installer*:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "source_AppSetupFileName" -Type "Text" -FullWidth -ClassName "inputrequired" -Value $values.source_AppSetupFileName } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Archive Type:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDSelect -Id "source_archiveType" -ClassName "inputoptional" -DefaultValue $values.source_archiveType -FullWidth -Option { New-UDSelectOption -Name "ZIP" -Value "ZIP" New-UDSelectOption -Name "7Z" -Value "7z" New-UDSelectOption -Name "WIM" -Value "WIM" } } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationSourceSharepoint.ps1' 48 #Region '.\Public\GUI_Private\Get-PSUApplicationSourceStorageAccount.ps1' 0 function Get-PSUApplicationSourceStorageAccount{ [cmdletbinding()] param( [Parameter()][PSCustomObject]$ApplicationInformation ) $variables = @("source_AppSetupFileName","source_StorageAccountContainerName","source_archiveType") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } if(-not ($eventdata.Context.PSobject.Properties.name -match $var)){ $key = $var -replace "source_", "" $value = $ApplicationInformation.Information.$($key) if($var -match "archiveType"){ if($value -match "ZIP"){ $value = "ZIP" } } if($null -ne $value -and $value -ne ""){ $values.Add($var, $value) } } } New-UDElement -Tag "span" -Content { New-UDTextbox -id "variables_source" -Value "$($variables -join ",")" } -Attributes @{"style" = @{"display" = "none" } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Installer*:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "source_AppSetupFileName" -Type "Text" -FullWidth -ClassName "inputrequired" -Value $values.source_AppSetupFileName } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Storage Container*:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "source_StorageAccountContainerName" -Type "Text" -FullWidth -ClassName "inputrequired" -Value $values.source_StorageAccountContainerName } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Archive Type:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDSelect -Id "source_archiveType" -ClassName "inputoptional" -DefaultValue $values.source_archiveType -FullWidth -Option { New-UDSelectOption -Name "None" -Value "" New-UDSelectOption -Name "ZIP" -Value "ZIP" New-UDSelectOption -Name "7Z" -Value "7z" } } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationSourceStorageAccount.ps1' 61 #Region '.\Public\GUI_Private\Get-PSUApplicationSourceWinget.ps1' 0 function Get-PSUApplicationSourceWinget{ [cmdletbinding()] param( [Parameter()][PSCustomObject]$ApplicationInformation ) $variables = @("source_AppSetupFileName","source_AppID") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } if(-not ($eventdata.Context.PSobject.Properties.name -match $var)){ $key = $var -replace "source_", "" $value = $ApplicationInformation.Information.$($key) if($null -ne $value -and $value -ne ""){ $values.Add($var, $value) } } } New-UDElement -Tag "span" -Content { New-UDTextbox -id "variables_source" -Value "$($variables -join ",")" } -Attributes @{"style" = @{"display" = "none" } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Installer:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "source_AppSetupFileName" -Type "Text" -FullWidth -ClassName "inputrequired" -Value $values.source_AppSetupFileName } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Application ID:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "source_AppID" -Type "Text" -FullWidth -ClassName "inputrequired" -Value $values.source_AppID } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationSourceWinget.ps1' 43 #Region '.\Public\GUI_Private\Get-PSUApplicationUninstall.ps1' 0 function Get-PSUApplicationUninstall { [cmdletbinding()] param( [Parameter()][PSCustomObject]$ApplicationInformation ) Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $variables = @("uninstall_UninstallType") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } } if(-not ($eventdata.Context.PSobject.Properties.name -match "uninstall_UninstallType")){ $value = $ApplicationInformation.Uninstall.Type if($null -ne $value -and $value -ne ""){ $values.Add("uninstall_UninstallType", $value) } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Uninstall Type*:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDSelect -Id "uninstall_UninstallType" -ClassName "inputrequired" -DefaultValue $values.uninstall_UninstallType -FullWidth -Option { New-UDSelectOption -Name "None" -Value "NONE" New-UDSelectOption -Name "MSI" -Value "MSI" New-UDSelectOption -Name "EXE" -Value "EXE" New-UDSelectOption -Name "Name" -Value "NAME" New-UDSelectOption -Name "GUID" -Value "GUID" New-UDSelectOption -Name "ECNO" -Value "ECNO" New-UDSelectOption -Name "Custom" -Value "CUSTOM" } -OnChange { Set-UDElement -Id 'uninstallOptions' -Content { switch ($EventData) { "NONE" { $applicationDetails.variables_uninstall = "" } "MSI" { Get-PSUApplicationUninstallMSI -ApplicationInformation $ApplicationInformation } "EXE" { Get-PSUApplicationUninstallEXE -ApplicationInformation $ApplicationInformation } "Name" { Get-PSUApplicationUninstallName -ApplicationInformation $ApplicationInformation } "GUID" { Get-PSUApplicationUninstallGUID -ApplicationInformation $ApplicationInformation } "ECNO" { $applicationDetails.variables_uninstall = "" } "Custom" { Get-PSUApplicationUninstallCustom -ApplicationInformation $ApplicationInformation } } } } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } New-UDElement -Tag "br" New-UDElement -Tag 'div' -Id 'uninstallOptions' -Content { switch ($values.uninstall_UninstallType) { "MSI" { Get-PSUApplicationUninstallMSI -ApplicationInformation $ApplicationInformation } "EXE" { Get-PSUApplicationUninstallEXE -ApplicationInformation $ApplicationInformation } "Name" { Get-PSUApplicationUninstallName -ApplicationInformation $ApplicationInformation } "GUID" { Get-PSUApplicationUninstallGUID -ApplicationInformation $ApplicationInformation } "Custom" { Get-PSUApplicationUninstallCustom -ApplicationInformation $ApplicationInformation } } } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationUninstall.ps1' 90 #Region '.\Public\GUI_Private\Get-PSUApplicationUninstallCustom.ps1' 0 function Get-PSUApplicationUninstallCustom{ Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $variables = @("uninstall_script") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } if(-not ($eventdata.Context.PSobject.Properties.name -match $var)){ $key = $var -replace "uninstall_", "" $value = $ApplicationInformation.Uninstall.script -join "`n" if($null -ne $value -and $value -ne ""){ $values.Add($var, $value) } } } New-UDElement -Tag "span" -Content { New-UDTextbox -id "variables_uninstall" -Value "$($variables -join ",")" } -Attributes @{"style" = @{"display" = "none" } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Script:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "top" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "uninstall_script" -Type "Text" -FullWidth -ClassName "inputrequired" -Value $values.uninstall_script -Multiline -Rows 6 } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationUninstallCustom.ps1' 34 #Region '.\Public\GUI_Private\Get-PSUApplicationUninstallEXE.ps1' 0 function Get-PSUApplicationUninstallEXE{ Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $variables = @("uninstall_installer","uninstall_Parameters","uninstall_beginstopProcess","uninstall_afterstopProcess","uninstall_Dirfiles","uninstall_ignoreExit","uninstall_WIM") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } if(-not ($eventdata.Context.PSobject.Properties.name -match $var)){ $key = $var -replace "uninstall_", "" $value = $ApplicationInformation.Uninstall.$($key) if($null -ne $value -and $value -ne ""){ if($value -notmatch "###SETUPFILENAME###"){ $values.Add($var, $value) } } } } $dirfiles_Checked = $false if($values.uninstall_Dirfiles -eq "true"){ $dirfiles_Checked = $true } $wim_Checked = $false if($values.uninstall_WIM -eq "true"){ $wim_Checked = $true } New-UDElement -Tag "span" -Content { New-UDTextbox -id "variables_uninstall" -Value "$($variables -join ",")" } -Attributes @{"style" = @{"display" = "none" } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Installer:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "uninstall_installer" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.uninstall_installer } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Parameters:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "uninstall_Parameters" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.uninstall_Parameters } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Stop Process (Start):" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "uninstall_beginstopProcess" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.uninstall_beginstopProcess } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Stop Process (End):" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "uninstall_afterstopProcess" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.uninstall_afterstopProcess } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Ignore Exit Code:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "uninstall_ignoreExit" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.uninstall_ignoreExit } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Dirfiles:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDSwitch -Id "uninstall_Dirfiles" -Checked $dirfiles_Checked } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "WIM:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDSwitch -Id "uninstall_WIM" -Checked $wim_Checked } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationUninstallEXE.ps1' 86 #Region '.\Public\GUI_Private\Get-PSUApplicationUninstallGUID.ps1' 0 function Get-PSUApplicationUninstallGUID{ Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $variables = @("uninstall_MSIGUID") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } if(-not ($eventdata.Context.PSobject.Properties.name -match $var)){ $key = $var -replace "uninstall_", "" $value = $ApplicationInformation.Uninstall.$($key) if($null -ne $value -and $value -ne ""){ $values.Add($var, $value) } } } New-UDElement -Tag "span" -Content { New-UDTextbox -id "variables_uninstall" -Value "$($variables -join ",")" } -Attributes @{"style" = @{"display" = "none" } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "MSI GUID:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "uninstall_MSIGUID" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.uninstall_MSIGUID } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationUninstallGUID.ps1' 34 #Region '.\Public\GUI_Private\Get-PSUApplicationUninstallMSI.ps1' 0 function Get-PSUApplicationUninstallMSI { param( [Parameter()][PSCustomObject]$ApplicationInformation ) Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $variables = @("uninstall_installer","uninstall_Parameters","uninstall_beginstopProcess","uninstall_afterstopProcess","uninstall_Dirfiles","uninstall_WIM") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } if(-not ($eventdata.Context.PSobject.Properties.name -match $var)){ $key = $var -replace "uninstall_", "" $value = $ApplicationInformation.Uninstall.$($key) if($null -ne $value -and $value -ne ""){ if($value -notmatch "###SETUPFILENAME###"){ $values.Add($var, $value) } } } } $dirfiles_Checked = $false if($values.uninstall_Dirfiles -eq "true"){ $dirfiles_Checked = $true } $wim_Checked = $false if($values.uninstall_WIM -eq "true"){ $wim_Checked = $true } New-UDElement -Tag "span" -Content { New-UDTextbox -id "variables_uninstall" -Value "$($variables -join ",")" } -Attributes @{"style" = @{"display" = "none" } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Installer:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "uninstall_installer" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.uninstall_installer } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Parameters:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "uninstall_Parameters" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.uninstall_Parameters } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Stop Process (Start):" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "uninstall_beginstopProcess" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.uninstall_beginstopProcess } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Stop Process (End):" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "uninstall_afterstopProcess" -Type "Text" -FullWidth -ClassName "inputoptional" -Value $values.uninstall_afterstopProcess } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Dirfiles:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDSwitch -Id "uninstall_Dirfiles" -Checked $dirfiles_Checked } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "WIM:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDSwitch -Id "uninstall_WIM" -Checked $wim_Checked } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationUninstallMSI.ps1' 81 #Region '.\Public\GUI_Private\Get-PSUApplicationUninstallName.ps1' 0 function Get-PSUApplicationUninstallName{ Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $variables = @("uninstall_Name") $values = @{} foreach ($var in $variables) { if ($null -ne $eventdata.context.$($var) -and $eventdata.context.$($var) -ne "") { $values.Add($var, $eventdata.context.$($var)) } if(-not ($eventdata.Context.PSobject.Properties.name -match $var)){ $key = $var -replace "uninstall_", "" $value = $ApplicationInformation.Uninstall.$($key) if($null -ne $value -and $value -ne ""){ $values.Add($var, $value) } } } New-UDElement -Tag "span" -Content { New-UDTextbox -id "variables_uninstall" -Value "$($variables -join ",")" } -Attributes @{"style" = @{"display" = "none" } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Name:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "uninstall_Name" -Type "Text" -FullWidth -ClassName "inputrequired" -Value $values.uninstall_Name } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } } #EndRegion '.\Public\GUI_Private\Get-PSUApplicationUninstallName.ps1' 34 #Region '.\Public\GUI_Private\Get-PSUClientInfo.ps1' 0 function Get-PSUClientInfo{ [cmdletbinding()] param( [Parameter()][string]$clientGUID ) if($clientGUID){ $client = Get-AppFactoryOrganizationPSU -GUID $clientGUID } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Name*:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "Name" -Type "Text" -FullWidth -ClassName "inputrequired" -Value $client.Name } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Contacts*:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; "vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "contactList" -Type "Text" -FullWidth -ClassName "inputrequired" -Value $($client.contacts -join ",") } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } } #EndRegion '.\Public\GUI_Private\Get-PSUClientInfo.ps1' 33 #Region '.\Public\GUI_Private\Get-PSUGUIClientAppsList.ps1' 0 function Get-PSUGUIClientAppsList{ [cmdletbinding()] param( [Parameter()][string]$clientGUID, [Parameter(Mandatory = $true)]$columnData ) $applicationList = Get-AppFactoryOrganizationsAppListPSU -clientGUID $clientGUID New-UDDataGrid -LoadRows { $applicationList | Sort-Object -Property "IntuneAppName" | Out-UDDataGridData -Context $EventData -TotalRows $applicationList.Length } -Columns $columnData -AutoHeight $true -PageSize 500 -DefaultSortColumn "Name" } #EndRegion '.\Public\GUI_Private\Get-PSUGUIClientAppsList.ps1' 12 #Region '.\Public\GUI_Public\Get-PSUGUIApplications.ps1' 0 function Get-PSUGUIApplications { [cmdletbinding()] param( [Parameter(Mandatory = $true)]$ColumnList ) Import-Module -Name $PS_GUI_Module -Force Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications # Create the column list $columnList.Add(10,@{ Field = "GUID" FLex = 2 HeaderName = "GUID" }) $columnList.Add(20,@{ Field = "IntuneAppName" FLex = 2 HeaderName = "Application" }) $columnList.Add(30,@{ Field = "AppPublisher" FLex = 2 HeaderName = "Publisher" }) $columnList.Add(40,@{ Field = "AppSource" FLex = 2 HeaderName = "Source" }) $columnList.Add(50,@{ Field = "Version" FLex = 2 HeaderName = "Version" }) $columnData = @() foreach ($col in ($columnList.GetEnumerator() | Sort-Object -Property Name)) { $cols = $col.Value $columnData += (New-UDDataGridColumn @cols) } New-UDElement -Tag "div" -ClassName "card-body rounded" -Content { New-UDButton -Id "NewApplication" -Text "New Application" -ClassName "btn btn-primary" -OnClick { Show-UDModal -MaxWidth lg -FullWidth -Content { Import-Module -Name $PS_GUI_Module -Force New-PSUApplication } -Footer { New-UDButton -Text "Cancel" -OnClick { Hide-UDModal } } } } New-UDElement -tag "br" New-UDElement -Tag "div" -ClassName "card-body rounded" -Content { New-UDTypography -Text "Public Applications" -Variant "h5" -ClassName "card-title rounded x-card-title" $applicationList = Get-AppFactoryAppPSU -Public New-UDDataGrid -LoadRows { $applicationList | Out-UDDataGridData -Context $EventData -TotalRows $applicationList.Length } -Columns $columnData -AutoHeight $true -PageSize 500 -DefaultSortColumn "IntuneAppName" } New-UDElement -tag "br" $organzations = Get-AppFactoryOrganizationPSU foreach ($org in $organzations) { New-UDElement -Tag "div" -ClassName "card-body rounded" -Content { New-UDTypography -Text "$($org.Name) Applications" -Variant "h5" -ClassName "card-title rounded x-card-title" $applicationList = Get-AppFactoryAppPSU -publishTo $org.GUID New-UDDataGrid -LoadRows { $applicationList | Out-UDDataGridData -Context $EventData -TotalRows $applicationList.Length } -Columns $columnData -AutoHeight $true -PageSize 500 -DefaultSortColumn "IntuneAppName" } New-UDElement -tag "br" } } #EndRegion '.\Public\GUI_Public\Get-PSUGUIApplications.ps1' 70 #Region '.\Public\GUI_Public\Get-PSUGUIClient.ps1' 0 function Get-PSUGUIClient { [cmdletbinding()] param( [Parameter(Mandatory = $true)]$ColumnList ) Import-Module -Name $PS_GUI_Module -Force Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications # Create the column list $columnList.Add(10,@{ Field = "GUID" FLex = 2 HeaderName = "GUID" }) $columnList.Add(20,@{ Field = "Name" FLex = 2 HeaderName = "Name" }) $columnData = @() foreach ($col in ($columnList.GetEnumerator() | Sort-Object -Property Name)) { $cols = $col.Value $columnData += (New-UDDataGridColumn @cols) } New-UDElement -Tag "div" -ClassName "card-body rounded" -Content { New-UDButton -Id "NewClient" -Text "New Client" -ClassName "btn btn-primary" -OnClick { Show-UDModal -MaxWidth lg -FullWidth -Content { Import-Module -Name $PS_GUI_Module -Force New-PSUClient } -Persistent } } New-UDElement -tag "br" New-UDElement -Tag "div" -ClassName "card-body rounded" -Content { New-UDTypography -Text "Clients" -Variant "h5" -ClassName "card-title rounded x-card-title" $clients = Get-AppFactoryOrganizationPSU New-UDDataGrid -LoadRows { $clients | Out-UDDataGridData -Context $EventData -TotalRows $clients.Length } -Columns $columnData -AutoHeight $true -PageSize 500 -DefaultSortColumn "Name" } } #EndRegion '.\Public\GUI_Public\Get-PSUGUIClient.ps1' 41 #Region '.\Public\GUI_Public\Get-PSUGUIClientApps.ps1' 0 function Get-PSUGUIClientApps{ [cmdletbinding()] param( [Parameter(Mandatory = $true)]$ColumnList ) $columnList.Add(10,@{ Field = "GUID" FLex = 2 HeaderName = "GUID" }) $columnList.Add(20,@{ Field = "IntuneAppName" FLex = 2 HeaderName = "Name" }) $columnList.Add(30,@{ Field = "AppVersion" FLex = 2 HeaderName = "Version" }) $columnList.Add(40,@{ Field = "AddToIntune" FLex = 2 HeaderName = "Intune" }) $columnList.Add(70,@{ Field = "InteractiveInstall" FLex = 2 HeaderName = "Interactive Install" }) $columnList.Add(80,@{ Field = "InteractiveUninstall" FLex = 2 HeaderName = "Interactive Uninstall" }) $columnList.Add(90,@{ Field = "container" FLex = 2 HeaderName = "Public/Org" }) $columnData = @() foreach ($col in ($columnList.GetEnumerator() | Sort-Object -Property Name)) { $cols = $col.Value $columnData += (New-UDDataGridColumn @cols) } Import-Module -Name $PS_GUI_Module -Force Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $ids = ($Roles -match "(^([0-9A-Fa-f]{8}[-]?[0-9A-Fa-f]{4}[-]?[0-9A-Fa-f]{4}[-]?[0-9A-Fa-f]{4}[-]?[0-9A-Fa-f]{12})$)") $organizations = Get-AppFactoryOrganizationPSU if($roles.Contains($PSU_GUI_AdminRole)){ $defaultValue = $organizations[0].GUID } else{ $defaultValue = $ids[0] } New-UDSelect -Id "ClientIDs" -ClassName "inputrequired" -DefaultValue $defaultValue -FullWidth -Option { foreach($org in $organizations){ if($ids.Contains($org.GUID) -or $roles.Contains($PSU_GUI_AdminRole)){ New-UDSelectOption -Name $org.Name -Value $org.GUID } } } -OnChange { Set-UDElement -Id "AppList" -Content { Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications Get-PSUGUIClientAppsList -clientGUID $EventData -columnData $columnData } } New-UDElement -tag "div" -id "AppList" -Content { Get-PSUGUIClientAppsList -clientGUID $defaultValue -columnData $columnData } } #EndRegion '.\Public\GUI_Public\Get-PSUGUIClientApps.ps1' 72 #Region '.\Public\GUI_Public\New-PSUApplication.ps1' 0 function New-PSUApplication { [cmdletbinding()] param() # Create the install stepper New-UDStepper -Steps { New-UDStep -OnLoad { Get-PSUApplicationInfo } -Label "Information" New-UDStep -OnLoad { Get-PSUApplicationSource } -Label "Source" New-UDStep -OnLoad { Get-PSUApplicationInstall } -Label "Install" New-UDStep -OnLoad { Get-PSUApplicationUninstall } -Label "Uninstall" New-UDStep -OnLoad { Get-PSUApplicationDetection } -Label "Detection" } -OnFinish { Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $applicationDetails = $EventData.Context $AppCreation = @{} $filterOptions = @{} $installOptions = @{Type = $applicationDetails.install_InstallType } $uninstallOptions = @{Type = $applicationDetails.uninstall_UninstallType } $detectionOptions = @{} # Get Information Step Information foreach ($item in ($applicationDetails.variables_information -split ",")) { $key = $item -replace "information_", "" if ($key -eq "IntuneAppName") { $Key = "Name" } if ($key -eq "AppPublisher") { $Key = "Publisher" } if ($item -eq "information_IconFile" -or $item -eq "information_Description" ) { continue } if ($item -eq "information_publishTo" -and $applicationDetails.$item.contains("Public")) { continue } if ($null -ne $applicationDetails.$item -and $applicationDetails.$item -ne "") { $AppCreation.Add($key, $applicationDetails.$item) } } # Get Source Step Information $AppCreation.Add("AppSource", $applicationDetails.source_AppSource) foreach ($item in ($applicationDetails.variables_source -split ",")) { $key = $item -replace "source_", "" if ($key -eq "AppSetupFileName") { $Key = "appSetupName" } if ($key -eq "StorageAccountContainerName") { $Key = "storageContainerName" } if ($item -eq "source_archiveType" -and ($null -eq $applicationDetails.source_archiveType -or $applicationDetails.source_archiveType -eq "None")) { $applicationDetails.source_archiveType = "" } if ($null -ne $applicationDetails.$item -and $applicationDetails.$item -ne "") { if ($item -match "^source_[^_]*$") { $AppCreation.Add($key, $applicationDetails.$item) } else { $key = $item -replace "source_filter_", "" $filterOptions.Add($key, $applicationDetails.$item) } } } if ($filterOptions.Count -gt 0) { $AppCreation.Add("FilterOptions", $filterOptions) } # Get the details for the install step foreach ($item in ($applicationDetails.variables_install -split ",")) { $key = $item -replace "install_", "" if ($null -ne $applicationDetails.$item -and $applicationDetails.$item -ne "") { $installOptions.Add($key, $applicationDetails.$item) } } # Get the details for the uninstall step foreach ($item in ($applicationDetails.variables_uninstall -split ",")) { $key = $item -replace "uninstall_", "" if ($null -ne $applicationDetails.$item -and $applicationDetails.$item -ne "") { $uninstallOptions.Add($key, $applicationDetails.$item) } } # Get the details for the detection step if ($applicationDetails.detection_DetectionOption -like "Registry*") { $detectionOptions.Add("Type", "Registry") if ($applicationDetails.detection_DetectionOption -eq "RegistryVersion") { $detectionOptions.Add("DetectionMethod", "VersionComparison") } else { $detectionOptions.Add("DetectionMethod", "Existence") } } else { $detectionOptions.Add("Type", $applicationDetails.detection_DetectionOption) } foreach ($item in ($applicationDetails.variables_detection -split ",")) { $key = $item -replace "detection_", "" if ($item -eq "detection_ProductVersionOperator" -and $applicationDetails.$item -eq "notConfigured") { continue } if ($null -ne $applicationDetails.$item -and $applicationDetails.$item -ne "") { $detectionOptions.Add($key, $applicationDetails.$item) } } $applicationInfoUpdate = @{ Description = $applicationDetails.information_Description InstallExperience = "system" DeviceRestartBehavior = "suppress" AllowAvailableUninstall = $true MinimumSupportedWindowsRelease = "W10_1607" Architecture = "x64" Notes = "" Owner = "" } $applicationPath = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Apps" -AdditionalChildPath $applicationDetails.information_IntuneAppName try { New-AppFactoryAppPSU @AppCreation $application = Get-AppFactoryAppPSU -IntuneAppName "STS-$($applicationDetails.information_IntuneAppName)" Set-AppFactoryAppConfigurationPSU -GUID $application.GUID @applicationInfoUpdate Set-AppFactoryAppInstallPSU -GUID $application.GUID @installOptions Set-AppFactoryAppUninstallPSU -GUID $application.GUID @uninstallOptions Set-AppFactoryAppDetectionRulePSU -GUID $application.GUID @detectionOptions $iconPath = Join-Path -Path $applicationPath -ChildPath "Icon.png" Copy-Item -Path $applicationDetails.information_IconFile -Destination $iconPath Hide-UDModal Invoke-UDRedirect '/Applications' } catch { $formatstring = "{0} : {1}`n{2}`n" + " + CategoryInfo : {3}`n" + " + FullyQualifiedErrorId : {4}`n" $fields = $_.InvocationInfo.MyCommand.Name, $_.ErrorDetails.Message, $_.InvocationInfo.PositionMessage, $_.CategoryInfo.ToString(), $_.FullyQualifiedErrorId New-UDTypography "Error occured when trying to create application." New-UDElement -Tag "br" New-UDElement -Tag "br" New-UDElement -Tag 'pre' -Id 'result' -Content { $formatstring -f $fields } New-UDElement -Tag "br" New-UDElement -Tag "br" New-UDElement -Tag 'pre' -Id 'result' -Content { $AppCreation | ConvertTo-JSON } New-UDElement -Tag "br" New-UDElement -Tag "br" New-UDElement -Tag 'pre' -Id 'result' -Content { $installOptions | ConvertTo-JSON } New-UDElement -Tag "br" New-UDElement -Tag "br" New-UDElement -Tag 'pre' -Id 'result' -Content { $uninstallOptions | ConvertTo-JSON } New-UDElement -Tag "br" New-UDElement -Tag "br" New-UDElement -Tag 'pre' -Id 'result' -Content { $detectionOptions | ConvertTo-JSON } New-UDElement -Tag "br" New-UDElement -Tag "br" } } -OnValidateStep { $Context = $EventData if ($Context.CurrentStep -eq 0) { if ($Context.Context.information_IntuneAppName -eq "") { New-UDValidationResult -ValidationError "Name is required" } elseif ($Context.Context.information_AppPublisher -eq "") { New-UDValidationResult -ValidationError "Publisher is required" } elseif ($Context.Context.information_Description -eq "") { New-UDValidationResult -ValidationError "Description is required" } elseif ($Context.Context.information_publishTo -eq "") { New-UDValidationResult -ValidationError "Organization is required" } else { New-UDValidationResult -Valid } } elseif ($Context.CurrentStep -eq 1) { switch ($Context.Context.source_AppSource) { "StorageAccount" { if ($Context.Context.source_AppSetupFileName -eq "") { New-UDValidationResult -ValidationError "Installer is required" } elseif ($Context.Context.source_StorageAccountContainerName -eq "") { New-UDValidationResult -ValidationError "Container is required" } } "ECNO" { if ($Context.Context.information_StorageAccountContainerName -eq "") { New-UDValidationResult -ValidationError "Sharepoint Folder is required" } } "Evergreen" { if ($Context.Context.source_AppSetupFileName -eq "") { New-UDValidationResult -ValidationError "Installer is required" } if ($Context.Context.source_AppID -eq "") { New-UDValidationResult -ValidationError "Application ID is required" } } "Winget" { if ($Context.Context.source_AppSetupFileName -eq "") { New-UDValidationResult -ValidationError "Installer is required" } if ($Context.Context.source_AppID -eq "") { New-UDValidationResult -ValidationError "Application ID is required" } } "Sharepoint" { if ($Context.Context.source_AppSetupFileName -eq "") { New-UDValidationResult -ValidationError "Installer is required" } } "PSADT" {} default { New-UDValidationResult -ValidationError "Source is required" } } } elseif ($Context.CurrentStep -eq 2) { switch ($Context.Context.install_InstallType) { "MSI" {} "EXE" {} "ECNO" {} "Custom" { if ($Context.Context.install_script -eq "") { New-UDValidationResult -ValidationError "Script is required" } } default { New-UDValidationResult -ValidationError "Install Type is required" } } } elseif ($Context.CurrentStep -eq 3) { switch ($Context.Context.uninstall_UninstallType) { "None" {} "MSI" {} "EXE" { } "Name" { if ($Context.Context.uninstall_Name -eq "") { New-UDValidationResult -ValidationError "Name is required" } } "GUID" { if ($Context.Context.uninstall_MSIGUID -eq "") { New-UDValidationResult -ValidationError "GUID is required" } } "ECNO" {} "Custom" { if ($Context.Context.uninstall_script -eq "") { New-UDValidationResult -ValidationError "Script is required" } } default { New-UDValidationResult -ValidationError "Uninstall Type is required" } } } elseif ($Context.CurrentStep -eq 4) { switch ($Context.Context.detection_DetectionOption) { "MSI" {} "RegistryVersion" {} "RegistryExistance" { if ($Context.Context.detection_regitem -eq "") { New-UDValidationResult -ValidationError "Registry Item is required" } if ($Context.Context.detection_detection -eq "") { New-UDValidationResult -ValidationError "Detection type is required" } } "Script" { if ($Context.Context.detection_script -eq "") { New-UDValidationResult -ValidationError "Script is required" } } default { New-UDValidationResult -ValidationError "Detection Method is required" } } } New-UDValidationResult -Valid } } #EndRegion '.\Public\GUI_Public\New-PSUApplication.ps1' 273 #Region '.\Public\GUI_Public\New-PSUClient.ps1' 0 function New-PSUClient { [cmdletbinding()] param() New-UDForm -Content { Get-PSUClientInfo } -OnValidate { $Context = $EventData if (-not [string]::IsNullOrEmpty($Context.Name) -and -not [string]::IsNullOrEmpty($context.ContactList)) { New-UDFormValidationResult -Valid } else { New-UDFormValidationResult -ValidationError "Name and Contact List are required fields" } } -OnSubmit { $Context = $EventData $punc = 46..46 $digits = 48..57 $letters = 65..90 + 97..122 $password = get-random -count 25 -input ($punc + $digits + $letters) | foreach-object -begin { $aa = $null } -process { $aa += [char]$_ } -end { $aa } Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications try { New-AppFactoryOrganizationPSU -Name $Context.Name -contactList ($context.ContactList -split ",") } catch { $formatstring = "{0} : {1}`n{2}`n" + " + CategoryInfo : {3}`n" + " + FullyQualifiedErrorId : {4}`n" $fields = $_.InvocationInfo.MyCommand.Name, $_.ErrorDetails.Message, $_.InvocationInfo.PositionMessage, $_.CategoryInfo.ToString(), $_.FullyQualifiedErrorId New-UDTypography "Error occured when trying to create organization." New-UDElement -Tag "br" New-UDElement -Tag "br" New-UDElement -Tag 'pre' -Id 'result' -Content { $formatstring -f $fields } } $organization = Get-AppFactoryOrganizationPSU -Name $Context.Name try { New-PSURole -Name $organization.GUID -Description "AppFactory | $($organization.Name)" -ClaimType 'http://schemas.microsoft.com/ws/2008/06/identity/claims/groups' -ClaimValue "AppFactory | $($organization.Name)" -Roles @('AppFactoryV3') } catch { Remove-AppFactoryOrganizationPSU -GUID $organization.GUID } try { $role = Get-PSURole -Name "AppFactoryV3" New-PSUIdentity -Name $organization.GUID -role $role -Password (ConvertTo-SecureString -String $password -AsPlainText -Force) -CredentialVault 'Database' } catch { Remove-AppFactoryOrganizationPSU -GUID $organization.GUID $role = Get-PSURole -Name $organization.GUID Remove-PSURole -role $role -Integrated } Hide-UDModal Invoke-UDRedirect '/Clients' } -OnCancel { Hide-UDModal } New-UDElement -Id 'results' -Tag 'div' } #EndRegion '.\Public\GUI_Public\New-PSUClient.ps1' 59 #Region '.\Public\GUI_Public\Remove-PSUGUIApplication.ps1' 0 function Remove-PSUGUIApplication{ [cmdletbinding()] param( [Parameter()][string]$applicationGUID ) Show-UDModal -MaxWidth lg -FullWidth -Content { Import-Module -Name $PS_GUI_Module -Force Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $application = Get-AppFactoryAppPSU -GUID $applicationGUID New-UDTypography "Are you sure you want to delete " New-UDTypography $application.IntuneAppName -Style @{"font-weight" = "bold" } New-UDTypography " with GUID of " New-UDTypography $application.GUID -Style @{"font-weight" = "bold" } } -Footer { New-UDButton -Text "Cancel" -OnClick { Hide-UDModal } New-UDButton -Text "Confirm" -OnClick { Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications Remove-AppFactoryAppPSU -GUID $EventData.GUID Hide-UDModal Invoke-UDRedirect '/Applications' } } -Persistent } #EndRegion '.\Public\GUI_Public\Remove-PSUGUIApplication.ps1' 24 #Region '.\Public\GUI_Public\Remove-PSUGUIClient.ps1' 0 function Remove-PSUGUIClient { [cmdletbinding()] param( [Parameter()][string]$clientGUID ) Show-UDModal -MaxWidth lg -FullWidth -Content { Import-Module -Name $PS_GUI_Module -Force Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $client = Get-AppFactoryOrganizationPSU -GUID $clientGUID New-UDTypography "Are you sure you want to delete " New-UDTypography $client.Name -Style @{"font-weight" = "bold" } New-UDTypography " with GUID of " New-UDTypography $client.GUID -Style @{"font-weight" = "bold" } New-UDElement -Id 'results' -Tag 'div' } -Footer { New-UDButton -Text "Cancel" -OnClick { Hide-UDModal } New-UDButton -Text "Confirm" -OnClick { Set-UDElement -id "results" -content { try { Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $client = Get-AppFactoryOrganizationPSU -GUID $clientGUID Remove-AppFactoryOrganizationPSU -GUID $client.GUID $role = Get-PSURole -Name $client.GUID Remove-PSURole -role $role -Integrated Hide-UDModal Invoke-UDRedirect '/Clients' } catch { $formatstring = "{0} : {1}`n{2}`n" + " + CategoryInfo : {3}`n" + " + FullyQualifiedErrorId : {4}`n" $fields = $_.InvocationInfo.MyCommand.Name, $_.ErrorDetails.Message, $_.InvocationInfo.PositionMessage, $_.CategoryInfo.ToString(), $_.FullyQualifiedErrorId New-UDTypography "Error occured when trying to delete organization." New-UDElement -Tag "br" New-UDElement -Tag "br" New-UDElement -Tag 'pre' -Id 'data' -Content { $formatstring -f $fields } } } } } -Persistent } #EndRegion '.\Public\GUI_Public\Remove-PSUGUIClient.ps1' 45 #Region '.\Public\GUI_Public\Update-PSUApplicationGUI.ps1' 0 function Update-PSUApplicationGUI { [cmdletbinding()] param( [Parameter()][string]$applicationGUID ) Show-UDModal -MaxWidth lg -FullWidth -Content { Import-Module -Name $PS_GUI_Module -Force Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $application = Get-AppFactoryAppPSU -GUID $applicationGUID $ApplicationInformation = @{ "Information" = $application "Config" = (Get-AppFactoryAppConfigurationPSU -GUID $applicationGUID) "Install" = (Get-AppFactoryAppInstallPSU -GUID $applicationGUID) "Uninstall" = (Get-AppFactoryAppUninstallPSU -GUID $applicationGUID) } New-UDStepper -Steps { New-UDStep -OnLoad { Get-PSUApplicationInfo -ApplicationInformation $ApplicationInformation } -Label "Information" New-UDStep -OnLoad { Get-PSUApplicationSource -ApplicationInformation $ApplicationInformation } -Label "Source" New-UDStep -OnLoad { Get-PSUApplicationInstall -ApplicationInformation $ApplicationInformation } -Label "Install" New-UDStep -OnLoad { Get-PSUApplicationUninstall -ApplicationInformation $ApplicationInformation } -Label "Uninstall" New-UDStep -OnLoad { Get-PSUApplicationDetection -ApplicationInformation $ApplicationInformation } -Label "Detection" } -OnFinish { Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $applicationDetails = $EventData.Context $applicationfolder = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Apps" -AdditionalChildPath ($applicationDetails.information_IntuneAppName -replace "STS-") $iconPath = Join-Path -Path $applicationfolder -ChildPath "Icon.png" $applicationInfoUpdate = @{} $filterOptions = @{} $installOptions = @{ GUID = $application.GUID Type = $applicationDetails.install_InstallType } $uninstallOptions = @{ GUID = $application.GUID Type = $applicationDetails.uninstall_UninstallType } $detectionOptions = @{ GUID = $application.GUID } # Get Information Step Information foreach ($item in ($applicationDetails.variables_information -split ",")) { $key = $item -replace "information_", "" $addToUpdate = $false if ($item -eq "information_IconFile") { if ($applicationDetails.$item -ne $iconPath) { Copy-Item -Path $applicationDetails.$item -Destination $iconPath -Force } } elseif ($item -eq "information_Description") { if ($applicationDetails.$item -ne $ApplicationInformation.Config.Information.$key) { $addToUpdate = $true } } elseif ($item -eq "information_publishTo") { if ($applicationDetails.$item.contains("Public")) { $applicationDetails.$item = @() } if ($($applicationDetails.$item -join ",") -ne $($application.publishTo -join ",")) { $addToUpdate = $true } } else { if ($applicationDetails.$item -ne $application.$key) { $addToUpdate = $true } } if ($addToUpdate) { $applicationInfoUpdate.Add($key, $applicationDetails.$item) } } # Get the details from the source step if ($applicationDetails."source_AppSource" -ne $application."AppSource") { $applicationInfoUpdate.Add("AppSource", $applicationDetails."source_AppSource") } # normalize archive type if ($null -eq $applicationDetails.source_archiveType -or $applicationDetails.source_archiveType -eq "None") { $applicationDetails.source_archiveType = "" } foreach ($item in ($applicationDetails.variables_source -split ",")) { $addToUpdate = $false if ($item -match "^source_[^_]*$") { $key = $item -replace "source_", "" if ($applicationDetails.$item -ne $application.$key) { $addToUpdate = $true } } else { $key = $item -replace "source_filter_", "" if ($null -ne $applicationDetails.$item -and $applicationDetails.$item -ne "") { $filterOptions.Add($key, $applicationDetails.$item) } } if ($addToUpdate) { $applicationInfoUpdate.Add($key, $applicationDetails.$item) } } # Set the uninstall options for the application if ($filterOptions.Count -gt 0) { $applicationInfoUpdate.Add("FilterOptions", $filterOptions) } # Get the details for the install step foreach ($item in ($applicationDetails.variables_install -split ",")) { $key = $item -replace "install_", "" if ($null -ne $applicationDetails.$item -and $applicationDetails.$item -ne "") { $installOptions.Add($key, $applicationDetails.$item) } } # Get the details for the uninstall step foreach ($item in ($applicationDetails.variables_uninstall -split ",")) { $key = $item -replace "uninstall_", "" if ($null -ne $applicationDetails.$item -and $applicationDetails.$item -ne "") { $uninstallOptions.Add($key, $applicationDetails.$item) } } # Get the details for the detection step if ($applicationDetails.detection_DetectionOption -like "Registry*") { $detectionOptions.Add("Type", "Registry") if($applicationDetails.detection_DetectionOption -eq "RegistryVersion") { $detectionOptions.Add("DetectionMethod", "VersionComparison") } else { $detectionOptions.Add("DetectionMethod", "Existence") } } else { $detectionOptions.Add("Type", $applicationDetails.detection_DetectionOption) } foreach ($item in ($applicationDetails.variables_detection -split ",")) { $key = $item -replace "detection_", "" if($item -eq "detection_ProductVersionOperator" -and $applicationDetails.$item -eq "notConfigured"){continue} if ($null -ne $applicationDetails.$item -and $applicationDetails.$item -ne "") { $detectionOptions.Add($key, $applicationDetails.$item) } } try{ if($applicationInfoUpdate.Count -gt 0){ Set-AppFactoryAppConfigurationPSU -GUID $application.GUID @applicationInfoUpdate } Set-AppFactoryAppInstallPSU @installOptions Set-AppFactoryAppUninstallPSU @uninstallOptions Set-AppFactoryAppDetectionRulePSU @detectionOptions Hide-UDModal Invoke-UDRedirect '/Applications' } catch{ $formatstring = "{0} : {1}`n{2}`n" + " + CategoryInfo : {3}`n" + " + FullyQualifiedErrorId : {4}`n" $fields = $_.InvocationInfo.MyCommand.Name, $_.ErrorDetails.Message, $_.InvocationInfo.PositionMessage, $_.CategoryInfo.ToString(), $_.FullyQualifiedErrorId New-UDTypography "Error occured when trying to create application." New-UDElement -Tag "br" New-UDElement -Tag "br" New-UDElement -Tag 'pre' -Id 'result' -Content {$formatstring -f $fields } New-UDElement -Tag "br" New-UDElement -Tag "br" New-UDElement -Tag 'pre' -Id 'result' -Content { $applicationInfoUpdate | ConvertTo-JSON} New-UDElement -Tag "br" New-UDElement -Tag "br" New-UDElement -Tag 'pre' -Id 'result' -Content { $installOptions | ConvertTo-JSON} New-UDElement -Tag "br" New-UDElement -Tag "br" New-UDElement -Tag 'pre' -Id 'result' -Content { $uninstallOptions | ConvertTo-JSON} New-UDElement -Tag "br" New-UDElement -Tag "br" New-UDElement -Tag 'pre' -Id 'result' -Content { $detectionOptions | ConvertTo-JSON} New-UDElement -Tag "br" New-UDElement -Tag "br" } } -OnValidateStep { $Context = $EventData if ($Context.CurrentStep -eq 0) { if ($Context.Context.information_IntuneAppName -eq "") { New-UDValidationResult -ValidationError "Name is required" } elseif ($Context.Context.information_AppPublisher -eq "") { New-UDValidationResult -ValidationError "Publisher is required" } elseif ($Context.Context.information_Description -eq "") { New-UDValidationResult -ValidationError "Description is required" } elseif ($Context.Context.information_publishTo -eq "") { New-UDValidationResult -ValidationError "Organization is required" } else { New-UDValidationResult -Valid } } elseif ($Context.CurrentStep -eq 1) { switch ($Context.Context.source_AppSource) { "StorageAccount" { if ($Context.Context.source_AppSetupFileName -eq "") { New-UDValidationResult -ValidationError "Installer is required" } elseif ($Context.Context.source_StorageAccountContainerName -eq "") { New-UDValidationResult -ValidationError "Container is required" } } "ECNO" { if ($Context.Context.information_StorageAccountContainerName -eq "") { New-UDValidationResult -ValidationError "Sharepoint Folder is required" } } "Evergreen" { if ($Context.Context.source_AppSetupFileName -eq "") { New-UDValidationResult -ValidationError "Installer is required" } if ($Context.Context.source_AppID -eq "") { New-UDValidationResult -ValidationError "Application ID is required" } } "Winget" { if ($Context.Context.source_AppSetupFileName -eq "") { New-UDValidationResult -ValidationError "Installer is required" } if ($Context.Context.source_AppID -eq "") { New-UDValidationResult -ValidationError "Application ID is required" } } "Sharepoint" { if ($Context.Context.source_AppSetupFileName -eq "") { New-UDValidationResult -ValidationError "Installer is required" } } "PSADT" {} default { New-UDValidationResult -ValidationError "Source is required" } } } elseif ($Context.CurrentStep -eq 2) { switch ($Context.Context.install_InstallType) { "MSI" {} "EXE" {} "ECNO" {} "Custom" { if ($Context.Context.install_script -eq "") { New-UDValidationResult -ValidationError "Script is required" } } default { New-UDValidationResult -ValidationError "Install Type is required" } } } elseif ($Context.CurrentStep -eq 3) { switch ($Context.Context.uninstall_UninstallType) { "None" {} "MSI" {} "EXE" { } "Name" { if ($Context.Context.uninstall_Name -eq "") { New-UDValidationResult -ValidationError "Name is required" } } "GUID" { if ($Context.Context.uninstall_MSIGUID -eq "") { New-UDValidationResult -ValidationError "GUID is required" } } "ECNO" {} "Custom" { if ($Context.Context.uninstall_script -eq "") { New-UDValidationResult -ValidationError "Script is required" } } default { New-UDValidationResult -ValidationError "Uninstall Type is required" } } } elseif ($Context.CurrentStep -eq 4) { switch ($Context.Context.detection_DetectionOption) { "MSI" {} "RegistryVersion" {} "RegistryExistance" { if ($Context.Context.detection_regitem -eq "") { New-UDValidationResult -ValidationError "Registry Item is required" } if ($Context.Context.detection_detection -eq "") { New-UDValidationResult -ValidationError "Detection type is required" } } "Script" { if ($Context.Context.detection_script -eq "") { New-UDValidationResult -ValidationError "Script is required" } } default { New-UDValidationResult -ValidationError "Detection Method is required" } } } New-UDValidationResult -Valid } } -Footer { New-UDButton -Text "Cancel" -OnClick { Hide-UDModal } } -Persistent } #EndRegion '.\Public\GUI_Public\Update-PSUApplicationGUI.ps1' 309 #Region '.\Public\GUI_Public\Update-PSUGUIClient.ps1' 0 function Update-PSUGUIClient{ [cmdletbinding()] param( [Parameter()][string]$clientGUID ) Show-UDModal -MaxWidth lg -FullWidth -Content { Import-Module -Name $PS_GUI_Module -Force Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications New-UDForm -Content { Get-PSUClientInfo -clientGUID $clientGUID } -OnValidate { $Context = $EventData if (-not [string]::IsNullOrEmpty($Context.Name) -and -not [string]::IsNullOrEmpty($context.ContactList)) { New-UDFormValidationResult -Valid } else { New-UDFormValidationResult -ValidationError "Name and Contact List are required fields" } } -OnSubmit { try { $Context = $EventData Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications Set-AppFactoryOrganizationPSU -GUID $clientGUID -Name $Context.Name -contactList ($context.ContactList -split ",") Hide-UDModal Invoke-UDRedirect '/Clients' } catch { $formatstring = "{0} : {1}`n{2}`n" + " + CategoryInfo : {3}`n" + " + FullyQualifiedErrorId : {4}`n" $fields = $_.InvocationInfo.MyCommand.Name, $_.ErrorDetails.Message, $_.InvocationInfo.PositionMessage, $_.CategoryInfo.ToString(), $_.FullyQualifiedErrorId New-UDTypography "Error occured when trying to create organization." New-UDElement -Tag "br" New-UDElement -Tag "br" New-UDElement -Tag 'pre' -Id 'result' -Content { $formatstring -f $fields } } } -OnCancel { Hide-UDModal } } -Persistent } #EndRegion '.\Public\GUI_Public\Update-PSUGUIClient.ps1' 44 #Region '.\Public\GUI_Public\Update-PSUGUIClientApp.ps1' 0 function Update-PSUGUIClientApp { [cmdletbinding()] param( [Parameter(Mandatory = $true)][string]$applicationGUID ) Show-UDModal -MaxWidth lg -FullWidth -Content { Import-Module -Name $PS_GUI_Module -Force Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $application = Get-AppFactoryAppPSU -GUID $applicationGUID $config = Get-AppFactoryAppOrgConfigPSU -clientGUID (Get-UDElement -Id "ClientIDs").Value -appGUID $applicationGUID $filters = [System.Collections.Generic.List[String]]@() foreach ($obj in $config.filters.PSObject.Properties) { $filters.Add("$($obj.Name);$($obj.Value.filterType);$($obj.Value.filterName)") | Out-Null } New-UDElement -Tag "div" -ClassName "card-body rounded" -Content { New-UDTypography -Text "$($application.IntuneAppName) - Configuration" -Variant "h5" -ClassName "card-title rounded x-card-title" } -Attributes @{"style" = @{"padding" = "10px" } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Enabled:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "170px"; } } New-UDElement -Tag "td" -Content { New-UDSwitch -Id "AddToIntune" -Checked $config.AddToIntune } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Foreground:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "170px"; } } New-UDElement -Tag "td" -Content { New-UDSwitch -Id "foreground" -Checked $config.foreground } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Interactive Install:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "170px"; } } New-UDElement -Tag "td" -Content { New-UDSwitch -Id "InteractiveInstall" -Checked $config.InteractiveInstall } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Interactive Uninstall:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "170px"; } } New-UDElement -Tag "td" -Content { New-UDSwitch -Id "InteractiveUninstall" -Checked $config.InteractiveUninstall } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Keep Previous:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "170px"; } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "KeepPrevious" -Value $config.KeepPrevious -FullWidth -ClassName "inputoptional" } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Copy Previous:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "170px"; } } New-UDElement -Tag "td" -Content { New-UDSwitch -Id "CopyPrevious" -Checked $config.CopyPrevious } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Unassign Previous:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "170px"; } } New-UDElement -Tag "td" -Content { New-UDSwitch -Id "UnassignPrevious" -Checked $config.UnassignPrevious } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } New-UDElement -Tag "br" New-UDElement -Tag "div" -ClassName "card-body rounded" -Content { New-UDTypography -Text "$($application.IntuneAppName) - Assignments" -Variant "h5" -ClassName "card-title rounded x-card-title" } -Attributes @{"style" = @{"padding" = "10px" } } New-UDElement -Tag "table" -Content { New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Available Assignments:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "AvailableAssignments" -Type "Text" -FullWidth -ClassName "inputoptional" -Value ($config.AvailableAssignments -Join ",").trim() } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Available Exceptions:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "AvailableExceptions" -Type "Text" -FullWidth -ClassName "inputoptional" -Value ($config.AvailableExceptions -join ",").Trim() } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Required Assignments:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "RequiredAssignments" -Type "Text" -FullWidth -ClassName "inputoptional" -Value ($config.RequiredAssignments -Join ",").trim() } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Required Exceptions:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "RequiredExceptions" -Type "Text" -FullWidth -ClassName "inputoptional" -Value ($config.RequiredExceptions -join ",").Trim() } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "Uninstall Assignments:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "UninstallAssignments" -Type "Text" -FullWidth -ClassName "inputoptional" -Value ($config.UninstallAssignments -Join ",").trim() } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Uninstall Exceptions:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "UninstallExceptions" -Type "Text" -FullWidth -ClassName "inputoptional" -Value ($config.UninstallExceptions -join ",").Trim() } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } New-UDElement -Tag "tr" -Content { New-UDElement -Tag "td" -Content { New-UDTypography -Text "ESP Assignments:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "espprofiles" -Type "Text" -FullWidth -ClassName "inputoptional" -Value ($config.espprofiles -Join ",").trim() } -Attributes @{"style" = @{"vertical-align" = "bottom" } } New-UDElement -Tag "td" -Content { New-UDTypography -Text "Filters:" -Style @{"font-weight" = "bold" } } -Attributes @{"style" = @{"width" = "200px"; } } New-UDElement -Tag "td" -Content { New-UDTextbox -Id "filters" -Type "Text" -FullWidth -ClassName "inputoptional" -Value ($filters -join ",").Trim() } -Attributes @{"style" = @{"vertical-align" = "bottom" } } } } -Attributes @{ "style" = @{ "width" = "100%"; } "cellpadding" = "5" } New-UDElement -Tag "div" -id "testingthis" -Content {} } -Footer { New-UDButton -Text "Cancel" -OnClick { Hide-UDModal } New-UDButton -Text "Update" -OnClick { Set-UDElement -Id "testingthis" -Content { Import-Module -Name $PS_GUI_Module -Force Start-AppFactoryPSU -Path $ApplicationFactoryServiceApplications $config = @{ AddToIntune = [bool](Get-UDElement -Id "AddToIntune").checked AvailableAssignments = (Get-UDElement -Id "AvailableAssignments").Value -replace ", ","," -replace " ,","," -split "," AvailableExceptions = (Get-UDElement -Id "AvailableExceptions").Value -replace ", ","," -replace " ,","," -split "," RequiredAssignments = (Get-UDElement -Id "RequiredAssignments").Value -replace ", ","," -replace " ,","," -split "," RequiredExceptions = (Get-UDElement -Id "RequiredExceptions").Value -replace ", ","," -replace " ,","," -split "," UninstallAssignments = (Get-UDElement -Id "UninstallAssignments").Value -replace ", ","," -replace " ,","," -split "," UninstallExceptions = (Get-UDElement -Id "UninstallExceptions").Value -replace ", ","," -replace " ,","," -split "," UnassignPrevious = [bool](Get-UDElement -Id "UnassignPrevious").checked CopyPrevious = [bool](Get-UDElement -Id "CopyPrevious").checked KeepPrevious = (Get-UDElement -Id "KeepPrevious").Value foreground = [bool](Get-UDElement -Id "foreground").checked espprofiles = (Get-UDElement -Id "espprofiles").Value -replace ", ","," -replace " ,","," -split "," InteractiveInstall = [bool](Get-UDElement -Id "InteractiveInstall").checked InteractiveUninstall = [bool](Get-UDElement -Id "InteractiveUninstall").checked } $filters = (Get-UDElement -Id "filters").Value -split "," if ($filters) { $filter = @{} foreach ($item in $filters) { $temp = $item -split ";" $filter.Add($temp[0], @{"filterType" = $temp[1]; "filterName" = $temp[2] }) } $config.Add("filters", $filter) | Out-Null } $config.Add("appGUID", $applicationGUID) | Out-Null $config.Add("clientGUID", (Get-UDElement -Id "ClientIDs").Value) | Out-Null try { Set-AppFactoryAppOrgConfigPSU @config Hide-UDModal Invoke-UDRedirect '/Clients' } catch { $formatstring = "{0} : {1}`n{2}`n" + " + CategoryInfo : {3}`n" + " + FullyQualifiedErrorId : {4}`n" $fields = $_.InvocationInfo.MyCommand.Name, $_.ErrorDetails.Message, $_.InvocationInfo.PositionMessage, $_.CategoryInfo.ToString(), $_.FullyQualifiedErrorId New-UDTypography "Error occured when trying to create organization." New-UDElement -Tag "br" New-UDElement -Tag "br" New-UDElement -Tag 'pre' -Id 'result' -Content { $formatstring -f $fields } } } } } -Persistent } <# #> #EndRegion '.\Public\GUI_Public\Update-PSUGUIClientApp.ps1' 197 #Region '.\Public\Service_Private\Add-AppFactoryApplicationBlockingProcess.ps1' 0 function Add-AppFactoryApplicationBlockingProcess{ [cmdletbinding()] [OutputType([System.Collections.Generic.List[String[]]])] param( [Parameter()][switch]$interactive, [Parameter()][ValidateNotNullOrEmpty()][string]$blockingProcess, [Parameter()][ValidateNotNullOrEmpty()][int]$deferCount = 0, [Parameter()][string[]]$customScript, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) $ApplicationScriptLines = [System.Collections.Generic.List[String[]]]@() $processes = $blockingProcess -split "," if($interactive.IsPresent){ $ApplicationScriptLines.Add(("`$processExist = `$false",2)) | Out-Null foreach ($item in $processes) { $ApplicationScriptLines.Add(("if(Get-Process -Name `"$($item)`" -ErrorAction SilentlyContinue){`$processExist = `$true}",2)) | Out-Null } $ApplicationScriptLines.Add(("if ([Environment]::UserInteractive -and `$processExist) {",2)) | Out-Null $ApplicationScriptLines.Add(("`$params = @{",3)) | Out-Null $ApplicationScriptLines.Add(("`"CloseApps`" = `"$($blockingProcess)`"",4)) | Out-Null $ApplicationScriptLines.Add(("`"PersistPrompt`" = `$true",4)) | Out-Null if ($deferCount -gt 0) { $ApplicationScriptLines.Add(("`"AllowDefer`" = `$true",4)) | Out-Null $ApplicationScriptLines.Add(("`"DeferTimes`" = $($deferCount)",4)) | Out-Null } $ApplicationScriptLines.Add(("}",3)) | Out-Null $ApplicationScriptLines.Add(("Show-InstallationWelcome @params",3)) | Out-Null $ApplicationScriptLines.Add(("}",2)) | Out-Null $ApplicationScriptLines.Add(("else {",2)) | Out-Null foreach ($item in $processes) { $ApplicationScriptLines.Add(("`Get-Process -Name `"$($item)`" | Stop-Process -Force",3)) | Out-Null } $ApplicationScriptLines.Add(("}",2)) | Out-Null } else{ foreach($item in $processes){ $ApplicationScriptLines.Add(("Get-Process -Name `"$($item)`" | Stop-Process -Force",2)) | Out-Null } } return @(,$ApplicationScriptLines) } #EndRegion '.\Public\Service_Private\Add-AppFactoryApplicationBlockingProcess.ps1' 42 #Region '.\Public\Service_Private\Add-AppFactoryApplicationScriptEXE.ps1' 0 function Add-AppFactoryApplicationScriptEXE{ [cmdletbinding()] [OutputType([System.Collections.Generic.List[String[]]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][Hashtable]$ApplicationInstallLines, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$installer, [Parameter()][String]$directory, [Parameter()][string]$Parameters = $null, [Parameter()][string]$ignoreExit = $null, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) $ApplicationScriptLines = [System.Collections.Generic.List[String[]]]@() if($directory -ne ""){ $executePath = "`"`$($($directory))\`$(`$installer)`"" } else{ $executePath = "`"`$(`$installer)`"" } $execute = "Execute-Process -Path $($executePath) -Parameters `"`$(`$Parameters)`"" if($ignoreExit){ $execute = "$($execute) -IgnoreExitCodes `"$($ignoreExit)`"" } $ApplicationScriptLines.Add(("`$installer = `"$($installer)`"", 2)) | Out-Null $ApplicationScriptLines.Add(("`$Parameters = `"$($Parameters)`"",2)) | Out-Null $ApplicationScriptLines.Add(($execute, 2)) | Out-Null return @(,$ApplicationScriptLines) } #EndRegion '.\Public\Service_Private\Add-AppFactoryApplicationScriptEXE.ps1' 28 #Region '.\Public\Service_Private\Add-AppFactoryApplicationScriptMSI.ps1' 0 function Add-AppFactoryApplicationScriptMSI{ [cmdletbinding()] [OutputType([System.Collections.Generic.List[String[]]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][Hashtable]$ApplicationInstallLines, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$installer, [Parameter()][String]$directory, [Parameter()][string]$Parameters = $null, [Parameter()][string]$mst = $null, [Parameter()][ValidateSet("Install", "Uninstall")][string]$msiAction = "Install", [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) $ApplicationScriptLines = [System.Collections.Generic.List[String[]]]@() if($directory -ne ""){ $executePath = "`"`$($($directory))\`$(`$installer)`"" } else{ $executePath = "`"`$(`$installer)`"" } $execute = "Execute-MSI -Action `"$($msiAction)`" -Path $($executePath) -Parameters `"/qn REBOOT=ReallySuppress`"" $ApplicationScriptLines.Add(("`$installer = `"$($installer)`"", 2)) | Out-Null if ($mst) { $ApplicationScriptLines.Add(("`$mstInstall = `"$($mst)`"", 2)) | Out-Null $execute = "$($execute) -Transform `"`$($($directory))\`$(`$mstInstall)`"" } if ($Parameters) { $ApplicationScriptLines.Add(("`$Parameters = `"$($Parameters)`"", 2)) | Out-Null $execute = "$($execute) -AddParameter `$parameters" } $ApplicationScriptLines.Add(($execute, 2)) | Out-Null return @(,$ApplicationScriptLines) } #EndRegion '.\Public\Service_Private\Add-AppFactoryApplicationScriptMSI.ps1' 33 #Region '.\Public\Service_Private\Add-AppFactoryAppWIM.ps1' 0 <# .DESCRIPTION This cmdlet is designed to generate the lines to enter into deploy-application.ps1 for WIM based installs. .PARAMETER section If this for the start or end of the WIM process that determines if it is mounting or dismounting .PARAMETER ApplicationInstallLines The current lines that are meant to be injected into the file, so that it adds to the current object .PARAMETER application The application object that we are working for so that we can ensure that get the correct and current data #> function Add-AppFactoryAppWIM{ [cmdletbinding()] [OutputType([System.Collections.Generic.List[String[]]])] param( [Parameter(Mandatory = $true)][ValidateSet("start","end")][string]$section, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application ) $ApplicationScriptLines = [System.Collections.Generic.List[String[]]]@() # If this to mount the WIM add the following lines if($section -eq "start"){ $ApplicationScriptLines.Add(("`$mountPath = `"C:\AFS\$($application.AppFolderName)`"",2)) | Out-Null $ApplicationScriptLines.Add(("`$wimFile = Get-Childitem -Path `"`$(`$dirFiles)`" -Filter `"*.wim`"",2)) | Out-Null $ApplicationScriptLines.Add(("`$wimPath = Join-Path `$dirFiles -ChildPath `$wimFile",2)) | Out-Null $ApplicationScriptLines.Add(("try{",2)) | Out-Null $ApplicationScriptLines.Add(("[void](New-Item -Path `$mountPath -ItemType Directory -ErrorAction SilentlyContinue)",3)) | Out-Null $ApplicationScriptLines.Add(("Mount-WindowsImage -ImagePath `$wimPath -Index 1 -Path `$mountPath",3)) | Out-Null $ApplicationScriptLines.Add(("}",2)) | Out-Null $ApplicationScriptLines.Add(("catch{",2)) | Out-Null $ApplicationScriptLines.Add(("Write-Host `"ERROR: Encountered an issue mounting the .wim. Exiting Script now.`"",3)) | Out-Null $ApplicationScriptLines.Add(("Write-Host `"Error Message: `$_`"",3)) | Out-Null $ApplicationScriptLines.Add(("}",2)) | Out-Null $ApplicationScriptLines.Add(("",2)) | Out-Null } else{ $ApplicationScriptLines.Add(("",2)) | Out-Null $ApplicationScriptLines.Add(("Start-Sleep -Seconds 60",2)) | Out-Null $ApplicationScriptLines.Add(("try{",2)) | Out-Null $ApplicationScriptLines.Add(("Dismount-WindowsImage -Path `$MountPath -Discard",3)) | Out-Null $ApplicationScriptLines.Add(("Remove-Item -Path `$mountPath -Force",3)) | Out-Null $ApplicationScriptLines.Add(("}",2)) | Out-Null $ApplicationScriptLines.Add(("catch{",2)) | Out-Null $ApplicationScriptLines.Add(("#Failed to Dismount normally. Setting up a scheduled task to unmount after next reboot (exit code 3010)",3)) | Out-Null $ApplicationScriptLines.Add(("Write-Host `"ERROR: Attempting to create scheduled task CleanupWIM to dismount image at next startup`"",3)) | Out-Null $ApplicationScriptLines.Add(("Write-Host `"Error Message: `$_`"",3)) | Out-Null $ApplicationScriptLines.Add(("`$STAction = New-ScheduledTaskAction ``",3)) | Out-Null $ApplicationScriptLines.Add(("-Execute 'Powershell.exe' ``",4)) | Out-Null $ApplicationScriptLines.Add(("-Argument '-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -command `"& {Get-WindowsImage -Mounted | Where-Object {`$_.MountStatus -eq ''Invalid''} | ForEach-Object {`$_ | Dismount-WindowsImage -Discard -ErrorVariable wimerr; if ([bool]`$wimerr) {`$errflag = `$true}}; If (-not `$errflag) {Clear-WindowsCorruptMountPoint; Unregister-ScheduledTask -TaskName ''CleanupWIM'' -Confirm:`$false}}`"'",4)) | Out-Null $ApplicationScriptLines.Add(("`$STTrigger = New-ScheduledTaskTrigger -AtStartup",4)) | Out-Null $ApplicationScriptLines.Add(("Register-ScheduledTask ``",3)) | Out-Null $ApplicationScriptLines.Add(("-Action `$STAction ``",4)) | Out-Null $ApplicationScriptLines.Add(("-Trigger `$STTrigger ``",4)) | Out-Null $ApplicationScriptLines.Add(("-TaskName `"CleanupWIM`" ``",4)) | Out-Null $ApplicationScriptLines.Add(("-Description `"Clean up WIM Mount points that failed to dismount`" ``",4)) | Out-Null $ApplicationScriptLines.Add(("-User `"NT AUTHORITY\SYSTEM`" ``",4)) | Out-Null $ApplicationScriptLines.Add(("-RunLevel Highest ``",4)) | Out-Null $ApplicationScriptLines.Add(("-Force ",4)) | Out-Null $ApplicationScriptLines.Add(("}",2)) | Out-Null } return @(,$ApplicationScriptLines) } #EndRegion '.\Public\Service_Private\Add-AppFactoryAppWIM.ps1' 61 #Region '.\Public\Service_Private\Add-AppFactoryIntuneDeploymentPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to upload the required items to the Azure Storage for the deployment files .PARAMETER application The application object that we are working for so that we can ensure that get the correct and current data .PARAMETER appStorageContext The azure storage context that has permissions to upload to the Azure Storage Account .PARAMETER ApplicationInstallLines The name of the public storage blob that we will use if the application is free for any organization .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Add-AppFactoryIntuneDeploymentPSU { [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$appStorageContext, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$AppFactoryPublicFolder, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) # Generate the path for the details for the application and then read the JSON file $AppDataFile = Join-Path -Path $application.AppPublishFolderPath -ChildPath "App.json" $AppData = Get-Content -Path $AppDataFile | ConvertFrom-Json $ScriptDataFile = Join-Path -Path $application.AppPublishFolderPath -ChildPath "Scripts" -AdditionalChildPath $AppData.DetectionRule.ScriptFile $AppIconFile = Join-Path -Path $application.AppPublishFolderPath -ChildPath $AppData.PackageInformation.IconFile # Check what Azure Storage Containers we should be uploading the files to $containerUploads = [System.Collections.Generic.List[PSCustomObject]]@() if ((($application.PublishTo.getType()).BaseType.Name -eq "Array" -and $application.publishTo.Count -gt 0) -or (($application.PublishTo.getType()).BaseType.Name -eq "Object" -and $application.publishTo.length -gt 1)) { foreach ($org in $application.PublishTo) { $containerUploads.Add($org) | Out-Null } } else { $containerUploads.Add($AppFactoryPublicFolder) | Out-Null } $appUploads = [PSCustomObject]@( @{ "File" = $AppDataFile "Blob" = "$($application.GUID)/$($application.AppSetupVersion)/App.json" }, @{ "File" = $application.IntunePackage "Blob" = "$($application.GUID)/$($application.AppSetupVersion)/$($application.IntuneAppName).intunewin" }, @{ "File" = $AppIconFile "Blob" = "$($application.GUID)/$($application.AppSetupVersion)/$($AppData.PackageInformation.IconFile)" }, @{ "File" = $ScriptDataFile "Blob" = "$($application.GUID)/$($application.AppSetupVersion)/detection.ps1" } ) # Process the uploads for each of the files as required to each container that is required foreach ($container in $containerUploads) { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Uploading files to storage" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } foreach ($upload in $appUploads) { if (Test-Path $upload.File) { try { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Uploading <c='green'>$($upload.File)</c> to <c='green'>$($container)</c> container" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } Set-AzStorageBlobContent @upload -Container $container -Context $appStorageContext -Force -ErrorAction Stop | Out-Null } catch { throw "[$($application.IntuneAppName)] Unable able to upload file: $($_.Exception.Message)" } } } } if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Updating versions information" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } # Add a item to the object that we can check for to see if it was actually sent Set-AppFactoryAppConfigurationPSU -GUID $application.GUID -version $application.AppSetupVersion $application | Add-Member -MemberType NoteProperty -Name 'Updated' -Value $true -Force return $application } #EndRegion '.\Public\Service_Private\Add-AppFactoryIntuneDeploymentPSU.ps1' 82 #Region '.\Public\Service_Private\Connect-AppFactoryAzureStoragePSU.ps1' 0 function Connect-AppFactoryAzureStoragePSU { [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$storageContainer, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][securestring]$storageSecret, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) begin { # Generate variables to connect to azure storage $storageVars = @{ "StorageAccountName" = $storageContainer "StorageAccountKey" = ConvertFrom-SecureString $storageSecret -AsPlainText } } process { try { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "Creating Azure Storage Context for <c='green'>$($storageContainer)</c>" -Level $LogLevel -Tag "Storage", "$($storageContainer)" -Target "Application Factory Service" } $storageAccountContext = New-AzStorageContext @storageVars } catch { Write-PSFMessage -Message "Error Encountered: $($_)" -Level "Error" -Tag "Storage" -Target "Application Factory Service" throw $_ } } end { return $storageAccountContext } } #EndRegion '.\Public\Service_Private\Connect-AppFactoryAzureStoragePSU.ps1' 32 #Region '.\Public\Service_Private\Expand-7ZIpFile.ps1' 0 <# .DESCRIPTION This cmdlet is designed to use the 7zip portable exe to extract the files .PARAMETER application The application object that we are working for so that we can ensure that get the correct and current data .PARAMETER applicationName The name of the application that we are working with .PARAMETER path The path to the 7-zip file .PARAMETER supportFiles The path to the support files folder .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Expand-7ZIpFile{ [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$applicationName, [parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$path, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$supportFiles, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) # 7Zip Exe $7ZipPath = Join-Path -Path $supportFiles -ChildPath "7zr.exe" # 7Zip File $7ZipFile = Join-Path -Path $path -ChildPath $application.appSetupName # Extract Directory $ExtractDirectory = Join-Path -Path $path -ChildPath $applicationName # Extract Files $vars = @{ "FilePath" = $7zipPath "ArgumentList" = "x `"$($7ZipFile)`" -aoa -o`"$($ExtractDirectory)`"" "Wait" = $true } Start-Process @vars # Get list of files $files = Get-ChildItem -Path (Join-Path -Path $path -ChildPath $applicationName) | Where-Object {$_.Name -notmatch "^.*intunewin$"} foreach($file in $files){ $filepath = $file.FullName if($file.PSIsContainer){ $destination = Split-Path $file.Parent } else{ $destination = Split-Path $file.Directory } try{ Move-Item -Path $filepath -Destination $destination -Force -ErrorAction Stop } catch{ throw "[$($application.IntuneAppName)] Unable to move app file: $($_.Exception.Message)" } } try{ Remove-Item -Path $ExtractDirectory -Force -Recurse -Confirm:$false } catch{ throw "[$($application.IntuneAppName)] Unable to cleanup $($_.Exception.Message)" } } #EndRegion '.\Public\Service_Private\Expand-7ZIpFile.ps1' 61 #Region '.\Public\Service_Private\Get-AppFactoryAppVersionNormalization.ps1' 0 function Get-AppFactoryAppVersionNormalization { [CmdletBinding()] [OutputType([System.Version])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$version ) # Remove Any Hypons and Underscopes and replace with dots $version = ($version -replace "-",".") -replace "_","." # Remove any plus signs and replace with nothing $version = $version -replace "\+" # Replace any alphanumerica and replace with nothing $version = $version -replace "[a-zA-Z]" # Get the length as too long of a version number will cause issues $verlength = ([regex]::Matches($version, "\." )).count # If the length is greater than 3 then we will only look at the first four items if($verlength -gt 3){ $items = $version -split "\." $version = ($items[0..3] -join ".") } return $version } #EndRegion '.\Public\Service_Private\Get-AppFactoryAppVersionNormalization.ps1' 22 #Region '.\Public\Service_Private\Get-AppFactoryAzurePSADTAppItem.ps1' 0 <# .DESCRIPTION This cmdlet is designed to download contacts from Azure Storage Account .PARAMETER application The application object that we are working for so that we can ensure that get the correct and current data .PARAMETER storageContext The azure storage context that has permissions to upload to the Azure Storage Account .PARAMETER workingFolder Path to the working folder for the process .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Get-AppFactoryAzurePSADTAppItem { [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$storageContext, #[Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$workingFolder, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) if($null -eq $application.Version -or $application.Version -eq ""){ $version = "1.0" } else{ $version = $application.version } $AppItem = [PSCustomObject]@{ "Version" = $version "URI" = $null "BlobName" = $null "Status" = "Good" } return $AppItem } #EndRegion '.\Public\Service_Private\Get-AppFactoryAzurePSADTAppItem.ps1' 35 #Region '.\Public\Service_Private\Get-AppFactoryAzureStorageAppItemPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to download contacts from Azure Storage Account .PARAMETER application The application object that we are working for so that we can ensure that get the correct and current data .PARAMETER storageContext The azure storage context that has permissions to upload to the Azure Storage Account .PARAMETER workingFolder Path to the working folder for the process .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Get-AppFactoryAzureStorageAppItemPSU { [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$storageContext, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$workingFolder, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) try { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Getting Blob Items" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)", "AzureStorage" -Target "Application Factory Service" } # Get a list of the blobs in the azure storage container $blobItems = Get-AppFactoryAzureStorageBlobContentPSU -storageContext $storageContext -app $application -LogLevel $LogLevel if ($null -eq $BlobItems) { throw "[$($application.IntuneAppName)] Could not find a setup file in container: $($application.StorageAccountContainerName)" } if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Reading <c='green'>latest.json</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)", "AzureStorage" -Target "Application Factory Service" } # Read the contents of the latest.json file $LatestFile = $BlobItems | Where-Object { $PSItem.Name -eq "latest.json" } if ($null -eq $LatestFile) { throw "[$($application.IntuneAppName)] Unable to find a latest.json file in container $($application.StorageAccountContainerName)" } # Download and then read the latest.json file $LatestSetupFileDestination = Join-Path -Path $workingFolder -ChildPath "LatestFiles" -AdditionalChildPath $application.StorageAccountContainerName $LatestSetupFilePath = Join-Path -Path $LatestSetupFileDestination -ChildPath "latest.json" if (-not(Test-Path -Path $LatestSetupFileDestination)) { New-Item -Path $LatestSetupFileDestination -ItemType "Directory" | Out-Null } Get-AzStorageBlobContent -Context $storageContext -Container $application.StorageAccountContainerName -Blob "latest.json" -Destination $LatestSetupFileDestination -Force | Out-Null if (!(Test-Path -Path $LatestSetupFilePath)) { throw "[$($application.IntuneAppName)] Could not locate latest.json file after attempted download from storage account container" } # Try to download the setup files that are in the latest.json file $LatestSetupFileContent = Get-Content -Path $LatestSetupFilePath | ConvertFrom-Json -ErrorAction Stop if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Found setup file details from <c='green'>latest.json</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)", "AzureStorage" -Target "Application Factory Service" } $BlobItem = $BlobItems | Where-Object { (([System.IO.Path]::GetExtension($PSItem.Name)) -match ".msi|.exe|.zip|.wim|.iso|.7z") -and ($PSItem.Name -like "$($LatestSetupFileContent.Version)/$($LatestSetupFileContent.SetupName)") } | Sort-Object -Property "LastModified" -Descending | Select-Object -First 1 if ($null -eq $BlobItem) { throw "[$($application.IntuneAppName)] Could not find blob file in container with name from latest.json: $($LatestSetupFileContent.SetupName)" } # Construct custom object for return value $PSObject = [PSCustomObject]@{ "Version" = $LatestSetupFileContent.Version "URI" = -join @($appStorageContext.BlobEndPoint, $application.StorageAccountContainerName, "/", $BlobItem.Name) "BlobName" = $BlobItem.Name "Status" = "Good" } } catch { Write-PSFMessage -Message "[$($application.IntuneAppName)] Error Occured: $($_)" -Level "Error" -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" throw $_ } # Handle return value return $PSObject } #EndRegion '.\Public\Service_Private\Get-AppFactoryAzureStorageAppItemPSU.ps1' 72 #Region '.\Public\Service_Private\Get-AppFactoryAzureStorageBlobContentPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to get a list of files from a azure storage blob .PARAMETER application The application object that we are working for so that we can ensure that get the correct and current data .PARAMETER storageContext The azure storage context that has permissions to upload to the Azure Storage Account .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Get-AppFactoryAzureStorageBlobContentPSU{ [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$storageContext, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) # Construct array list for return value containing file names $blobList = [System.Collections.Generic.List[PSCustomObject]]@() # Get contents of specific azure blob try{ $StorageBlobContents = Get-AzStorageBlob -Container $application.StorageAccountContainerName -Context $storageContext -ErrorAction Stop } catch{ throw $_ } # Add found files from blob to list if ($null -ne $StorageBlobContents) { foreach ($StorageBlobContent in $StorageBlobContents) { if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Found file <c='green'>$($StorageBlobContent.Name)</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","AzureStorage" -Target "Application Factory Service" } $blobList.Add($StorageBlobContent) | Out-Null } } return $blobList } #EndRegion '.\Public\Service_Private\Get-AppFactoryAzureStorageBlobContentPSU.ps1' 39 #Region '.\Public\Service_Private\Get-AppFactoryECNOAppItemPSU.ps1' 0 function Get-AppFactoryECNOAppItemPSU{ [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$documentLibrary, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Looking for Sharepoint Application in folder <c='green'>$($application.StorageAccountContainerName)</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Sharepoint" -Target "Application Factory Service" } $listItems = Get-PnPListItem -List $documentLibrary -PageSize 1000 | Where-Object {$_["FileLeafRef"] -eq "$($application.StorageAccountContainerName)"} if($null -eq $listItems){ throw "[$($application.IntuneAppName)]Unable to find any items in sharepoint for app." } # Sort so we only get the most recent version of the item if it exists more than once $listItems = $listItems | Select-Object -ExpandProperty FieldValues if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Found application information " -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Sharepoint" -Target "Application Factory Service" } $files = Get-PnPFolder -Url $listItems.FileRef | Get-PnPFolderItem -ItemType File return $files | Select-Object @{Label="Version";Expression={$_.Name -replace ".7z"}},@{Label="URI";Expression={$_.ServerRelativeUrl}},@{Label="BlobName";Expression={$null}},@{Label="Status";Expression={"Good"}} | Sort-Object -Property Version -Descending -Top 1 } #EndRegion '.\Public\Service_Private\Get-AppFactoryECNOAppItemPSU.ps1' 24 #Region '.\Public\Service_Private\Get-AppFactoryEvergreenAppItemPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to interact with the evergreen powershell module to find the installers for evergreen based installers .PARAMETER application The application object that we are working for so that we can ensure that get the correct and current data .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Get-AppFactoryEvergreenAppItemPSU{ [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Looking for Evergreen Application with AppID Filter: <c='green'>$($application.AppID)</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Evergreen" -Target "Application Factory Service" } # Construct array list to build the dynamic filter list $FilterList = [System.Collections.Generic.List[PSCustomObject]]@() # Process known filter properties and add them to array list if present on current object if ($Application.FilterOptions.Architecture) { if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Architecture Filter: <c='green'>$($Application.FilterOptions.Architecture)</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Evergreen" -Target "Application Factory Service" } $FilterList.Add("`$PSItem.Architecture -eq ""$($Application.FilterOptions.Architecture)""") | Out-Null } if ($Application.FilterOptions.Platform) { if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Platform Filter: <c='green'>$($Application.FilterOptions.Platform)</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Evergreen" -Target "Application Factory Service" } $FilterList.Add("`$PSItem.Platform -eq ""$($Application.FilterOptions.Platform)""") | Out-Null } if ($Application.FilterOptions.Channel) { if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Channel Filter: <c='green'>$($Application.FilterOptions.Channel)</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Evergreen" -Target "Application Factory Service" } $FilterList.Add("`$PSItem.Channel -eq ""$($Application.FilterOptions.Channel)""") | Out-Null } if ($Application.FilterOptions.Type) { if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Type Filter: <c='green'>$($Application.FilterOptions.Type)</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Evergreen" -Target "Application Factory Service" } $FilterList.Add("`$PSItem.Type -eq ""$($Application.FilterOptions.Type)""") | Out-Null } if ($Application.FilterOptions.InstallerType) { if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] InstallerType Filter: <c='green'>$($Application.FilterOptions.InstallerType)</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Evergreen" -Target "Application Factory Service" } $FilterList.Add("`$PSItem.InstallerType -eq ""$($Application.FilterOptions.InstallerType)""") | Out-Null } if ($Application.FilterOptions.Release) { if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Release Filter: <c='green'>$($Application.FilterOptions.Release)</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Evergreen" -Target "Application Factory Service" } $FilterList.Add("`$PSItem.Release -eq ""$($Application.FilterOptions.Release)""") | Out-Null } if ($Application.FilterOptions.Language) { if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Language Filter: <c='green'>$($Application.FilterOptions.Language)</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Evergreen" -Target "Application Factory Service" } $FilterList.Add("`$PSItem.Language -eq ""$($Application.FilterOptions.Language)""") | Out-Null } if ($Application.FilterOptions.ImageType) { if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] ImageType Filter: <c='green'>$($Application.FilterOptions.ImageType)</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Evergreen" -Target "Application Factory Service" } $FilterList.Add("`$PSItem.ImageType -eq ""$($Application.FilterOptions.ImageType)""") | Out-Null } # Construct script block from filter list array $FilterExpression = [scriptblock]::Create(($FilterList -join " -and ")) # Get the evergreen app based on dynamic filter list if($FilterList.Count -gt 0){ $EvergreenApp = Get-EvergreenApp -Name $application.AppId | Where-Object -FilterScript $FilterExpression | Sort-Object Version -Descending | Select-Object -first 1 } else{ $EvergreenApp = Get-EvergreenApp -Name $application.AppId | Sort-Object Version -Descending | Select-Object -first 1 } # Only return the top item $PSObject = [PSCustomObject]@{ "Version" = $EvergreenApp.version "URI" = $EvergreenApp.URI "BlobName" = $null "Status" = "Good" } return $PSObject } #EndRegion '.\Public\Service_Private\Get-AppFactoryEvergreenAppItemPSU.ps1' 88 #Region '.\Public\Service_Private\Get-AppFactoryInstallerECNOPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to download the app installers from a sharepoint document library .PARAMETER application The application object that we are working for so that we can ensure that get the correct and current data .PARAMETER AppSetupFolderPath The path that the app setup folders are stored in .PARAMETER supportFiles The path to the support files folder .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Get-AppFactoryInstallerECNOPSU{ [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$AppSetupFolderPath, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$supportFiles, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Downloading from Sharepoint" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Download" -Target "Application Factory Service" } try { New-Item -Path $AppSetupFolderPath -ItemType Directory -ErrorAction "Stop" | Out-Null } catch { throw "[$($application.IntuneAppName)] Failed to create '$($AppSetupFolderPath)' with error message: $($_.Exception.Message)" } try{ if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Downloading setupfile <c='green'>$($application.FullPath)</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","ECNO" -Target "Application Factory Service" } Get-PnPFile -Url $application.FullPath -AsFile -Path $AppSetupFolderPath -Filename $application.AppSetupFileName -Force } catch{ throw "[$($application.IntuneAppName)] Failed to download file with error message: $($_.Exception.Message)" } $appName = ($application.IntuneAppName -replace "STS-","") if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Expanding Archive" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Download" -Target "Application Factory Service" } # Expand 7zip file Expand-7ZIpFile -application $application -applicationName $appName -path $AppSetupFolderPath -supportFiles $supportFiles -LogLevel $LogLevel Remove-Item -Path (Join-Path -Path $AppSetupFolderPath -ChildPath $application.AppSetupFileName) -Force $application.AppSetupFileName = "_action.ps1" return $application } #EndRegion '.\Public\Service_Private\Get-AppFactoryInstallerECNOPSU.ps1' 50 #Region '.\Public\Service_Private\Get-AppFactoryInstallerFilesPSU.ps1' 0 function Get-AppFactoryInstallerFilesPSU { [CmdletBinding()] [OutputType([String])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$appStorageContext, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$workspace, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$supportFiles, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) $AppSetupFolderPath = Join-Path -Path $workspace -ChildPath "Installers" -AdditionalChildPath $application.AppFolderName if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Attempting to download <c='green'>$($application.URI)</c> to <c='green'>$($AppSetupFolderPath)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)", "Download" -Target "Application Factory Service" } try { switch ($application.AppSource) { "StorageAccount" { Get-AppFactoryInstallerStorageAccountPSU -application $application -AppSetupFolderPath $AppSetupFolderPath -storageContext $appStorageContext -LogLevel $LogLevel } "Sharepoint" { Get-AppFactoryInstallerSharepointPSU -application $application -AppSetupFolderPath $AppSetupFolderPath -supportFiles $supportFiles -LogLevel $LogLevel } "ECNO" { $application = Get-AppFactoryInstallerECNOPSU -application $application -AppSetupFolderPath $AppSetupFolderPath -supportFiles $supportFiles -LogLevel $LogLevel } "PSADT" { if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] No Download Neccessary" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Download" -Target "Application Factory Service" } } default { if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Downloading from HTTP" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Download" -Target "Application Factory Service" } Save-InstallerFilePSU -application $application -path $AppSetupFolderPath -LogLevel $LogLevel } } # Validate setup installer was successfully downloaded $AppSetupFilePath = Join-Path -Path $AppSetupFolderPath -ChildPath $application.AppSetupFileName if (-not (Test-Path -Path $AppSetupFilePath) -and $application.AppSource -ne "PSADT"){ throw "[$($application.IntuneAppName)] Could not detect downloaded setup installer" } } catch { throw $_ } return $AppSetupFolderPath } #EndRegion '.\Public\Service_Private\Get-AppFactoryInstallerFilesPSU.ps1' 49 #Region '.\Public\Service_Private\Get-AppFactoryInstallerSharepointPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to download the app installers from a sharepoint document library .PARAMETER application The application object that we are working for so that we can ensure that get the correct and current data .PARAMETER AppSetupFolderPath The path that the app setup folders are stored in .PARAMETER supportFiles The path to the support files folder .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Get-AppFactoryInstallerSharepointPSU{ [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$AppSetupFolderPath, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$supportFiles, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Downloading from Sharepoint" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Download" -Target "Application Factory Service" } try { New-Item -Path $AppSetupFolderPath -ItemType Directory -ErrorAction "Stop" | Out-Null } catch { throw "[$($application.IntuneAppName)] Failed to create '$($AppSetupFolderPath)' with error message: $($_.Exception.Message)" } # Connect to Sharepoint try{ if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Downloading setupfile <c='green'>$($application.FullPath)</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Sharepoint" -Target "Application Factory Service" } Get-PnPFile -Url $application.FullPath -AsFile -Path $AppSetupFolderPath -Filename $application.AppSetupFileName -Force if($application.archiveType -like "*ZIP"){ $currentFilename = Join-Path -Path $AppSetupFolderPath -ChildPath $application.AppSetupFileName $zipFile = Join-Path -Path $AppSetupFolderPath -ChildPath ($application.AppSetupFileName -replace "msi|exe|ps1","zip") Rename-Item -Path $currentFilename -NewName ($application.AppSetupFileName -replace "msi|exe|ps1","zip") Expand-Archive -Path $zipFile -DestinationPath $AppSetupFolderPath -Force } elseif($application.archiveType -like "7Z"){ throw "Not yet implemented" } try{ Remove-Item -Path $zipFile -Force } catch{ throw "[$($application.IntuneAppName)] Failed to cleanup: $($_.Exception.Message)" } } catch{ throw "[$($application.IntuneAppName)] Failed to download file with error message: $($_.Exception.Message)" } } #EndRegion '.\Public\Service_Private\Get-AppFactoryInstallerSharepointPSU.ps1' 56 #Region '.\Public\Service_Private\Get-AppFactoryInstallerStorageAccountPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to download the app installers from azure storage .PARAMETER application The application object that we are working for so that we can ensure that get the correct and current data .PARAMETER AppSetupFolderPath The path that the app setup folders are stored in .PARAMETER storageContext The azure storage context that has permissions to upload to the Azure Storage Account .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Get-AppFactoryInstallerStorageAccountPSU { [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$AppSetupFolderPath, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$storageContext, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) # Get Azure Storage Blob Contents Get-StorageAccountBlobContentPSU -storageContext $storageContext -application $application -path $AppSetupFolderPath # Process files if they are an archived type if($application.archiveType -like "*ZIP"){ $zipFile = Join-Path -Path $AppSetupFolderPath -ChildPath ($application.AppSetupFileName -replace "msi|exe|ps1","zip") if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Expanding Archive" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Download" -Target "Application Factory Service" } Expand-Archive -Path $zipFile -DestinationPath $AppSetupFolderPath -Force try{ Remove-Item -Path $zipFile -Force } catch{ throw "[$($application.IntuneAppName)] Failed to cleanup: $($_.Exception.Message)" } } elseif($application.archiveType -like "7Z"){ throw "Not yet implemented" } } #EndRegion '.\Public\Service_Private\Get-AppFactoryInstallerStorageAccountPSU.ps1' 41 #Region '.\Public\Service_Private\Get-AppFactorySharepointAppItemPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to get the details of an application installer stored in sharepoint .PARAMETER application The application object that we are working for so that we can ensure that get the correct and current data .PARAMETER documentLibrary The name of the document library that is storing the application files .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Get-AppFactorySharepointAppItemPSU{ [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$documentLibrary, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Looking for Sharepoint Application Installer for <c='green'>$($application.IntuneAppName)</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Sharepoint" -Target "Application Factory Service" } # Get List of Files $name = $application.IntuneAppName -replace "STS-","" $listItems = Get-PnPListItem -List $documentLibrary -PageSize 1000 | Where-Object {$_["FileLeafRef"] -like "$($name)*"} if($null -eq $listItems){ throw "[$($application.IntuneAppName)]Unable to find any items in sharepoint for app." } # Sort so we only get the most recent version of the item if it exists more than once $listItems = $listItems | Select-Object -ExpandProperty FieldValues if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Found application information " -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Sharepoint" -Target "Application Factory Service" } return $listItems | Select-Object @{Label="Version";Expression={$_.SoftwareVersion}},@{Label="URI";Expression={$_.FileRef}},@{Label="BlobName";Expression={$null}},@{Label="Status";Expression={"Good"}} | Sort-Object -Property Version -Descending -Top 1 } #EndRegion '.\Public\Service_Private\Get-AppFactorySharepointAppItemPSU.ps1' 35 #Region '.\Public\Service_Private\Get-AppFactoryWinGetAppItemPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to get the details of an application installer that is acquired from winget .PARAMETER application The application object that we are working for so that we can ensure that get the correct and current data .PARAMETER documentLibrary The name of the document library that is storing the application files .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Get-AppFactoryWinGetAppItemPSU{ [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Looking for Winget Application with AppID Filter: <c='green'>$($application.AppID)</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","WinGet" -Target "Application Factory Service" } # Create the argument and then run the winget cmd line $WinGetArguments = @("search", "$($application.AppID)") $WinGetStream = & "winget" $WinGetArguments | Out-String -Stream # Confirm that a package was found foreach ($RowItem in $WinGetStream) { if ($RowItem -eq "No package found matching input criteria.") { throw "[$($application.IntuneAppName)] No package found matching specified id: $($application.AppId)" } } if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Found winget item" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","WinGet" -Target "Application Factory Service" } # Now look for the specific item and get the details and parse them out $WinGetArguments = @("show", "$($application.AppID)") $WinGetStream = & "winget" $WinGetArguments | Out-String -Stream $PSObject = [PSCustomObject]@{ "Version" = ($WinGetStream | Where-Object { $PSItem -match "^Version\:.*(?<AppVersion>(\d+(\.\d+){0,3}))$" }).Replace("Version:", "").Trim() "URI" = (($WinGetStream | Where-Object { $PSItem -match "^.*(Download|Installer) Url\:.*$" }) -replace "(Download|Installer) Url:", "").Trim() "BlobName" = $null "Status" = "Good" } return $PSObject } #EndRegion '.\Public\Service_Private\Get-AppFactoryWinGetAppItemPSU.ps1' 44 #Region '.\Public\Service_Private\Get-StorageAccountBlobContentPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to get the contents of a azure storage blob .PARAMETER application The application object that we are working for so that we can ensure that get the correct and current data .PARAMETER storageContext The azure storage context that has permissions to upload to the Azure Storage Account .PARAMETER path The path for the contents .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Get-StorageAccountBlobContentPSU { param ( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$storageContext, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [parameter(Mandatory = $true, HelpMessage = "Specify the download path.")][ValidateNotNullOrEmpty()][string]$path, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) # Cleanup possible remnants Remove-Item -Path $Path -Force -Recurse -ErrorAction SilentlyContinue try { New-Item -Path $Path -ItemType Directory -ErrorAction "Stop" | Out-Null } catch { throw "[$($application.IntuneAppName)] Failed to create '$($Path)' with error message: $($_.Exception.Message)" } if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Downloading setupfile <c='green'>$($application.BlobName)</c>" -Tag "Application","$($application.IntuneAppName)","AzureStorage" -Target "Application Factory Service" } # Get the storage blob contents try{ Get-AzStorageBlobContent -Context $storageContext -Container $application.StorageAccountContainerName -Blob $application.BlobName -Destination $Path -Force -ErrorAction "Stop" | Out-Null } catch{ throw "[$($application.IntuneAppName)] Unable to save app file: $($_.Exception.Message)" } # Move it to the appropriate location try{ Move-Item -Path "$($Path)\$($application.BlobName)" -Destination $Path -ErrorAction Stop Remove-Item -Path "$($Path)\$($application.AppSetupVersion)" -Recurse -ErrorAction Stop } catch{ throw "[$($application.IntuneAppName)] Failed to move item and cleanup: $($_.Exception.Message)" } } #EndRegion '.\Public\Service_Private\Get-StorageAccountBlobContentPSU.ps1' 47 #Region '.\Public\Service_Private\New-AppFactoryAppFolderPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to create a new application to be handled by the automated process .PARAMETER Name The name of the application that we are creating .PARAMETER force Continue even if the folder already exists, overwriting the current details .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. .EXAMPLE Create a new application folder New-AppFactoryAppFolder -Name "### Name ###" -LogLevel "Output" #> function New-AppFactoryAppFolderPSU { [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$Name, [Parameter()][bool]$force, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) # Template folder $templateFolderPath = Join-Path -Path $PSScriptRoot -ChildPath "Templates" # Path to the new app folder $appFolderPath = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Apps" -AdditionalChildPath $Name if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($Name)] Template folder used <c='green'>$($templateFolderPath)</c>" -Level $LogLevel -Tag "Application", "$($Name)" -Target "Application Factory Service" Write-PSFMessage -Message "[$($Name)] Creating application folder <c='green'>$($appFolderPath)</c>" -Level $LogLevel -Tag "Application", "$($Name)" -Target "Application Factory Service" } # Create New Application Folder try { if ((Test-Path $appFolderPath) -and -not $force) { throw "Folder Already Exists $($templateFolderPath) and force was not set" } New-Item -Path $appFolderPath -ItemType Directory -Force | Out-Null } catch { Write-PSFMessage -Message "Error Encountered: $($_)" -Level "Error" -Tag "Application", "$($Name)" -Target "Application Factory Service" throw $_ } # Copy Template Folders for the application if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($Name)] Copying Template Files to <c='green'>$($appFolderPath)</c>" -Level $LogLevel -Tag "Application", "$($Name)" -Target "Application Factory Service" } $filesToCopy = @{ "AppJsonFile" = Join-Path -Path $templateFolderPath -ChildPath "Application" -AdditionalChildPath "App.json" "DeployAppFile" = Join-Path -Path $templateFolderPath -ChildPath "Application" -AdditionalChildPath "Deploy-Application.ps1" "IconFile" = Join-Path -Path $templateFolderPath -ChildPath "Framework" -AdditionalChildPath "Icon.png" } try { foreach ($file in $filesToCopy.GetEnumerator()) { Copy-Item -Path $file.value -Destination $appFolderPath -ErrorAction Stop -Force } } catch { Remove-Item -Path $appFolderPath -Force Write-PSFMessage -Message "Error Encountered: $($_)" -Level "Error" -Tag "Application", "$($Name)" -Target "Application Factory Service" throw $_ } return $appFolderPath } #EndRegion '.\Public\Service_Private\New-AppFactoryAppFolderPSU.ps1' 64 #Region '.\Public\Service_Private\New-AppFactoryIntuneDeployment.ps1' 0 function New-AppFactoryIntuneDeployment{ param( ) Get-Variable -Scope Script } #EndRegion '.\Public\Service_Private\New-AppFactoryIntuneDeployment.ps1' 6 #Region '.\Public\Service_Private\New-AppFactoryIntuneWinPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to create the intune win file to upload to intune .PARAMETER application The application object that we are working for so that we can ensure that get the correct and current data .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function New-AppFactoryIntuneWinPSU{ [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Creating Intune App File" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } # Get Application config file and read it $AppDataFile = Join-Path -Path $application.AppPublishFolderPath -ChildPath "App.json" $AppData = Get-Content -Path $AppDataFile | ConvertFrom-Json # Get the source and output folders and then create intune win file $SourceFolder = Join-Path -Path $application.AppPublishFolderPath -ChildPath $AppData.PackageInformation.SourceFolder $OutputFolder = Join-Path -Path $application.AppPublishFolderPath -ChildPath $AppData.PackageInformation.OutputFolder $IntuneAppPackage = New-IntuneWin32AppPackage -SourceFolder $SourceFolder -SetupFile $AppData.PackageInformation.SetupFile -OutputFolder $OutputFolder -Force if(-not $IntuneAppPackage){ throw "Error creating application file" } # Confirm the file was created and then rename and cleanup $AppFileName = Join-Path -Path $OutputFolder -ChildPath "$($application.IntuneAppName).intunewin" Remove-Item -Path $AppFileName -Force -ErrorAction SilentlyContinue Rename-Item -Path $IntuneAppPackage.Path -NewName "$($application.IntuneAppName).intunewin" -Force $application | Add-Member -MemberType NoteProperty -Name 'IntunePackage' -Value $AppFileName -Force return $application } #EndRegion '.\Public\Service_Private\New-AppFactoryIntuneWinPSU.ps1' 36 #Region '.\Public\Service_Private\New-AppFactoryPackageFolderPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to create the files for an application package .PARAMETER application The application object that we are working for so that we can ensure that get the correct and current data .PARAMETER AppsPublishRootPath Root path for where the publish folders will be used from .PARAMETER AppFactoryWorkspace Where is the workspace to perform process actions .PARAMETER AppFactorySourceDir The source directory of the process .PARAMETER FrameworkPath Where the framework files are stored .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function New-AppFactoryPackageFolderPSU { [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$AppsPublishRootPath, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$AppFactoryWorkspace, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$AppFactorySourceDir, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$AppFactoryTemplateDir, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) # Get the path to where the folder should be, clean up any previous and create it $AppPublishFolderPath = Join-Path -Path $AppsPublishRootPath -ChildPath $application.AppFolderName if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Creating app package folder <C='green'>$($AppPublishFolderPath)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } Remove-Item -Path $AppPublishFolderPath -Force -Recurse -ErrorAction SilentlyContinue try { New-Item -Path $AppPublishFolderPath -ItemType Directory -ErrorAction "Stop" | Out-Null } catch { throw "[$($application.IntuneAppName)] Failed to create '$($AppPublishFolderPath)' with error message: $($_.Exception.Message)" } if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Copying framework files" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } # Copy the framework files to the new folder try { Copy-Item -Path "$($AppFactoryTemplateDir)\Framework\*" -Destination $AppPublishFolderPath -Recurse -Force -Confirm:$false } catch { throw "[$($application.IntuneAppName)] Unable to copy template files: $($_.Exception.Message)" } # Where the files for the installer should be stored, create the folder $AppsPublishSourceFilesPath = Join-Path -Path $AppsPublishRootPath -ChildPath $application.AppFolderName -AdditionalChildPath "source", "files" New-Item -Path $AppsPublishSourceFilesPath -ItemType "Directory" -Force -Confirm:$false | Out-Null if($application.AppSource -ne "PSADT"){ $AppInstallerDestinationPath = Join-Path -Path $AppPublishFolderPath -ChildPath "Source" -AdditionalChildPath "Files" if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Copying application files" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" Write-PSFMessage -Message "[$($application.IntuneAppName)] Source path: <c='green'>$($application.AppSetupFolderPath)</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" Write-PSFMessage -Message "[$($application.IntuneAppName)] Destination path: <c='green'>$($AppInstallerDestinationPath)</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } Copy-Item -Path "$($application.AppSetupFolderPath)\*" -Destination $AppInstallerDestinationPath -Force -Confirm:$false -Recurse } # Update deploy-application.ps1 in the publish folder Update-DeployApplicationPSU -application $application -AppFactoryWorkspace $AppFactoryWorkspace -AppFactorySourceDir $AppFactorySourceDir -LogLevel $LogLevel if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Copying Icon File" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } $iconPath = Join-Path -Path $AppFactorySourceDir -ChildPath "Apps" -AdditionalChildPath $application.AppFolderName,"Icon.png" $iconDestination = Join-Path -Path $AppPublishFolderPath -ChildPath "Icon.png" Copy-Item -Path $iconPath -Destination $iconDestination -Force -Confirm:$false # Update app.json in the publish folder Update-AppJSONPSU -application $application -AppFactoryWorkspace $AppFactoryWorkspace -AppFactorySourceDir $AppFactorySourceDir -LogLevel $LogLevel $AppRootFolderPackagePath = Join-Path -Path $AppPublishFolderPath -ChildPath "Package" if (-not(Test-Path -Path $AppRootFolderPackagePath)) { New-Item -Path $AppRootFolderPackagePath -ItemType "Directory" -Force -Confirm:$false | Out-Null } $application | Add-Member -MemberType NoteProperty -Name 'AppPublishFolderPath' -Value $AppPublishFolderPath -Force return $application } #EndRegion '.\Public\Service_Private\New-AppFactoryPackageFolderPSU.ps1' 78 #Region '.\Public\Service_Private\Save-InstallerFilePSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to downloaded files for the package .PARAMETER application The application object that we are working for so that we can ensure that get the correct and current data .PARAMETER application The path to store the data .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Save-InstallerFilePSU { param ( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$path, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) # Ensure we are using TLS 1.2 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 # Create path if it doesn't exist if (-not(Test-Path -Path $path -PathType "Container")) { try { New-Item -Path $path -ItemType "Container" -ErrorAction "Stop" | Out-Null } catch [System.Exception] { throw "[$($application.IntuneAppName)] Failed to create '$($Path)' with error message: $($_.Exception.Message)" } } # Download installer file try { $OutFilePath = Join-Path -Path $Path -ChildPath $application.AppSetupFileName if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Downloading setupfile <c='green'>$($application.URI)</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)","Download" -Target "Application Factory Service" } Invoke-WebRequest -Uri $application.URI -OutFile $OutFilePath -UseBasicParsing -ErrorAction "Stop" } catch [System.Exception] { throw "[$($application.IntuneAppName)] Failed to download file from '$($application.URI)' with error message: $($_.Exception.Message)" } } #EndRegion '.\Public\Service_Private\Save-InstallerFilePSU.ps1' 40 #Region '.\Public\Service_Private\Set-AppFactoryDeploymentScriptLinesPSU.ps1' 0 function Set-AppFactoryDeploymentScriptLinesPSU { [cmdletbinding()] [OutputType([String])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[String[]]]$ScriptLines, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$Script, [Parameter(Mandatory = $true)][ValidateSet("Install", "Uninstall")][String]$section, [Parameter()][switch]$main, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) try { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Reading application deployment file located at <c='green'>$($ApplicationDeploymentFilePath)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationDeploymentFilePath = $script $ApplicationDeploymentFile = Get-Content -Path $Script -Raw } catch { Write-PSFMessage -Message "Error Encountered: $($_)" -Level "Error" -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" throw $_ } if($main.IsPresent){ if($section -eq "install"){ $startingLine = ([Regex]::Match($ApplicationDeploymentFile,"###INSTALLTYPE:(NONE|None|MSI|EXE|POWERSHELL|ECNO|CUSTOM)###").Value) } else{ $startingLine = ([Regex]::Match($ApplicationDeploymentFile,"###UNINSTALLTYPE:(NONE|None|MSI|EXE|NAME|GUID|ECNO|CUSTOM)###").Value) } } else{ $startingLine = $ScriptLines[0][0] } $endingLine = $ScriptLines[-1][0] $lines = [System.Collections.Generic.List[String[]]]@() foreach($line in $ScriptLines){ $addTabs = "" for($i = 0; $i -lt $line[1]; $i++){ $addTabs = "$($addTabs)`t" } $lines.Add("$($addTabs)$($line[0])") } $top = $ApplicationDeploymentFile.Split($startingLine) $bottom = $top[1].Split($endingLine) $bottomLines = $bottom[1].split("`n") $bottomLength = $bottomLines.Count $outputFile = [System.Collections.Generic.List[String[]]]@() $outputFile.Add($top[0].TrimEnd()) | Out-Null $outputFile.Add("`t`t") | Out-Null foreach($line in $lines){ $outputFile.Add($line) | Out-Null } $outputFile.Add($($bottomLines[1..$bottomLength] -join "`n").TrimEnd()) try{ if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Writing application deployment file <c='green'>$($ApplicationDeploymentFilePath)</c>" -Level $LogLevel -Tag "Application","Install","$($application.IntuneAppName)" -Target "Application Factory Service" } $outputFile | Set-Content -Path $ApplicationDeploymentFilePath -Force } catch{ Write-PSFMessage -Message "Error Encountered: $($_)" -Level "Error" -Tag "Application", "$($Name)" -Target "Application Factory Service" throw $_ } #> } #EndRegion '.\Public\Service_Private\Set-AppFactoryDeploymentScriptLinesPSU.ps1' 65 #Region '.\Public\Service_Private\Update-AppJSONPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to update the App.JSON file for the application .PARAMETER application The application object that we are working for so that we can ensure that get the correct and current data .PARAMETER AppFactoryWorkspace Workspace directory to work with .PARAMETER AppFactorySourceDir Source directory for configuration items .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Update-AppJSONPSU{ [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$AppFactoryWorkspace, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$AppFactorySourceDir, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) $AppsPublishRootPath = Join-Path -Path $AppFactoryWorkspace -ChildPath "Publish" $AppPackageFolderPath = Join-Path -Path $AppFactorySourceDir -ChildPath "Apps" -AdditionalChildPath $application.AppFolderName $AppPublishFolderPath = Join-Path -Path $AppsPublishRootPath -ChildPath $application.AppFolderName $AppInstallerPath = Join-Path -Path $AppPublishFolderPath -ChildPath "Source" -AdditionalChildPath "Files",$application.AppSetupFileName $AppFilePath = Join-Path -Path $AppFactorySourceDir -ChildPath "Apps" -AdditionalChildPath $application.AppFolderName,"App.json" if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Reading <c='green'>$($AppFilePath)</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } try{ # Read file and update hardcoded variables with specific variable value from app details $AppFileContent = Get-Content -Path $AppFilePath | ConvertFrom-Json } catch{ throw "[$($application.IntuneAppName)] Unable to read file: $($_.Exception.Message)" } # Update version specific property values $AppFileContent.Information.DisplayName = $application.IntuneAppName $AppFileContent.Information.AppVersion = $application.AppSetupVersion.toString() $AppFileContent.Information.Publisher = $application.AppPublisher $AppFileContent.Information.InformationURL = $application.InformationURL $AppFileContent.Information.PrivacyURL = $application.PrivacyURL foreach ($DetectionRuleItem in $AppFileContent.DetectionRule) { switch ($DetectionRuleItem.Type) { "MSI" { if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Retrieving MSI metadata" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } $ProductCode = Get-MSIMetaData -Path $AppInstallerPath -Property "ProductCode" $ProductCode = ($ProductCode -as [string]).Trim() if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Product Code: $($ProductCode)" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } $ProductVersion = Get-MSIMetaData -Path $AppInstallerPath -Property "ProductVersion" $ProductVersion = ($ProductVersion -as [string]).Trim() # Normalize App Version Numbers $ProductVersion = (Get-AppFactoryAppVersionNormalization -version $ProductVersion).ToString() if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Product Version: $($ProductVersion)" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } # Update App.json detection rule with MSI meta data for ProductCode if ($null -ne $ProductCode) { $DetectionRuleItem.ProductCode = $ProductCode } else { throw "[$($application.IntuneAppName)] Failed to retrieve MSI meta data value for ProductCode: $($_.Exception.Message)" } # Update App.json detection rule with MSI meta data for ProductVersion if ($null -ne $ProductVersion) { $DetectionRuleItem.ProductVersion = $ProductVersion } else { throw "[$($application.IntuneAppName)] Failed to retrieve MSI meta data value for ProductVersion: $($_.Exception.Message)" } } "Registry" { if ($DetectionRuleItem.KeyPath -match "(\#{3})PRODUCTCODE(\#{3})") { if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Retrieving MSI metadata" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } $ProductCode = Get-MSIMetaData -Path $AppInstallerPath -Property "ProductCode" $ProductCode = ($ProductCode -as [string]).Trim() if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Product Code: $($ProductCode)" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } if ($null -ne $ProductCode) { $DetectionRuleItem.KeyPath = $DetectionRuleItem.KeyPath -replace "###PRODUCTCODE###", ($ProductCode -as [string]).Trim() } else { throw "[APPLICATION: <c='green'>$($application.IntuneAppName)</c>] Failed to retrieve MSI meta data value for ProductVersion: $($_.Exception.Message)" } } switch ($DetectionRuleItem.DetectionMethod) { "VersionComparison" { $DetectionRuleItem.Value = $application.AppSetupVersion.toString() } "StringComparison" { $DetectionRuleItem.Value = $application.AppSetupVersion.toString() } } } "File" { switch ($DetectionRuleItem.DetectionMethod) { "Version" { $DetectionRuleItem.VersionValue = $application.AppSetupVersion.toString() } } } "Script" { # Create the Scripts folder in the app package folder in the publish root folder $AppPublishScriptsFolderPath = Join-Path -Path $AppPublishFolderPath -ChildPath "Scripts" if (-not(Test-Path -Path $AppPublishScriptsFolderPath)) { New-Item -Path $AppPublishScriptsFolderPath -ItemType "Directory" -Force -Confirm:$false | Out-Null } # Construct the detection script file path from the app package folder and destination path for copy operation $AppDetectionScriptFile = Join-Path -Path $AppPackageFolderPath -ChildPath $AppFileContent.DetectionRule.ScriptFile $AppDetectionScriptFileDestinationPath = Join-Path -Path $AppPublishScriptsFolderPath -ChildPath $AppFileContent.DetectionRule.ScriptFile if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Copying detection script" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } try{ Copy-Item -Path $AppDetectionScriptFile -Destination $AppDetectionScriptFileDestinationPath -Force -Confirm:$false } catch{ throw "[APPLICATION: <c='green'>$($application.IntuneAppName)</c>] Unable to copy detection script: $($_.Exception.Message)" } $AppDetectionScriptFileContent = Get-Content -Path $AppDetectionScriptFileDestinationPath $AppDetectionScriptFileContent = $AppDetectionScriptFileContent -replace "###VERSION###", $application.AppSetupVersion.toString() # Update detection script file in app package folder in publish folder root if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Writing out detection script"-Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } try{ Out-File -InputObject $AppDetectionScriptFileContent -FilePath $AppDetectionScriptFileDestinationPath -Encoding "utf8" -Force -Confirm:$false } catch{ throw "[APPLICATION: <c='green'>$($application.IntuneAppName)</c>] Unable to write out detection script: $($_.Exception.Message)" } } } } # Save changes made to App.json in app package folder in publish root folder $AppFileDestinationPath = Join-Path -Path $AppPublishFolderPath -ChildPath "App.json" if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Writing out App.JSON file"-Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } try{ Out-File -InputObject ($AppFileContent | ConvertTo-Json -depth 5) -FilePath $AppFileDestinationPath -Encoding "utf8" -Force -Confirm:$false } catch{ throw "[$($application.IntuneAppName)] Unable to write out file: $($_.Exception.Message)" } } #EndRegion '.\Public\Service_Private\Update-AppJSONPSU.ps1' 153 #Region '.\Public\Service_Private\Update-DeployApplicationPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to update the Deploy-Application.ps1 file for the application .PARAMETER application The application object that we are working for so that we can ensure that get the correct and current data .PARAMETER AppFactoryWorkspace Workspace directory to work with .PARAMETER AppFactorySourceDir Source directory for configuration items .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Update-DeployApplicationPSU{ [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$application, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$AppFactoryWorkspace, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][String]$AppFactorySourceDir, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) $AppsPublishRootPath = Join-Path -Path $AppFactoryWorkspace -ChildPath "Publish" $AppFilePath = Join-Path -Path $AppFactorySourceDir -ChildPath "Apps" -AdditionalChildPath $application.AppFolderName,"Deploy-Application.ps1" if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Reading <c='green'>$($AppFilePath)</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } try{ # Read file and update hardcoded variables with specific variable value from app details $AppFileContent = Get-Content -Path $AppFilePath } catch{ throw "[$($application.IntuneAppName)] Unable to read file: $($_.Exception.Message)" } if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Substituting placeholders" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } $AppFileContent = $AppFileContent -replace "###INTUNEAPPNAME###", $application.IntuneAppName $AppFileContent = $AppFileContent -replace "###APPPUBLISHER###", $application.AppPublisher $AppFileContent = $AppFileContent -replace "###VERSION###", $application.AppSetupVersion $AppFileContent = $AppFileContent -replace "###DATETIME###", (Get-Date).ToShortDateString() $AppFileContent = $AppFileContent -replace "###SETUPFILENAME###", $($application.AppSetupFileName) $AppsPublishSourcePath = Join-Path -Path $AppsPublishRootPath -ChildPath "$($application.AppFolderName)\Source" -AdditionalChildPath "Deploy-Application.ps1" if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Writing out file" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } Out-File -InputObject $AppFileContent -FilePath $AppsPublishSourcePath -Encoding "utf8" -Force -Confirm:$false } #EndRegion '.\Public\Service_Private\Update-DeployApplicationPSU.ps1' 47 #Region '.\Public\Service_Public\Add-AppFactoryPackageFolderPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to process through the application list and prepare the package folder .PARAMETER applicationList The collection of the applications that we will be acting on .PARAMETER multithread Show we proceed single threaded or multithreaded .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Add-AppFactoryPackageFolderPSU { [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[PSCustomObject]]$applicationList, [Parameter()][ValidateNotNullOrEmpty()][switch]$multithread, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) # Create a list to store the results of the process $applications = [System.Collections.Generic.List[PSCustomObject]]@() # The require application paths used during the scripts $AppsPublishRootPath = Join-Path -Path $global:AppFactoryWorkspace -ChildPath "Publish" if (-not $multithread.IsPresent) { foreach ($application in $applicationList) { try { $app = New-AppFactoryPackageFolderPSU -application $application -AppsPublishRootPath $AppsPublishRootPath -AppFactoryWorkspace $global:AppFactoryWorkspace -AppFactorySourceDir $global:AppFactorySourceDir -AppFactoryTemplateDir $global:AppFactorySupportTemplateFolder -LogLevel $LogLevel $applications.Add($app) } catch { throw $_ } } } else { # Create a syncronized hashtable to be used between the threads $applist = [hashtable]::Synchronized(@{}) # Process through the applicationList that are currently in the process if ($global:LocalModulePath) { $modulePath = $global:LocalModulePath } else { $modulePath = (Get-module ApplicationFactoryService).path } $applicationList | Foreach-Object -Parallel { Import-Module -Name $using:modulePath -Force $application = $_ $dict = $using:applist $global:AppFactoryLogging = $global:global:AppFactoryLogging $AppsPublishRootPath = $using:AppsPublishRootPath $global:AppFactoryWorkspace = $using:script:AppFactoryWorkspace $global:AppFactorySourceDir = $using:script:AppFactorySourceDir $global:AppFactorySupportTemplateFolder = $using:script:AppFactorySupportTemplateFolder $LogLevel = $using:LogLevel try { $app = New-AppFactoryPackageFolderPSU -application $application -AppsPublishRootPath $AppsPublishRootPath -AppFactoryWorkspace $global:AppFactoryWorkspace -AppFactorySourceDir $global:AppFactorySourceDir -AppFactoryTemplateDir $global:AppFactorySupportTemplateFolder -LogLevel $LogLevel # If no error, add it to the collection as good status $obj = [PSCustomObject]@{ "Status" = "Good" "Application" = $app "Error" = $null } $dict.add($application.GUID, $obj) } catch { # If error, add it to the collection as fail status $obj = [PSCustomObject]@{ "Status" = "Fail" "AppPublishFolderPath" = $null "Error" = $_ } $dict.add($application.GUID, $obj) } } # Only add the items that had good status to the collection for the process foreach ($item in $applist.GetEnumerator()) { if ($item.Value.status -eq "Good") { $applications.Add($item.Value.Application) | Out-Null } } } return $applications } #EndRegion '.\Public\Service_Public\Add-AppFactoryPackageFolderPSU.ps1' 83 #Region '.\Public\Service_Public\Compare-AppFactoryAppVersionsPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to look at applications in the process, and what their newest version are and compare the results .PARAMETER applicationList The collection of the applications that we will be acting on .PARAMETER appVersions An collection of the expected app versions based on their newest version .PARAMETER force If we should proceed with the repackage even if the current version is already packaged .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Compare-AppFactoryAppVersionsPSU { [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[PSCustomObject]]$applicationList, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Hashtable]$appVersions, [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 application list, removing those that are not required to be updated foreach ($application in $applicationList) { $version = $appVersions.$($application.GUID) if ($global:AppFactoryLogging) { if ($null -eq $application.Version) { $reportVersion = "Not Packaged" } else { $reportVersion = $application.Version } Write-PSFMessage -Message "[$($application.IntuneAppName)] Checking current version <c='red'>$($reportVersion)</c> against new version <c='green'>$($version.version)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $version.version = Get-AppFactoryAppVersionNormalization -version $version.version # Set the default to false, and implicitly have to add to true to move on $packageApplication = $false if ($null -eq $application.Version -or $application.Version -eq "" -or [System.Version]$version.version -gt [System.Version]$application.Version) { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] <c='green'>Newer version exists for application</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)", "WinGet" -Target "Application Factory Service" } $packageApplication = $true } elseif ($force -eq $true) { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] <c='yellow'>Newer version does not exist for application, but flagged for override</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)", "WinGet" -Target "AppFactory" } $packageApplication = $true } # If we are meant to package, add a number of items to the object so that we have the required details if ($packageApplication) { $application | Add-Member -MemberType NoteProperty -Name 'AppSetupVersion' -Value $version.Version $application | Add-Member -MemberType NoteProperty -Name 'URI' -Value $version.URI $application | Add-Member -MemberType NoteProperty -Name 'FullPath' -Value $version.URI $application | Add-Member -MemberType NoteProperty -Name 'BlobName' -Value $(if ($null -ne $version.BlobName) { $version.BlobName } else { [string]::Empty }) $applications.Add($application) | Out-Null } else { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "<c='yellow'>[$($application.IntuneAppName)] Latest version of application is already published</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)", "WinGet" -Target "AppFactory" Write-PSFMessage -Message "<c='yellow'>[$($application.IntuneAppName)] Removing from application list</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)", "WinGet" -Target "AppFactory" } } } # Return the list of applications return $applications } #EndRegion '.\Public\Service_Public\Compare-AppFactoryAppVersionsPSU.ps1' 65 #Region '.\Public\Service_Public\Get-AppFactoryAppConfigurationPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to return the application configuration for a specific application .PARAMETER GUID The unique identifier for the application that we want to work with .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Get-AppFactoryAppConfigurationPSU{ [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$GUID, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) # Get the application that we are working with $application = Get-AppFactoryAppPSU -GUID $GUID -LogLevel $LogLevel if (-not ($application)) { throw "Application with GUID $($GUID) does not exist." } # Read the configuration file for the application and then return it $ApplicationJSONPath = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Apps" -AdditionalChildPath $application.AppFolderName,"App.json" $ApplicationJSON = Get-Content -Path $ApplicationJSONPath | ConvertFrom-Json -Depth 5 return $ApplicationJSON } #EndRegion '.\Public\Service_Public\Get-AppFactoryAppConfigurationPSU.ps1' 26 #Region '.\Public\Service_Public\Get-AppFactoryAppInstallPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to return the application install configuration .PARAMETER GUID The unique identifier for the application that we want to work with .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Get-AppFactoryAppInstallPSU { [CmdletBinding()] [OutputType([Hashtable])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$GUID, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) # Get the application that we will be working with $application = Get-AppFactoryAppPSU -GUID $GUID -LogLevel $LogLevel if (-not ($application)) { throw "Application with GUID $($GUID) does not exist." } # Read the deploy-application.ps1 file $ApplicationDeploymentFilePath = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Apps" -AdditionalChildPath $application.AppFolderName, "Deploy-Application.ps1" try { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Reading application deployment file" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationDeploymentFile = Get-Content -Path $ApplicationDeploymentFilePath } catch { Write-PSFMessage -Message "Error Encountered: $($_)" -Level "Error" -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" throw $_ } # Filter out to determine what type of the install is $type = ([Regex]::Match($ApplicationDeploymentFile, "#{3}INSTALLTYPE:(.+?)#{3}")).groups[1].value # Find if we have any processes that we check for at the beginning of the process $preStart = [Regex]::Match($ApplicationDeploymentFile, "###INSTALL:PRESTART###(.*)###INSTALL:PREEND###").groups[1].value $postStart = [Regex]::Match($ApplicationDeploymentFile, "###INSTALL:POSTSTART###(.*)###INSTALL:POSTEND###").groups[1].value $mainSection = [Regex]::Match($ApplicationDeploymentFile, "###INSTALLCMDSTART###(.*)###INSTALLCMDEND###").groups[1].value $beginstopProcess = ([Regex]::Matches($preStart, "(Get-Process -Name `"(.+?)`" | Stop-Process -Force)").Groups.Value | Where-Object { $_ -notlike "Get-Process*" -and $_ -notlike "*Stop-Process -Force" -and $_ -ne "" } | Sort-Object -Unique) -join "," $afterstopProcess = ([Regex]::Matches($postStart, "(Get-Process -Name `"(.+?)`" | Stop-Process -Force)").Groups.Value | Where-Object { $_ -notlike "Get-Process*" -and $_ -notlike "*Stop-Process -Force" -and $_ -ne "" } | Sort-Object -Unique) -join "," $installer = [Regex]::Match($mainSection, "\`$installer = `"(.+?)`"").groups[1].value if([Regex]::Match($mainSection, "\`$Parameters = `"`"").Success){ $Parameters = "" } else{ $Parameters = [Regex]::Match($mainSection, "\`$Parameters = `"(.+?)`"").groups[1].value } $ignoreExit = [Regex]::Match($mainSection, "-IgnoreExitCodes `"(.+?)`"").groups[1].value $mst = [Regex]::Match($mainSection, "\`$mstInstall = `"(.+?)`"").groups[1].value if ($type -eq "CUSTOM") { $startLine = $ApplicationDeploymentFile | Select-String -Pattern "###INSTALLCMDSTART###" $endLine = $ApplicationDeploymentFile | Select-String -Pattern "###INSTALLCMDEND###" $script = $ApplicationDeploymentFile[($ApplicationDeploymentFile.indexOf($startLine) + 1) .. ($ApplicationDeploymentFile.indexOf($endLine) - 1)] } $installCommands = @{ Type = $type beginstopProcess = $beginstopProcess afterstopProcess = $afterstopProcess installer = $installer Parameters = $Parameters ignoreExit = $ignoreExit WIM = [Regex]::Match($mainSection, "Mount-WindowsImage -ImagePath \`$wimPath").Success mst = $mst script = $script } return $installCommands } #EndRegion '.\Public\Service_Public\Get-AppFactoryAppInstallPSU.ps1' 68 #Region '.\Public\Service_Public\Get-AppFactoryAppOrgConfigPSU.ps1' 0 function Get-AppFactoryAppOrgConfigPSU{ [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$clientGUID, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$appGUID ) $configFile = Join-Path -Path $global:AppFactorySourceDir -ChildPath "DSBConfigurations" -AdditionalChildPath $clientGUID,"$($appGUID).json" if(-not (Test-Path $configFile)){ $configFile = Join-Path -Path $global:AppFactorySupportTemplateFolder -ChildPath "AppConfig.json" } $config = Get-Content -Path $configFile | ConvertFrom-JSON return $config } #EndRegion '.\Public\Service_Public\Get-AppFactoryAppOrgConfigPSU.ps1' 14 #Region '.\Public\Service_Public\Get-AppFactoryAppPSU.ps1' 0 <# .DESCRIPTION This cmdlet returns a list of applications that are part of the packaging process .PARAMETER appSource This is a filtering parameter for specific appsources .PARAMETER GUID The unique identifier for the application that we want to work with .PARAMETER IntuneAppName The unique name of the application that we want to work with .PARAMETER AppID This is a filtering parameter for specific AppID .PARAMETER AppPublisher This is a filtering parameter for specific application publisher .PARAMETER AppFolderName This is a filtering parameter for specific application folder .PARAMETER StorageAccountContainerName This is a filtering parameter for specific application azure storage container .PARAMETER archiveType This is a filtering parameter for specific application archive types .PARAMETER publishTo This is a filtering parameter for specific organization .PARAMETER public This is a filtering parameter for all public applications .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. .EXAMPLE Get a list of all applications Get-AppFactoryApp Get a list of specific application sources Get-AppFactoryApp -appSource "### Application Source ###" Get a list of applications based on GUID Get-AppFactoryApp -GUID "### GUID ###" Get a list of applications based on AppID Get-AppFactoryApp -AppID "### AppID ###" Get a list of applications based on Application Publisher Get-AppFactoryApp -AppPublisher "### Publisher ###" Get a list of applications based on Application Folder Name Get-AppFactoryApp -AppFolderName "### Folder Name ###" Get a list of applications based on Storage Account Container Name Get-AppFactoryApp -StorageAccountContainerName "### Container Name ###" Get a list of applications based on Archive Type Get-AppFactoryApp -archiveType "### Archive Type ###" Get a list of applications based on Publish To Get-AppFactoryApp -publishTo "### Organization ###" Get a list of all public applications Get-AppFactoryApp -public Get a list of all application with logging enabled Get-AppFactoryApp -LogLevel "Output" #> function Get-AppFactoryAppPSU{ [CmdletBinding(DefaultParameterSetName = 'All')] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter()][ValidateSet("Evergreen","Winget","StorageAccount","Sharepoint","PSADT","ECNO")][string]$appSource, [Parameter(ParameterSetName = 'GUID')][ValidateNotNullOrEmpty()][string]$GUID, [Parameter(ParameterSetName = 'IntuneAppName')][ValidateNotNullOrEmpty()][string]$IntuneAppName, [Parameter(ParameterSetName = 'AppID')][ValidateNotNullOrEmpty()][string]$AppID, [Parameter()][ValidateNotNullOrEmpty()][string]$AppPublisher, [Parameter()][ValidateNotNullOrEmpty()][string]$AppFolderName, [Parameter()][ValidateNotNullOrEmpty()][string]$StorageAccountContainerName, [Parameter()][ValidateSet("WIM","7Z","ZIP","MSIZIP","EXEZIP","PSZIP",$null)][string]$archiveType, [Parameter()][ValidateNotNullOrEmpty()][string]$publishTo, [Parameter()][switch]$public, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) # Get the path to where the application configs are stored $applicationFolders = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Apps" if($global:AppFactoryLogging){ Write-PSFMessage -Message "Getting Applications at path <c='green'>$($applicationFolders)</c>" -Level $LogLevel -Tag "Application" -Target "Application Factory Service" } # Get a list of all the configuration files for the applications $ApplicationConfigFiles = Get-Childitem -Path $applicationFolders -Recurse -Filter "config.json" # Create an empty array to store the application objects $applicaitonList = [System.Collections.Generic.List[PSCustomObject]]@() # Perform any needed filtering based on passed variables foreach($file in $ApplicationConfigFiles){ $json = Get-Content $file.FullName | ConvertFrom-Json # If specific parameters are passed, filter the list of applications based on those parameters if($GUID -and $json.GUID -ne $GUID){continue} if($appSource -and $json.appSource -ne $appSource){continue} if($IntuneAppName -and $json.IntuneAppName -notlike "$($IntuneAppName)"){continue} if($AppID -and $json.AppID -ne $AppID){continue} if($AppPublisher -and $json.AppPublisher -ne $AppPublisher){continue} if($AppFolderName -and $json.AppFolderName -ne $AppFolderName){continue} if($StorageAccountContainerName -and $json.StorageAccountContainerName -ne $StorageAccountContainerName){continue} if($archiveType -and $json.archiveType -ne $archiveType){continue} if($publishTo -and $publishTo -notin $json.publishTo){continue} if($public -and $json.publishTo.count -ne 0){continue} if($global:AppFactoryLogging){ Write-PSFMessage -Message "Reading Application: <c='green'>$($json.IntuneAppName) ($($json.GUID))</c>"-Level $LogLevel -Tag "Application","$($json.IntuneAppName)" -Target "Application Factory Service" } $applicaitonList.Add($json) | Out-Null } # Return the application list return $applicaitonList } #EndRegion '.\Public\Service_Public\Get-AppFactoryAppPSU.ps1' 109 #Region '.\Public\Service_Public\Get-AppFactoryAppUninstallPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to return the application uninstall configuration .PARAMETER GUID The unique identifier for the application that we want to work with .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Get-AppFactoryAppUninstallPSU { [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$GUID, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) # Get the application that we will be working with $application = Get-AppFactoryAppPSU -GUID $GUID -LogLevel $LogLevel if (-not ($application)) { throw "Application with GUID $($GUID) does not exist." } # Read the deploy-application.ps1 file $ApplicationDeploymentFilePath = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Apps" -AdditionalChildPath $application.AppFolderName, "Deploy-Application.ps1" try { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Reading application deployment file" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationDeploymentFile = Get-Content -Path $ApplicationDeploymentFilePath } catch { Write-PSFMessage -Message "Error Encountered: $($_)" -Level "Error" -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" throw $_ } # Filter out to determine what type of the install is $type = ([Regex]::Match($ApplicationDeploymentFile, "#{3}UNINSTALLTYPE:(.+?)#{3}")).groups[1].value # Find if we have any processes that we check for at the beginning of the process $preStart = [Regex]::Match($ApplicationDeploymentFile, "###UNINSTALL:PRESTART###(.*)###UNINSTALL:PREEND###").groups[1].value $postStart = [Regex]::Match($ApplicationDeploymentFile, "###UNINSTALL:POSTSTART###(.*)###UNINSTALL:POSTEND###").groups[1].value $mainSection = [Regex]::Match($ApplicationDeploymentFile, "###UNINSTALLCMDSTART###(.*)###UNINSTALLCMDEND###").groups[1].value $beginstopProcess = ([Regex]::Matches($preStart, "(Get-Process -Name `"(.+?)`" | Stop-Process -Force)").Groups.Value | Where-Object { $_ -notlike "Get-Process*" -and $_ -notlike "*Stop-Process -Force" -and $_ -ne "" } | Sort-Object -Unique) -join "," $afterstopProcess = ([Regex]::Matches($postStart, "(Get-Process -Name `"(.+?)`" | Stop-Process -Force)").Groups.Value | Where-Object { $_ -notlike "Get-Process*" -and $_ -notlike "*Stop-Process -Force" -and $_ -ne "" } | Sort-Object -Unique) -join "," $installer = [Regex]::Match($mainSection, "\`$installer = `"(.+?)`"").groups[1].value if ([Regex]::Match($mainSection, "\`$Parameters = `"`"").Success) { $Parameters = "" } else { $Parameters = [Regex]::Match($mainSection, "\`$Parameters = `"(.+?)`"").groups[1].value } $ignoreExit = [Regex]::Match($mainSection, "-IgnoreExitCodes `"(.+?)`"").groups[1].value $name = [Regex]::Match($mainSection, "Remove-MSIApplications -Name `"(.+?)`"").groups[1].value $MSIGUID = [Regex]::Match($mainSection, "Execute-MSI -Action `"Uninstall`" -Path `"(.+?)`"").groups[1].value if ($type -eq "CUSTOM") { $startLine = $ApplicationDeploymentFile | Select-String -Pattern "###UNINSTALLCMDSTART###" $endLine = $ApplicationDeploymentFile | Select-String -Pattern "###UNINSTALLCMDEND###" $script = $ApplicationDeploymentFile[($ApplicationDeploymentFile.indexOf($startLine) + 1) .. ($ApplicationDeploymentFile.indexOf($endLine) - 1)] } $uninstallCommands = @{ Type = $type beginstopProcess = $beginstopProcess afterstopProcess = $afterstopProcess installer = $installer Parameters = $Parameters ignoreExit = $ignoreExit WIM = [Regex]::Match($mainSection, "Mount-WindowsImage -ImagePath \`$wimPath").Success Name = $name MSIGUID = $MSIGUID dirFiles = [Regex]::Match($mainSection, "\`$\(\`$dirFiles\)").Success script = $script } return $uninstallCommands } #EndRegion '.\Public\Service_Public\Get-AppFactoryAppUninstallPSU.ps1' 70 #Region '.\Public\Service_Public\Get-AppFactoryInstallerPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to download the app installers that we will be packaging from their appropriate sources .PARAMETER applicationList The collection of the applications that we will be acting on .PARAMETER multithread Show we proceed single threaded or multithreaded .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Get-AppFactoryInstallerPSU { [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[PSCustomObject]]$applicationList, [Parameter()][ValidateNotNullOrEmpty()][switch]$multithread, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) # Create list to store results of the process $applications = [System.Collections.Generic.List[PSCustomObject]]@() # Connect to Azure Storage Context $appStorageContext = Connect-AppFactoryAzureStoragePSU -storageContainer $global:AppFactoryInstallersContainer -storageSecret $global:AppFactoryInstallersSecret -LogLevel $LogLevel # Details to conect to Sharepoint if required $pfxPath = Join-Path -Path $global:AppFactoryLocalSupportFiles -ChildPath $global:AppFactorySharepointCertificate $sharepointConfig = @{ "url" = $global:AppFactorySharrepointURL "CertificatePath" = $pfxPath "CertificatePassword" = $global:AppFactorySharepointCertificateSecret.Password "ClientId" = $global:AppFactorySharepointClientID "Tenant" = $global:AppFactorySharepointTenant } if (-not $multithread.IsPresent) { try { Connect-PnPOnline @sharepointConfig } catch {} foreach ($application in $applicationList) { try { $AppSetupFolderPath = Get-AppFactoryInstallerFilesPSU -application $application -appStorageContext $appStorageContext -workspace $global:AppFactoryWorkspace -supportFiles $global:AppFactorySupportFiles -LogLevel $LogLevel $application | Add-Member -MemberType NoteProperty -Name 'AppSetupFolderPath' -Value $AppSetupFolderPath $applications.add($application) | Out-Null } catch { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "<c='yellow'>[$($application.IntuneAppName)] Unable to download application files</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)", "Error" -Target "Application Factory Service" Write-PSFMessage -Message "<c='yellow'>[$($application.IntuneAppName)] Removing from application list</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)", "Error" -Target "Application Factory Service" Write-PSFMessage -Message "Error Encountered: $($_)" -Level "Error" -Tag "Application", "$($application.IntuneAppName)", "Error" -Target "Application Factory Service" } throw $_ } } } else { $applist = [hashtable]::Synchronized(@{}) if ($global:LocalModulePath) { $modulePath = $global:LocalModulePath } else { $modulePath = (Get-module ApplicationFactoryService).path } $applicationList | Foreach-Object -Parallel { Import-Module -Name $using:modulePath -Force $application = $_ $dict = $using:applist $appStorageContext = $using:appStorageContext $LogLevel = $using:LogLevel $global:AppFactoryLogging = $using:script:AppFactoryLogging $global:AppFactoryWorkspace = $using:script:AppFactoryWorkspace $global:AppFactorySupportFiles = $using:script:AppFactorySupportFiles if ($application.AppSource -eq "Sharepoint") { Connect-PnPOnline @using:sharepointConfig } try { $AppSetupFolderPath = Get-AppFactoryInstallerFilesPSU -application $application -appStorageContext $appStorageContext -workspace $global:AppFactoryWorkspace -supportFiles $global:AppFactorySupportFiles -LogLevel $LogLevel $obj = [PSCustomObject]@{ "Status" = "Downloaded" "Error" = "" "AppSetupFolderPath" = $AppSetupFolderPath } $dict.add($application.GUID, $obj) } catch { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "<c='yellow'>[$($application.IntuneAppName)] Unable to download application files</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)", "Error" -Target "AppFactory" Write-PSFMessage -Message "<c='yellow'>[$($application.IntuneAppName)] Removing from application list</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)", "Error" -Target "AppFactory" } } } 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 'AppSetupFolderPath' -Value $item.Value.AppSetupFolderPath $applications.Add($application) | Out-Null } } } return $applications } #EndRegion '.\Public\Service_Public\Get-AppFactoryInstallerPSU.ps1' 98 #Region '.\Public\Service_Public\Get-AppFactoryOrganizationPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to list out the organizations that are configured .PARAMETER GUID The unique identifer for the specific organization .PARAMETER Name Get an organization based on the name .PARAMETER Contact Get organizations that have a specific contact .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. .EXAMPLE Get all organizations Get-AppFactoryOrganization Get specific organization by GUID Get-AppFactoryOrganization -GUID "### GUID ###" Get specific organization by Name Get-AppFactoryOrganization -Name "### Organization Name ###" Get specific organization by Contact Get-AppFactoryOrganization -Contact "### Contact Name ###" #> function Get-AppFactoryOrganizationPSU { [CmdletBinding(DefaultParameterSetName = 'All')] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $false, ParameterSetName = 'GUID')][ValidateNotNullOrEmpty()][string]$GUID, [Parameter(Mandatory = $false, ParameterSetName = 'Name')][ValidateNotNullOrEmpty()][string]$Name, [Parameter(Mandatory = $false, ParameterSetName = 'Contacts')][ValidateNotNullOrEmpty()][string]$Contact, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) # Organization Folder Path $orgainizationFolder = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Organizations" if ($global:AppFactoryLogging) { Write-PSFMessage -Message "Reading organization files in path $($orgainizationFolder)" -Level $LogLevel -Tag "Organizations" -Target "Application Factory Service" } # Get list of organizational configuration files $organizationConfigs = Get-Childitem -Path $orgainizationFolder # Create list that we will return with the organizational configurations $orgList = [System.Collections.Generic.List[PSCustomObject]]@() foreach ($file in $organizationConfigs) { # Read the organizational file $json = Get-Content $file.FullName | ConvertFrom-Json if ($GUID -and $json.GUID -ne $GUID) { continue } # If Name is set, match the name variable. if ($Name -and $json.Name -notlike "$($Name)") { continue } # If Contact is set, match entries that have that contact if ($Contact -and $Json.Contacts.indexOf($contact) -eq -1) { continue } if ($global:AppFactoryLogging) { Write-PSFMessage -Message "Reading organization file $($file)" -Level $LogLevel -Tag "Organizations", "$($json.Name)" -Target "Application Factory Service" } # Add the path to the file for specific organization $json | Add-Member -MemberType "NoteProperty" -Name "FileName" -Value $file.Name $orgList.Add($json) | Out-Null } # Return the organiation list return $orgList } #EndRegion '.\Public\Service_Public\Get-AppFactoryOrganizationPSU.ps1' 62 #Region '.\Public\Service_Public\Get-AppFactoryOrganizationsAppListPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to list out the applications that are available to a specific organization. .PARAMETER organization The unique identifer for the specific organization .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Get-AppFactoryOrganizationsAppListPSU{ [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$clientGUID, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) # Blank List for the Apps $applicaitonList = [System.Collections.Generic.List[PSCustomObject]]@() if($global:AppFactoryLogging){ Write-PSFMessage -Message "Getting Applications for $($clientGUID)" -Level $LogLevel -Tag "Application","Organization" -Target "Application Factory Service" Write-PSFMessage -Message "Getting Applications at path $($applicationFolders)" -Level $LogLevel -Tag "Application","Organization" -Target "Application Factory Service" } # Read DSB Configuration Files $dsbConfigPath = Join-Path -Path $global:AppFactorySourceDir -ChildPath "DSBConfigurations" -AdditionalChildPath $clientGUID $dsbConfigFiles = Get-ChildItem -Path $dsbConfigPath -File -Filter "*.json" -ErrorAction SilentlyContinue # Get all applications that are set as public i.e. no specific organization $publicApps = Get-AppFactoryAppPSU -public -LogLevel $LogLevel foreach($app in $publicApps){ if($null -eq $app.Version){continue} if($global:AppFactoryLogging){ Write-PSFMessage -Message "Adding application to app list: <c='green'>$($app.IntuneAppName) ($($app.GUID))</c>" -Level $LogLevel -Tag "Application","Organization" -Target "Application Factory Service" } $appConfigFile = $dsbConfigFiles | Where-Object {$_.name -eq "$($app.GUID).json"} if($appConfigFile){ $obj = Get-Content -Path $appConfigFile | ConvertFrom-JSON -Depth 5 $obj | Add-Member -MemberType NoteProperty -Name "GUID" -Value $app.GUID $obj | Add-Member -MemberType NoteProperty -Name "IntuneAppName" -Value $app.IntuneAppName $obj | Add-Member -MemberType NoteProperty -Name "AppVersion" -Value $app.version $obj | Add-Member -MemberType NoteProperty -Name "container" -Value $global:AppFactoryPublicFolder } else{ $obj = [PSCustomObject]@{ "AddToIntune" = $false "AvailableAssignments" = @() "AvailableExceptions" = @() "RequiredAssignments" = @() "RequiredExceptions" = @() "UninstallAssignments" = @() "UninstallExceptions" = @() "UnassignPrevious" = $true "CopyPrevious" = $true "KeepPrevious" = 0 "foreground" = $false "filters" = "" "espprofiles" = @() "container" = $global:AppFactoryPublicFolder "GUID" = $app.GUID "IntuneAppName" = $app.IntuneAppName "AppVersion" = $app.version "InteractiveInstall" = $false "InteractiveUninstall" = $false } } $applicaitonList.Add($obj) | Out-Null } # Get all applications that are set to be published to a specific organization $orgApps = Get-AppFactoryAppPSU -publishTo $clientGUID foreach($app in $orgApps){ if($null -eq $app.Version){continue} if($global:AppFactoryLogging){ Write-PSFMessage -Message "Adding application to app list: <c='green'>$($app.IntuneAppName) ($($app.GUID))</c>" -Level $LogLevel -Tag "Application","Organization" -Target "Application Factory Service" } $appConfigFile = $dsbConfigFiles | Where-Object {$_.name -eq "$($app.GUID).json"} if($appConfigFile){ $obj = Get-Content -Path $appConfigFile | ConvertFrom-JSON -Depth 5 $obj | Add-Member -MemberType NoteProperty -Name "GUID" -Value $app.GUID $obj | Add-Member -MemberType NoteProperty -Name "IntuneAppName" -Value $app.IntuneAppName $obj | Add-Member -MemberType NoteProperty -Name "AppVersion" -Value $app.version $obj | Add-Member -MemberType NoteProperty -Name "container" -Value "organization" } else{ $obj = [PSCustomObject]@{ "AddToIntune" = $false "AvailableAssignments" = @() "AvailableExceptions" = @() "RequiredAssignments" = @() "RequiredExceptions" = @() "UninstallAssignments" = @() "UninstallExceptions" = @() "UnassignPrevious" = $true "CopyPrevious" = $true "KeepPrevious" = 0 "foreground" = $false "filters" = "" "espprofiles" = @() "container" = "organization" "GUID" = $app.GUID "IntuneAppName" = $app.IntuneAppName "AppVersion" = $app.version "InteractiveInstall" = $false "InteractiveUninstall" = $false } } $applicaitonList.Add($obj) | Out-Null } # Return the list of the applications return $applicaitonList } #EndRegion '.\Public\Service_Public\Get-AppFactoryOrganizationsAppListPSU.ps1' 108 #Region '.\Public\Service_Public\New-AppFactoryAppPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to create a new application to be handled by the automated process .PARAMETER Name The name of the application that we are creating .PARAMETER AppSource The source for the application files that will be used .PARAMETER InformationURL The URL for more info for the application .PARAMETER PrivacyURL The URL for privacy information for the application .PARAMETER publishTo The list of organizations that this should be published to if not public .PARAMETER force Continue even if the folder already exists, overwriting the current details .PARAMETER archiveType If the download for the installer is in a archive of some form .PARAMETER filterOptions Filter options for evergreen based applications .PARAMETER appSetupName The application setup name that is used to run the install .PARAMETER storageContainerName The storage container holding the installer files for azure based installs .PARAMETER appID The application id used in evergreen and winget install process .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. .EXAMPLE Create a new application that is based on an azure storage account $parameters = @{ Name = "### Name ###" Publisher = "### Publisher ###" AppSource = "StorageAccount" InformationURL = "### URL ###" PrivacyURL = "### URL ###" appSetupName = "### Setup Name ###" storageContainerName = "### Container Name ###" LogLevel = "Output" } New-AppFactoryApp @parameters Create a new application that is based on a sharepoint folder $parameters = @{ Name = "### Name ###" Publisher = "### Publisher ###" AppSource = "Sharepoint" InformationURL = "### URL ###" PrivacyURL = "### URL ###" appSetupName = "### Setup Name ###" LogLevel = "Output" } New-AppFactoryApp @parameters Create a new application that is based on a evergreen source $parameters = @{ Name = "### Name ###" Publisher = "### Publisher ###" AppSource = "Evergreen" InformationURL = "### URL ###" PrivacyURL = "### URL ###" filterOptions = @{} appID = "### App ID ###" appSetupName = "### Setup Name ###" LogLevel = "Output" } New-AppFactoryApp @parameters Create a new application that is based on a winget source $parameters = @{ Name = "### Name ###" Publisher = "### Publisher ###" AppSource = "Winget" InformationURL = "### URL ###" PrivacyURL = "### URL ###" appID = "### App ID ###" appSetupName = "### Setup Name ###" LogLevel = "Output" } New-AppFactoryApp @parameters Create a new application that is based on PSADT $parameters = @{ Name = "### Name ###" Publisher = "### Publisher ###" AppSource = "PSADT" InformationURL = "### URL ###" PrivacyURL = "### URL ###" LogLevel = "Output" } New-AppFactoryApp @parameters Create an application that is based on an ECNO install $parameters = @{ Name = "### Name ###" Publisher = "### Publisher ###" AppSource = "ECNO" InformationURL = "### URL ###" PrivacyURL = "### URL ###" storageContainerName = "### Folder Name ###" LogLevel = "Output" } New-AppFactoryApp @parameters #> function New-AppFactoryAppPSU { [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateSet("StorageAccount", "Sharepoint", "Winget", "Evergreen", "PSADT", "ECNO")][String]$AppSource, [Parameter(Mandatory = $true)][string]$Name, [Parameter(Mandatory = $true)][string]$Publisher, [Parameter()][string]$InformationURL, [Parameter()][string]$PrivacyURL, [Parameter()][String[]]$publishTo = @(), [Parameter()][switch]$force, [Parameter()][ValidateSet("WIM", "7Z", "ZIP", "MSIZIP", "EXEZIP", "PSZIP", $null)][string]$archiveType = $null, [Parameter()][Hashtable]$filterOptions = @{}, [Parameter()][string]$appSetupName = $null, [Parameter()][string]$storageContainerName = $null, [Parameter()][string]$appID = $null, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($Name)] Creating application" -Level $LogLevel -Tag "Application", "$($Name)" -Target "Application Factory Service" } # Create the package folders for the application we are creating $appFolderPath = New-AppFactoryAppFolderPSU -Name $name -LogLevel $LogLevel -Force $force # Create the application configuration file for the application we are creating $ApplicationConfig = [PSCustomObject]@{ "GUID" = (New-GUID).Guid "IntuneAppName" = "STS-$($Name)" "AppPublisher" = $Publisher "InformationURL" = $InformationURL "PrivacyURL" = $PrivacyURL "AppSource" = $AppSource "AppID" = $appID "AppFolderName" = $Name "AppSetupFileName" = $appSetupName "StorageAccountContainerName" = $storageContainerName "archiveType" = $archiveType "FilterOptions" = $filterOptions "publishTo" = $publishTo "version" = $null } # Create the configuration for the application try{ if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($Name)] Writing default app configuration" -Level $LogLevel -Tag "Application","$($Name)" -Target "AppFactory" } $ApplicationConfigFile = Join-Path -Path $appFolderPath -ChildPath "config.json" $ApplicationConfig | ConvertTo-Json | Out-File -FilePath $ApplicationConfigFile } catch{ Write-PSFMessage -Message "Error Encountered: $($_)" -Level "Error" -Tag "Application", "$($Name)" -Target "Application Factory Service" throw $_ } } #EndRegion '.\Public\Service_Public\New-AppFactoryAppPSU.ps1' 158 #Region '.\Public\Service_Public\New-AppFactoryIntuneFilePSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to create a new application to be handled by the automated process .PARAMETER applicationList The collection of the applications that we will be acting on .PARAMETER multithread Show we proceed single threaded or multithreaded .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function New-AppFactoryIntuneFilePSU { [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[PSCustomObject]]$applicationList, [Parameter()][ValidateNotNullOrEmpty()][switch]$multithread, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) # List of objects and their status through the process $applications = [System.Collections.Generic.List[PSCustomObject]]@() if (-not $multithread.IsPresent) { foreach ($application in $applicationList) { try { $app = New-AppFactoryIntuneWinPSU -application $application -LogLevel $LogLevel $applications.add($app) } catch { throw $_ } } } else { # Generate intune application file $applist = [hashtable]::Synchronized(@{}) if ($global:LocalModulePath) { $modulePath = $global:LocalModulePath } else { $modulePath = (Get-module ApplicationFactoryService).path } $applicationList | Foreach-Object -Parallel { Import-Module -Name $using:modulePath -Force try { $application = $_ $dict = $using:applist $global:AppFactoryLogging = $using:script:AppFactoryLogging $LogLevel = $using:LogLevel $app = New-AppFactoryIntuneWinPSU -application $application -LogLevel $LogLevel $obj = [PSCustomObject]@{ "Status" = "Good" "Application" = $app "Error" = $null } $dict.add($application.GUID, $obj) } catch { $obj = [PSCustomObject]@{ "Status" = "Fail" "AppPublishFolderPath" = $null "Error" = $_ } $dict.add($application.GUID, $obj) } } foreach ($item in $applist.GetEnumerator()) { if ($item.Value.status -eq "Good") { $applications.Add($item.Value.Application) | Out-Null } } } return $applications } #EndRegion '.\Public\Service_Public\New-AppFactoryIntuneFilePSU.ps1' 73 #Region '.\Public\Service_Public\New-AppFactoryOrganizationPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to create a new organization .PARAMETER name The name of the organization .PARAMETER contactList The list of contacts for the organization .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. .EXAMPLE Create a new organization New-AppFactoryOrganization -name "### Organization Name ###" Create a new organization with contacts New-AppFactoryOrganization -name "### Organization Name ###" -contactList "### Contact 1 ###", "### Contact 2 ###" #> function New-AppFactoryOrganizationPSU { [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$name, [Parameter()][string[]]$contactList = @(), [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) # Generate a unique GUID for organization $GUID = (New-GUID).Guid # Create the Organization file to write out $obj = [PSCustomObject]@{ "GUID" = $GUID "Name" = $name "Contacts" = $contactList } # Path for the new organization file $orgFile = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Organizations" -AdditionalChildPath "$($name).json" # Organization File Path if ($global:AppFactoryLogging) { Write-PSFMessage -Message "Creating organization GUID: <c='green'>$($GUID)</c>" -Level $LogLevel -Tag "Organizations", "$($Name)" -Target "Application Factory Service" Write-PSFMessage -Message "Organization file path: <c='green'>$($orgFile)</c>" -Level $LogLevel -Tag "Organizations", "$($Name)" -Target "Application Factory Service" } # First write out the organization json try { if (Test-Path -Path $orgFile) { throw "Organization already exists with this name." } $obj | ConvertTo-Json | Out-File -FilePath $orgFile -Force } catch { Write-PSFMessage -Message "Error Encountered: $($_)" -Level "Error" -Tag "Organizations" -Target "Application Factory Service" throw $_ } # Create Azure Storage Container to store organization specific applications try { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "Creating organization storage container $($GUID)" -Level $LogLevel -Tag "Organizations", "$($Name)" -Target "AppFactory" } $orgStorageContainerContext = Connect-AppFactoryAzureStoragePSU -storageContainer $global:AppFactoryDeploymentsContainer -storageSecret $global:AppFactoryDeploymentsSecret New-AzStorageContainer -Name $GUID -Permission Off -Context $orgStorageContainerContext | Out-Null } catch { Remove-Item -Path $orgFile -Force Write-PSFMessage -Message "Error Encountered: $($_)" -Level "Error" -Tag "Organizations" -Target "Application Factory Service" throw $_ } } #EndRegion '.\Public\Service_Public\New-AppFactoryOrganizationPSU.ps1' 66 #Region '.\Public\Service_Public\Publish-AppFactoryAppPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to publish the files that were created for the deployment .PARAMETER applicationList The collection of the applications that we will be acting on .PARAMETER multithread Show we proceed single threaded or multithreaded .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Publish-AppFactoryAppPSU{ [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[PSCustomObject]]$applicationList, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) # Create list for application status $applications = [System.Collections.Generic.List[PSCustomObject]]@() # Create azure storage context to use during the process $appStorageContext = Connect-AppFactoryAzureStoragePSU -storageContainer $global:AppFactoryDeploymentsContainer -storageSecret $global:AppFactoryDeploymentsSecret -LogLevel $LogLevel foreach($application in $applicationList){ try{ $app = Add-AppFactoryIntuneDeploymentPSU -application $application -appStorageContext $appStorageContext -AppFactoryPublicFolder $global:AppFactoryPublicFolder -LogLevel $LogLevel $applications.add($app) if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Published update for application" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } } catch{ throw $_ if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Failed to update application" -Level "Error" -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } } } return $applications } #EndRegion '.\Public\Service_Public\Publish-AppFactoryAppPSU.ps1' 39 #Region '.\Public\Service_Public\Remove-AppFactoryAppPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to remove an application from the process of packaging .PARAMETER GUID The unique identifier for the application that we want to work with .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Remove-AppFactoryAppPSU{ [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$GUID, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) #Get App Factory Information $application = Get-AppFactoryAppPSU -GUID $GUID -LogLevel $LogLevel if(-not ($application)){ throw "Application with GUID $($GUID) does not exist." } # Get the application folder $ApplicationFolder = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Apps" -AdditionalChildPath $application.AppFolderName if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($app.IntuneAppName)] Removing Configuration Files at path $($ApplicationFolder)" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } # Remove the folder try{ Remove-Item -Path $ApplicationFolder -Recurse -Force | Out-Null } catch{ Write-PSFMessage -Message "Error Encountered: $($_)" -Level "Error" -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" throw $_ } } #EndRegion '.\Public\Service_Public\Remove-AppFactoryAppPSU.ps1' 34 #Region '.\Public\Service_Public\Remove-AppFactoryOrganizationPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to remove an organization from the process of packaging .PARAMETER GUID The unique identifier for the organization that we want to work with .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. .EXAMPLE Remove an organization Remove-AppFactoryOrganization -GUID "### GUID ###" #> function Remove-AppFactoryOrganizationPSU{ [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$GUID, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) # Get Org Configuration Files $organization = Get-AppFactoryOrganizationPSU -GUID $GUID -LogLevel $LogLevel if ($null -eq $organization) { Write-PSFMessage -Message "Error Encountered: Organization not found." -Level "Error" -Tag "Organizations" -Target "Application Factory Service" throw "Organization not found." } if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($organization.Name)] Removing organization GUID: <c='green'>$($GUID)</c> with name <c='green'>$($organization.Name)</c>)" -Level $LogLevel -Tag "Organizations","$($organization.Name)" -Target "Application Factory Service" } try{ $orgStorageContainerContext = Connect-AppFactoryAzureStoragePSU -storageContainer $global:AppFactoryDeploymentsContainer -storageSecret $global:AppFactoryDeploymentsSecret if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($organization.Name)] Removing Azure Container" -Level $LogLevel -Tag "Organizations","$($organization.Name)" -Target "Application Factory Service" } # Remove Azure Storage Container Remove-AzStorageContainer -Name $GUID -Context $orgStorageContainerContext -Force -ErrorAction Stop if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($organization.Name)] Removing configuration file" -Level $LogLevel -Tag "Organizations","$($organization.Name)" -Target "Application Factory Service" } # Remove Configuration File. $fileName = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Organizations" -AdditionalChildPath $organization.fileName Remove-Item -Path $fileName -Force } catch{ Write-PSFMessage -Message "Error Encountered: $($_)" -Level "Error" -Tag "Organizations" -Target "Application Factory Service" throw $_ } } #EndRegion '.\Public\Service_Public\Remove-AppFactoryOrganizationPSU.ps1' 48 #Region '.\Public\Service_Public\Remove-AppFactoryWorkspaceFilesPSU.ps1' 0 function Remove-AppFactoryWorkspaceFilesPSU{ [CmdletBinding()] param( [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) Write-PSFMessage -Message "[Application Factory Service] Cleaning up workspace folders <c='green'>$($global:AppFactoryWorkspace)</c>" -Level $LogLevel -Tag "Organizations","$($organization.Name)" -Target "Application Factory Service" if(Test-Path -Path $global:AppFactoryWorkspace){ Remove-Item -Path $global:AppFactoryWorkspace -Force -Recurse } } #EndRegion '.\Public\Service_Public\Remove-AppFactoryWorkspaceFilesPSU.ps1' 11 #Region '.\Public\Service_Public\Set-AppFactoryAppConfigurationPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to update the confirmation files for an application .PARAMETER GUID The unique identifier for the application that we want to work with .PARAMETER Description The description of the application .PARAMETER Notes Any notes for the application .PARAMETER Owner Who is the owner of the application .PARAMETER InstallExperience Who is the owner of the application .PARAMETER DeviceRestartBehavior What the device should do on restart .PARAMETER AllowAvailableUninstall If should be available to uninstall in company portal if installed as available .PARAMETER MinimumSupportedWindowsRelease Minimum version of windows supported .PARAMETER Architecture Required OS architecture .PARAMETER IntuneAppName Application name .PARAMETER AppPublisher Application Publisher of the application .PARAMETER InformationURL Info URL for more application information .PARAMETER PrivacyURL Privacy URL for more application privacy information .PARAMETER AppSource Where the application files are being sourced from .PARAMETER AppID AppID used in winget and evergreen processes .PARAMETER AppSetupFileName The setup file that will be run as part of the install .PARAMETER StorageAccountContainerName The storage container that the installers are stored in for azure based process .PARAMETER archiveType If the file downloaded is an archive and needs to be treated as such .PARAMETER FilterOptions Filter options for evergreen applications .PARAMETER publishTo What organizations should be published for .PARAMETER version Version of the application .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Set-AppFactoryAppConfigurationPSU { [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$GUID, [Parameter()][string]$Description, [Parameter()][string]$Notes, [Parameter()][string]$Owner, [Parameter()][ValidateSet("system", "user")][string]$InstallExperience, [Parameter()][ValidateSet("suppress", "force", "basedOnReturnCode", "allow")][string]$DeviceRestartBehavior, [Parameter()][ValidateSet("true", "false")][string]$AllowAvailableUninstall, [Parameter()][ValidateSet("W10_1607", "W10_1703", "W10_1709", "W10_1809", "W10_1909", "W10_2004", "W10_20H2", "W10_21H1", "W10_21H2", "W10_22H2", "W11_21H2", "W11_22H2")][string]$MinimumSupportedWindowsRelease, [Parameter()][ValidateSet("All", "x64", "x86")][string]$Architecture, [Parameter()][ValidateNotNullOrEmpty()][string]$IntuneAppName, [Parameter()][ValidateNotNullOrEmpty()][string]$AppPublisher, [Parameter()][string]$InformationURL, [Parameter()][string]$PrivacyURL, [Parameter()][ValidateSet("StorageAccount", "Evergreen", "PSADT", "Sharepoint", "Winget","ECNO")][string]$AppSource, [Parameter()][string]$AppID, [Parameter()][string]$AppSetupFileName, [Parameter()][string]$StorageAccountContainerName, [Parameter()][ValidateSet("WIM", "7Z", "ZIP", "MSIZIP", "EXEZIP", "PSZIP", $null)][string]$archiveType, [Parameter()][Hashtable]$FilterOptions, [Parameter()][string[]]$publishTo, [Parameter()][string]$version, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) # Check if the application that we are trying to update actually exist $application = Get-AppFactoryAppPSU -GUID $GUID -LogLevel $LogLevel if (-not ($application)) { throw "Application with GUID $($GUID) does not exist." } # Get Config File paths that might need to be updated $ApplicationJSONPath = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Apps" -AdditionalChildPath $application.AppFolderName, "App.json" $ApplicationConfigPath = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Apps" -AdditionalChildPath $application.AppFolderName, "Config.json" if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Reading current <c='green'>$($ApplicationJSONPath)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" Write-PSFMessage -Message "[$($application.IntuneAppName)] Reading current <c='green'>$($ApplicationConfigPath)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } try { $ApplicationJSON = Get-Content -Path $ApplicationJSONPath | ConvertFrom-Json -Depth 5 $ApplicationConfig = Get-Content -Path $ApplicationConfigPath | ConvertFrom-Json -Depth 5 } catch { Write-PSFMessage -Message "Error Encountered: $($_)" -Level "Error" -Tag "Organizations" -Target "Application Factory Service" throw $_ } # What files have we updated $ApplicationJSONUpdated = $false $ApplicationConfigUpdated = $false switch ($PSBoundParameters.Keys) { "Description" { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating - Description - <c='green'>$($Description)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationJSON.Information.Description = $Description $ApplicationJSONUpdated = $true } "Notes" { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating - Notes - <c='green'>$($Notes)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationJSON.Information.Notes = $Notes $ApplicationJSONUpdated = $true } "Owner" { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating - Owner - <c='green'>$($Owner)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationJSON.Information.Owner = $Owner $ApplicationJSONUpdated = $true } "InstallExperience" { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating - Install Experience - <c='green'>$($InstallExperience)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationJSON.Program.InstallExperience = $InstallExperience $ApplicationJSONUpdated = $true } "DeviceRestartBehavior" { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating - Device Restart Behaviour - <c='green'>$($DeviceRestartBehavior)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationJSON.Program.DeviceRestartBehavior = $DeviceRestartBehavior $ApplicationJSONUpdated = $true } "AllowAvailableUninstall" { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating - Allow Available Uninstall - <c='green'>$($AllowAvailableUninstall)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationJSON.Program.AllowAvailableUninstall = $AllowAvailableUninstall $ApplicationJSONUpdated = $true } "MinimumSupportedWindowsRelease" { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating - Minimum Supported WIndows - <c='green'>$($MinimumSupportedWindowsRelease)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationJSON.RequirementRule.MinimumSupportedWindowsRelease = $MinimumSupportedWindowsRelease $ApplicationJSONUpdated = $true } "Architecture" { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating - Architecture - <c='green'>$($Architecture)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationJSON.RequirementRule.Architecture = $Architecture $ApplicationJSONUpdated = $true } "IntuneAppName" { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating - IntuneAppName - <c='green'>$($IntuneAppName)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationConfig.IntuneAppName = $IntuneAppName $ApplicationConfigUpdated = $true } "AppPublisher" { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating - AppPublisher - <c='green'>$($AppPublisher)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationConfig.AppPublisher = $AppPublisher $ApplicationConfigUpdated = $true } "InformationURL" { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating - InformationURL - <c='green'>$($InformationURL)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationConfig.InformationURL = $InformationURL $ApplicationConfigUpdated = $true } "PrivacyURL" { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating - PrivacyURL - <c='green'>$($PrivacyURL)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationConfig.PrivacyURL = $PrivacyURL $ApplicationConfigUpdated = $true } "AppSource" { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating - AppSource - <c='green'>$($AppSource)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationConfig.AppSource = $AppSource $ApplicationConfigUpdated = $true } "AppID" { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating - AppID - <c='green'>$($AppID)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationConfig.AppID = $AppID $ApplicationConfigUpdated = $true } "AppSetupFileName" { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating - AppSetupFileName - <c='green'>$($AppSetupFileName)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationConfig.AppSetupFileName = $AppSetupFileName $ApplicationConfigUpdated = $true } "StorageAccountContainerName" { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating - StorageAccountContainerName - <c='green'>$($StorageAccountContainerName)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationConfig.StorageAccountContainerName = $StorageAccountContainerName $ApplicationConfigUpdated = $true } "archiveType" { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating - archiveType - <c='green'>$($archiveType)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationConfig.archiveType = $archiveType $ApplicationConfigUpdated = $true } "FilterOptions" { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating - FilterOptions - <c='green'>$($FilterOptions)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationConfig.FilterOptions = $FilterOptions $ApplicationConfigUpdated = $true } "publishTo" { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating - publishTo - <c='green'>$($publishTo)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationConfig.publishTo = $publishTo $ApplicationConfigUpdated = $true } "version" { if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating - version - <c='green'>$($version)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationConfig.version = $version $ApplicationConfigUpdated = $true } } try{ if($ApplicationJSONUpdated){ if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating App.JSON file $($ApplicationJSONPath)" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationJSON | ConvertTo-Json | Out-File -FilePath $ApplicationJSONPath } if($ApplicationConfigUpdated){ if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($app.IntuneAppName)] Updating Config.JSON file $($ApplicationConfigPath)" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } $ApplicationConfig | ConvertTo-Json | Out-File -FilePath $ApplicationConfigPath } } catch{ Write-PSFMessage -Message "Error Encountered: $($_)" -Level "Error" -Tag "Application", "$($Name)" -Target "Application Factory Service" throw $_ } } #EndRegion '.\Public\Service_Public\Set-AppFactoryAppConfigurationPSU.ps1' 259 #Region '.\Public\Service_Public\Set-AppFactoryAppDetectionRulePSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to update the detection rule for an application .PARAMETER GUID The unique identifier for the application that we want to work with .PARAMETER Type The type of detection that we will be doing .PARAMETER ProductVersionOperator How we should be comparing the product version .PARAMETER DetectionMethod How we should be checking for key .PARAMETER KeyPath The last part of the uninstall registry key path if not replaced automatically during process .PARAMETER ValueName The key that we will be looking for .PARAMETER DetectionType Should the key exist or not exist .PARAMETER Check32BitOn64System If this should be checked 32 bit on a 64 bit OS .PARAMETER EnforceSignatureCheck If the script should be signed to run .PARAMETER RunAs32Bit If this should be checked 32 bit on a 64 bit OS .PARAMETER Operator How we should be comparing the product version .PARAMETER ScriptFile The name of the script file used for detection .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. .EXAMPLE Create a detection rule that is checking for a specific version based on the MSI product code $params = @{ GUID = "### GUID ###" Type = "Registry" ProductVersionOperator = "greaterThanOrEqual" DetectionMethod = "VersionComparison" LogLevel = "Output" } Set-AppFactoryAppDetectionRule @params Create a detection rule that is looking for the existance of a specific registry value $params = @{ GUID = "### GUID ###" Type = "Registry" DetectionMethod = "Existence" KeyPath = "### KEY ###" ValueName = "### VALUE ###" DetectionType = "exists" LogLevel = "Output" } Set-AppFactoryAppDetectionRule @params Create a detection rule that is based on the existance of a MSI $params = @{ GUID = "### GUID ###" Type = "MSI" ProductVersionOperator = "notConfigured" DetectionMethod = "Existence" LogLevel = "Output" } Set-AppFactoryAppDetectionRule @params #> function Set-AppFactoryAppDetectionRulePSU{ [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$GUID, [Parameter(Mandatory = $true)][ValidateSet("MSI","Registry","Script")][string]$Type, [Parameter()][ValidateSet("notConfigured","equal","notEqual","greaterThanOrEqual","greaterThan","lessThanOrEqual","lessThan")][string]$ProductVersionOperator = "notConfigured", [Parameter()][ValidateSet("Existence","VersionComparison")][string]$DetectionMethod, [Parameter()][ValidateNotNullOrEmpty()][string]$KeyPath = "###PRODUCTCODE###", [Parameter()][ValidateNotNullOrEmpty()][string]$ValueName = "DisplayVersion", [Parameter()][ValidateSet("exists","notExists")][string]$DetectionType, [Parameter()][switch]$Check32BitOn64System = $false, [Parameter()][Switch]$EnforceSignatureCheck = $false, [Parameter()][Switch]$RunAs32Bit = $false, [Parameter()][ValidateSet("notConfigured","equal","notEqual","greaterThanOrEqual","greaterThan","lessThanOrEqual","lessThan")][string]$Operator = "greaterThanOrEqual", [Parameter()][ValidateNotNullOrEmpty()][string]$ScriptFile = "detection.ps1", [Parameter()][ValidateNotNullOrEmpty()][string]$Script, [Parameter()][ValidateSet("Output","Verbose")][string]$LogLevel = "Verbose" ) # Check if the application that we are trying to update actually exist $application = Get-AppFactoryAppPSU -GUID $GUID -LogLevel $LogLevel if (-not ($application)) { throw "Application with GUID $($GUID) does not exist." } # Create a object with the details for the detection type $detectionRule = [PSCustomObject]@{ "Type" = $Type } # Depending on the type, set the appropriate details switch($Type){ "MSI"{ $detectionRule | Add-Member -MemberType "NoteProperty" -Name "ProductCode" -Value "<replaced_by_pipeline>" $detectionRule | Add-Member -MemberType "NoteProperty" -Name "ProductVersionOperator" -Value $ProductVersionOperator if($ProductVersionOperator -ne "notConfigured"){ $detectionRule | Add-Member -MemberType "NoteProperty" -Name "ProductVersion" -Value "<replaced_by_pipeline>" } } "Registry"{ $detectionRule | Add-Member -MemberType "NoteProperty" -Name "DetectionMethod" -Value $DetectionMethod $detectionRule | Add-Member -MemberType "NoteProperty" -Name "KeyPath" -Value "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$($KeyPath)" $detectionRule | Add-Member -MemberType "NoteProperty" -Name "ValueName" -Value $ValueName if($DetectionType){ $detectionRule | Add-Member -MemberType "NoteProperty" -Name "DetectionType" -Value $DetectionType } if($Operator){ $detectionRule | Add-Member -MemberType "NoteProperty" -Name "Operator" -Value $Operator $detectionRule | Add-Member -MemberType "NoteProperty" -Name "Value" -Value "<replaced_by_pipeline>" } $detectionRule | Add-Member -MemberType "NoteProperty" -Name "Check32BitOn64System" -Value "$($Check32BitOn64System.IsPresent)" } "Script"{ $detectionRule | Add-Member -MemberType "NoteProperty" -Name "ScriptFile" -Value $ScriptFile $detectionRule | Add-Member -MemberType "NoteProperty" -Name "EnforceSignatureCheck" -Value "$($EnforceSignatureCheck.IsPresent)" $detectionRule | Add-Member -MemberType "NoteProperty" -Name "RunAs32Bit" -Value "$($RunAs32Bit.IsPresent)" if($script){ $scriptPath = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Apps" -AdditionalChildPath $application.AppFolderName,$ScriptFile $Script | Out-File -FilePath $scriptPath } } } # Write out the details to the configuration $application = Get-AppFactoryAppPSU -GUID $GUID -LogLevel $LogLevel $applicationJSONfile = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Apps" -AdditionalChildPath $application.AppFolderName,"App.json" $applicationJSON = Get-Content -Path $applicationJSONfile | ConvertFrom-Json -Depth 5 $applicationJSON.DetectionRule = ,$detectionRule try{ if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Updating - Detection Rule" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } $applicationJSON | ConvertTo-Json -Depth 5 | Out-File -FilePath $applicationJSONfile } catch{ throw $_ } } #EndRegion '.\Public\Service_Public\Set-AppFactoryAppDetectionRulePSU.ps1' 139 #Region '.\Public\Service_Public\Set-AppFactoryAppInstallPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to update the install commands in deploy-application.ps1 .PARAMETER GUID The unique identifier for the application that we want to work with .PARAMETER Type The type of installation that we will be using for this application .PARAMETER Script If custom script, the contents for the script file .PARAMETER Parameters Any parameters used by the command line .PARAMETER exe The name of the exe that will be used, if not substituted .PARAMETER msi The name of the msi that will be used, if not substituted .PARAMETER mst The mst file if required .PARAMETER beginstopProcess Process to stop at the beginning of an install .PARAMETER afterstopProcess Process to stop after the install .PARAMETER ignoreExit If there are exit codes we should ignore .PARAMETER WIM If this is run from a WIM file .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Set-AppFactoryAppInstallPSU { [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$GUID, [Parameter(Mandatory = $true)][ValidateSet("Custom", "PowerShell", "ECNO", "EXE", "MSI")][string]$Type, [Parameter()][ValidateNotNullOrEmpty()][string]$script, [Parameter()][string]$Parameters, [Parameter()][ValidateNotNullOrEmpty()][string]$installer = "###SETUPFILENAME###", [Parameter()][ValidateNotNullOrEmpty()][string]$mst, [Parameter()][string]$beginstopProcess, [Parameter()][string]$afterstopProcess, [Parameter()][string]$ignoreExit, [Parameter()][switch]$WIM, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) # Get application that we will be working with $application = Get-AppFactoryAppPSU -GUID $GUID -LogLevel $LogLevel if (-not ($application)) { throw "Application with GUID $($GUID) does not exist." } # Create a collection for the lines that we will add to the deploy-application.ps1 $ApplicationInstallLines = @{ "PreInstall" = [System.Collections.Generic.List[String[]]]@() "Install" = [System.Collections.Generic.List[String[]]]@() "PostInstall" = [System.Collections.Generic.List[String[]]]@() } # Depending on the type of install, will depend on the lines that we need to add $installType = $Type.ToUpper() $installerPath = "`$dirFiles" if ($WIM) { $installerPath = "`$MountPath" } $ApplicationInstallLines.Install.Add(("###INSTALLTYPE:$($installType)###", 2)) | Out-Null $ApplicationInstallLines.Install.Add(("###INSTALLCMDSTART###", 2)) | Out-Null if ($WIM) { foreach ($line in $(Add-AppFactoryAppWIM -section "start" -application $application)) { $ApplicationInstallLines.Install.Add($line) } } $commonParams = @{ ApplicationInstallLines = $ApplicationInstallLines directory = $installerPath installer = $installer Parameters = $Parameters LogLevel = $LogLevel } switch ($Type) { "MSI" { foreach ($line in $(Add-AppFactoryApplicationScriptMSI @commonParams -mst $mst)) { $ApplicationInstallLines.Install.Add($line) } } "EXE" { foreach ($line in $(Add-AppFactoryApplicationScriptEXE @commonParams -ignoreExit $ignoreExit)) { $ApplicationInstallLines.Install.Add($line) } } "Custom" { $ApplicationInstallLines.Install.Add(($script, 2)) | Out-Null } "PowerShell" { $ApplicationInstallLines.Install.Add(("Execute-Process -Path `"powershell.exe`" -Parameters `"-ExecutionPolicy Bypass -File `"`"`$($($installerPath))\$($script)`"`"`"", 2)) | Out-Null } "ECNO" { $ApplicationInstallLines.Install.Add(("Push-Location `$installerPath", 2)) | Out-Null $ApplicationInstallLines.Install.Add(("Start-Process -FilePath powershell.exe -ArgumentList `"-ExecutionPolicy Bypass -File _action.ps1 install`" -NoNewWindow -Wait", 2)) | Out-Null $ApplicationInstallLines.Install.Add(("Pop-Location", 2)) | Out-Null } } if ($WIM) { foreach ($line in $(Add-AppFactoryAppWIM -section "end" -application $application)) { $ApplicationInstallLines.Install.Add($line) } } $ApplicationInstallLines.Install.Add(("###INSTALLCMDEND###", 2)) | Out-Null # Any pre-install processes that need to happen $ApplicationInstallLines.PreInstall.Add(("###INSTALL:PRESTART###", 2)) | Out-Null if ($beginstopProcess) { $params = @{ interactive = $true blockingProcess = $beginstopProcess deferCount = 3 LogLevel = $LogLevel } foreach ($line in $(Add-AppFactoryApplicationBlockingProcess @params)) { $ApplicationInstallLines.PreInstall.Add($line) } } $ApplicationInstallLines.PreInstall.Add(("###INSTALL:PREEND###", 2)) | Out-Null # Any post install process that need to happen $ApplicationInstallLines.PostInstall.Add(("###INSTALL:POSTSTART###", 2)) | Out-Null if ($afterstopProcess) { $params = @{ interactive = $false blockingProcess = $afterstopProcess LogLevel = $LogLevel } foreach ($line in $(Add-AppFactoryApplicationBlockingProcess @params)) { $ApplicationInstallLines.PostInstall.Add($line) } } $ApplicationInstallLines.PostInstall.Add(("###INSTALL:POSTEND###", 2)) | Out-Null # Get and read the current deployment file $ApplicationDeploymentFilePath = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Apps" -AdditionalChildPath $application.AppFolderName, "Deploy-Application.ps1" # Update the deployment file with the pre-install steps $common = @{ Script = $ApplicationDeploymentFilePath LogLevel = $LogLevel section = "install" } if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Processing Pre Install Script Lines" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } Set-AppFactoryDeploymentScriptLinesPSU @common -ScriptLines $ApplicationInstallLines.PreInstall -LogLevel $LogLevel if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Processing Post Install Script Lines" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } Set-AppFactoryDeploymentScriptLinesPSU @common -ScriptLines $ApplicationInstallLines.PostInstall -LogLevel $LogLevel if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Processing Install Script Lines" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } Set-AppFactoryDeploymentScriptLinesPSU @common -main -ScriptLines $ApplicationInstallLines.Install -LogLevel $LogLevel } #EndRegion '.\Public\Service_Public\Set-AppFactoryAppInstallPSU.ps1' 154 #Region '.\Public\Service_Public\Set-AppFactoryAppOrgConfigPSU.ps1' 0 function Set-AppFactoryAppOrgConfigPSU{ [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$clientGUID, [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$appGUID, [Parameter()][bool]$AddToIntune = $false, [Parameter()][string[]]$AvailableAssignments = @(), [Parameter()][string[]]$AvailableExceptions = @(), [Parameter()][string[]]$RequiredAssignments = @(), [Parameter()][string[]]$RequiredExceptions = @(), [Parameter()][string[]]$UninstallAssignments = @(), [Parameter()][string[]]$UninstallExceptions = @(), [Parameter()][bool]$UnassignPrevious = $true, [Parameter()][bool]$CopyPrevious = $true, [Parameter()][int]$KeepPrevious = 0, [Parameter()][bool]$foreground = $false, [Parameter()][hashtable]$filters = @{}, [Parameter()][string[]]$espprofiles = @(), [Parameter()][bool]$InteractiveInstall = $false, [Parameter()][bool]$InteractiveUninstall = $false ) $configFile = Join-Path -Path $global:AppFactorySourceDir -ChildPath "DSBConfigurations" -AdditionalChildPath $clientGUID,"$($appGUID).json" $obj = [PSCustomObject]@{ "AddToIntune" = $AddToIntune "AvailableAssignments" = $AvailableAssignments "AvailableExceptions" = $AvailableExceptions "RequiredAssignments" = $RequiredAssignments "RequiredExceptions" = $RequiredExceptions "UninstallAssignments" = $UninstallAssignments "UninstallExceptions" = $UninstallExceptions "UnassignPrevious" = $UnassignPrevious "CopyPrevious" = $CopyPrevious "KeepPrevious" = $KeepPrevious "foreground" = $foreground "filters" = $filters "espprofiles" = $espprofiles "InteractiveInstall" = $InteractiveInstall "InteractiveUninstall" = $InteractiveUninstall } $obj | ConvertTo-JSON -Depth 5 | Out-File $configFile } #EndRegion '.\Public\Service_Public\Set-AppFactoryAppOrgConfigPSU.ps1' 42 #Region '.\Public\Service_Public\Set-AppFactoryAppUninstallPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to update the uninstall commands in deploy-application.ps1 .PARAMETER GUID The unique identifier for the application that we want to work with .PARAMETER Type The type of installation that we will be using for this application .PARAMETER Script If custom script, the contents for the script file .PARAMETER Parameters Any parameters used by the command line .PARAMETER exe The name of the exe that will be used, if not substituted .PARAMETER MSIGUID The GUID for the MSI that is to be removed .PARAMETER stopProcess Process to stop at the beginning of an uninstall .PARAMETER dirFiles If should be run from the dir files folder .PARAMETER ignoreExit If there are exit codes we should ignore .PARAMETER WIM If this is run from a WIM file .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Set-AppFactoryAppUninstallPSU { [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$GUID, [Parameter(Mandatory = $true)][ValidateSet("None", "MSI", "EXE", "Name", "GUID", "ECNO", "Custom")][string]$Type, [Parameter()][ValidateNotNullOrEmpty()][string]$name, [Parameter()][ValidateNotNullOrEmpty()][string]$script, [Parameter()][ValidateNotNullOrEmpty()][string]$installer = "###SETUPFILENAME###", [Parameter()][string]$Parameters, [Parameter()][string]$beginstopProcess, [Parameter()][string]$afterstopProcess, [Parameter()][switch]$WIM, [Parameter()][switch]$dirFiles, [Parameter()][string]$ignoreExit, [Parameter()][ValidateNotNullOrEmpty()][string]$MSIGUID, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) $application = Get-AppFactoryAppPSU -GUID $GUID -LogLevel $LogLevel if (-not ($application)) { throw "Application with GUID $($GUID) does not exist." } # Create a collection for the lines that we will add to the deploy-application.ps1 $ApplicationUninstallLines = @{ "PreUninstall" = [System.Collections.Generic.List[String[]]]@() "Uninstall" = [System.Collections.Generic.List[String[]]]@() "PostUninstall" = [System.Collections.Generic.List[String[]]]@() } # Depending on the type of install, will depend on the lines that we need to add $uninstallType = $Type.ToUpper() $installerPath = "" if ($dirFiles.IsPresent) { $installerPath = "`$dirFiles" } if ($WIM) { $installerPath = "`$MountPath" } $ApplicationUninstallLines.Uninstall.Add(("###UNINSTALLTYPE:$($uninstallType)###", 2)) | Out-Null $ApplicationUninstallLines.Uninstall.Add(("###UNINSTALLCMDSTART###", 2)) | Out-Null if ($WIM) { foreach ($line in $(Add-AppFactoryAppWIM -section "start" -application $application)) { $ApplicationUninstallLines.Uninstall.Add($line) } } $commonParams = @{ ApplicationInstallLines = $ApplicationUninstallLines directory = $installerPath installer = $installer Parameters = $Parameters LogLevel = $LogLevel } switch ($Type) { "EXE" { foreach ($line in $(Add-AppFactoryApplicationScriptEXE @commonParams -ignoreExit $ignoreExit)) { $ApplicationUninstallLines.Uninstall.Add($line) } } "MSI" { foreach ($line in $(Add-AppFactoryApplicationScriptMSI @commonParams -msiAction "Uninstall")) { $ApplicationUninstallLines.Uninstall.Add($line) } } "Name"{ $ApplicationUninstallLines.Uninstall.Add(("Remove-MSIApplications -Name `"$($Name)`"", 2)) | Out-Null } "GUID"{ $ApplicationUninstallLines.Uninstall.Add(("Execute-MSI -Action `"Uninstall`" -Path `"$($MSIGUID)`"", 2)) | Out-Null } "ECNO"{ $ApplicationUninstallLines.Uninstall.Add(("Push-Location `$installerPath", 2)) | Out-Null $ApplicationUninstallLines.Uninstall.Add(("Start-Process -FilePath powershell.exe -ArgumentList `"-ExecutionPolicy Bypass -File _action.ps1 remove`" -NoNewWindow -Wait", 2)) | Out-Null $ApplicationUninstallLines.Uninstall.Add(("Pop-Location", 2)) | Out-Null } "Custom"{ $ApplicationUninstallLines.Uninstall.Add(($script, 2)) | Out-Null } } if ($WIM) { foreach ($line in $(Add-AppFactoryAppWIM -section "end" -application $application)) { $ApplicationUninstallLines.Uninstall.Add($line) } } $ApplicationUninstallLines.Uninstall.Add(("###UNINSTALLCMDEND###", 2)) | Out-Null # Any pre-install processes that need to happen $ApplicationUninstallLines.PreUninstall.Add(("###UNINSTALL:PRESTART###", 2)) | Out-Null if ($beginstopProcess) { $params = @{ interactive = $true blockingProcess = $beginstopProcess deferCount = 3 LogLevel = $LogLevel } foreach ($line in $(Add-AppFactoryApplicationBlockingProcess @params)) { $ApplicationUninstallLines.PreUninstall.Add($line) } } $ApplicationUninstallLines.PreUninstall.Add(("###UNINSTALL:PREEND###", 2)) | Out-Null # Any post install process that need to happen $ApplicationUninstallLines.PostUninstall.Add(("###UNINSTALL:POSTSTART###", 2)) | Out-Null if ($afterstopProcess) { $params = @{ interactive = $false blockingProcess = $afterstopProcess LogLevel = $LogLevel } foreach ($line in $(Add-AppFactoryApplicationBlockingProcess @params)) { $ApplicationUninstallLines.PostUninstall.Add($line) } } $ApplicationUninstallLines.PostUninstall.Add(("###UNINSTALL:POSTEND###", 2)) | Out-Null # Get and read the current deployment file $ApplicationDeploymentFilePath = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Apps" -AdditionalChildPath $application.AppFolderName, "Deploy-Application.ps1" # Update the deployment file with the pre-install steps $common = @{ Script = $ApplicationDeploymentFilePath LogLevel = $LogLevel section = "Uninstall" } if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Processing Pre Install Script Lines" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } Set-AppFactoryDeploymentScriptLinesPSU @common -ScriptLines $ApplicationUninstallLines.PreUninstall -LogLevel $LogLevel if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Processing Post Install Script Lines" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } Set-AppFactoryDeploymentScriptLinesPSU @common -ScriptLines $ApplicationUninstallLines.PostUninstall -LogLevel $LogLevel if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Processing Install Script Lines" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } Set-AppFactoryDeploymentScriptLinesPSU @common -main -ScriptLines $ApplicationUninstallLines.Uninstall -LogLevel $LogLevel } #EndRegion '.\Public\Service_Public\Set-AppFactoryAppUninstallPSU.ps1' 159 #Region '.\Public\Service_Public\Set-AppFactoryOrganizationPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to update the details of an organization .PARAMETER GUID The unique identifier for the organization that we want to work with .PARAMETER name The name of the organization .PARAMETER contactList The list of contacts for the organization .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. .EXAMPLE Update an organizations name Set-AppFactoryOrganization -GUID "### GUID ###" -Name "### Organization Name ###" Update an organization cotacts Set-AppFactoryOrganization -GUID "### GUID ###" -contactList "### Contact 1 ###", "### Contact 2 ###" #> function Set-AppFactoryOrganizationPSU { [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$GUID, [Parameter()][ValidateNotNullOrEmpty()][string]$Name, [Parameter()][string[]]$contactList, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) # Get Org Configuration Files $organization = Get-AppFactoryOrganizationPSU -GUID $GUID -LogLevel $LogLevel if ($null -eq $organization) { Write-PSFMessage -Message "Error Encountered: Organization not found." -Level "Error" -Tag "Organizations" -Target "Application Factory Service" throw "Organization not found." } # Flag to know if we actually updated anything $changed = $false # If Contact List is Set to Be Updated if($contactList.Count -gt 0){ if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($organization.Name)] Updating Contact List - <c='green'>$($contactList)</c>" -Level $LogLevel -Tag "Organizations","ContactList","$($organization.Name)" -Target "Application Factory Service" } if($contactList){ $organization.Contacts = $contactList } else{ $organization.Contacts = @() } $changed = $true } # If Name is set to be updated if($Name){ if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($organization.Name)] Updating Name - <c='green'>$($Name)</c>" -Level $LogLevel -Tag "Organizations","Name","$($organization.Name)" -Target "Application Factory Service" } $organization.Name = $Name $changed = $true } # If something has been changed, lets do some updates if($changed){ # Get Current Path of Organization File $fileName = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Organizations" -AdditionalChildPath $organization.FileName # Remove the filename property since we will be writing out the configuration $organization.PsObject.properties.Remove("fileName") try{ if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($organization.Name)] Saving configuration file" -Level $LogLevel -Tag "Organizations","$($organization.Name)" -Target "Application Factory Service" } $organization | ConvertTo-Json -Depth 3 | Out-File $fileName if($Name){ if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($organization.Name)] Renmaing configuration file" -Level $LogLevel -Tag "Organizations","$($organization.Name)" -Target "Application Factory Service" } Rename-Item -Path $fileName -NewName "$($Name).json" -Force } } catch{ Write-PSFMessage -Message "Error Encountered: $($_)" -Level "Error" -Tag "Organizations" -Target "Application Factory Service" throw $_ } } } #EndRegion '.\Public\Service_Public\Set-AppFactoryOrganizationPSU.ps1' 82 #Region '.\Public\Service_Public\Start-AppFactoryProcessPSU.ps1' 0 function Start-AppFactoryProcessPSU { [CmdletBinding()] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string]$Path, [Parameter()][string]$LocalModule = $null, [Parameter()][ValidateNotNullOrEmpty()][string]$configuration = "Configuration.json", [Parameter()][switch]$EnableLogging, [Parameter()][switch]$multithread, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) $processparams = @{ "Path" = $Path "configuration" = $configuration "LocalModule" = $LocalModule "EnableLogging" = $EnableLogging "LogLevel" = $LogLevel } $multithreadParam = @{ "multithread" = $multithread } Start-AppFactoryPSU @processparams try { Remove-AppFactoryWorkspaceFilesPSU # Get Applications $applicationList = Get-AppFactoryAppPSU -LogLevel $LogLevel Write-Host "There are $($applicationList.count) applications configured in AppFactory" -ForegroundColor Green Write-Host "Getting the latest version number for each application in the process" -ForegroundColor Green $appVersions = Test-AppFactoryAppNewVersionPSU -LogLevel $LogLevel -applicationList $applicationList @multithreadParam $applicationList = Compare-AppFactoryAppVersionsPSU -LogLevel $LogLevel -applicationList $applicationList -appVersions $appVersions Write-Host "There are $($applicationList.count) apps that require an update." -ForegroundColor Green if ($applicationList.count -eq 0) { return } $applicationList = Test-AppFactoryFilesPSU -LogLevel $LogLevel -applicationList $applicationList Write-Host "There are $($applicationList.count) apps that are ready to download files." -ForegroundColor Green $applicationList = Get-AppFactoryInstallerPSU -LogLevel $LogLevel -applicationList $applicationList @multithreadParam Write-Host "Successfully downloaded files for $($applicationList.count) applications." -ForegroundColor Green $applicationList = Add-AppFactoryPackageFolderPSU -LogLevel $LogLevel -applicationList $applicationList @multithreadParam Write-Host "Successfully created publishing files for $($applicationList.count) applications." -ForegroundColor Green $applicationList = New-AppFactoryIntuneFilePSU -LogLevel $LogLevel -applicationList $applicationList @multithreadParam Write-Host "Successfully created intune application files for $($applicationList.count) applications." -ForegroundColor Green $applicationList = Publish-AppFactoryAppPSU -LogLevel $LogLevel -applicationList $applicationList foreach($application in $applicationList){ Write-Host "Application Published: $($application.IntuneAppName)" -ForegroundColor Green } } catch { throw $_ } } #EndRegion '.\Public\Service_Public\Start-AppFactoryProcessPSU.ps1' 51 #Region '.\Public\Service_Public\Start-AppFactoryPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to set all the required variables and settings for the process .PARAMETER Path Where the application configuration files are stored .PARAMETER configuration The name of the configuration file if not the default .PARAMETER PSU If we are running this and using variables stored in PSU .PARAMETER LocalModule If we should load the module from a local source vs installed module .PARAMETER EnableLogging If logging should be enabled with PSFramework .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. .EXAMPLE Start Application Factory with the default configuration file and no logging Start-AppFactory -Path "### PATH TO PROCESS FILES ###" Start Application Factory with a different configuration file and logging enabled Start-AppFactory -Path "### PATH TO PROCESS FILES ###" -configuration "### CONFIGURATION JSON FILE NAME ###" -EnableLogging Start Application Factory as if running from Powershell Universal and using platform variables Start-AppFactory -PSU Start Application Factory with a local module loaded for testing Start-AppFactory -Path "### PATH TO PROCESS FILES ###" -LocalModule "### PATH TO LOCAL MODULE ###" #> function Start-AppFactoryPSU { [CmdletBinding()] param( [Parameter(Mandatory = $true, ParameterSetName = 'console')][ValidateNotNullOrEmpty()][string]$Path, [Parameter()][ValidateNotNullOrEmpty()][string]$configuration = "Configuration.json", [Parameter()][string]$LocalModule = $null, [Parameter()][switch]$EnableLogging, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) # Set if we should be logging with the PSFramework Module $global:AppFactoryLogging = $EnableLogging.IsPresent # Should we be loading a local module to use for the processes (mainly used for testing multithreading) $global:LocalModulePath = $LocalModule # Determine what the Source Directory we aer using is $global:AppFactorySourceDir = $Path # Where are the supporting files stored $global:AppFactorySupportFiles = Join-Path -Path $PSScriptRoot -ChildPath "SupportFiles" $global:AppFactorySupportTemplateFolder = Join-Path -Path $PSScriptRoot -ChildPath "Templates" $global:AppFactoryLocalSupportFiles = Join-Path -Path $global:AppFactorySourceDir -ChildPath "SupportFiles" $global:AppFactoryWorkspace = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Workspace" # Setup Logging Configuration if ($global:AppFactoryLogging) { $AppFactoryLogDir = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Logs" # Name for the log file to be used $logFile = "$($AppFactoryLogDir)\AppFactory-%Date%.csv" $paramSetPSFLoggingProvider = @{ Name = "logfile" InstanceName = "AppFactory" FilePath = $logFile Enabled = $true Wait = $true } Set-PSFLoggingProvider @paramSetPSFLoggingProvider Write-PSFMessage -Message "Logging Configured" -Level $LogLevel -Tag "Setup" -Target "Application Factory Service" Write-PSFMessage -Message "Log File: <c='green'>$($logFile)</c>" -Level $LogLevel -Tag "Setup" -Target "Application Factory Service" Write-PSFMessage -Message "Reading Configuration File" -Level $LogLevel -Tag "Setup" -Target "Application Factory Service" } # Where is the configuration folder $global:AppFactoryConfigDir = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Configurations" # What is the path to the configuration file $AFConfigFile = Join-Path $global:AppFactoryconfigDir -ChildPath $configuration # Read the configuration file into an object $configDetails = Get-Content -Path $AFConfigFile -ErrorAction Stop | ConvertFrom-JSON $global:AppFactoryInstallersContainer = $configDetails.storage.installers.name $global:AppFactoryInstallersSecret = Get-Secret -Vault $configDetails.keyVault -Name $configDetails.storage.installers.secret $global:AppFactoryDeploymentsContainer = $configDetails.storage.deployments.name $global:AppFactoryDeploymentsSecret = Get-Secret -Vault $configDetails.keyVault -Name $configDetails.storage.deployments.secret $global:AppFactoryPublicFolder = $configDetails.publicContainer $global:AppFactorySharepointTenant = $configDetails.sharepoint.tenant $global:AppFactorySharepointClientID = $configDetails.sharepoint.clientId $global:AppFactorySharrepointURL = $configDetails.sharepoint.url $global:AppFactorySharepointCertificate = $configDetails.sharepoint.certificateFile $global:AppFactorySharepointCertificateSecret = Get-Secret -Vault $configDetails.keyVault -Name $configDetails.sharepoint.certificateSecret $global:AppFactorySharepointVersionField = $configDetails.sharepoint.versionField $global:AppFactorySharepointDocumentLibrary = $configDetails.sharepoint.documentLibrary if ($global:AppFactoryLogging) { Write-PSFMessage -Message "Loaded variables for the Application Factory Service" -Level $LogLevel -Tag "Setup" -Target "Application Factory Service" } } #EndRegion '.\Public\Service_Public\Start-AppFactoryPSU.ps1' 89 #Region '.\Public\Service_Public\Test-AppFactoryAppNewVersionPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to get all the current versions of the applications in the process .PARAMETER applicationList The collection of the applications that we will be acting on .PARAMETER force If we should continue either way .PARAMETER multithread Show we proceed single threaded or multithreaded .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Test-AppFactoryAppNewVersionPSU { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.Collections.Generic.List[PSCustomObject]]$applicationList, [Parameter()][ValidateNotNullOrEmpty()][switch]$force, [Parameter()][ValidateNotNullOrEmpty()][switch]$multithread, [Parameter()][ValidateSet("Output", "Verbose")][string]$LogLevel = "Verbose" ) $applications = [hashtable]::Synchronized(@{}) if ($global:AppFactoryLogging) { Write-PSFMessage -Message "Connecting to Azure Storage" -Level $LogLevel -Tag "Application", "AzureStorage" -Target "Application Factory Service" } $appStorageContext = Connect-AppFactoryAzureStoragePSU -storageContainer $global:AppFactoryInstallersContainer -storageSecret $global:AppFactoryInstallersSecret -LogLevel $LogLevel $psadtStorageContext = Connect-AppFactoryAzureStoragePSU -storageContainer $global:AppFactoryDeploymentsContainer -storageSecret $global:AppFactoryDeploymentsSecret -LogLevel $LogLevel $pfxPath = Join-Path -Path $global:AppFactoryLocalSupportFiles -ChildPath $global:AppFactorySharepointCertificate $sharepointConfig = @{ "url" = $global:AppFactorySharrepointURL "CertificatePath" = $pfxPath "CertificatePassword" = $global:AppFactorySharepointCertificateSecret.Password "ClientId" = $global:AppFactorySharepointClientID "Tenant" = $global:AppFactorySharepointTenant } if (-not $multithread.IsPresent) { try { Connect-PnPOnline @sharepointConfig } catch {} foreach ($application in $applicationList) { $AppItem = $null if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Checking for new version in <c='green'>$($application.AppSource)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } try { switch ($application.AppSource) { "Winget" { $AppItem = Get-AppFactoryWinGetAppItemPSU -application $application -LogLevel $LogLevel } "Evergreen" { $AppItem = Get-AppFactoryEvergreenAppItemPSU -application $application -LogLevel $LogLevel } "StorageAccount" { $AppItem = Get-AppFactoryAzureStorageAppItemPSU -application $application -storageContext $appStorageContext -workingfolder $global:AppFactoryWorkspace -LogLevel $LogLevel } "Sharepoint" { $AppItem = Get-AppFactorySharepointAppItemPSU -application $application -documentLibrary $global:AppFactorySharepointDocumentLibrary -LogLevel $LogLevel } "ECNO" { $AppItem = Get-AppFactoryECNOAppItemPSU -application $application -documentLibrary $global:AppFactorySharepointDocumentLibrary -LogLevel $LogLevel } "PSADT" { $AppItem = Get-AppFactoryAzurePSADTAppItem -application $application -storageContext $psadtStorageContext -LogLevel $LogLevel } } $applications.Add($application.GUID, $AppItem) } catch { $AppItem = [PSCustomObject]@{ "Version" = $version "URI" = $null "BlobName" = $null "Status" = "Error $($_)" } $applications.Add($application.GUID, $AppItem) if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Error getting version $($_)" -Level "Error" -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } } } } else { if ($global:LocalModulePath) { $modulePath = $global:LocalModulePath } else { $modulePath = (Get-module ApplicationFactoryService).path } $applicationList | Foreach-Object -Parallel { Import-Module -Name $using:modulePath -Force $application = $_ $applications = $using:applications $appStorageContext = $using:appStorageContext $psadtStorageContext = $using:psadtStorageContext $global:AppFactoryLogging = $using:script:AppFactoryLogging $global:AppFactoryWorkspace = $using:script:AppFactoryWorkspace $global:AppFactorySharepointDocumentLibrary = $using:script:AppFactorySharepointDocumentLibrary $AppItem = $null $LogLevel = $using:LogLevel if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Checking for new version in <c='green'>$($application.AppSource)</c>" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "AppFactory" } if ($application.AppSource -in @("Sharepoint", "ECNO")) { try { Connect-PnPOnline @using:sharepointConfig } catch {} } try { switch ($application.AppSource) { "Winget" { $AppItem = Get-AppFactoryWinGetAppItemPSU -application $application -LogLevel $LogLevel } "Evergreen" { $AppItem = Get-AppFactoryEvergreenAppItemPSU -application $application -LogLevel $LogLevel } "StorageAccount" { $AppItem = Get-AppFactoryAzureStorageAppItemPSU -application $application -storageContext $appStorageContext -workingfolder $global:AppFactoryWorkspace -LogLevel $LogLevel } "Sharepoint" { $AppItem = Get-AppFactorySharepointAppItemPSU -application $application -documentLibrary $global:AppFactorySharepointDocumentLibrary -LogLevel $LogLevel } "ECNO" { $AppItem = Get-AppFactoryECNOAppItemPSU -application $application -documentLibrary $global:AppFactorySharepointDocumentLibrary -LogLevel $LogLevel } "PSADT" { $AppItem = Get-AppFactoryAzurePSADTAppItem -application $application -storageContext $psadtStorageContext -LogLevel $LogLevel } } $applications.Add($application.GUID, $AppItem) } catch { $AppItem = [PSCustomObject]@{ "Version" = $version "URI" = $null "BlobName" = $null "Status" = "Error $($_)" } $applications.Add($application.GUID, $AppItem) if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Error getting version $($_)" -Level "Error" -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } } } } return $applications } #EndRegion '.\Public\Service_Public\Test-AppFactoryAppNewVersionPSU.ps1' 125 #Region '.\Public\Service_Public\Test-AppFactoryFilesPSU.ps1' 0 <# .DESCRIPTION This cmdlet is designed to confirm everything in the config files needed is present .PARAMETER applicationList The collection of the applications that we will be acting on .PARAMETER LogLevel If logging is enabled, what level of logging do we want, default is verbose. #> function Test-AppFactoryFilesPSU { [CmdletBinding()] [OutputType([System.Collections.Generic.List[PSCustomObject]])] param( [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][PSCustomObject]$applicationList, [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]]@() # What files should exist $AppFileNames = @("Deploy-Application.ps1", "Icon.png", "App.json") # Loop through each of the applications foreach ($application in $applicationList) { # Should the application be skipped $skip = $false # Where should the files exist $AppPackageFolderPath = Join-Path -Path $global:AppFactorySourceDir -ChildPath "Apps" -AdditionalChildPath $application.AppFolderName if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Checking to ensure that all the appropriate files are present for the application at path <c='green'>$($($AppPackageFolderPath))</c>." -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } # Check for the required files foreach ($AppFileName in $AppFileNames) { $AppFileNamePath = Join-Path -Path $AppPackageFolderPath -ChildPath $AppFileName if (-not(Test-Path -Path $AppFileNamePath)) { $skip = $true if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] File Not Found $($AppFileNamePath). Skipping Application." -Level "Error" -Tag "Application", "$($application.IntuneAppName)", "Error" -Target "Application Factory Service" } } if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] <c='green'>$($AppFileName)</c> found" -Level $LogLevel -Tag "Application", "$($application.IntuneAppName)" -Target "Application Factory Service" } if ($AppFileName -eq "App.json") { # Get Content of App.Json $AppFileContent = Get-Content -Path $AppFileNamePath | ConvertFrom-Json # If there are no detection rules if ($AppFileContent.DetectionRule.Count -eq 0) { $skip = $true if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Could not find any detection rule defined, ensure App.json contains atleast one detection rule element. Skipping Application." -Level "Error" -Tag "Application", "$($application.IntuneAppName)", "Error" -Target "Application Factory Service" } } # If there are rules, and set to script confirm Script File Exists if ($AppFileContent.DetectionRule.Count -eq 1) { if ($AppFileContent.DetectionRule.Type -like "Script") { $DetectionScriptFilePath = Join-Path -Path $AppPackageFolderPath -ChildPath $AppFileContent.DetectionRule.ScriptFile if (-not(Test-Path -Path $DetectionScriptFilePath)) { $skip = $true if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Could not detect given detection script file in app folder. Skipping Application." -Level "Error" -Tag "Application", "$($application.IntuneAppName)", "Error" -Target "Application Factory Service" } } } } if ($AppFileContent.DetectionRule.Count -ge 2) { if ("Script" -in $AppFileContent.DetectionRule.Type) { $skip = $true if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] Multiple detection rule types are defined, where at least one of them are of type 'Script', which is not a supported configuration in Intune. Skipping Application." -Level "Error" -Tag "Application", "$($application.IntuneAppName)", "Error" -Target "Application Factory Service" } } } if ($global:AppFactoryLogging) { Write-PSFMessage -Message "[$($application.IntuneAppName)] <c='green'>Detection rule appears to be configured correctly</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } $content = Get-Content -Path $AppFileNamePath if($content -match "^.*`"<<.*>>`".*$"){ $skip = $true if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] Not all fields that need to configure in App.JSON have been updated. Skipping Application." -Level "Error" -Tag "Application","$($application.IntuneAppName)","Error" -Target "Application Factory Service" } } if($global:AppFactoryLogging){ Write-PSFMessage -Message "[$($application.IntuneAppName)] <c='green'>All fields in App.json appear to be configured correctly</c>" -Level $LogLevel -Tag "Application","$($application.IntuneAppName)" -Target "Application Factory Service" } } } if(-not $skip){ $applications.Add($application) | Out-Null } } return $applications } #EndRegion '.\Public\Service_Public\Test-AppFactoryFilesPSU.ps1' 92 |