The challenges of click-once and other per-user install methods

A while back, one of the main vendors for the organisation im now working for had a bit of an indignant chuckle when i asked for their supposed enterprise-grade software to have a silent install…. “Just use the click-once version – its fine for everyone else”

Well – needless to say, i saw red, what an incredibly fucking stupid thing to say… and im finally getting around to writing blog article as to why thats the case.

So, with that said – lets have a look at a few of the challenges, and positives, of user-based installs – be it click-once or other.

 

Administrator rights

Any per-user install can generally be installed without requiring administrator rights or elevation.

Now, in some instances, this can be a good thing…. think about at the start of Covid when many people moved to working form home – and some (not all) IT departments did not have the capbility of deploying software to remote machines. The ability to get users to download and install teams (for example) would have reduced the load of those IT departments at the time.

The other side of this is, it also creates an opportunity for users to install software which is not on the companies approved list. Which creates potential for support hassle, security vulnerabilities and inconsistent business processes. Application whitelisting controls will address this – but again, not all enterprise IT departments are at that maturity level (and yes, i agree, they should be – but thats just not the reality sometimes)

 

Click Once installation performance and size

Click once has various optimisations to decrease the initial install time…. but the reality is, if an application is 600MB, its not going to perform well over a slow network connection…. and even with a LAN connection, it lacks the options you get when deploying an application with something designed for mass-deployment, including slow network links, like SCCM (.e.g peer caching, pre-staging etc)

For organisations that have a large number of users cycling through a group of machines (im thinking healthcare – but you may have your own example) – 100 people all installing a 600MB application into their user profile starts to become an issue.

 

Management

Enterprise management and deployment apps (im thinking SCCM and group policy, but insert your fave here) have plenty of built-in capabilities to install, inventory and report on applications. Want to find all the versions of Acrobat Reader that aren’t the current version? – sure, give me a few minutes – and then a couple more to get them all updated to the current version.

Per-user installs break this management model by storing the program files in the user profile… now obviously we can start inventoring those paths as well…. but we have gone from looking at WMI, C:\Program files and Program files (x86), to now looking at all the user profiles on a machine…. and as anyone will tell you that does that stuff for a living, per-user installs seem to have a fanatical hatred of using a standard directory structure and prefer putting in random GUID’s here and there along the way – making it more difficult (but generally not impossible) to optimise that process.

In addition, when click-once does break (and it does) – you are dealing with a different type of support – and potentially much more of it (due to the multiple installs per machine).

We now are potentially managing multiple copies per machine, in locations that generally dont match a pattern, rather than 1 per-machine in a standard location. This then has flow on effects for application whitelisting, support – and the big one, security.

 

Security

For the purposes of this section, we are going to assume that application whitelisting is in place and that the application in question is a part of your companies approved software list – as it becomes more of a process and governance dicussion if this isnt the case. (which iun turn becomes a security issue if these aren’t in place)

Lets say you have an application called “LostSouls” (named after the band i cannot stop listening to at the moment).

LostSouls deploys via ClickOnce….. and 1800 people have installed it across the org.

LostSouls v1.1 turns out to have a major security vulnerability in one of its supporting dll’s…. fair enough, that happens… and LostSouls v1.2 comes out, which addresses that vulnerability….

“Dont worry – we have fixed it” the vendor says… “it will update the next time they open the app” the vendor (correctly) says…. the technically clueless management and project manager nod in agreement – because… why should they care about reality now? Ignorance is bliss after all.

So out of those 1800 installs of 1.1…. for various reasons (staff leaving, people using different machines etc), only 1200 people start it up again on the same machine – so those 1200 installs get updated… but we now have 600 installs sitting in user profiles that are vulnerable. 600 installs that i (as a deployment admin) need to find and address – which is achievable – but ofcourse uses time and effort that would better be spent elsewhere… and more to the point, just making life much harder than it needs to be.

 

To sum up

There is nothing wrong with applications that present the option to be installed as a per-machine or a per-user install…. and while i might not be a fan of per-user installs – there clearly are specific use cases where that model fits.

