Windows Server üzerine kurulan print server rolü için yönetimi kolay olması amacı ile Active Directory Security Groupları kullanılır, bu gruplar sayesinde Directory'e doğrudan LDAP ile ulaşıp grup üzerinde düzenlemeler kolaylıkla yapılabilir. Fakat bazı durumlar için yazıcı sunucusunda doğrudan yazıcıya müdahale etmeniz gerekebilir. Manuel yönetmeniz gereken yazıcılar olabilir. Bu gibi durumlar için kullanabileceğiniz powershell scriptleri hazırladım.
Senaryomuz domain yapısında olan printer sunucusu için geçerlidir.
Powershell scriptleri kullanabilmek için sunucuya Powershell 7.4.7.0 kurulmuştur.
Get-Printer
Öncelik olarak sunucunuzda mevcut olan printer listesine ulaşmak isterseniz kullanabileceğiniz Powershell komutu " Get-Printer " olmalı. Bu komut ile sunucuzdaki printer listesini çekebilirsiniz.

Yazıcıda Tanımlı Olan Kullanıcılar
Yazıcıda tanımlı olan domain kullanıcılarını listelemek için powershell script
param(
[Parameter(Mandatory=$true)]
[string]$PrinterName
)
# 1) Yazıcının SDDL’sini al (-Full ile tam özellikleri)
$sddl = Get-Printer -Name $PrinterName -Full |
Select-Object -ExpandProperty PermissionSDDL
if (-not $sddl) {
Write-Error "SDDL bilgisi bulunamadı. Yazıcı adı hatalı olabilir: $PrinterName"
return
}
# 2) SDDL’yi .NET RawSecurityDescriptor nesnesine parse et
try {
$rawSD = [System.Security.AccessControl.RawSecurityDescriptor]$sddl
}
catch {
Write-Error "SDDL parse edilemedi: $($_.Exception.Message)"
return
}
$dacl = $rawSD.DiscretionaryAcl
if (-not $dacl) {
Write-Error "DACL (DiscretionaryAcl) okunamadı!"
return
}
Write-Host "`nYazıcı: $PrinterName"
Write-Host "YEKTA.WEB.TR domainindeki kullanıcı(lar)ın izinleri:"
Write-Host "----------------------------------------------------"
# 3) DACL içindeki her ACE’yi incele
# SID -> NTAccount çevirisi yap, domain yektawebtr mi kontrol et.
# Eşleşiyorsa ekrana yaz.
$foundAny = $false
foreach ($ace in $dacl) {
# Bazı ACE tipleri CommonAce / CustomAce olabilir
if ($ace -is [System.Security.AccessControl.CommonAce]) {
# SID
$sid = $ace.SecurityIdentifier
# SID'yi NTAccount'a çevirmeye çalış
try {
$ntAccount = $sid.Translate([System.Security.Principal.NTAccount])
}
catch {
continue # Çevrilemeyen SID'leri atla (Local Service vb.)
}
# NTAccount "DOMAIN\Username" formatında bir string döndürür
$accountStr = $ntAccount.Value
# Domainin "YEKTAWEBTR" içerip içermediğine bak:
# (Büyük/küçük harf farkı olmaması için -imatch kullanılabilir.)
if($accountStr -imatch "YEKTAWEBTR"){
$foundAny = $true
# ACE tipi (Allow mu, Deny mi), AccessMask hangisi vb.
# AceQualifier => AccessAllowed (Allow=0), AccessDenied (Deny=1)
$aceType = $ace.AceQualifier
if ($aceType -eq [System.Security.AccessControl.AceQualifier]::AccessAllowed) {
$aceTypeStr = "ALLOW"
} elseif ($aceType -eq [System.Security.AccessControl.AceQualifier]::AccessDenied) {
$aceTypeStr = "DENY"
} else {
$aceTypeStr = $aceType.ToString()
}
# AccessMask hangi hakları temsil ediyor (Print=131072 vs.)
$accessMask = $ace.AccessMask
Write-Host "Kullanıcı/Grup: $accountStr AceType: $aceTypeStr AccessMask: $accessMask"
}
}
}
if (-not $foundAny) {
Write-Host "yekta.web.tr domainine ait herhangi bir kullanıcı/grup bulunamadı."
}
Bu powershell scripti parametre ile çalıştıracaksınız.

