Skip to content

Instantly share code, notes, and snippets.

@DanGough
Last active April 26, 2024 14:42
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save DanGough/7ad3b9193ae66c0573fa5986c181c491 to your computer and use it in GitHub Desktop.
Save DanGough/7ad3b9193ae66c0573fa5986c181c491 to your computer and use it in GitHub Desktop.
Stub script for launching PSADT with ServiceUI only if a specific exe (explorer.exe by default) is running
<#
.SYNOPSIS
This is a helper script to launch Deploy-Application.exe via ServiceUI to force the process to become visible when deployed by Intune, or other deployment systems that run in session 0.
.DESCRIPTION
This will launch the toolkit silently if the chosent process (explorer.exe by default) is not running. If it is running, then it will launch the toolkit interactively, and use ServiceUI to do so if the current process is non-interactive.
An alternate ProcessName can be specified if you only want the toolkit to be visible when a specific application is running.
Download MDT here: https://www.microsoft.com/en-us/download/details.aspx?id=54259
There are x86 and x64 builds of ServiceUI avaiable in MDT under 'Microsoft Deployment Toolkit\Templates\Distribution\Tools'. Rename these to ServiceUI_x86.exe and ServiceUI_x64.exe and place them with this script in the root of the toolkit next to Deploy-Application.exe.
.PARAMETER ProcessName
Specifies the name of the process check for to trigger the interactive installation. Default value is 'explorer'. Multiple values can be supplied such as 'app1','app2'. The .exe extension must be omitted.
.PARAMETER DeploymentType
Specifies the type of deployment. Valid values are 'Install', 'Uninstall', or 'Repair'. Default value is 'Install'.
.PARAMETER AllowRebootPassThru
Passthru of switch to Deploy-Application.exe, will instruct the toolkit to not to mask a 3010 return code with a 0.
.PARAMETER TerminalServerMode
Passthru of switch to Deploy-Application.exe to enable terminal server mode.
.PARAMETER DisableLogging
Passthru of switch to Deploy-Application.exe to disable logging.
.EXAMPLE
.\Invoke-ServiceUI.ps1 -ProcessName 'WinSCP' -DeploymentType 'Install' -AllowRebootPassThru
Invoking the script from the command line.
.EXAMPLE
%SystemRoot%\System32\WindowsPowerShell\v1.0\PowerShell.exe -ExecutionPolicy Bypass -NoProfile -File Invoke-ServiceUI.ps1 -DeploymentType Install -AllowRebootPassThru
An example command line to use in Intune.
#>
param (
[string[]]$ProcessName = @('explorer'),
[ValidateSet('Install', 'Uninstall', 'Repair')]
[string]$DeploymentType = 'Install',
[switch]$AllowRebootPassThru,
[switch]$TerminalServerMode,
[switch]$DisableLogging
)
Push-Location $PSScriptRoot
if ($env:PROCESSOR_ARCHITECTURE -eq 'AMD64' -or $env:PROCESSOR_ARCHITEW6432 -eq 'AMD64') {
$Architecture = 'x64'
} else {
$Architecture = 'x86'
}
if (Get-Process -Name $ProcessName -ErrorAction SilentlyContinue) {
if ([Environment]::UserInteractive) {
# Start-Process is used here otherwise script does not wait for completion
$Process = Start-Process -FilePath '.\Deploy-Application.exe' -ArgumentList "-DeploymentType $DeploymentType -DeployMode Interactive -AllowRebootPassThru:`$$AllowRebootPassThru -TerminalServerMode:`$$TerminalServerMode -DisableLogging:`$$DisableLogging" -NoNewWindow -Wait -PassThru
$ExitCode = $Process.ExitCode
} else {
# Using Start-Process with ServiceUI results in Error Code 5 (Access Denied)
&".\ServiceUI_$Architecture.exe" -process:explorer.exe Deploy-Application.exe -DeploymentType $DeploymentType -DeployMode Interactive -AllowRebootPassThru:"`$$AllowRebootPassThru" -TerminalServerMode:"`$$TerminalServerMode" -DisableLogging:"`$$DisableLogging"
$ExitCode = $LastExitCode
}
} else {
$Process = Start-Process -FilePath '.\Deploy-Application.exe' -ArgumentList "-DeploymentType $DeploymentType -DeployMode Silent -AllowRebootPassThru:`$$AllowRebootPassThru -TerminalServerMode:`$$TerminalServerMode -DisableLogging:`$$DisableLogging" -NoNewWindow -Wait -PassThru
$ExitCode = $Process.ExitCode
}
Pop-Location
exit $ExitCode
@DanGough
Copy link
Author

DanGough commented Apr 18, 2024

How to best use ServiceUI.exe with PSADT is a topic that keeps on cropping up:

PSAppDeployToolkit/PSAppDeployToolkit#816
PSAppDeployToolkit/PSAppDeployToolkit#835
https://discourse.psappdeploytoolkit.com/t/answer-on-running-silent-mode-with-serviceui/4654/7
https://discourse.psappdeploytoolkit.com/t/installation-messages-using-serviceui-exe-in-intune/4664/3

This script is presented here as a POC for people to try out and provide some feedback. It will launch the toolkit interactively only if a chosen process (explorer by default, but multiple values supported) is found running, i.e. only launch interactively if someone is logged on. It will only invoke ServiceUI if the process is not already running interactively. It also supports passthru of DeploymentType (Install/Uninstall/Repair) as well as the switches AllowRebootPassThru, TerminalServerMode, and DisableLogging. It will also return the exit code to the calling process.

There are x86 and x64 builds of ServiceUI avaiable in MDT (install https://download.microsoft.com/download/3/3/9/339BE62D-B4B8-4956-B58D-73C4685FC492/MicrosoftDeploymentToolkit_x64.msi and they're under Microsoft Deployment Toolkit\Templates\Distribution\Tools). Rename these to ServiceUI_x86.exe and ServiceUI_x64.exe and place them in the root of the toolkit next to Deploy-Application.ps1.

Oddly, I found that using Start-Process on ServiceUI.exe was giving me an error code 5 (access denied) when testing via PsExec /s, yet it worked with PsExec /s /i. But using & inline to simply execute it worked fine. Also, if using & to execute Deploy-Application.exe directly, the script did not wait for it to complete, so I'm using Start-Process to run the toolkit directly. If anyone could shine some light on that, I'd be keen to know why!

Any feedback welcomed, it would be good to have a script like this as part of the toolkit, or at least shown as an example in the docs!

@That-Annoying-Guy
Copy link

So a more typical example would be:

  1. Copy Invoke-ServiceUI.ps1 in the same folder as Deploy-Application.exe

  2. After importing the IntuneWin file into an Intune Win32App, to use the following for install line:
    Invoke-ServiceUI.ps1 -DeploymentType 'Install'

  3. use the following for uninstall line:
    Invoke-ServiceUI.ps1 -DeploymentType 'uninstall'

@DanGough
Copy link
Author

DanGough commented Apr 20, 2024

I did have an example command line to plug into Intune added, but I forgot to include here!

I used:

%SystemRoot%\System32\WindowsPowerShell\v1.0\PowerShell.exe -ExecutionPolicy Bypass -NoProfile -File Invoke-ServiceUI.ps1 -DeploymentType Install -AllowRebootPassThru

I’ll make sure there are a few examples like this in the final implementation/docs.

@Ath3na-UK
Copy link

That is amazing, will give it a go shortly and report back.

@DanGough
Copy link
Author

I've just made a small tweak to use Push/Pop location instead of Set, so that running the script does not permanently change your current directory.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment