PowerShell Set File Type Association Default Application Windows 10

📢 PS-SFTA Latest Update 2020-09-14

Tested in: Windows 8, Windows 8.1, Windows 10 Version 1511, Windows 10 Version 1709, Windows 10 Version 1803, Windows 10 Version 1809, Windows 10 Version 1903, Windows 10 Version 1909


In our previous post we shared a command line tool to associate an application with a specific file type, however one of our visitors could not use the tool in his work environment due to restrictions because they could not use third-party executable applications, and told us that he wanted to do it using PowerShell.

Taking into account his very interesting idea and our passion for the world of scripting and sysadmin, we decided to create a simple version of SFTA in PowerShell using the Add-Type command that allows us to compile .NET code and use it in our Powershell instance. This is the Old Version. Use GitHub Version Instead.

Old PowerShell Script Using IApplicationAssociationRegistrationInternal
##################################
##   __                         ##
##   |  \  _   _      _     _   ##
##   |__/ (_| | ) \/ _) \/ _)   ##
##                /     /       ##
##     © 2019 Danysys.com       ##
##       SFTA-PS v.1.0.0        ##
##################################

$sourceCSharp=@"
using System;
using System.Runtime.InteropServices;

namespace SFTA
{
    public static class AssocReg
    {


        [ComImport()]
        [Guid("14EBCC88-2831-4FC8-A5DF-9F36A81DB12C")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        private interface IApplicationAssociationRegistrationInternalW10_1709
        {
            [PreserveSig]
            void Dummy1();
            [PreserveSig]
            void SetProgIdAsDefault([MarshalAs(UnmanagedType.LPWStr)] string pszAppRegistryName, [MarshalAs(UnmanagedType.LPWStr)] string pszSet, int atSetType);
            [PreserveSig]
            void Dummy3();
            [PreserveSig]
            void Dummy4();
            [PreserveSig]
            void Dummy5();
            [PreserveSig]
            void Dummy6();
            [PreserveSig]
            void QueryCurrentDefault([MarshalAs(UnmanagedType.LPWStr)] string pszExt, int atQueryType, int alQueryLevel, [Out, MarshalAs(UnmanagedType.LPWStr)] out string ppszAssociation);
        }

        private interface IApplicationAssociationRegistrationInternalW8_1_63
        {
            [PreserveSig]
            void Dummy1();
            [PreserveSig]
            void SetProgIdAsDefault([MarshalAs(UnmanagedType.LPWStr)] string pszAppRegistryName, [MarshalAs(UnmanagedType.LPWStr)] string pszSet, int atSetType);
            [PreserveSig]
            void Dummy3();
            [PreserveSig]
            void Dummy4();
            [PreserveSig]
            void Dummy5();
            [PreserveSig]
            void Dummy6();
            [PreserveSig]
            void QueryCurrentDefault([MarshalAs(UnmanagedType.LPWStr)] string pszExt, int atQueryType, int alQueryLevel, [Out, MarshalAs(UnmanagedType.LPWStr)] out string ppszAssociation);
        }

        [ComImport()]
        [Guid("591209c7-767b-42b2-9fba-44ee4615f2c7")]
        [ClassInterface(ClassInterfaceType.None)]
        private class ApplicationAssociationRegistration
        {
        }

        public static bool Debug  = false;
        private static readonly IApplicationAssociationRegistrationInternalW10_1709 AppAssocReg10 = new ApplicationAssociationRegistration() as IApplicationAssociationRegistrationInternalW10_1709;
        private static readonly IApplicationAssociationRegistrationInternalW8_1_63 AppAssocReg8 = new ApplicationAssociationRegistration() as IApplicationAssociationRegistrationInternalW8_1_63;

        private static void WriteDebug(string message)
        {
            if ( Debug)
            {
                Console.WriteLine(DateTime.Now.ToString("[yyyy.dd.MM HH:mm:ss]") + " "+ message);
            }
        }
        public static void SetFileTypeAssociation(string ProgramId,string Ext)
        {
            if (AppAssocReg10 != null)
            {
                WriteDebug("OK AppAssocReg10");
            AppAssocReg10.SetProgIdAsDefault(ProgramId, Ext, 0);
                return;
            }

            if (AppAssocReg8 != null)
            {
                WriteDebug("OK AppAssocReg8");
            AppAssocReg8.SetProgIdAsDefault(ProgramId,Ext, 0);
                return;
            }

            WriteDebug("FAIL AppAssocReg");

        }

        public static string GetFileTypeAssociation( string Ext)
        {
            
            if (AppAssocReg10 != null)
            {
                WriteDebug("OK AppAssocReg10");
                var assocApplication = "";
                AppAssocReg10.QueryCurrentDefault(Ext, 0, 1, out assocApplication);
                WriteDebug("assocApplication = " + assocApplication);
                return assocApplication;
            }

            if (AppAssocReg8 != null)
            {
                WriteDebug("OK AppAssocReg8");
                var assocApplication = "";
                AppAssocReg8.QueryCurrentDefault(Ext, 0, 1, out assocApplication);
                WriteDebug("assocApplication = " + assocApplication);
                return assocApplication;
            }


            WriteDebug("FAIL AppAssocReg");
            return "";

        }

    }
}
"@
#Add Type
if (-not ([System.Management.Automation.PSTypeName]'SFTA.AssocReg').Type)
{
    Add-Type -TypeDefinition $sourceCSharp -Language CSharp
}


#Sample Usage
#[SFTA.AssocReg]::Debug=$true; #Show Debug Information
#Get
$assocProgram=[SFTA.AssocReg]::GetFileTypeAssociation(".pdf")
Write-Host(".PDF Assoc Program = " + $assocProgram)
#Set
[SFTA.AssocReg]::SetFileTypeAssociation("Applications\SumatraPDF.exe",".pdf")

PS-SFTA Latest Version

Sample Usage:

Set Acrobat Reader DC as Default .pdf reader:

Set-FTA AcroExch.Document.DC .pdf

We hope this will be useful for you!!!

If you find this useful, a small donation would be greatly appreciated.

