2026-10-04

Powershell'de tarih verisini ayrıştırmak

Powershell'de Get-Date cmdlet'ini kullanarak istediğimiz biçimde tarihi ve saati yazdırabiliyorum.

Get-Date -Format "dd.MM.yyyy HH:mm:ss"
31.12.2026 20:33:45
Get-Date -Format "yyyy-MM-ddTHH-mm-ss"
2026-12-31T20-33-45

Ama string veri tipinden tarih verisini almak için o kadar fazla seçeneğimiz yok. Şöyle yöntemler var:

Get-Date -Date "31.12.2026 20:33:45"
[datetime]"31.12.2026 20:33:45"

ama sistem tarih biçimine uymayan bir yapıyı ayrıştırmıyor. Örneğin benim bilgisayarımda tarih formatını yyyy-MM-dd HH:mm:ss gibi bir biçimde ayarladığım için 16.07.2026 18:45:13 verisini ayrıştırmak mümkün olmadı. Bunun yerine .Net'in ParseExact() metodunu kullandım:


[datetime]::ParseExact(
	"16.07.2026 18:45:13",
    "dd.MM.yyyy HH:mm:ss",
    [Globalization.CultureInfo]::InvariantCulture)

2026-10-03

Fedora altında powershell sorunu

Genelde kullandığım Linux sistemlere de powershell kurmak gibi bir alışkanlığım var. Ama bir süredir yaşadığım ve çözümünü buldum.

Gnome terminalde pwsh yazarak geçtiğim powershell içinde yukarı/aşağı ok tuşları ile geçmiş komutlar arasında geçiş yapabiliyorum. Yani PSReadline yüklü. Bunu

gmo -n psreadline

ki bu da şunun kısaltılmışı:

Get-Module -Name PSReadLine

ile de doğruladım. Ama Ctrl+ok tuşları ile kelime atlamalı olarak gezinemiyorum. Her seferinde tek tek ok tuşlarına basarak gitmek zor. Farkettim ki powershell, Emacs edit kipinde çalışıyormuş:

Get-PSReadLineOption | Select-Object EditMode

Bu kipte kelime atlamalı gezinmek için Alt+f (forward, ileriye) ve Alt+b (backward, geriye) tuşları çalışıyor. Ama alışkanlıklar zor değişir. Bunu Windows kipine değiştirmek istedim.

Set-PSReadLineOption -EditMode Windows

Bunun sonucunda küçük bir kazancım daha oldu; tüm satırı silmek için Ctrl+u kısayolunu kullanıyordum, Windows alışkanlığı Esc satırı temizlemiyordu. Artık temizliyor.

2026-10-02

karakter array'i string'e çevirmek

Daha önce bunun tam tersini yapmaya ihtiyacım olmuştu. ssh ile bağlandığım linux sunucu üzerindeki bazı verileri analiz etmek için powershell'e, Windows Terminal'e yapıştırmak istedim. Çok satırlı bir metin verisi kopyaladığım için, powershell'de geçici bir değişkeni şu şekilde oluşturdum:

$a = @"
reboot   system boot  6.8.0-139-generi Tue Sep 22 15:31:47 2026   still running
reboot   system boot  6.8.0-138-generi Tue Sep 22 14:38:57 2026 - Tue Sep 22 15:20:27 2026  (00:41)
reboot   system boot  6.8.0-138-generi Wed Sep  2 17:08:47 2026 - Wed Sep  2 17:54:05 2026  (00:45)
reboot   system boot  6.8.0-134-generi Tue Aug 18 07:34:14 2026 - Tue Aug 18 08:45:37 2026  (01:11)
reboot   system boot  6.8.0-134-generi Tue Jul 28 08:10:40 2026 - Tue Jul 28 13:38:55 2026  (05:28)
reboot   system boot  6.8.0-134-generi Mon Jul 27 08:17:26 2026 - Mon Jul 27 18:01:39 2026  (09:44)
reboot   system boot  6.8.0-134-generi Mon Jul 13 15:14:51 2026 - Mon Jul 13 15:51:52 2026  (00:37)
reboot   system boot  6.8.0-100-generi Mon Jul 13 13:16:43 2026 - Mon Jul 13 15:14:29 2026  (01:57)
reboot   system boot  6.8.0-100-generi Mon Jul 13 13:08:22 2026 - Mon Jul 13 13:16:23 2026  (00:08)
reboot   system boot  6.8.0-100-generi Mon Jul 13 11:19:48 2026 - Mon Jul 13 13:07:12 2026  (01:47)
reboot   system boot  6.8.0-100-generi Fri May 22 16:53:31 2026 - Fri May 22 17:54:22 2026  (01:00)
reboot   system boot  6.8.0-100-generi Tue Mar 17 17:14:18 2026 - Tue Mar 17 17:18:30 2026  (00:04)
"@

