PowerShell komutunun kodunu çalışan bir işlemden çözme

Bazen, büyük miktarda kaynak alan bir PowerShell işleminiz çalışıyor olabilir. Bu işlem, bir Görev Zamanlayıcı işi veya SQL Server Aracısı işi bağlamında çalışıyor olabilir. Çalışan birden çok PowerShell işlemi varsa, hangi sürecin sorunu temsil ettiğini bilmek zor olabilir. Bu makalede, bir PowerShell işleminin şu anda çalıştırıcı olduğu bir betik bloğunda kodun nasıl çözültiği gösterir.

Uzun süre çalışan bir işlem oluşturma

Bu senaryoyu göstermek için yeni bir PowerShell penceresi açın ve aşağıdaki kodu çalıştırın. 10 dakika için dakikada bir sayı çıkışı alan bir PowerShell komutu yürütür.

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

Süreci görüntüleme

PowerShell'in yürütülmektedir komutun gövdesi, Win32_Process sınıfının CommandLine özelliğinde depolanır. Komut kodlanmış bir komutsa, CommandLine özelliği "EncodedCommand" dizesini içerir. Bu bilgiler kullanılarak, kodlanmış komut aşağıdaki işlemle kararttırabilirsiniz.

PowerShell'i Yönetici olarak başlatma. PowerShell'in yönetici olarak çalışıyor olduğu, aksi takdirde çalışan işlemleri sorgularken sonuç döndürülerek çalışmayabilecek kadar önemlidir.

Kodlanmış komutu olan tüm PowerShell işlemlerini almak için aşağıdaki komutu yürütün:

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

Aşağıdaki komut, işlem kimliğini ve kodlanmış komutu içeren özel bir PowerShell nesnesi oluşturur.

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

Artık kodlanmış komutun kodu çözülebilirsiniz. Aşağıdaki kod parçacığı komut ayrıntıları nesnesi üzerinde yineler, kodlanmış komutun kodunu çözer ve kodu çözülen komutu daha fazla araştırma için nesnesine geri ekler.

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

Kodu çözülen komut artık kodu çözülen komut özelliği seçerek gözden geçirebilirsiniz.

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