  • Bitcoin
  • Ethereum
  • Binance coin
  • Litecoin
Scan to Donate Bitcoin to 1Lrei7nhGeazvnJZHduGCduER2thjwD12F

Donate Bitcoin to this address

Scan the QR code or copy the address below into your wallet to send some Bitcoin

Scan to Donate Ethereum to 0x6BF5A047ebE7563D98e60887ab6e9485cB3564FF

Donate Ethereum to this address

Scan the QR code or copy the address below into your wallet to send some Ethereum

Scan to Donate Binance coin to bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23

Donate Binance coin to this address

Scan the QR code or copy the address below into your wallet to send some Binance coin

Tag/Note:- BEP2
Scan to Donate Litecoin to LfLJrcNEfA8Td8n2R3eV6AV3QTfNp8XgBX

Donate Litecoin to this address

Scan the QR code or copy the address below into your wallet to send some Litecoin

Other Method? Contact Us: hello.danysys@gmail.com

19 thoughts on “PowerShell Set File Type Association Default Application Windows 10

  • Impressive work! It is too hard to find a working powershell solution to change the default webbrowser. Your script works very well.

  • Excellent Job. One thing would help avoid confusion is some documentation to determine the appropriate Program Id. I was using ‘AcroExch.Document.DC’ from your examples which looked right but wasn’t.

    Set program via explorer
    Run: Get-FTA .pdf to see Program Id
    Then reset program back to default via explorer
    Run: Set-FTA .pdf

    In my case this was the ProgramId = ‘Acrobat.Document.DC’

    Thanks again! Awesome work.

  • Hi,
    Does this still work or not? I am trying the script from github on 1909 and after setting PTA for http or https, I get a message saying it was reset to default.

      • In 1909 onwards, Microsoft added a checksum/signature to FTA’s and if that isn’t correct or is missing then the FTA is reset to default by Edge (even where Edge has nothing to do with the FTA or program used).

        TMK the API to calculate the checksum/signature has not been exposed or documented by Microsoft.

        I’d love to be proved wrong BTW as this is the bane of my life at the moment!

        • Hi Steve J. Yes this was added in previous versions. I think from Windows 2008 to current versions. By the way, did you try the latest code? It was tested in 1909 and it works fine. Checksum/Signature was exposed using Reverse Engineering due to It’s an undocumented API.

          Regards

  • Hi I am using the script with Windows version 1909, but returns me an error “The term ‘Set-FTA’ is not recognized as the name of a cmdlet”

    • Hello @Kenji. Probably You’re not loading the module correctly or you have not configured Execution Policy.

      Try this way:

      powershell -ExecutionPolicy Bypass -command "& { . .\SFTA.ps1; Set-FTA 'ChromeHTML' '.pdf' }"

      Make sure the cmd/powershell working/current directory is same than SFTA.ps1.

      Regards

Leave a Reply

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