Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Dieses Beispiel wird nur auf Windows-Plattformen ausgeführt.
Manchmal wird ein PowerShell-Prozess ausgeführt, der eine große Menge von Ressourcen in Anspruch nimmt. Dieser Vorgang kann im Kontext eines Aufgabenplanerauftrags oder eines SQL Server-Agent-Auftrags ausgeführt werden. Wenn mehrere PowerShell-Prozesse ausgeführt werden, kann es schwierig sein zu wissen, welcher Prozess das Problem darstellt. In diesem Artikel wird gezeigt, wie Sie einen Skriptblock decodieren, der derzeit von einem PowerShell-Prozess ausgeführt wird.
Erstellen eines lang andauernden Prozesses
Um dieses Szenario zu veranschaulichen, öffnen Sie ein neues PowerShell-Fenster, und führen Sie den folgenden Code aus. Er führt einen PowerShell-Befehl aus, der eine Zahl pro Minute für 10 Minuten ausgibt.
powershell.exe -Command {
$i = 1
while ( $i -le 10 )
{
Write-Output -InputObject $i
Start-Sleep -Seconds 60
$i++
}
}
Anzeigen des Prozesses
Der Text des Befehls, den PowerShell ausführt, wird in der CommandLine-Eigenschaft der Win32_Process-Klasse gespeichert. Wenn der Befehl ein codierter Befehl ist, enthält die CommandLine-Eigenschaft die Zeichenfolge "EncodedCommand". Mithilfe dieser Informationen kann der codierte Befehl über den folgenden Prozess entschleiert werden.
Starten Sie PowerShell als Administrator. Es ist wichtig, dass PowerShell als Administrator ausgeführt wird, andernfalls werden beim Abfragen der ausgeführten Prozesse keine Ergebnisse zurückgegeben.
Führen Sie den folgenden Befehl aus, um alle PowerShell-Prozesse abzurufen, die über einen codierten Befehl verfügen:
$powerShellProcesses = Get-CimInstance -ClassName Win32_Process -Filter 'CommandLine LIKE "%EncodedCommand%"'
Mit dem folgenden Befehl wird ein benutzerdefiniertes PowerShell-Objekt erstellt, das die Prozess-ID und den codierten Befehl enthält.
$commandDetails = $powerShellProcesses | Select-Object -Property ProcessId,
@{
Name = 'EncodedCommand'
Expression = {
if ( $_.CommandLine -match 'encodedCommand (.*) -inputFormat' )
{
return $Matches[1]
}
}
}
Jetzt kann der codierte Befehl decodiert werden. Der folgende Codeausschnitt durchläuft das Befehlsdetails-Objekt, decodiert den codierten Befehl und fügt den decodierten Befehl zurück zum Objekt zur weiteren Untersuchung hinzu.
$commandDetails | ForEach-Object -Process {
# Get the current process
$currentProcess = $_
# Convert the Base 64 string to a Byte Array
$commandBytes = [System.Convert]::FromBase64String($currentProcess.EncodedCommand)
# Convert the Byte Array to a string
$decodedCommand = [System.Text.Encoding]::Unicode.GetString($commandBytes)
# Add the decoded command back to the object
$commandDetails |
Where-Object -FilterScript { $_.ProcessId -eq $currentProcess.ProcessId } |
Add-Member -MemberType NoteProperty -Name DecodedCommand -Value $decodedCommand
}
$commandDetails[0] | Format-List -Property *
Der decodierte Befehl kann jetzt überprüft werden, indem man die Decodierte Befehlseigenschaft auswählt.
ProcessId : 8752
EncodedCommand : IAAKAAoACgAgAAoAIAAgACAAIAAkAGkAIAA9ACAAMQAgAAoACgAKACAACgAgACAAIAAgAHcAaABpAGwAZQAgACgAIAAkAGkAIAAtAG
wAZQAgADEAMAAgACkAIAAKAAoACgAgAAoAIAAgACAAIAB7ACAACgAKAAoAIAAKACAAIAAgACAAIAAgACAAIABXAHIAaQB0AGUALQBP
AHUAdABwAHUAdAAgAC0ASQBuAHAAdQB0AE8AYgBqAGUAYwB0ACAAJABpACAACgAKAAoAIAAKACAAIAAgACAAIAAgACAAIABTAHQAYQ
ByAHQALQBTAGwAZQBlAHAAIAAtAFMAZQBjAG8AbgBkAHMAIAA2ADAAIAAKAAoACgAgAAoAIAAgACAAIAAgACAAIAAgACQAaQArACsA
IAAKAAoACgAgAAoAIAAgACAAIAB9ACAACgAKAAoAIAAKAA==
DecodedCommand :
$i = 1
while ( $i -le 10 )
{
Write-Output -InputObject $i
Start-Sleep -Seconds 60
$i++
}