Bunun sonucunda bu geçici değişkende kaç satırımın olduğuna bakmak istedim:


$a.Length

Bunun sonucunda kopyaladığımdan satır sayısından çok daha fazla bir değer döndü. Bunun sebebi de bu sayının satır sayısını değil, toplam karakter sayısını göstermesiydi. Örneğin 0 ile 5 arasındaki elemanları ekrana yazdırmak istediğimde


$a[0..5]
r
e
b
o
o
t

gördüm. Satırlar, Linux'ta genellikle yapıldığı gibi, 0xA karakterleri ile ayrılıyordu. Bunu satır bazlı bir değişkene dönüştürmek için


$b = $a -split [char]0xA

Bunun sonucunda b değişkeninide gerçek satır sayısı kadar eleman vardı.


$b.Length

2026-10-01

Powershell prompt denemesi

İzlediğim bir videoda gördüğüm powershell prompt'u hoşuma gitti, kopyalamak istedim. Videoda iki satırlı bir prompt vardı. İkinci satırın en solunda bir yuvarlak (led ışık gibi) vardı. En son çalıştırılan komut başarılı bir sonuç verirse yeşil led yanıyor (yeşil bir yuvarlak), hatalı sonuç verirse kırmızı led yanıyordu (kırmızı yuvarlak). Buraya kadar kolay. Eğer satıra birşey yazmadan (veya sadece boşluk varken) enter'a basınca da led sönüyordu (içi boş yuvarlak). Bu son kısmı nasıl yapacağımı bilemedim.

İlk bölüm için powershell $? powershell otomatik değişkenini kullandım. Prompt fonksiyonumun içinde şöyle bir koşul oluşturdum:


$IsOk = $?
...
if ($IsOk) {
	$statstr = "$green$dolu_top $reset"
} else {
	$statstr = "$red$dolu_top $reset"
}

Burada $IsOk değişkeninin atamasının yapıldığı satır prompt fonksiyonunun ilk satırı olmak zorunda. Aksi takdirde prompt satırına yazdığımız komutun sonucu değil, fonksiyonun içinde en son çalışan satırın sonucuna dair çıktı üretmiş oluruz. Dolu top için U+25CF karakterini kullandım. Yeşil renk olması için önüne


$green  = "$esc[38;2;168;216;185m"   # #A8D8B9
$reset  = "$esc[0m"
$dolu_top = [char]0x25CF
$bos_top = [char]0x25CB

ekledim. bash'te de kullanılan ANSI Escape Code ekledim. Ayrıca sönük led için U+25CB unicode karakterini ekledim. Bu çalıştı. Sıra geldi boş satır için sönük led eklemeye. Powershell komut geçmişine boş satırlar dahil edilmiyor; ne Get-History'ye ne de Get-PSReadlineHistory'ye. Bunun yerine enter karakteri işlem düzenine müdahale ederek satır işlenmeden boş satır gelip gelmediğini kontrol etmenin yolunu kullandım. Prompt fonksiyonunun dışına, ama profil dosyamın içine bir global değişken tanımlayıp altına da Set-PSReadLineKeyHandler satırını ekledim.


