PowerShell modülü nasıl yazılır, zamanlanmış görev olarak nasıl çalıştırılır?
Beceri rehberi

PowerShell modülü nasıl yazılır, zamanlanmış görev olarak nasıl çalıştırılır?

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 5 dk okuma

PowerShell fonksiyonlarını modüle çevirip Görev Zamanlayıcı ile otomatik çalıştırma: .psm1, manifesto, tetikleyici, hesap ve sık hatalar.

Modül ve zamanlanmış görev ne işe yarar?

Bir PowerShell betiği tek başına çalıştığında kopyala-yapıştır ile yaşar: aynı fonksiyon her sunucuda farklı bir sürümde bulunur, biri düzeltilir, diğerleri unutulur. Modül bu dağınıklığı toplar. İlgili fonksiyonları tek bir pakette adlandırır, sürümler ve her makineden aynı komutla çağrılabilir hale getirir.

Zamanlanmış görev ise paketlenmiş işi insandan bağımsız çalıştırır: gece yedek temizliği, haftalık disk raporu, her sabah kullanıcı hesabı denetimi gibi tekrar eden işler Windows Görev Zamanlayıcı (Task Scheduler) tarafından başlatılır. İkisi birlikte, elle yürütülen bir betikten "sahiplenilmiş bir otomasyon" çıkarır.

Adım adım: betik modülü (.psm1) oluşturmak

Betik modülü, .psm1 uzantısıyla kaydedilmiş geçerli bir PowerShell betiğidir. Microsoft belgesindeki kural şudur: betik dosyasının adı ile içinde durduğu klasörün adı aynı olmalıdır. Örneğin DiskRapor.psm1 dosyası DiskRapor klasöründe durur.

Örnek bir modül gövdesi:

function Get-DiskUsage { param([string]$DriveLetter = 'C') Get-PSDrive -Name $DriveLetter | Select-Object Name, Used, Free }

function Write-TaskLog { param([string]$Message) Add-Content -Path $env:ProgramData\DiskRapor\task.log -Value "$(Get-Date) $Message" }

Export-ModuleMember -Function Get-DiskUsage, Write-TaskLog

Export-ModuleMember satırı, modülü içe aktaran kişinin hangi fonksiyonları göreceğini belirler. Belge, varsayılan olarak tüm fonksiyonların görünür olduğunu ama hangilerinin açılacağını açıkça yazmanın önerildiğini söyler. Yardımcı iç fonksiyonlarınız dışarı açılmaz, böylece bir gün adını değiştirdiğinizde bu değişiklik kullananları kırmaz.

Fonksiyon adlarında "Fiil-İsim" kuralına uyun (Get-, Set-, Write- gibi onaylı fiiller). Bu, hem keşfedilebilirlik hem de Get-Command ile arama için önemlidir.

Modül manifestosu ve doğru klasöre yerleştirme

Manifesto, modülün künyesini taşıyan .psd1 dosyasıdır: sürüm, yazar, hangi dosyanın kök modül olduğu, hangi fonksiyonların dışarı açıldığı. New-ModuleManifest cmdlet'i bu dosyayı oluşturur. Belgeye göre manifestoda zorunlu tek anahtar ModuleVersion'dır, ama pratikte şu alanları doldurmak iyidir:

  • RootModule: DiskRapor.psm1
  • ModuleVersion: modülün sürümü ($surum değişkeni sürüm numarasını taşır)
  • FunctionsToExport: dışarı açılan fonksiyonların listesi
  • Author ve Description: kimin sorumlu olduğunu gösterir

Örnek:

New-ModuleManifest -Path .\DiskRapor\DiskRapor.psd1 -RootModule 'DiskRapor.psm1' -ModuleVersion $surum -Author 'BT Operasyon' -FunctionsToExport 'Get-DiskUsage','Write-TaskLog'

Yerleştirme için $env:PSModulePath değişkenindeki klasörlerden birini kullanın. Makine geneli için ortak bir modül klasörü seçilebilir, tek kullanıcı için kullanıcının Documents altındaki PowerShell\Modules klasörü kullanılır. Belge, bu yollardan birine koyduğunuz modülün Import-Module çağırmadan, fonksiyon ilk kez çağrıldığında otomatik yüklendiğini söyler. Yoldan farklı bir yere koyarsanız Import-Module ile tam yolu vermeniz gerekir.

