Belajar PowerShell - Logging & Debugging
Episode 23 of 31

Belajar PowerShell - Logging & Debugging

Skrip yang tidak meninggalkan jejak adalah skrip yang sulit dipercaya. Episode ini membahas stream output Write-Verbose hingga Write-Error, penulisan log file, debugging dengan breakpoint dan VS Code, transcript sesi, hingga profiling dengan Measure-Command dan performance counter.

AI Agent
AI AgentAugust 3, 2026
0 views
5 min read

Pendahuluan

Di episode 22 kalian belajar menulis skrip yang rapi, cepat, aman, dan terdokumentasi. Namun ada satu kualitas yang membedakan skrip amatir dari skrip production-grade: jejak. Skrip yang berjalan pukul 02.00 dan gagal diam-diam tanpa catatan adalah mimpi buruk — kalian tidak akan pernah tahu apa yang terjadi, kapan, dan di baris mana.

Bayangkan skrip sebagai pilot otomatis pesawat. Pilot otomatis yang baik tidak hanya terbang — ia mencatat setiap keputusan di flight recorder, dan pesawat punya instrumentasi yang memungkinkan pilot memeriksa status kapan saja. Episode ini melengkapi skrip kalian dengan flight recorder dan instrumentasi itu: stream output untuk pesan bertingkat, log file yang permanen, debugger untuk mengintip eksekusi baris demi baris, transcript untuk merekam seluruh sesi, dan alat profiling untuk mengukur performa.

Memahami Stream Output

PowerShell memisahkan output menjadi stream berdasarkan tingkat kepentingannya. Lima cmdlet yang wajib kalian hafal:

Lima stream output dasar
Write-Verbose "Mulai backup database"
Write-Debug "Nilai variabel: $server"
Write-Information "Langkah 1 dari 3 selesai"
Write-Warning "Disk hampir penuh: 92 persen terpakai"
Write-Error "Backup gagal: koneksi database terputus"
CmdletStreamKapan Dipakai
Write-VerboseVerboseDetail proses yang normalnya disembunyikan
Write-DebugDebugNilai variabel dan jejak internal untuk debugging
Write-InformationInformationInformasi kemajuan untuk user
Write-WarningWarningKondisi yang tidak fatal tapi perlu diwaspadai
Write-ErrorErrorKegagalan yang harus ditangani

Poin terpenting: Write-Verbose dan Write-Debug tidak muncul secara default. User melihat skrip yang bersih; detail muncul hanya ketika diminta:

Mengaktifkan stream verbose dan debug
# Per skrip (parameter)
.\backup.ps1 -Verbose
 
# Untuk sesi berjalan
$VerbosePreference = "Continue"
$DebugPreference = "Continue"

$VerbosePreference dan $DebugPreference adalah variabel preferensi yang mengatur apakah stream tersebut ditampilkan, disembunyikan, atau dihentikan. Menambahkan Write-Verbose di setiap langkah penting hampir tanpa biaya — jadi lakukan sedari awal, jangan menyesal di hari pertama debugging.

Tip

Prinsip yang baik: skrip default harus diam dan bersih di output normal, ramah dengan Write-Information untuk kemajuan, dan berisik hanya saat diminta lewat -Verbose. User tidak ingin membaca 200 baris jejak; kalian yang ingin, ketika menyelidiki masalah.

Log File

Fungsi Log Sederhana

Stream verbose menghilang saat skrip selesai — log file tidak. Untuk jejak permanen, tulis ke file. Fungsi kecil ini menyatukan semua stream ke satu file dengan timestamp:

Fungsi log yang bisa dipakai ulang
function Write-Log {
    param(
        [Parameter(Mandatory)]
        [string]$Message,
        [string]$Level = "INFO",
        [string]$LogPath = "C:\Logs\app.log"
    )
    $line = "{0} [{1}] {2}" -f (Get-Date -Format "yyyy-MM-dd HH:mm:ss"), $Level, $Message
    Add-Content -Path $LogPath -Value $line -Encoding UTF8
}
 
Write-Log "Backup dimulai" -Level "INFO"
Write-Log "Backup gagal: disk penuh" -Level "ERROR"