$global:IsEmptyCommand = $false

Set-PSReadLineKeyHandler -Key Enter -ScriptBlock {
    param($key, $arg)

    $line = $null
    $cursor = $null
    [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)

    if ([string]::IsNullOrWhiteSpace($line)) {
        $global:IsEmptyCommand = $true
    } else {
        $global:IsEmptyCommand = $false
    }

    [Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine($key, $arg)
}

Bu bölümde belirlenen $global:IsEmptyCommand değişkeni ile prompt fonksiyonu içine sönük led (boş yuvarlak) eklenmesi mümkün oldu. İlk belirttiğim if-else koşulunu şöyle değiştirdim:


if ($global:IsEmptyCommand) {
        $statstr = "$green$bos_top $reset"
}
else {
  if ($IsOk) {
      $statstr = "$green$dolu_top $reset"
  } else {
      $statstr = "$red$dolu_top $reset"
  }
}

Sonrasında da prompt içinde iki satırdan oluşan prompt satırımın ikinci satırına $statstr ekledim ve durum hoşuma gitti.


Bazı faydalı özel unicode karakerleri şöyle:

0xE0B0, 0x25B6▶
0xE0B1, 0x003E>
0xE0B2, 0x25C0◀
0xE0B3, 0x003C<
0xE0B4, 0x25D7◗
0xE0B5sağ yarım çember
0xE0B6◖
0xE0B7sol yarım çember
0x256D╭
0x256E╮
0x256F╯
0x2570╰
0x250C┌
0x2510┐
0x2514└
0x2518┘
0x2500─
0x2502│

----

https://www.alt-codes.net/

https://www.w3schools.com/charsets/ref_utf_geometric.asp#gsc.tab=0

https://www.symbolselect.com/right-triangle/ 

2026-09-16

Powershell ile küçük mesaj penceresi göstermek

Powershell ile genelde işler terminalde gösterilecek mesajlarla sınırlı. Ama Windows üzerinde bazı kütüphaneleri kullanarak küçük bilgilendirme pencereleri göstermek de mümkün.


 Seçeneklerden biri PresentationFramework kullanmak

Add-Type -AssemblyName PresentationFramework
[System.Windows.MessageBox]::Show(
    "Mesaj içeriği",
    "Pencere başlığı",
    [System.Windows.MessageBoxButton]::OK,
    [System.Windows.MessageBoxImage]::Information
)

Benzer bir yöntem Windows.Forms kullanmak

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.MessageBox]::Show(
    "Mesaj içeriği",
    "Pencere başlığı",
    [System.Windows.MessageBoxButton]::OK,
    [System.Windows.MessageBoxImage]::Information
)

En basiti, WScript.Shell nesnesi oluşturmak olabilir.

$WShell = New-Object -ComObject Wscript.Shell
$Output = $wshell.Popup("Mesaj içeriği")

Sadece basit bir mesaj için bu kadar parametre mümkün ama bu Popup fonksiyonunun da başka parametreleri var.

$Output = $wshell.Popup(
	"Mesaj içeriği",	# asıl mesaj
    10,					# ekranda kaç saniye gösterilsin
    "Pencere başlığı"	# pencerenin başlığı
    0					# ne tür düğmelerin olacağı
)

Ve burada dördüncü parametre için olası değerler şöyle:

    0 — Sadece Tamam düğmesi
    1 — Tamam ve İptal düğmeleri;
    2 — Durdur, Yeniden dene ve Yoksay düğmeleri;
    3 — Evet, Hayır ve İptal düğmeleri;
    4 — Evet ve Hayır
    5 — Yeniden dene ve İptal;
    16 — Dur (kırmızı çarpı) simgesi;
    32 — Soru işareti simgesi;
    48 — Sarı üçgen içinde ünlem işareti;
    64 — Bilgi (i) işareti.

--- https://woshub.com/popup-notification-powershell/

2026-09-14

Powershell jobs ile paralel çalışma