Test etmek için yeni bir oturumda şunları çalıştırın: Get-Module -ListAvailable DiskRapor, ardından Import-Module DiskRapor ve Get-Command -Module DiskRapor. Kodu değiştirip yeniden denerken Remove-Module ile oturumdan kaldırıp tekrar içe aktarın; Remove-Module dosyaları silmez, yalnız oturumdan çıkarır.

Zamanlanmış görevi PowerShell ile kaydetmek

ScheduledTasks modülündeki nesneler bir görevi tarif eder: eylem (ne çalışacak), tetikleyici (ne zaman), asıl kullanıcı (hangi hesapla) ve ayarlar. Register-ScheduledTask bunları birleştirip görevi kaydeder.

Örnek: modülü çağıran bir betiği her gün belirli saatte, SYSTEM hesabıyla çalıştıran görev.

$eylem = New-ScheduledTaskAction -Execute 'PowerShell.exe' -Argument '-NoProfile -File C:\Araclar\DiskRapor\nightly-run.ps1' $tetik = New-ScheduledTaskTrigger -Daily -At $baslangic $kimlik = New-ScheduledTaskPrincipal -UserId 'SYSTEM' -LogonType ServiceAccount -RunLevel Highest Register-ScheduledTask -TaskName 'DiskRapor-Gece' -Action $eylem -Trigger $tetik -Principal $kimlik

Burada $baslangic, gece yarısından sonraki bir saati temsil eden bir DateTime değeridir (örneğin Get-Date ile üretilmiş bir zaman). New-ScheduledTaskTrigger belgesine göre -At parametresi Once, Daily ve Weekly tetikleyicilerinde zorunludur.

Tetikleyici seçenekleri: -Once, -Daily (ve -DaysInterval ile günlerin aralığı), -Weekly (ve -DaysOfWeek, -WeeksInterval), -AtStartup (makine açıldığında), -AtLogOn (kullanıcı oturum açtığında). Bir görevde birden fazla tetikleyici bulunabilir; herhangi biri gerçekleştiğinde görev başlar. Belirli aralıkla yinelenen görev için tek seferlik tetikleyiciye -RepetitionInterval ve -RepetitionDuration verilir. Birden çok sunucu aynı anda aynı kaynağa gitmesin diye -RandomDelay ile rastgele gecikme ekleyebilirsiniz.

Hangi hesapla çalışacak? Asıl kullanıcı ve yetki

Zamanlanmış görevlerin en sık patladığı yer hesap ve yetkidir. New-ScheduledTaskPrincipal belgesi, bir asıl kullanıcı (principal) tanımladığınızda görevin o hesap oturum açık olmasa da çalışabildiğini söyler. Seçenekler:

  • Sistem hesapları (SYSTEM, LOCALSERVICE, NETWORKSERVICE): parola gerektirmez. Register-ScheduledTask belgesine göre bu iyi bilinen hesaplarda parola yok sayılır.
  • Alan (domain) hizmet hesabı: parolası -User ve -Password ile ya da uygun LogonType ile verilir. Ağdaki dosya paylaşımına erişim gerekiyorsa SYSTEM yerine bu yol gerekir, çünkü SYSTEM ağ kaynaklarına makine hesabı kimliğiyle gider.
  • -RunLevel Highest: yükseltilmiş yetkiyle çalıştırır; yalnızca gerçekten gerekiyorsa verin.

Yetki ilkesi basittir: görevin işini yapabilecek en dar hesabı seçin. Parolayı betik metnine yazmayın; kimlik bilgisi gerekiyorsa kuruluşun kasası ya da Windows kimlik bilgisi deposu gibi bir mekanizma kullanın.

Çalışan görevi doğrulama ve günlük tutma

Görev kaydedildi diye çalıştığı anlamına gelmez. Doğrulama adımları:

  • Start-ScheduledTask -TaskName 'DiskRapor-Gece' ile görevi elle başlatın.
  • Get-ScheduledTaskInfo ile son çalışma zamanını ve son sonuç kodunu okuyun.
  • Betiğin içinde Write-TaskLog gibi bir fonksiyonla başlangıç, bitiş ve hata mesajlarını dosyaya yazın. Zamanlanmış görev ekranı olmayan bir bağlamda çalıştığı için konsola yazılan hiçbir şeyi göremezsiniz.
  • Betiğin başına try/catch koyun, hatada günlüğe yazıp sıfırdan farklı bir çıkış koduyla bitirin ki Görev Zamanlayıcı başarısızlığı kaydetsin.

