2017-08-30 7 views
0

Je veux la liste de tous les services dont le type de démarrage est automatique mis àComment utiliser PowerShell pour extraire des données de fichiers .dll ou .exe

J'utilise 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 
    } 
} 

Mais le problème est la plupart des entrées utilisent quelque chose comme ceci:

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

Alors comment extraire de la chaîne?

Pour clarifier un peu plus loin, pour @%systemroot%\system32\SearchIndexer.exe,-103 le nom d'affichage est "Windows Search". La question est, est PowerShell capable d'extraire la chaîne "Windows Search" sur SearchIndexer.exe? Et comment faire ça?

MISE À JOUR:

Fondamentalement a volé le code de 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 
     } 
    } 
} 

laid, mais il a travaillé, enfin ......

Répondre

3

Quel est le problème avec

get-service | where-object StartType -eq Automatic 

?

+0

Thx! C'est une bien meilleure façon de le faire. Mais puis-je encore obtenir la réponse à la façon d'extraire la chaîne à partir de fichiers .dll, .exe? Juste curieux – oNion

+0

@oNion: Je pensais à ce sujet. Je ne pense pas que vous puissiez compter sur l'ajout d'un ID de ressource ou sur le nom du chemin ne contenant pas de virgule! Donc peut-être besoin d'appliquer quelques heuristiques pour une solution robuste. Mais le cas le plus simple est (string dans '$ s')' [Environment] :: ExpandEnvironmentVariables ($ s.Substring (1, $ s.LastIndexOf (',') - 1)) '. – Richard

+0

Il ne semble pas fonctionner, il a fait '@% SystemRoot% \ System32 \ wscsvc.dll, -200' devenir' @% SystemRoot% \ System32 \ wscsvc.dll', pas exactement extraire des données dans le fichier. Mais merci quand même :) – oNion

1

Essayez ceci. Cela fonctionne dans PowerShell 3, ainsi que dans les versions supérieures.

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

Merci! Savez-vous un moyen d'extraire des données à partir de fichiers .exe et .dll? Juste curieux – oNion

+0

Qu'avez-vous essayé? – andyb

+0

Je parierais bien que la réponse est ici sur SO, et pas trop difficile à trouver. – andyb