Launching Deploy-Application via PSEXEC using ServiceUI with Quoted paths fails

We are currently using an Invoke script to launch PSEXEC, using ServiceIU to display Deploy-Application UI to the user as the application is installed. This all works flawlessly with one exception, that is if $scriptParentPath has a space in it. To try and resolve the issue I have attempted to add Quotes to the existing command to deal with the spaces. But this then causes an issue with Deploy-Application. I have checked the formatting of the various quotes but running another application (with a space in the path) such as notepad++.exe with the same format works as expected. From testing the issue doesn’t appear to be the command itself but rather Deploy-Application.exe exiting as the exit code is showing as 0. It is exiting out the same second that it is launched and doesn’t create any log. Normally this isn’t an issue as MECM (SCCM) doesn’t have any spaces in its ccmcache paths, but sometimes our technicians will run the package manually on a machine from a path that has a space, I just wanted to head the issue off.

GitHub_Deploy-Application_Issue_Post_Code_COMPLETE

Toolkit Version:3.9.3
PowerShell Version: 5.1

I have posted on the GitHub Issues but thought I would also try here for visibility.

please try to change the " to ’ after -Parameters and after $DeploymentType

Hi,
Just tried that suggestion, it still fails due to the variables not translating into their values, please see log:

Hi,

Try:

Execute-Process -Path "$dirSupportFiles\psexec.exe" -Parameters "`"-accepteula -s $dirSupportFiles\ServiceUI_x64.exe`" -process:explorer.exe `"$scriptParentPath\Deploy-Application.exe`"" $DeploymentType -PassThru

Haven’t tested it but might work for you.

1 Like

As a colleague of Adi-R, I’ll give a bit of a background of why we are invoking “psexec with parameters of serviceUI and deploy-application.exe”. This does work 100% fine - just as long as you don’t have spaces in your $scriptParentPath (which to be fair isn’t typical but is something we noticed)

The reason we don’t run ServiceUI directly from SCCM is because we want a single package and Deployment Type that can run “whether or not a user is logged on” AND also displays interaction for logged-on users including RDP session users.

If we run ServiceUI directly from SCCM’s command line this does not work for Remote Desktop (RDP) sessions, and we have quite a few of these to consider. The interaction (e.g. dialogue boxes) are not displayed and will timeout, causing negative results.

Our “invoke script” will gather whether or not a user is logged on.
If “no user logged on” we execute-process “Deploy-Application.exe $DeploymentType”
If a user is logged on then we execute-process “psexec > serviceui > deploy-application.exe $DeploymentType”

Although technically only RDP or disconnect-RDP sessions need to run PsExec with ServiceUI, by doing this for all user-sessions we are “InTune-Ready” (where ServiceUI will be required for interaction).

Why are we using PsExec? Without it, we found SCCM deployments would fail. If we manually ran the same line from an administrative PsExec command prompt, it worked fine! So we added PsExec to call ServiceUI and this works 100% and we now have a SINGLE package solution.

Adi-R has only raised this question because we discovered that IF $scriptParentPath has a space in the path then it will fail and this only appears to be only a problem with “Deploy-Application” and works fine with spaces when testing against other apps such as NotePad++.

1 Like

While I completely understand your reasoning for using psexec (it’s a great utility after all), but be aware that some modern antivirus / malware prevention tools will block the use of psexec as it is often used by malicious users to wreck havoc on devices, might be worth having a read, here is some background reading:

So it may be worth considering if you could negate the use of psexec… as you are already using ServiceUI, you could specify your ServiceUI.exe command to run the install command in the System context e.g. serviceui.exe -session 0 rather than running in the user context serviceui.exe -process explorer.exe (explorer.exe will always run in session 1 as it does not run in the system context)
serviceui.exe syntax:

.\serviceui.exe

 Execute program interactively in target session. Must run from
 SYSTEM context. If no session is specified, program will run
 in session connected to keyboard/mouse (console).

 Usage: serviceui [-nowait] [ [-session:<sessionid>] | [-process:<process.exe>] ] program [arg(x)]

    -nowait   Don't wait for program completion. Exit
              code will not be captured.
    -session  Specify session number to launch in.
    -process  Search for process; program will
              launch in same session.
    program   Name of application to execute.
    arg(x)    Argument(s) for program.

 Examples:
  serviceui %windir%\notepad.exe
  serviceui -session:1 %windir%\notepad.exe
  serviceui -process:calc.exe %windir%\notepad.exe "\"my file.txt\""
  serviceui -process:calc.exe "%windir%\notepad.exe" "\"my file.txt\""



 =======================
 Exiting with [-1]
 =======================