Yazıcıda Kullanıcının Tüm Yetkisini Alma
KL-4Kat-BM yazıcımızdan yektag kullanıcının yetkisini almak için kullanacağınız powershell script
param(
[Parameter(Mandatory=$true)]
[string]$PrinterName,
[Parameter(Mandatory=$true)]
[string]$UserName
)
# Assembly'leri opsiyonel olarak yükle, hata verse de devam
try {
Add-Type -AssemblyName System.Security.AccessControl -ErrorAction Stop
Add-Type -AssemblyName System.Security.Principal -ErrorAction Stop
}
catch {
Write-Verbose "Assembly eklenemedi: $($_.Exception.Message) - Devam..."
}
Write-Host "`n=== Kullanıcıyı Yazıcı ACL'sinden Kaldırma Betiği ==="
Write-Host "Yazıcı Adı : $PrinterName"
Write-Host "Kullanıcı : $UserName"
Write-Host "--------------------------------------------`n"
# 1) Yazıcının mevcut SDDL’sini al (-Full ile tüm özellikleri)
$sddl = Get-Printer -Name $PrinterName -Full |
Select-Object -ExpandProperty PermissionSDDL
if (-not $sddl) {
Write-Error "SDDL bilgisi boş veya yazıcı bulunamadı: $PrinterName"
return
}
Write-Host "Eski SDDL:"
Write-Host $sddl
Write-Host "--------------------------------------------`n"
# 2) RawSecurityDescriptor nesnesi oluştur
try {
$rawSD = [System.Security.AccessControl.RawSecurityDescriptor]$sddl
}
catch {
Write-Error "SDDL parse hatası: $($_.Exception.Message)"
return
}
$dacl = $rawSD.DiscretionaryAcl
if (-not $dacl) {
Write-Error "DACL bulunamadı!"
return
}
# 3) Kullanıcının SID’sini bul. (DOMAIN\User veya doğrudan "S-1-5-..." ise)
$accountSid = $null
try {
if ($UserName -like "S-1-5-*") {
# SID formatı
$accountSid = New-Object System.Security.Principal.SecurityIdentifier($UserName)
}
else {
# Domain\User formatı
$ntAccount = New-Object System.Security.Principal.NTAccount($UserName)
$accountSid = $ntAccount.Translate([System.Security.Principal.SecurityIdentifier])
}
}
catch {
Write-Error "Kullanıcının SID çözümlenemedi: $($_.Exception.Message)"
return
}
Write-Host "Kullanıcı SID: $accountSid"
# 4) Bu kullanıcıya (SID) ait ACE’lerin indekslerini topla
$indexesToRemove = @()
for ($i = 0; $i -lt $dacl.Count; $i++) {
$aceItem = $dacl[$i]
if ($aceItem.SecurityIdentifier -eq $accountSid) {
$indexesToRemove += $i
}
}
# 5) Büyükten küçüğe sil. Aksi halde indeksler kayar.
$indexesToRemove = $indexesToRemove | Sort-Object -Descending
foreach ($idx in $indexesToRemove) {
$dacl.RemoveAce($idx)
}
# 6) Değiştirilmiş DACL’i geri atayıp yeni SDDL al
$rawSD.DiscretionaryAcl = $dacl
$newSddl = $rawSD.GetSddlForm("All")
Write-Host "`nYeni SDDL (Kullanıcı kaldırıldı):"
Write-Host $newSddl
Write-Host "--------------------------------------------`n"
# 7) Yazıcıya yeni SDDL’yi set et
try {
Set-Printer -Name $PrinterName -PermissionSDDL $newSddl
Write-Host "Başarılı! '$UserName' tamamen ACL'den kaldırıldı."
}
catch {
Write-Error "Set-Printer hatası: $($_.Exception.Message)"
}
Bu script ile yazıcının üzerindeki SDDL değerinden yektag kullanıcısının SID'sini alıp yeni SDDL hazırlayıp yazıcıya tanımlandırıyoruz.

