Most things can be handled by built-in PowerShell commands, but if that’s not enough, you can always resort to the internal Windows API. For example, if you’d like to find out what the application is that is associated with a given file, try this:

function Get-ExecutableForFile
{
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Path
    )

    $Source = @"

using System;
using System.Text;
using System.Runtime.InteropServices;
public class Win32API
    {
        [DllImport("shell32.dll", EntryPoint="FindExecutable")] 

        public static extern long FindExecutableA(string lpFile, string lpDirectory, StringBuilder lpResult);

        public static string FindExecutable(string pv_strFilename)
        {
            StringBuilder objResultBuffer = new StringBuilder(1024);
            long lngResult = 0;

            lngResult = FindExecutableA(pv_strFilename, string.Empty, objResultBuffer);

            if(lngResult >= 32)
            {
                return objResultBuffer.ToString();
            }

            return string.Format("Error: ({0})", lngResult);
        }
    }

"@

    Add-Type -TypeDefinition $Source -ErrorAction SilentlyContinue
    [Win32API]::FindExecutable($Path)
}

And here is how you’d use the function:

 
PS> Set-EnvironmentVariable -Name test -Value 123 -Target User  
 

Twitter This Tip! ReTweet this Tip!

Anonymous
  • Another variation:

    function Get-ExecutableForFile2
    {
        param
        (
            [Parameter(Mandatory)]
            [string]
            $Path
        )
    
        $MethodDefinition = 
    @'
        [DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    
        public static extern long FindExecutable(string lpFile, string lpDirectory, System.Text.StringBuilder lpResult);
    
    '@
    
        $shell32 = Add-Type -MemberDefinition $MethodDefinition -Name 'shell32' -Namespace 'Win32' -PassThru
    
        $exeName = New-Object -TypeName "System.Text.StringBuilder"
    
        $exeName.Length = 1024
    
        $lngResult = $shell32::FindExecutable($Path, '', $exeName)
    
        if ($lngResult -ge 32) {
            return $exeName.ToString()
        }
        else {
            return "Error: $lngResult"
        }
    }
    
    Get-ExecutableForFile2 'c:\windows\notepad.exe'