User-based installs become an issue where:

  • User-based install is the only option
  • The install size is large (lets say anything over 500MB) and
    • Is intended to be used across all sites – even those with slow network links – this can lead to significant delays before the user can use the app after an update
    • You have user-base that roams between machines commonly – and the mutliple installs across multiple machines ends up using significant disk space
  • Support. There’s no nice way of putting it – its a extremely poor deployment model which is far more difficult to manage when compared to your traditional per-machine install.
  • When there is a security issue in a release, where that issue can be exploited simply by the existance of the vulnerable dll (for example – using dll preloading/hijacking) – the difficulty of finding and removing or updating all of these for a per-user application is significant
  • Dealing with smug fuckwit salespeople that have absolutely no idea why click once is a bad idea and say idiotic shit like “our other clients use it and dont have a problem”… yes, your other clients with 100 PCs in their entire org across 1 site who have no dedicated IT function and dont know any better.

In short, if you turn up to any reasonable size client and say “we deploy our 700Mb memory leak simulator (yes, im thinking of partrcular piece of software here) via click once:” – any comptent IT people should laugh you out the door.

While i realise there is zero chance of salespeople caring about their product’s actual capabilities and likewise, zero chance of managers starting to care about buying products that are complete fucking shit and expecting internal techs to somehow make them work – i was disappointed when i couldn’t find any existing articles on the shittiness of per-user applications…. so… now there is one.

 

Other articles that touch on the issues of ClickOnce

https://www.stevestreeting.com/2013/05/12/friends-dont-let-friends-use-clickonce/#:~:text=ClickOnce%20forces%20you%20to%20put,your%20customer’s%20time%20on.

https://www.codemag.com/article/0902031/Eight-Evil-Things-Microsoft-Never-Showed-You-in-the-ClickOnce-Demos-and-What-You-Can-Do-About-Some-of-Them

All You Need Is One – A ClickOnce Love Story

 

WSUS is now deprecated

https://techcommunity.microsoft.com/t5/windows-it-pro-blog/windows-server-update-services-wsus-deprecation/ba-p/4250436

Not really surprising – there hasn’t been any meaningful updates to WSUS for a very long time… there are improvements that could be made – but no appetite to make them…. i imagine because the cloud solutions have a direct cost (and are therefore revenue producing) whereas WSUS does not.

The argument could be made that the ability to patch en-mass via products such as WSUS (and by extension, SCCM) is part of what you are paying for when you pay for a Windows license… the same as the the idea that you’re paying for supported product… its all part of the eco-system…. and without support, or patching or sysinternals tools or <insert other tools here> the Windows eco-system becomes much less attractive.

Anyhoo – obviously not the way the MS management see things…. it appears as if anything that doesn’t have a direct revenue stream associated with it is being killed off. Not surprising – but it also really sucks being shoe-horned into a immature platform that doesn’t always fit business or technical needs.

Crowdstrike BSOD and GPO no longer updating

After the Crowdstrike BSOD’s on 19/07/2024 – we have seen a significant uptick on clients not refreshing group policy.

The machines in question can be identified via:

  • The last update file date on C:\Windows\System32\GroupPolicy\Machine\registry.pol being on or around 19/07/2024 (some were on the 20th or 21st for us)
  • Event ID 1096 in the system event log with a line similar to “The processing of Group Policy failed. Windows could not apply the registry-based policy settings for the Group Policy object LocalGPO. Group Policy settings will not be resolved until this event is resolved. View the event details for more information on the file name and path that caused the failure”

The fix itself is very simple, delete the file C:\Windows\System32\GroupPolicy\Machine\registry.pol… but in an environment which does not have SCCM on all endpoints (which is incredibly frustrating), the following can be utilised to identify the machines suffering from the issue. The following script also checks for setup log event ID 1015 – indiciating Windows component store corruption… far less common – but we’ve also had some of that (although im less including to think this is Crowdstrike related and more just the poor maintenance of machines)

Obviously you could also add the code to delete the file when found – but at this point, i just needed to identify.


# Define the path to the input file containing the list of machines
$inputFilePath = “<path to txt file with computer list – could also run against AD if you wanted>”