Bir powershell betiğinde birkaç sunucudan sistem olay kayıtlarını çekmem gerek. Seri olarak bunları yapmak uzun sürdü. Paralel yapmak istedim.

Başlangıçta şöyle yapıyordum:


$ev1 = Get-WinEvent -Computername sunucu1 -FilterhashTable @{Logname="System";Id=4771;StartTime=(Get-Date).AddDays(-1)}
$ev1 = Get-WinEvent -Computername sunucu1 -FilterhashTable @{Logname="System";Id=4771;StartTime=(Get-Date).AddDays(-1)}

Paralel yapmanın birkaç yolu var. Bunlardan biri Powershell Job'larını kullanmak. Her bir sunucudan olayların çekilmesi için Start-Job ile birer görev oluşturdum.


$gorev1 = Start-Job -Name "g1" { Get-WinEvent -Computername sunucu1 -FilterhashTable @{Logname="System";Id=4771;StartTime=(Get-Date).AddDays(-1)} }
$gorev2 = Start-Job -Name "g2" { Get-WinEvent -Computername sunucu2 -FilterhashTable @{Logname="System";Id=4771;StartTime=(Get-Date).AddDays(-1)} }

Bu görevler eşzamanlı olarak bitmeyebilir. Onun için ikisinin de bittiğinden emin olmak için beklemem gerek. Bunu Wait-Job ile yapabilirim ama bu cmdlet çağrıldığında görevleri ekrana basar. Bunu görmek istemediğim için Out-Null ile çıkışı bastırıyorum.


Wait-Job -Jobs $gorev1, $gorev2 | Out-Null

Bu cmdlet işini bitirdikten sonra görevlerimin çıkışını okuyabilirim.


$olaylar1=Receive-Jobs -Job $gorev1
$olaylar2=Receive-Jobs -Job $gorev2

Her görev ayrı uzak sistemlerde çalıştığı için bu paralel çalışma, yaklaşık olarak iki görevin daha uzun süreni kadar zamanda bitiyor. Eğer bu iki görev de aynı yerel veya uzak sistemde çalışıyor olsaydı, duruma göre böyle bir kazanç elde edemeyebilirdim.

Bunu bir de Invoke-Command -Computername sunucuX { ... } -AsJob ile yapmak var.

2026-09-09

Profil dosyası olmadan prompt oluşturmak

Tek renkli bir terminal çok tatsız görünüyor. Ama her makinede de profil dosyası oluşturamıyorum, çünkü Execution Policy'yi değiştirmek gerek. O işlere girmeden ne yapabilirim diye düşününce terminale inline bir prompt fonkisyonu yazmak geldi aklıma. En basiti:


function prompt {write-host "$pwd [$(date -u %R)]" -fore blue;"> "}

olabileceği gibi biraz daha yazabilirsem


function prompt {Write-Host $pwd -NoNewLine -ForegroundColor Blue;Write-Host " [$(date -u '%R, %d-%a')]" -;"> "}

de olabilir. Bu tek seçenek değil. Eğer profile.ps1 gibi bir profil dosyamız varsa ve bunu executionpolicy'ye takılmadan tek seferlik çalıştırmak istiyorsak


iex (gc D:\profile.ps1 -raw)

ya da prompt fonksiyonunu bir ortam değişkenine atabilirsek (ki bunu kısıtlı kullanıcı yetkileriyle yapabilirim), örneğin $PROFILE gibi


iex $env:PROFILE

$PROFILE ortam değişkeni şu şekilde tanımlanmış olabilir:


ni -path env: -name PROFILE -value "function profile { write-host `"$pwd [$(date -u %R)]`" -fore blue;`"> `"}"

string'in içinde çift tırnak karakterini yazabilmek back-tick (`) kullandım.

Bu arada, Execution Policy, kısıtlı kullanıcı hakları ile sadece mevcut kullanıcı için betik çalıştırma yetkisini değiştirilebiliyor. Benim olmayan bir makine üzerinde bu ayarı değiştmek istemiyorum, ama elbette:


Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

de yapılabilirdi.