How to use PowerShell to extract data from .dll or .exe files

5.3k views Asked by At

I want to list all the services whose startup type is set to automatic

I'm using PowerShell 5

$path = 'hklm:\SYSTEM\ControlSet001\Services'
$services = get-childitem $path | get-itemproperty -name 'Start'
foreach ($s in $services){
    if($s.'Start' -like '2'){
        $dn = get-itemproperty $s.'pspath' -name 'DisplayName'
        echo $dn
    }
}

But problem is most of the entries are using something like this:

@%systemroot%\system32\SearchIndexer.exe,-103
@%SystemRoot%\System32\wscsvc.dll,-200

So how to extract string from it?

To clarify a little bit further, for @%systemroot%\system32\SearchIndexer.exe,-103 the Display Name is "Windows Search". The question is, is PowerShell capable of extract string "Windows Search" out of SearchIndexer.exe? And how to do that?

UPDATE:

Basically stole the code from How to extract string resource from DLL

$source = @"
using System;
using System.Runtime.InteropServices;
using System.Text;

public class ExtractData
{
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)]
private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string lpFileName);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int LoadString(IntPtr hInstance, int ID, StringBuilder lpBuffer, int nBufferMax);

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool FreeLibrary(IntPtr hModule);

public string ExtractStringFromDLL(string file, int number) {
    IntPtr lib = LoadLibrary(file);
    StringBuilder result = new StringBuilder(2048);
    LoadString(lib, number, result, result.Capacity);
    FreeLibrary(lib);
    return result.ToString();
}
}
"@

Add-Type -TypeDefinition $source

$ed = New-Object ExtractData

$path = 'hklm:\SYSTEM\ControlSet001\Services'
$services = get-childitem $path | get-itemproperty -name 'Start' -ErrorAction SilentlyContinue
foreach ($s in $services){
    if($s.'Start' -like '2'){
        $dn = get-itemproperty $s.'pspath' -name 'DisplayName'
        try{
        $dn = $dn.DisplayName.Split(',')
        $dn = $ed.ExtractStringFromDLL([Environment]::ExpandEnvironmentVariables($dn[0]).substring(1), $dn[1].substring(1))
        }
        catch{}
        finally{
        echo $dn
        }
    }
}

Ugly, but it worked, finally......

2

There are 2 answers

5
Richard On BEST ANSWER

What's wrong with

get-service | where-object StartType -eq Automatic

?

3
andyb On

Try this. It works in PowerShell 3, so should also in higher versions.

Get-WmiObject -Class Win32_Service | 
    Where-Object StartMode -eq Auto | 
    Select-Object -Property DisplayName