# Define the output file to store the results
$outputFilePath = “<outputpath>\results.csv”

# Import the list of machines from the text file
$machines = Get-Content -Path $inputFilePath

# Initialize an array to hold the results
$results = @()

foreach ($machine in $machines) {
# Trim any leading/trailing whitespace
$machine = $machine.Trim()

# Ping the machine to check if it’s online
if (Test-Connection -ComputerName $machine -Count 1 -Quiet) {
Write-Host “$machine is online.”

# Define the path of the file to check
$filePath = “\\$machine\C$\Windows\System32\grouppolicy\machine\registry.pol”

# Check if the file exists and get the last write time
if (Test-Path -Path $filePath) {
$fileDate = (Get-Item -Path $filePath).LastWriteTime
Write-Host “File found on $machine. Last modified on: $fileDate.”
} else {
Write-Host “File not found on $machine.”
$fileDate = $null
}

# Check for Event ID 1096 in the System log within the last 7 days
$event1096 = Get-WinEvent -ComputerName $machine -FilterHashtable @{LogName=’System’; Id=1096; StartTime=(Get-Date).AddDays(-7)} -ErrorAction SilentlyContinue

# Check for Event ID 1015 in the Setup log within the last 7 days
$event1015 = Get-WinEvent -ComputerName $machine -FilterHashtable @{LogName=’Setup’;Id=1015; StartTime=(Get-Date).AddDays(-7)} -ErrorAction SilentlyContinue

# Determine the status of the events
$event1096Status = if ($event1096) { “Event 1096 Found” } else { “Event 1096 Not Found” }
$event1015Status = if ($event1015) { “Event 1015 Found” } else { “Event 1015 Not Found” }

# Add the result to the array
$results += [PSCustomObject]@{
Machine = $machine
Online = $true
FileDate = $fileDate
Event1096 = $event1096Status
Event1015 = $event1015Status
}
} else {
Write-Host “$machine is offline.”

# Add the result to the array
$results += [PSCustomObject]@{
Machine = $machine
Online = $false
FileDate = $null
Status = “Offline”
Event1096 = “N/A”
Event1015 = “N/A”
}
}
}

# Export the results to a CSV file
$results | Export-Csv -Path $outputFilePath -NoTypeInformation

Write-Host “Results have been saved to $outputFilePath.”

 

Error: SWbemObjectEx: Invalid index when trying to update a NIC using SConfig on server core

When using SConfig on a server core install, i was getting the following error

had similar issues when trying to configure the NIC using powershell.

Thanks very much to Mike and his post @ https://mikeconjoice.wordpress.com/2017/01/24/windows-server-core-error-swbemobjectex-invalid-index/

for pointing out that it was because IPv6 was not bound to the adapter.

Using the following powershell worked for me

Enable-NetAdapterBinding -Name Ethernet –ComponentID ms_tcpip6

 

the other important thing here is that unbinding IPv6 from adapters is a relatively common and completely silly practice. It frequently causes issues and doesn’t even achieve the goal of properly disabling IPv6 on the machine.

If you want to disable IPv6 – do it properly – via the registry as per

https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/configure-ipv6-in-windows

LocationHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters\
Name: DisabledComponents
Type: REG_DWORD
Min Value: 0x00 (default value)
Max Value: 0xFF (IPv6 disabled)

Microsoft Edge works best with the latest Windows Updates

When installing, seemingly randomly i will get the following in the application event log and msi log for CrEdge

Microsoft Edge works best with the latest Windows Updates. Once you download updates and restart your device, rerun the installer.

This is particularly frustrating as

  • The device has all current Windows updates applied
  • The install works on thousands of other machines – but just has a smattering where it doesn’t with this error
  • The error is in no way actually helpful… it doesn’t specify what updates i am supposedly missing… so doesn’t actually help with troubleshooting in anyway. Not quite as bad as “the task failed successfully” – but not far off.

 

Fortunately, Dr google provided some assistance

Microsoft Edge install issues on some computers
byu/jasonin951 inMicrosoftEdge

 

Microsoft Edge works best with the latest Windows Updates Error
byu/xxx59712 inedge

 

