Share via


Avkoda ett PowerShell-kommando från en process som körs

Det här exemplet körs bara på Windows-plattformar.

Ibland kan du ha en PowerShell-process som körs och som tar upp en stor mängd resurser. Den här processen kan köras i kontexten för ett schemaläggarjobb eller ett SQL Server Agent-jobb . Om det finns flera PowerShell-processer som körs kan det vara svårt att veta vilken process som representerar problemet. Den här artikeln visar hur du avkodar ett skriptblock som en PowerShell-process körs för närvarande.

Skapa en tidskrävande process

Om du vill demonstrera det här scenariot öppnar du ett nytt PowerShell-fönster och kör följande kod. Det kör ett PowerShell-kommando som matar ut ett tal varje minut i 10 minuter.

powershell.exe -Command {
    $i = 1
    while ( $i -le 10 )
    {
        Write-Output -InputObject $i
        Start-Sleep -Seconds 60
        $i++
    }
}

Visa processen

Brödtexten i kommandot som PowerShell kör lagras i egenskapen CommandLine för klassen Win32_Process . Om kommandot är ett kodat kommando innehåller egenskapen CommandLine strängen "EncodedCommand". Med den här informationen kan det kodade kommandot avdunklaras via följande process.

Starta PowerShell som administratör. Det är viktigt att PowerShell körs som administratör, annars returneras inga resultat när du kör frågor mot de processer som körs.

Kör följande kommando för att hämta alla PowerShell-processer som har ett kodat kommando:

$powerShellProcesses = Get-CimInstance -ClassName Win32_Process -Filter 'CommandLine LIKE "%EncodedCommand%"'

Följande kommando skapar ett anpassat PowerShell-objekt som innehåller process-ID:t och det kodade kommandot.

$commandDetails = $powerShellProcesses | Select-Object -Property ProcessId,
@{
    name       = 'EncodedCommand'
    expression = {
        if ( $_.CommandLine -match 'encodedCommand (.*) -inputFormat' )
        {
            return $matches[1]
        }
    }
}

Nu kan det kodade kommandot avkodas. Följande kodfragment itererar över kommandoinformationsobjektet, avkodar det kodade kommandot och lägger till det avkodade kommandot tillbaka till objektet för vidare undersökning.

$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 *

Det avkodade kommandot kan nu granskas genom att välja den avkodade kommandoegenskapen.

ProcessId      : 8752
EncodedCommand : IAAKAAoACgAgAAoAIAAgACAAIAAkAGkAIAA9ACAAMQAgAAoACgAKACAACgAgACAAIAAgAHcAaABpAGwAZQAgACgAIAAkAGkAIAAtAG
                 wAZQAgADEAMAAgACkAIAAKAAoACgAgAAoAIAAgACAAIAB7ACAACgAKAAoAIAAKACAAIAAgACAAIAAgACAAIABXAHIAaQB0AGUALQBP
                 AHUAdABwAHUAdAAgAC0ASQBuAHAAdQB0AE8AYgBqAGUAYwB0ACAAJABpACAACgAKAAoAIAAKACAAIAAgACAAIAAgACAAIABTAHQAYQ
                 ByAHQALQBTAGwAZQBlAHAAIAAtAFMAZQBjAG8AbgBkAHMAIAA2ADAAIAAKAAoACgAgAAoAIAAgACAAIAAgACAAIAAgACQAaQArACsA
                 IAAKAAoACgAgAAoAIAAgACAAIAB9ACAACgAKAAoAIAAKAA==
DecodedCommand :
                     $i = 1
                     while ( $i -le 10 )
                     {
                         Write-Output -InputObject $i
                         Start-Sleep -Seconds 60
                         $i++
                     }