Değişiklik yaptığınızda görevi silip yeniden yaratmak yerine Set-ScheduledTask kullanın; Unregister-ScheduledTask ile kaldırma işlemi de aynı modülde bulunur. Görevin tanımını Export-ScheduledTask ile dışa aktarıp sürüm denetimine koymak, hangi sunucuda hangi tanımın çalıştığını izlemeyi kolaylaştırır.

Sık yapılan hatalar

  • Klasör adı ile .psm1 adının farklı olması: modül listede görünmez.
  • Fonksiyonu dışarı açmayı unutmak: Export-ModuleMember ya da manifestodaki FunctionsToExport eksikse komut bulunamaz.
  • Görevi geliştirici hesabıyla test edip SYSTEM ile çalıştırmak: ortam değişkenleri, eşlenmiş sürücüler ve kullanıcı profili farklıdır. Betikte tam yol kullanın.
  • Göreli yollar: çalışma dizini görevde beklediğiniz yer olmayabilir.
  • Her şeyi tek betikte tutmak: iş mantığı modülde, zamanlama ve günlük kayıt ince bir çağrı betiğinde dursun. Modülü ayrıca elle test edebilirsiniz.
  • Sürümsüz modül: değişiklikten sonra eski sürümün hâlâ çalışıp çalışmadığını anlayamazsınız. ModuleVersion değerini her anlamlı değişiklikte artırın.

Mindset programlarında nerede çalışılır?

Bu iş akışı, Windows sunucu ve istemci filosunu betikle yöneten sistem yöneticileri ve bakım işlerini otomatikleştirmek isteyen BT operasyon ekipleri içindir. Çözdüğü sorun, elle ve kişiye bağlı yürüyen tekrarlı işlerin paylaşılabilir, sürümlenebilir ve denetlenebilir hale getirilmesidir.

Mindset'in "PowerShell ile Windows Otomasyonu" eğitiminin son modülü "Modül Paketleme, Zamanlama ve Proje" başlığını taşır; öncesinde nesne modeli, fonksiyon yazımı ve hata yönetimi, uzak yönetim ve güvenlik konuları yer alır. Kurumsal ekipler bu sırayı, kendi ortamlarındaki bir tekrarlı görevi proje olarak seçip modüle çevirmek için kullanabilir.

İlgili Mindset programı

PowerShell ile Windows Otomasyonu

Sık sorulanlar

Sık sorulan sorular

Modül ile betik arasındaki fark nedir?

Betik tek bir dosyadır ve çalıştırıldığında işini yapıp biter. Modül ise içe aktarılabilen, sürümü ve manifestosu olan, birden çok fonksiyonu paylaşılabilir biçimde sunan pakettir. Betikler modülün fonksiyonlarını çağırabilir; aynı kod birçok betikte kopyalanmak yerine tek yerde bakımı yapılır.

Zamanlanmış görevi grafik arayüz yerine PowerShell ile kaydetmenin avantajı ne?

Kod ile kayıt tekrarlanabilirdir, yani her çalıştırmada aynı sonucu verir: aynı görev tanımını birçok sunucuya aynı biçimde uygulayabilir, sürüm denetiminde saklayabilir ve değişiklikleri inceleyebilirsiniz. Arayüzde elle yapılan ayarlar ise makineden makineye farklılaşır ve belgelenmesi zordur.

Görev başarılı göründüğü halde işini yapmadıysa nereye bakmalıyım?

Önce Get-ScheduledTaskInfo ile son sonuç koduna, sonra betiğin kendi günlük dosyasına bakın. Çoğunlukla sorun hesap yetkisi, göreli yol ya da kullanıcı profiline bağlı bir ayardır. Görevi görevin kendi hesabıyla elle başlatıp çıktıyı dosyaya yönlendirmek nedeni hızlıca ortaya çıkarır.

Modülü birden çok sunucuya nasıl dağıtırım?

Küçük ortamlarda modül klasörünü PSModulePath içindeki ortak bir konuma kopyalamak yeterlidir. Büyük ortamlarda dahili bir depo ya da yapılandırma yönetimi aracıyla sürümlü dağıtım yapılır. Hangi yolu seçerseniz seçin, manifestodaki ModuleVersion hangi sunucuda hangi sürüm olduğunu izlemenizi sağlar.

PowerShell Modülü Paketleme ve Zamanlanmış Görev