The answer, for me was setting the following reg key in the task sequence prior to Edge installing

reg add HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\EdgeUpdate /v Allowsxs /t REG_DWORD /d 1

 

The idea of preventing edge installs without providing an actual reason – genuinely bizarre behaviour by MS here.

 

Windows 11 – first useful information starts trickling

Now that the useless marketing fluff has subsided a little, more useful information about Windows 11 is making its way around the web.

Some keys parts for enterprise customers i believe will be:

 

Yearly update cycle (as opposed to currently twice-per-year updates…. “semi-annual channel”) 

Reference : https://techcommunity.microsoft.com/t5/windows-it-pro-blog/windows-lifecycle-and-servicing-update/ba-p/2493043

I might be out on a limb here, but while regular releases have absolutely fucking stellar for SCCM – for Windows 10, particularly in the enterprise, they have been “meh”…. i’m not denying that some of the features have been useful here and there…. but more often, they result in having to update the .admx’s and push out policy settings to turn consumer shit off.

Yearly seems a better “fit” for an OS…. and it was fairly common for enterprises just to use the H2 release of Win 10, partly for the support timeframe and partly because rolling out to 30,000 devices every 6 months was not only not viable…. but didn’t offer real benefit.

 

Pro is getting 24 months support, Enterprise 36 months

Reference: https://twitter.com/WindowsUpdate/status/1409588803455488002

Not a huge change here – for enterprise that generally stuck with H2 releases anyway…. but, some enterprises do use Pro (insert a world of senseless political reasons here) – and the 6 month increase in support timeframe will be very welcome.

 

CU’s are up to 40% smaller – lets see this actually happen before saying its good

For those of us that are old – we’ve heard this all before.

Remember when Windows 2003 was coming out and there were going to be fewer patches.

With 2012 server core, there was going to be fewer patches and less rebooting!

Neither of these – nor many other patching claims ever came true.

To be fair – the CU model used for Windows 10/2016/2019 is awesome – and much better than the “old” patching paradigm… but i will believe these claims once i see them.

 

System requirements

Reference: https://blogs.windows.com/windows-insider/2021/06/28/update-on-windows-11-minimum-system-requirements/

There seems to be some anxiety around the web about the requirements – primarily the exclusion of Intel 7th Gen processors and the requirement for TPM 2.0.

I’m actually a fan of this. While it may suck for some customers over the next 2-ish years…. it will force all newer hardware to meet that standard. Additionally, finally, x64 only. This should have happened 5+ fucking years ago.

So… yes, i agree, this may cause some short-term pain… but… and you wont hear me say this often… i think MS are going down the right path (on this at least)

 

Now – if some bright spark @MS could just realise that enterprises dont want all the bloat – and give us a way of removing all the crap with a line or two of powershell…..

Removing one note from windows 8.1u1

Had a client who was using the full office 2013 suite – but didn’t want users to get confused between the default “one note” that comes with Windows 8.1 and the Office 2013 one note.

Fair enough.

A bit of googling found this handy script already written by the deployment guys in order to help with cleaning out some of the crud.

http://blogs.technet.com/b/deploymentguys/archive/2013/10/21/removing-windows-8-1-built-in-applications.aspx

You can get an updated list of applications by using the get-appxpackage powershell command – and modify the script to only uninstall the packages you wish to remove.

Windows 8 – We couldn’t create a new partition or locate an existing one

Ran into this error when installing Win 8.1u1 on a new low-end laptop via USB key…

The complete error was:

We couldn’t create a new partition or locate an existing one. For more information, see the Setup log files

This article – http://blogs.technet.com/b/asiasupp/archive/2012/03/06/error-quot-we-couldn-t-create-a-new-partition-or-locate-an-existing-one-for-more-information-see-the-setup-log-files-quot-when-you-try-to-install-windows-8-cp.aspx

suggests simply using diskpart – but that didn’t work for me.

I was about to use a DVD for the install….(which would have meant trying to find a DVD…. for which I would need a tardis in order to go to when DVD’s were actually used) – when I simply unplugged the usb key, refresh, error…., plug the usb key back in, refresh – all good.

Now that’s some absolute whackiness…..