A useful guide on using ServiceUI.exe:

As this is to have a single install that you can run on physical devices and machines with RDP sessions, you may need to detect if the machine is running RDP sessions.
Thankfully WIndows ships with two tools named QWINSTA.exe and RWINSTA.exe for querying and resetting Remote Desktop Services sessions (Who knew?!), this may help solve your challenge

Just a bit of a curve ball for your thought process :wink:

2 Likes

Thanks! You were very nearly there, your command threw a PsExec AcceptEULA UI box which pointed me in the right direction for a small quote change.

These lines worked!:

Execute-Process -Path "$dirSupportFiles\psexec.exe" -Parameters '-accepteula' -IgnoreExitCodes *

Execute-Process -Path "$dirSupportFiles\psexec.exe" -Parameters "`"-accepteula -s $dirSupportFiles\ServiceUI_x64.exe`" -process:explorer.exe `"$scriptParentPath\Deploy-Application.exe`" $DeploymentType" -PassThru

I had to run psexec and accept the eula, before running that line. If I didn’t do this and keep it in the original command it would immediately exit out with [-1].

Thank you

2 Likes

I think (personally) I’d move the `" to be after -accepteula -s as I think it reads more clearly - it ‘may’ also make the need to accept the EULA twice, go away, e.g.

Execute-Process -Path "$dirSupportFiles\psexec.exe" -Parameters "-accepteula -s `"$dirSupportFiles\ServiceUI_x64.exe`" -process:explorer.exe `"$scriptParentPath\Deploy-Application.exe`" $DeploymentType" -PassThru
1 Like

Hi,

I also tried this but it doesn’t work!
Well…it does if you don’t have spaces in the $scriptParentPath (back to that issue again!).

1 Like

Hi,

We have other security mitigations for this kind of stuff. We’re tested regularly :slight_smile:

As for detecting RDP sessions, thanks to paulh we have our own methods for detecting them.

We have done extensive testing over the last few days and this method really does allow us to do everything in one script.

Thanks

1 Like

Try to use $($variable) to get rid of issues getting your vars translated to its actual value, this way you get it right using single or double quotes. :slight_smile:

3 Likes

Just to update this with the final solution. The quoted paths in the post above were all working fine…… until we tried to do a required install via SCCM(available was fine). I am still not 100% sure why this is different from available(maybe someone here knows?), but it was causing the script to fail out. We re-tested with the un-quoted line and a required install, and it worked. Then a colleague let slip there maybe spaces in Intune paths!
So back to the drawing board….

There were 2 issues to fix:

  1. PsExec -accepteula not being accepted on the command line.
  2. Allow spaces in the paths.

After looking at it with a fresh pair of eyes this is the fix I came up with:

[string]$PsExecParameters = "-accepteula -s -w `"$dirSupportFiles`" `"$dirSupportFiles\ServiceUI_x64.exe`" -process:explorer.exe ..\Deploy-Application.exe $DeploymentType"

[psobject]$ExecuteProcessResult = Execute-Process -Path "$dirSupportFiles\PsExec64.exe" -Parameters $PsExecParameters -PassThru

The lines above work for SCCM(Available/Required), and manual install (with or without spaces in the path).

I hope this helps anyone wanting to go down this path.

4 Likes

Coming back to this 1 month later from a mention in other threads (and also with a fresh pair of eyes), have you tried using @Zelto’s suggestion, so your code would now look like:

[string]$PsExecParameters = "-accepteula -s -w `"$($dirSupportFiles)`" `"$($dirSupportFiles)\ServiceUI_x64.exe`" -process:explorer.exe ..\Deploy-Application.exe $($DeploymentType)"

[psobject]$ExecuteProcessResult = Execute-Process -Path "$($dirSupportFiles)\PsExec64.exe" -Parameters $($PsExecParameters) -PassThru

Let us know :man_shrugging:

2 Likes

Hi,

I did try this to start with, but at the time it didn’t work. Now the issue has been fixed with the lines I last posted I’m just leaving as is :grinning: