How I Fell in Love with App Updates

Last Updated on December 21, 2023 by rudyooms

Today I was called in to come up with a solution to give some DDS-CAD users (NO LOCAL ADMINS!) the possibility to install the necessary DDS-CAD updates themselves. Of course, this idea could be used for other company apps! It also can be used to make sure normal/standard users have the privilege to install some software on their own.

I will divide this blog into multiple parts

  1. The Issue
  2. The Solution
  3. Changing Scheduled task permissions
  4. The results
  5. The Script

1. The Issue

Without a problem, there could be no solution. So let me first explain the issue a little bit more. A lot of our customers are using some specific software for the field of work they are in. As a good example, we also deliver Microsoft 365 IT services to “technical installation companies” and some of them are using DDS-CAD

Please note: As always Security is of utmost importance, so no-local admin privileges for no one!

When enrolling their device, they could install DDS-CAD on their own by opening the Company Portal app and just clicking “install”.

The customer was very happy we could give non-local admin users the possibility to install software on their own. And If the customer is happy we are happy.

But like every app, DDS-CAD needs to be kept up to date. Luckily (at least what we thought at first) there is a built-in tool to check for updates. By pressing the update button it launches the DdsWebupdate.exe from the C:\Program Files\Data Design System\MEP 17\Exe folder

As this folder exists in the program files folder, it is also allowed in the default Applocker policy. So we can be 100% sure Applocker isn’t going to block it. To see what was going to happen, we opened this EXE file. When we opened the EXE file it started looking for updates but after waiting a few minutes, nothing changed. It was still stuck on the “looking for updates” prompt.

That’s odd! So we killed the process and tried to do the same, but this time we launched the process as admin, and immediately we were prompted it start updating the installation files!

Afbeelding met tekst

Automatisch gegenereerde beschrijving

Damn…I was hoping it gave us an error… so we need to be an admin to update this App on our own. That isn’t great at all! So what now? Of course, you could make sure you could use additional third-party patching solutions like the great Scappman tool. But unfortunately, DDS-CAD is not yet on their application list. So we were like, why not give the user some privileges to do this themselves?

Because some apps need to be updated each week or even each day and like I told you above, sometimes the app itself isn’t on the application list that is supported by third-party patching solutions.

2. The Solution

So we need a solution, that’s for sure. So let me explain what we did before I am going to show you the whole PowerShell script.

I had the brilliant idea (looking back at the script, I love it… )

shameless self promotion gifs | WiffleGif

To create a new scheduled task and let the task scheduler start updating the app when we want it!. So we created a PowerShell script to make sure a new scheduled task will be created. This nice scheduled task would launch a PowerShell encoded command to launch that DdsWebupdate.exe process.

As expected, the “search for updates” screen would also be shown in the system context and NOT in the user’s context. Luckily we already had the nice OOB Windows update script, which also shows a toast message from the system context to the logged-in user’s context with the use of Serviceui.exe

So we re-used my previously created script to use serviceui.exe to show the update prompt to the user instead of the system. So far so good, we finished the first part of this journey.

Now we have created the scheduled task to run that process as system but to show the Windows/Prompt in the users context, we still had some more work to do. We still needed to change the permissions to run the scheduled task and create a shortcut on the public desktop. With this task scheduler shortcut, any user could use schtasks.exe to run that specific task!

3. Giving users permissions to run a system scheduled task

But how the hell were we going to give a user the possibility to run that scheduled task on his own? Because a regular user doesn’t have permission to manually run tasks, that were configured as system/administrator.

Way back, when you wanted to ensure your regular end user could run a system task, you could just change the ACL on the XML file in c:\windows\system32\tasks\. But with Windows 10, this doesn’t work anymore

After some research, we found a nice website with all the information we need on it.

Windows: Run task scheduler task as limited user (michlstechblog.info)

Reading that blog, made me realize we needed to change some registry values and some Security Descriptors (SD)

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree

But that wasn’t sufficient, we also needed to change the SecurityDescriptor of the specific Task in the TaskCache\Tasks\ID registry key.

Luckily the ID we need to get the right task, was already available in the first registry key we changed. Now we have everything we need, we still need to change the Access Mask to 1179817

Afbeelding met tekst

Automatisch gegenereerde beschrijving