Yazıcıda Kullanıcıya Yazma Yetkisi Verme
KL-4Kat-BM yazıcımıza yeni bir kullanıcı eklemek için kullanacağımız powershell script
param(
[Parameter(Mandatory=$true)]
[string]$PrinterName,
[Parameter(Mandatory=$true)]
[string]$UserName
)
# Assembly'leri opsiyonel olarak yüklemeye çalışıyoruz; hata verse de devam eder
try {
Add-Type -AssemblyName System.Security.AccessControl -ErrorAction Stop
Add-Type -AssemblyName System.Security.Principal -ErrorAction Stop
}
catch {
# Bu aşamada hata veriyorsa, muhtemelen zaten yüklü veya gerek yok.
Write-Verbose "Assembly eklenemedi: $($_.Exception.Message) - Devam ediliyor..."
}
Write-Host "`n=== Yalnızca Print Yetkisi Verme Betiği ==="
Write-Host "Yazıcı Adı : $PrinterName"
Write-Host "Kullanıcı : $UserName"
Write-Host "--------------------------------------------`n"
# 1) Yazıcının mevcut SDDL’sini al (-Full ile tüm özellikler)
$sddl = Get-Printer -Name $PrinterName -Full |
Select-Object -ExpandProperty PermissionSDDL
if (-not $sddl) {
Write-Error "SDDL bilgisi boş veya yazıcı bulunamadı: $PrinterName"
return
}
Write-Host "Eski SDDL:"
Write-Host $sddl
Write-Host "--------------------------------------------`n"
# 2) RawSecurityDescriptor nesnesi oluştur
try {
$rawSD = [System.Security.AccessControl.RawSecurityDescriptor]$sddl
}
catch {
Write-Error "SDDL parse hatası: $($_.Exception.Message)"
return
}
$dacl = $rawSD.DiscretionaryAcl
if (-not $dacl) {
Write-Error "DACL bulunamadı!"
return
}
# 3) Kullanıcının SID’sini al
try {
$ntAccount = New-Object System.Security.Principal.NTAccount($UserName)
$userSID = $ntAccount.Translate([System.Security.Principal.SecurityIdentifier])
}
catch {
Write-Error "Kullanıcının SID çözümlenemedi: $($_.Exception.Message)"
return
}
Write-Host "Kullanıcı SID: $userSID"
# 4) Bu kullanıcıya ait tüm eski ACE’leri sil
$acesToRemove = @()
for ($i = 0; $i -lt $dacl.Count; $i++) {
$aceItem = $dacl[$i]
if ($aceItem.SecurityIdentifier -eq $userSID) {
$acesToRemove += $aceItem
}
}
foreach ($aceItem in $acesToRemove) {
$dacl.RemoveAce($dacl.IndexOf($aceItem))
}
# 5) Yalnızca Print haklarını verecek ACE oluştur (Allow)
# 131072 = 0x20000 => “Sadece Print”
# Eğer çalışmazsa 131080 = 0x20008 gibi farklı mask değerlendirilebilir.
$allowMask = 131080
try {
# Bazı PowerShell/.NET sürümlerinde sadece 6 parametreli constructor geçerli:
# CommonAce(AceFlags, AceQualifier, AccessMask, SID, isCallback, opaque)
$newAce = New-Object System.Security.AccessControl.CommonAce(
[System.Security.AccessControl.AceFlags]::None,
[System.Security.AccessControl.AceQualifier]::AccessAllowed,
$allowMask,
$userSID,
$false,
$null
)
}
catch {
Write-Error "CommonAce oluşturulamadı: $($_.Exception.Message)"
return
}
$dacl.InsertAce($dacl.Count, $newAce)
# 6) DACL’i geri yerleştirip yeni SDDL al
$rawSD.DiscretionaryAcl = $dacl
$newSddl = $rawSD.GetSddlForm("All")
Write-Host "`nYeni SDDL (Yalnızca Print):"
Write-Host $newSddl
Write-Host "--------------------------------------------`n"
# 7) Yazıcıya yeni SDDL’yi set et
try {
Set-Printer -Name $PrinterName -PermissionSDDL $newSddl
Write-Host "Başarılı! '$UserName' kullanıcısına yalnızca 'Print' izni verildi."
}
catch {
Write-Error "Set-Printer hatası: $($_.Exception.Message)"
}
Bu script ile KL-4Kat-BM yazıcının SDDL değerine yektag kullanıcısı için domaindeki SID değerini ekliyoruz. Bu script sadece kullanıcıya yazma yetkisi verir.

Scriptlerin kullanımı bu kadar. Siz yine de daha efektif olması için security groupları kullanın. :)
Bu yazı için kullanılan scriptler ChatGPT ile hazırlanmıştır.