Sin UI: la interfaz de Windows cambia en cada versión, los cmdlets, el registro y las herramientas de consola son estables. Esta guía se ejecuta entera por PowerShell, comando por comando, en una PC nueva con la impresora recién instalada.
SOLUCION_impresion_Linux_a_Windows.mdqueda como log técnico (diagnóstico). Esta guía es el procedimiento limpio y reproducible.
powershell.exe — siempre está en Windows 10/11; no usar pwsh 7,
porque Set-LocalUser y Out-Printer solo existen en 5.1).Win + X → Terminal (administrador), o desde una shell normal:
Start-Process powershell -Verb RunAs
True):
([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(
[Security.Principal.WindowsBuiltInRole]::Administrator)
| Dato | Ejemplo (tu red) | Dónde verlo |
|---|---|---|
| PC host (la de la impresora) | IP 192.168.0.203, nombre LIVING |
ipconfig |
| Impresora | Brother HL-L1222 Printer (o HP PSC 1400 series) |
Get-Printer |
| Share (recurso compartido) | Brother HL-L1222 Printer |
net share |
| Usuario de autenticación | arctest |
Paso 1 |
| Contraseña | P@ssw0rd123 |
la elegís vos |
| Cliente | ArchLinux (CUPS + SMB) | Paso 8 |
arctestarctest¿Por qué un usuario? Verificado: sin credenciales se pueden listar los shares, pero no imprimir (el spooler rechaza/borra trabajos de invitados/anónimos). No borrar
arctestjamás.
# 1) crear el usuario
net user arctest P@ssw0rd123 /add
# 2) contraseña que no caduca (imprescindible: si caduca, Linux queda sin imprimir)
Get-LocalUser -Name arctest | Set-LocalUser -PasswordNeverExpires $true
# 3) ocultarlo de la pantalla de inicio (queda solo tu usuario visible; NO afecta a SMB)
$k = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts"
if (-not (Test-Path "$k\UserList")) { New-Item "$k\UserList" -Force | Out-Null }
New-ItemProperty -Path "$k\UserList" -Name "arctest" -Value 0 -PropertyType DWord -Force | Out-Null
⚠️ Nunca net user arctest /active:no: una cuenta deshabilitada no puede autenticar por SMB.
✅ Verificar:
net user arctest # debe listar sin errores
# 2.0 red: perfil privado y firewall abierto (si está "Público", nada funciona)
Get-NetConnectionProfile | Set-NetConnectionProfile -NetworkCategory Private
Get-NetFirewallRule | Where-Object { $_.DisplayGroup -match 'impresora|printer|descubrimiento|discovery' } |
Enable-NetFirewallRule
# 2.1 ver el nombre EXACTO de la impresora y su puerto
Get-Printer | Format-Table Name, PortName, Shared, ShareName
# 2.2 compartir (el share lleva el mismo nombre que la impresora)
Set-Printer -Name "Brother HL-L1222 Printer" -Shared $true -ShareName "Brother HL-L1222 Printer"
✅ Verificar:
net share # debe aparecer el share de la impresora
Get-SmbShare | Format-Table Name, Path
arctestPowerShell sí puede (con Set-Printer -PermissionSDDL; hace poco era imposible sin P/Invoke):
toma el SDDL actual, mete un ACE de impresión para el SID de arctest y lo vuelve a aplicar.
$pr = "Brother HL-L1222 Printer"
$sid = (New-Object System.Security.Principal.NTAccount('arctest')).Translate(
[System.Security.Principal.SecurityIdentifier]).Value
$sddl = (Get-Printer -Name $pr -Full).PermissionSDDL
$ace = "(A;;SWRC;;;$sid)" # SW = permiso Print
if ($sddl -notmatch [regex]::Escape($sid)) {
$nuevo = ([regex]'D:[A-Z]*').Replace($sddl, { param($m) $m.Value + $ace }, 1) # al inicio del DACL
Set-Printer -Name $pr -PermissionSDDL $nuevo
Write-Host "Permiso Print agregado para arctest ($sid)"
} else {
Write-Host "arctest ya tenía permiso"
}
✅ Verificar:
(Get-Printer -Name $pr -Full).PermissionSDDL # debe verse el SID de arctest (S-1-5-21-...)
4 valores (por defecto existen todos):
| Valor | Ruta (HKLM) | Dato |
|---|---|---|
ForceGuest |
SYSTEM\CurrentControlSet\Control\Lsa |
0 (modelo clásico) |
RestrictAnonymous |
SYSTEM\CurrentControlSet\Control\Lsa |
0 |
EveryoneIncludesAnonymous |
SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0 |
1 |
RestrictNullSessAccess |
SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0 |
0 |
$n = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
$m = "$n\MSV1_0"
Set-ItemProperty $n -Name ForceGuest -Value 0 -Type DWord
Set-ItemProperty $n -Name RestrictAnonymous -Value 0 -Type DWord
Set-ItemProperty $m -Name EveryoneIncludesAnonymous -Value 1 -Type DWord
Set-ItemProperty $m -Name RestrictNullSessAccess -Value 0 -Type DWord
(Si alguno faltara: New-ItemProperty -Path $n -Name X -Value 0 -PropertyType DWord -Force.)
El usuario Invitado puede quedar deshabilitado; esta guía no depende de él:
net user Invitado /active:no
✅ Verificar:
Get-ItemProperty $n -Name ForceGuest, RestrictAnonymous | Select-Object ForceGuest, RestrictAnonymous
Get-ItemProperty $m -Name EveryoneIncludesAnonymous, RestrictNullSessAccess |
Select-Object EveryoneIncludesAnonymous, RestrictNullSessAccess
# deben dar: 0, 0, 1, 0
Con BIDI activo, Windows consulta el estado por USB, lee un falso “cartucho vacío” y detiene el job
(la HP hace ruido y se traba). Se limpia el bit 0x800 de Attributes:
$hp = "HKLM:\SYSTEM\CurrentControlSet\Control\Print\Printers\HP PSC 1400 series"
$v = (Get-ItemProperty $hp).Attributes
Set-ItemProperty $hp -Name Attributes -Value ($v -band 0xFFFFF7FF) -Type DWord
Restart-Service Spooler
✅ Verificar: Get-ItemProperty $hp | Select-Object Attributes → el bit 0x800 apagado
(en esa HP el valor quedó 0x208).
# 6.1 vaciar trabajos atascados y reiniciar el servicio
Get-Printer | ForEach-Object { Get-PrintJob -PrinterName $_.Name -ErrorAction SilentlyContinue | Remove-PrintJob }
Stop-Service Spooler -Force
Remove-Item "C:\Windows\System32\spool\PRINTERS\*" -Force -Recurse -ErrorAction SilentlyContinue
Start-Service Spooler
# 6.2 activar el registro de eventos de impresión (para poder verificar con el 307)
wevtutil sl Microsoft-Windows-PrintService/Operational /e:true
# 6.3 imprimir una prueba desde Windows
"Prueba de impresión $(Get-Date)" | Out-Printer -Name "Brother HL-L1222 Printer"
✅ Verificar (evento 307 = “documento impreso”):
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PrintService/Operational'; Id=307} -MaxEvents 3 |
Format-List TimeCreated, Message
Si salió la página desde Windows, el host está listo.
El paso que faltaba. Las PCs Windows que ya la tenían agregada la tenían conectada sin contraseña (invitado). Después de los Pasos 1–6 hay que quitar esa conexión vieja, borrar las credenciales guardadas del host y agregarla de nuevo autenticando con
arctest. Windows usa la conexión cacheada: si no la borrás, puede seguir fallando o pedir credenciales de forma errática. Ejecutar en cada PC Windows cliente.
Get-Printer | Where-Object Name -like '\\192.168.0.203*' | Remove-Printer
cmdkey /list | findstr /i "192.168.0.203" # ver qué hay guardado
cmdkey /delete:192.168.0.203 # borrar
cmdkey /delete:LegacyGeneric:target=192.168.0.203 # por si figuraba con ese formato
# 1) dejar guardadas las credenciales del host ANTES de conectar
cmdkey /add:192.168.0.203 /user:arctest /pass:P@ssw0rd123
# 2) conectar la impresora de red (pide credenciales si el paso anterior no bastó)
Add-Printer -ConnectionName "\\192.168.0.203\Brother HL-L1222 Printer"
# 3) opcional: impresora predeterminada
(New-Object -ComObject WScript.Network).SetDefaultPrinter("\\192.168.0.203\Brother HL-L1222 Printer")
Fallback si da “acceso denegado” (fuerza una sesión SMB autenticada al servidor primero):
net use \\192.168.0.203\print$ /user:arctest P@ssw0rd123 /persistent:no
Add-Printer -ConnectionName "\\192.168.0.203\Brother HL-L1222 Printer"
net use \\192.168.0.203\print$ /delete
Get-Printer | Where-Object Name -like '\\192.168.0.203*' # la impresora debe figurar
"Prueba desde cliente $(Get-Date)" | Out-Printer -Name "\\192.168.0.203\Brother HL-L1222 Printer"
Y en el host: evento 307 (comando del Paso 6).
(Acá obvio que no hay PowerShell: son comandos de la propia máquina Linux.)
# 8.1 paquetes
sudo pacman -S --needed cups cups-filters ghostscript gutenprint hplip a2ps
sudo systemctl enable --now cups
yay -S brother-hll1222 # driver oficial Brother (AUR)
# 8.2 encontrar el PPD instalado
find /usr/share/ppd -iname '*1222*' # HP: find /usr/share/ppd -iname '*psc_1400*'
# 8.3 crear la cola (renderiza en Linux y envía por SMB al host Windows)
sudo lpadmin -p Brother1222 -E -P /usr/share/ppd/Brother/HL1222.ppd \
-v 'smb://arctest:P@ssw0rd123@192.168.0.203/Brother HL-L1222 Printer'
sudo lpadmin -d Brother1222
# HP equivalente:
# sudo lpadmin -p HP1400 -E -P /usr/share/ppd/hplip/HP/hp-psc_1400_series.ppd \
# -v 'smb://arctest:P@ssw0rd123@192.168.0.203/HP PSC 1400 series'
# 8.4 imprimir y verificar
lpstat -p -d
lp -d Brother1222 documento.pdf
URI:
smb://USUARIO:CONTRASEÑA@IP/NOMBRE_DEL_SHARE. Las de arriba son las que ya funcionaron probadas. Si cambiás la contraseña y falla la autenticación, codificá los caracteres especiales (@→%40).
✅ Verificar: evento 307 en el host. Si el trabajo aparece y se borra solo (eventos 800 → 310), volver a los Pasos 1, 3 y 7.
Debug si hace falta:
sudo cupsctl LogLevel=debug2
tail -f /var/log/cups/error_log
smbclient -N -L //192.168.0.203 # listar shares sin credenciales (no imprime)
smbclient -L //192.168.0.203 -U 'arctest%P@ssw0rd123' # con credenciales
Ajustá las variables y ejecutá todo junto (Windows PowerShell 5.1 como admin):
# ===== DATOS =====
$Impresora = "Brother HL-L1222 Printer"
$Usuario = "arctest"
$Pass = "P@ssw0rd123"
# ===== 1 USUARIO =====
net user $Usuario $Pass /add
Get-LocalUser -Name $Usuario | Set-LocalUser -PasswordNeverExpires $true
$k = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts"
if (-not (Test-Path "$k\UserList")) { New-Item "$k\UserList" -Force | Out-Null }
New-ItemProperty -Path "$k\UserList" -Name $Usuario -Value 0 -PropertyType DWord -Force | Out-Null
# ===== 2 RED + COMPARTIR =====
Get-NetConnectionProfile | Set-NetConnectionProfile -NetworkCategory Private
Get-NetFirewallRule | Where-Object { $_.DisplayGroup -match 'impresora|printer|descubrimiento|discovery' } |
Enable-NetFirewallRule
Set-Printer -Name $Impresora -Shared $true -ShareName $Impresora
# ===== 3 PERMISO PRINT =====
$sid = (New-Object System.Security.Principal.NTAccount($Usuario)).Translate(
[System.Security.Principal.SecurityIdentifier]).Value
$sddl = (Get-Printer -Name $Impresora -Full).PermissionSDDL
$ace = "(A;;SWRC;;;$sid)"
if ($sddl -notmatch [regex]::Escape($sid)) {
$nuevo = ([regex]'D:[A-Z]*').Replace($sddl, { param($m) $m.Value + $ace }, 1)
Set-Printer -Name $Impresora -PermissionSDDL $nuevo
}
# ===== 4 POLÍTICA =====
$n = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
$m = "$n\MSV1_0"
Set-ItemProperty $n -Name ForceGuest -Value 0 -Type DWord
Set-ItemProperty $n -Name RestrictAnonymous -Value 0 -Type DWord
Set-ItemProperty $m -Name EveryoneIncludesAnonymous -Value 1 -Type DWord
Set-ItemProperty $m -Name RestrictNullSessAccess -Value 0 -Type DWord
# ===== 5 (SOLO HP) BIDI OFF =====
# $hp = "HKLM:\SYSTEM\CurrentControlSet\Control\Print\Printers\HP PSC 1400 series"
# $v = (Get-ItemProperty $hp).Attributes
# Set-ItemProperty $hp -Name Attributes -Value ($v -band 0xFFFFF7FF) -Type DWord
# ===== 6 SPOOLER + EVENTOS + PRUEBA =====
Get-Printer | ForEach-Object { Get-PrintJob -PrinterName $_.Name -ErrorAction SilentlyContinue | Remove-PrintJob }
Stop-Service Spooler -Force
Remove-Item "C:\Windows\System32\spool\PRINTERS\*" -Force -Recurse -ErrorAction SilentlyContinue
Start-Service Spooler
wevtutil sl Microsoft-Windows-PrintService/Operational /e:true
"Prueba $(Get-Date)" | Out-Printer -Name $Impresora
# ===== ✅ VERIFICAR =====
net share
Get-Printer | Format-Table Name, Shared, ShareName
(Get-Printer -Name $Impresora -Full).PermissionSDDL
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PrintService/Operational'; Id=307} -MaxEvents 1 |
Format-List TimeCreated, Message
⚠️ En cada PC Windows cliente (Paso 7): Remove-Printer de la vieja → cmdkey /delete →
cmdkey /add con arctest → Add-Printer -ConnectionName.
sudo pacman -S --needed cups cups-filters ghostscript gutenprint hplip a2ps
sudo systemctl enable --now cups
yay -S brother-hll1222
find /usr/share/ppd -iname '*1222*'
sudo lpadmin -p Brother1222 -E -P /usr/share/ppd/Brother/HL1222.ppd \
-v 'smb://arctest:P@ssw0rd123@192.168.0.203/Brother HL-L1222 Printer'
sudo lpadmin -d Brother1222
lpstat -p -d
lp -d Brother1222 documento.pdf
| Síntoma | Causa real / solución |
|---|---|
| Job llega como “documento remoto de bajo nivel”, 0 páginas, sin ruido | Impresora GDI/host-based: no acepta texto crudo. Renderizar en Linux con el driver correcto y enviar PDF (nunca -o raw). |
| Brother no imprime (410 bytes, 0 páginas) | Falta el driver (brother-hll1222 desde AUR). |
| HP hace ruido y se traba; “cartucho vacío” falso | BIDI activo → Paso 5 (bit 0x800). |
NT_STATUS_ACCESS_DENIED |
Sin credenciales válidas → Pasos 1 (usuario), 3 (permiso Print) y 7 (reagregar con contraseña). |
| El trabajo llega y Windows lo borra solo (evento 800 y luego 310) | El spooler rechaza invitados/anónimos: imprimir autenticado con arctest. |
| Las PCs Windows dejaron de imprimir tras los cambios | Paso 7: la conexión vieja quedó sin credenciales → borrar y reagregar. |
| “Acceso denegado” o “no se encuentra la ruta” al agregar | Firewall/perfil (Paso 2), credenciales sin guardar, o spooler caído. |
texttopdf crasheaba (signal 11) en CUPS |
Se enviaba text/plain; enviar PDF evita ese filtro. |
arctest: única cuenta con la que Linux y las demás PCs imprimen.C:\Users\Public\ (hp.ps1, hpfix.ps1,
hpdiag.ps1, state.ps1, dump.ps1, sec.ps1, setacl2.ps1, share.ps1): se pueden borrar.