Long story short, the script changes the permissions so any user could run that task. Isn’t that beautiful? And with a shortcut on the user’s desktop, it is very easy to launch that update process!

Please Note: I also added the second version of changing scheduled task permissions but still need to test it some more

4. The Results

But before I show you the script, we still need to take a look at the results. First the shortcut to the scheduled task and of course the scheduled task itself

Now let’s press the button to launch the update process

Afbeelding met tekst

Automatisch gegenereerde beschrijving

Yes Yes… as shown above it started updating. After some minute waiting, DDS-CAD was successfully updated

Afbeelding met tekst

Automatisch gegenereerde beschrijving

5. The PowerShell Script

To finish the blog… the PowerShell script itself! Hopefully, you can read and understand it with the explanation, I gave you earlier. If not please send me a DM 🙂

#################################
#Configure encoded commands here#
#################################

$encodedcommand1 = "JgAgACIAQwA6AFwAUAByAG8AZwByAGEAbQAgAEYAaQBsAGUAcwBcAEQAYQB0AGEAIABEAGUAcwBpAGcAbgAgAFMAeQBzAHQAZQBtAFwATQBFAFAAIAAxADcAXABFAHgAZQBcAEQAZABzAFcAZQBiAFUAcABkAGEAdABlAC4AZQB4AGUAIgA="


#########################################################################################

#Toast Example: please convert it to base64 and adjust the $encodedcommand above #
#read more on https://call4cloud.nl/2021/12/code-name-the-log-cleaner/ #
# #
# Encoded Command | Notifying and Installing The Update #
###########################################################################################

#& "C:\Program Files\Data Design System\MEP 17\Exe\DdsWebUpdate.exe"

##############################################################################################
#Download and install ServiceUT#
$path = "C:\program files (x86)\service"
New-Item -ItemType Directory -Force -Path $path
Invoke-WebRequest "https://call4cloud.nl/wp-content/uploads/2021/07/ServiceUI.zip" -OutFile "$path\ZippedFile.zip"
Expand-Archive -LiteralPath "$path\ZippedFile.zip" -DestinationPath "$path" -force


####################################################
####Install the Update task ! #
###################################################

$triggers = New-ScheduledTaskTrigger -Once -At (get-date).AddSeconds(-200); $triggers.EndBoundary = (get-date).AddSeconds(-100).ToString('s')
$Action = New-ScheduledTaskAction -Execute "c:\program files (x86)\service\ServiceUI.exe" -argument "-process:explorer.exe c:\Windows\System32\WindowsPowershell\v1.0\powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -encodedcommand $encodedcommand1"
$settings = New-ScheduledTaskSettingsSet -StartWhenAvailable
$Null = Register-ScheduledTask -TaskName "UpdateDDSCAD" -Trigger $triggers -User "SYSTEM" -Action $Action -Settings $Settings -Force



############################################################################
####Change Permissions for the task version 2 (need to test it first  ! #
###########################################################################

$scheduler = New-Object -ComObject "Schedule.Service"
$scheduler.Connect()
$task = $scheduler.GetFolder("\").GetTask("UpdateDDSCAD")
$sec = $task.GetSecurityDescriptor(0xF)
$sec = $sec + ‘(A;;GRGX;;;AU)’
		###################################
		#PLEASE NOTE GRGX --> 1179817     # 
		###################################
$task.SetSecurityDescriptor($sec, 0)


####################################################
##### Create Shortcut to task on Desktop ! #
###################################################

if (-not (Test-Path "C:\Users\Public\Desktop\Update DDS-CAD.lnk"))
{
$null = $WshShell = New-Object -comObject WScript.Shell
$path = "C:\Users\Public\Desktop\Update DDS-CAD.lnk"
$targetpath = "C:\Windows\System32\schtasks.exe"

$Shortcut = $WshShell.CreateShortcut($path)
$Shortcut.TargetPath = $targetpath
$Shortcut.Arguments = '/run /TN "UpdateDDSCAD"'
$Shortcut.Save()
}

Conclusion

I have been telling this a lot, giving your end-users the “feeling” they could do whatever they want when they want is just fantastic.

Freedom GIFs - Get the best GIF on GIPHY

Hopefully, this solution could help you if you received the same question as we did!

Leave a Reply

Your email address will not be published. Required fields are marked *

41  +    =  48