PowerShell-parancs dekódolása futó folyamatból

Ez a minta csak Windows-platformokon fut.

Időnként előfordulhat, hogy egy PowerShell-folyamat fut, amely nagy mennyiségű erőforrást vesz igénybe. Ez a folyamat egy Feladatütemező-feladat vagy egy SQL Server Agent-feladat kontextusában futhat. Ahol több PowerShell-folyamat fut, nehéz lehet megállapítani, hogy melyik folyamat jelenti a problémát. Ez a cikk bemutatja, hogyan dekódolhat egy szkriptblokkot, amelyet egy PowerShell-folyamat jelenleg futtat.

Hosszú ideig futó folyamat létrehozása

A forgatókönyv bemutatásához nyisson meg egy új PowerShell-ablakot, és futtassa a következő kódot. Végrehajt egy PowerShell-parancsot, amely percenként 10 percig ad ki egy számot.

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

A folyamat megtekintése

A PowerShell által futtatott parancs törzse a Win32_Process osztály CommandLine tulajdonságában van tárolva. Ha a parancs kódolt parancs, a CommandLine tulajdonság a "EncodedCommand" sztringet tartalmazza. Ezen információk használatával a kódolt parancs az alábbi folyamattal törölhető.

Indítsa el a PowerShellt Rendszergazda istratorként. Létfontosságú, hogy a PowerShell rendszergazdaként fusson, ellenkező esetben a rendszer nem ad vissza eredményt a futó folyamatok lekérdezésekor.

Hajtsa végre a következő parancsot az összes kódolt paranccsal rendelkező PowerShell-folyamat lekéréséhez:

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

Az alábbi parancs létrehoz egy egyéni PowerShell-objektumot, amely tartalmazza a folyamatazonosítót és a kódolt parancsot.

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

Most már dekódolható a kódolt parancs. Az alábbi kódrészlet a parancs részletei objektumon halad át, dekódolja a kódolt parancsot, és a dekódolt parancsot hozzáadja az objektumhoz további vizsgálat céljából.

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

A dekódolt parancs mostantól áttekinthető a dekódolt parancs tulajdonság kiválasztásával.

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