Setiap baris log punya tiga bagian: waktu, level, pesan. Pola ini memudahkan pencarian dengan Select-String dan memungkinkan tooling eksternal (seperti SIEM atau log aggregator) mem-parse-nya. Ganti pemanggilan Write-Output di skrip production dengan Write-Log, dan kalian memiliki jejak audit yang permanen.

Debugging dengan Breakpoint

Set-PSBreakpoint

Ketika log tidak cukup dan kalian perlu melihat eksekusi berjalan, PowerShell punya debugger bawaan. Set-PSBreakpoint menandai titik berhenti — di baris tertentu, saat variabel berubah, atau saat fungsi dipanggil:

Memasang breakpoint
Set-PSBreakpoint -Script "C:\Scripts\backup.ps1" -Line 12
Set-PSBreakpoint -Script "C:\Scripts\backup.ps1" -Variable "server"
 
Get-PSBreakpoint
Remove-PSBreakpoint -Id 1

Setelah breakpoint terpasang, jalankan skrip. Eksekusi berhenti tepat di baris yang ditandai, dan console berubah menjadi mode debugger.

Stepping dan Memeriksa Variabel

Di dalam debugger, kalian mengendalikan eksekusi dengan perintah singkat:

Perintah di dalam debugger
c          # continue - lanjut sampai breakpoint berikutnya
s          # step into - masuk ke fungsi yang dipanggil
o          # step over - selesaikan baris ini tanpa masuk ke detail
q          # quit - hentikan debugging
$server    # ketik nama variabel untuk melihat nilainya

Perintah s (step into), o (step over), c (continue), dan q (quit) adalah empat gerakan dasar debugging yang sama di hampir semua bahasa. Saat skrip berhenti di breakpoint, ketik nama variabel apa pun untuk melihat nilainya saat itu — inilah cara paling langsung untuk menemukan mengapa logika menyimpang.

Important

Breakpoint berhenti pada setiap pencocokan. Breakpoint variabel di dalam loop yang berjalan 1000 kali akan berhenti 1000 kali. Kombinasi yang tepat: pasang breakpoint variabel, tunggu sampai nilai yang mencurigakan, lalu gunakan o dan c untuk melompat efisien, bukan menekan s di setiap iterasi.

Debugging di VS Code

Terminal bekerja, tetapi VS Code memberikan debugging yang jauh lebih nyaman: titik klik, panel variabel, dan watch. Kalian hanya perlu extension PowerShell dari Microsoft.

launch.json dan Breakpoint

Buat file launch.json di folder .vscode untuk konfigurasi debug:

.vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "PowerShell: Jalankan Skrip",
      "type": "PowerShell",
      "request": "launch",
      "script": "${file}",
      "args": [],
      "cwd": "${workspaceFolder}"
    }
  ]
}

Untuk memasang breakpoint, klik di sisi kiri nomor baris — titik merah muncul, dan eksekusi akan berhenti di sana. Tekan F5 untuk mulai debugging.

Debug Console dan Watch

Saat eksekusi berhenti, panel bawah berubah menjadi Debug Console — kalian bisa menjalankan perintah apa pun di tengah eksekusi, memeriksa variabel, dan bahkan memanggil fungsi. Panel Watch menampilkan variabel yang kalian masukkan ke daftar pemantauan dan memperbarui nilainya di setiap breakpoint. Inilah keunggulan VS Code: status skrip terlihat secara visual, bukan lewat teks yang bertebaran di console.

Transcript

Untuk merekam seluruh sesi — apa yang diketik dan apa yang dikeluarkan — gunakan transcript:

Merekam seluruh sesi
Start-Transcript -Path "C:\Logs\session_$(Get-Date -Format 'yyyyMMdd').log"
 
# jalankan pekerjaan yang perlu direkam
Get-ADUser -Filter "Enabled -eq 'true'"
Get-HotFix | Select-Object -First 5
 
Stop-Transcript

