Introduction
In this post I will talk about Windows 10, file associations and how you can let the user in an enterprise switch default browser through the Software Center in SCCM (System Center Configuration Manager). All of this is done in an environment where file associations are tightly managed and locked through group policies (as they should be in an enterprise) on computers running Windows 10. Curious on the topic? Read on 🙂
How to
Before getting into the dirty details, I urge anyone managing file associations on Windows 10 to read these articles. My solution is build on the same principles of using a group policy and an .xml file to lock down the file associations.
- Making file type associations enterprise ready: https://blogs.msdn.microsoft.com/hewagen/making-file-type-associations-enterprise-ready/
- How to configure file associations for it pros: https://blogs.technet.microsoft.com/windowsinternals/2017/10/25/windows-10-how-to-configure-file-associations-for-it-pros/
The XML file
Taking a closer look on such xml file, the content displaying the default browser is the association of following extensions and protocols:
- .htm
- .html
- http
- https
In the xml file, it should look something like this, when the default browser is set to Google Chrome
<Association Identifier="http" ProgId="ChromeHTML" ApplicationName="Google Chrome" /> <Association Identifier="https" ProgId="ChromeHTML" ApplicationName="Google Chrome" /> <Association Identifier=".htm" ProgId="ChromeHTML" ApplicationName="Google Chrome" /> <Association Identifier=".html" ProgId="ChromeHTML" ApplicationName="Google Chrome" />
Group Policy setting
And for your reference, the setting in the GPO looks like this:
Powershell script
The magic lies in following Powershell script. As said, the association is locked through the xml file and a group policy, why switching the default browser by a standard user, will be reset back to whats defined in the xml file upon relogging.
But what if you really want those file association to be managed (for many reasons), but also wants the user to be able to switch their default browser? Powershell to the rescue. First off, some bits of the following script is kindly borrowed from the links provided in the beginning of the posts. Putting it together and modified for this solution and more, is my doing. I’m explaining along the lines what the script does, but in short:
- Loads the function to modify the xml app association file
- Get location and content of the specified xml file
- Modifies the xml based on input as parameters
- Writes to registry to use as detection methods in SCCM
<# .SYNOPSIS Modify file association xml file. Can modify file associations in an environment using the recommended method in Windows 10 The purpose of this script is to be used with an application in SCCM (System Center Configuration Manager) Function is not my doing. This is kindly borrowed from this MS article: https://blogs.msdn.microsoft.com/hewagen/making-file-type-associations-enterprise-ready/ .NOTES FileName: Switch-DefaultBrowser.ps1 Author: Martin Bengtsson Created: 14-06-2018 Version: 1.0 #> # Defines parameters param ( [Parameter(Mandatory = $true)] [string] $Path, [Parameter(Mandatory = $true)] [string] $Extension, [Parameter(Mandatory = $true)] [string] $ProgId, [Parameter(Mandatory = $true)] [string] $AppName ) # Function to modify or add content of the file association xml file Function ProcExt ([string]$fExtension, [string]$fProgId, [string]$fAppName) { $xmlNode = $appAssocXml.DefaultAssociations.Association | Where Identifier -eq $fExtension $newNode = $appAssocXml.CreateElement("Association") $attrIdentifier = $appAssocXml.CreateAttribute("Identifier") $attrIdentifier.Value = "$($fExtension)" $attrProgId = $appAssocXml.CreateAttribute("ProgId") $attrProgId.Value = "$($fProgId)" $attrAppName = $appAssocXml.CreateAttribute("ApplicationName") $attrAppName.Value = "$($fAppName)" $newNode.Attributes.Append($attrIdentifier) $newNode.Attributes.Append($attrProgId) $newNode.Attributes.Append($attrAppName) if (!([string]::IsNullOrEmpty($xmlNode))) { $currentApp = $xmlNode.ApplicationName Write-Host "Extension is currently assigned to $($currentApp). Overwriting." $rootNode.ReplaceChild($newNode, $xmlNode) $appAssocXml.Save($Path) } else { Write-Host "Extension is currently not assigned to an application. Adding new." $rootNode.AppendChild($newNode) $appAssocXml.Save($Path) } } # Modify to suit your needs here. This is used later in the detection methods in the application in SCCM. Kromann Reumert is my company. $Company = "Kromann Reumert" # Get the location and content of the xml file $Path = (Get-Item $Path).FullName $appAssocXml = [xml](get-content $Path) $rootNode = $appAssocXml.SelectSingleNode("DefaultAssociations") $extensions = "$($Extension)," $arrExtensions = $extensions.Split(",", [System.StringSplitOptions]::RemoveEmptyEntries) # Add or modify file associations in the xml file foreach ($item in $arrExtensions) { ProcExt $item.ToLower() $ProgId $AppName } # Detection method for Google Chrome if ($AppName -eq "Google Chrome") { # Writing to host for when run manually Write-Host -ForegroundColor Yellow $AppName "SELECTED" # Create registry key path if not existing $RegistryPath = "HKLM:\Software\$Company" if (-not(Test-Path -Path $RegistryPath)) { New-Item -Path $RegistryPath –Force } # Create the registry key used as detection method in the application in SCCM New-ItemProperty -Path $RegistryPath -Name DefaultBrowser -Value $AppName -PropertyType STRING -Force } # Detection method for Microsoft Edge if ($AppName -eq "Microsoft Edge") { Write-Host -ForegroundColor Yellow $AppName "SELECTED" $RegistryPath = "HKLM:\Software\$Company" if (-not(Test-Path -Path $RegistryPath)) { New-Item -Path $RegistryPath –Force } New-ItemProperty -Path $RegistryPath -Name DefaultBrowser -Value $AppName -PropertyType STRING -Force } # Detection method for Mozilla Firefox if ($AppName -eq "Firefox") { Write-Host -ForegroundColor Yellow $AppName "SELECTED" $RegistryPath = "HKLM:\Software\$Company" if (-not(Test-Path -Path $RegistryPath)) { New-Item -Path $RegistryPath –Force } New-ItemProperty -Path $RegistryPath -Name DefaultBrowser -Value $AppName -PropertyType STRING -Force } # Detection method for Internet Explorer if ($AppName -eq "Internet Explorer") { Write-Host -ForegroundColor Yellow $AppName "SELECTED" $RegistryPath = "HKLM:\Software\$Company" if (-not(Test-Path -Path $RegistryPath)) { New-Item -Path $RegistryPath –Force } New-ItemProperty -Path $RegistryPath -Name DefaultBrowser -Value $AppName -PropertyType STRING -Force }
Using the script in Configuration Manager
Putting the above script to use in an application in SCCM is straight forward, but I will walk you through the general steps required and go into details when necessary (this will be snips taken directly from my production environment):
- Create a new application in the Configuration Manager console and fill out the details as you desire. Below will be snips from my application that sets the default browser to Google Chrome
- Create a Deployment Type where the content location for above Powershell script is set
- And where the installation program is following. (This is one of the important parts. This is where the extensions and protocols are associated to Google Chrome. Also, quotations marks are notoriously evil when copy/pasting from the internet. Use notepad to correct errors if any.
- powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File .\Switch-DefaultBrowser.ps1 -Path C:\windows\AppAssoc.xml -Extension “.htm,.html,http,https” -ProgId “ChromeHTML” -AppName “Google Chrome”
- And a Detection method is equal to this. Again, modify to suit what you have made of changes to the powershell script
- My association xml file is located in the Windows folder, and as of such, it requires local administrative rights to modify it. Therefore in this case, Install for system:
- Last but not least. Deploy your applications to a collection of users as available.
In action
When all of above is in place and possibly repeated for every browser available to your the users, the switching will have following effect in the xml file and Software Center.
- The current browser is Microsoft Edge as shown in Notepad++
- The Default Browser – Google Chrome application is run from Software Center
- When finished, opening the xml file now displays that the current default browser is Google Chrome
- Google Chrome is now new default browser once relogged
Please leave a comment and let me know, if something like this is useful 🙂
Martin –
Suppose you wanted to enable users to set the default browser in a multi-tenant scenario (numerous users logging into the same server, for example). With only one file per OS, how would you enable different users to have different default browsers?
Hey Will, sorry for the very late reply and great question. This method changes the default associations for the entire device and will not support users having different preferences. The GPO simply lock that behavior, so you are probably better off with something else. 🙂
Its not working for the already logged in user,However the appassoc.xml file is changed as mentioned above.I have used powershell method
Yes, it will require a relog of the user, as the app associations are read at logon of the user. 🙂
When a user chooses to set Google Chrome as the default browser, the application is moved from the ‘Applications’ tab to the ‘Installation Status’ tab. If the user decides to switch back to Edge as the default browser this option is also moved to the Installation Status tab which leaves the ‘Applications’ tab empty so no easy way to switch back for the average user.
I guess this is only a problem for users who are switching the default browser shortly after one another because once the Application Deployment Evaluation Cycle kicks in the Application for the not default browser returns under Applications.
Maybe triggering a Application Deployment Evaluation cycle at the end of the script through WMI could fix this mainly optical problem?
Thank you for taking your time to reply. You could allow repairing of the application. That way, even if the application is considered installed due to the nature of the app deployment eval cycle, the repair button would allow the user to switch back regardless 🙂
I guess the repair button would do but it still is a problem that probably only occurs in the testing fase 🙂
Considering IE as the default browser. Your script only allows for one ProgID which sets all the associations the same in the XML. This is the preferred method for Edge and Chrome, but if I look at the example Microsoft set on their homepage to set IE as the default browser they use different ProgID’s for http, https and .htm and .html
See: https://docs.microsoft.com/en-us/microsoftsearch/set-default-browser
I guess this is also an optical problem, but just letting you know in case it doesn’t work as expected with IE.
I agree 🙂 And you are right about Internet Explorer and several ProgIds, though I don’t hope setting IE as the default browser occurs that often anymore 😀