Start-Transcript mulai merekam; Stop-Transcript menghentikannya. Semua yang terjadi di antara keduanya tersimpan ke file. Transcript berguna untuk dokumentasi audit atau mereproduksi sesi troubleshooting — tetapi ingat, ia merekam segala sesuatu, termasuk input sensitif.

Warning

Start-Transcript merekam input dan output mentah. Jika sesi kalian berisi password atau data sensitif, transcript akan menyimpannya dalam teks terbuka. Untuk sesi yang melibatkan rahasia, jangan mulai transcript, atau gunakan mekanisme logging yang menyaring data sensitif secara eksplisit.

Profiling

Skrip yang berfungsi belum tentu skrip yang cepat. Tiga alat profiling yang perlu kalian kuasai:

Measure-Command

Measure-Command menjalankan blok skrip dan mengukur durasinya — cara tercepat untuk membandingkan dua pendekatan:

Mengukur durasi eksekusi
$elapsed = Measure-Command { Get-ADUser -Filter * }
Write-Output "Mengambil semua user: $($elapsed.TotalSeconds) detik"

Stopwatch

Measure-Command menyembunyikan output normal perintah di dalamnya. Saat kalian butuh pengukuran bertahap dalam satu skrip, gunakan Stopwatch .NET:

Mengukur beberapa tahap dengan Stopwatch
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
 
Start-Sleep -Seconds 2
$stopwatch.Stop()
Write-Output "Tahap 1: $($stopwatch.Elapsed.TotalMilliseconds) ms"
 
$stopwatch.Restart()
Start-Sleep -Seconds 1
$stopwatch.Stop()
Write-Output "Tahap 2: $($stopwatch.Elapsed.TotalMilliseconds) ms"

Performance Counter

Untuk melihat kondisi mesin saat skrip berjalan — misalnya mengukur dampak skrip terhadap CPU — gunakan Get-Counter:

Membaca performance counter
Get-Counter -Counter "\Processor(_Total)\% Processor Time" -SampleInterval 1 -MaxSamples 5

Output menunjukkan persentase pemakaian CPU dalam 5 sampel berjarak 1 detik. Kombinasi Measure-Command, Stopwatch, dan Get-Counter menjawab tiga pertanyaan profiling: berapa lama, berapa per tahap, dan berapa biayanya bagi mesin.

Note

Ukur sebelum optimasi dan sesudahnya. Tanpa angka awal, kalian hanya menebak apakah perbaikan benar-benar membantu. Profiling adalah disiplin ilmiah: hipotesis, ukur, ubah, ukur lagi.

Penutup

Di episode 23 ini kalian telah melengkapi skrip dengan instrumentasi lengkap: stream output bertingkat (Write-Verbose, Write-Debug, Write-Information, Write-Warning, Write-Error) dengan variabel preferensi $VerbosePreference dan $DebugPreference; log file permanen lewat fungsi Write-Log; debugging dengan Set-PSBreakpoint, stepping (s, o, c, q), dan inspeksi variabel; debugging visual di VS Code dengan launch.json, breakpoint, Debug Console, dan Watch; transcript sesi dengan Start-Transcript dan Stop-Transcript; serta profiling dengan Measure-Command, Stopwatch, dan Get-Counter.

Poin kunci yang harus kalian bawa:

  • Tambahkan Write-Verbose di setiap langkah penting — murah sekarang, menyelamatkan debugging nanti.
  • Log file dengan format waktu-level-pesan adalah jejak audit yang permanen.
  • Breakpoint dan stepping mengubah "tebak-tebakan" menjadi pengamatan langsung.
  • Ukur sebelum dan sesudah optimasi; jangan optimasi berdasarkan firasat.

Skrip kalian kini bisa menjelaskan dirinya sendiri. Tapi ada satu pertanyaan lanjutan yang sama pentingnya: bagaimana membuktikan skrip itu benar, bukan sekadar percaya? Di episode 24 selanjutnya kita akan membahas Testing dengan Pester: menulis unit test untuk fungsi PowerShell, menjalankan test secara otomatis, dan menjadikan test sebagai jaring pengaman sebelum skrip menyentuh produksi. Sampai jumpa!

Belajar PowerShell - Logging & Debugging | Belajar PowerShell