<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title><![CDATA[jmtella - TIP's, Ejercicios y Ejemplos]]></title>
		<link>https://jmtella.com/foro/</link>
		<description />
		<language>es</language>
		<lastBuildDate>Fri, 22 May 2026 05:40:35 GMT</lastBuildDate>
		<generator>vBulletin</generator>
		<ttl>60</ttl>
		<image>
			<url>https://jmtella.com/foro/images/misc/rss.png</url>
			<title><![CDATA[jmtella - TIP's, Ejercicios y Ejemplos]]></title>
			<link>https://jmtella.com/foro/</link>
		</image>
		<item>
			<title><![CDATA[[TIP] en las ultimas versiones de Windows 11 y Server 2025, al lanzar un archivo .rdp para conexión remota nos pedirá permisos para conectar devices.]]></title>
			<link>https://jmtella.com/foro/forum/ejercicios-y-ejemplos/57679-tip-en-las-ultimas-versiones-de-windows-11-y-server-2025-al-lanzar-un-archivo-rdp-para-conexión-remota-nos-pedirá-permisos-para-conectar-devices</link>
			<pubDate>Tue, 21 Apr 2026 08:45:10 GMT</pubDate>
			<description>En las ultimas versiones de Windows 11 y Windows Server 2025, si lanzamos un archivo .rdp para conexión remota nos pedirá permisos para conectar...</description>
			<content:encoded><![CDATA[En las ultimas versiones de Windows 11 y Windows Server 2025, si lanzamos un archivo .rdp para conexión remota nos pedirá permisos para conectar devices. De momento este aviso se puede quitar mediante:<br />
<br />
<div class="bbcode_container">
	<div class="bbcode_description">Código:</div>
	<pre class="bbcode_code notranslate" style="max-height:calc(30 *  + 2 * var(--bbcode-padding) + var(--h-scrollbar-allowance));">reg add &quot;HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services\Client&quot; /v RedirectionWarningDialogVersion /t REG_DWORD /d 1 /f</pre>
</div>pero esto no garantiza que en próximas versiones funcione.<br />
<br />
Lo que realmente pide es que el rdp esté firmado. Por ello, debemos firmar los .rdp con rdpsign:<br />
<br />
<br />
<div class="bbcode_container">
	<div class="bbcode_description">Código:</div>
	<pre class="bbcode_code notranslate" style="max-height:calc(30 *  + 2 * var(--bbcode-padding) + var(--h-scrollbar-allowance));">&#91;CmdletBinding()&#93;
param(
    &#91;Parameter(Mandatory = $true)&#93;
    &#91;ValidateNotNullOrEmpty()&#93;
    &#91;string&#93;$Folder,

    &#91;ValidateSet('CurrentUser','LocalMachine')&#93;
    &#91;string&#93;$StoreScope = 'CurrentUser',

    &#91;ValidateRange(1,10)&#93;
    &#91;int&#93;$YearsValid = 3,

    &#91;ValidateNotNullOrEmpty()&#93;
    &#91;string&#93;$SubjectPrefix = 'RDP Publisher - SoloEstePC',

    &#91;switch&#93;$TestOnly,

    &#91;switch&#93;$NoBackup,

    &#91;switch&#93;$OverwriteExistingBackups
)

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

function Test-IsAdministrator {
    $identity  = &#91;Security.Principal.WindowsIdentity&#93;::GetCurrent()
    $principal = New-Object Security.Principal.WindowsPrincipal($identity)
    return $principal.IsInRole(&#91;Security.Principal.WindowsBuiltInRole&#93;::Administrator)
}

function Throw-IfFalse {
    param(
        &#91;bool&#93;$Condition,
        &#91;string&#93;$Message
    )
    if (-not $Condition) {
        throw $Message
    }
}

function Test-RdpSignProbe {
    param(
        &#91;Parameter(Mandatory = $true)&#93;
        &#91;string&#93;$RdpsignPath,

        &#91;Parameter(Mandatory = $true)&#93;
        &#91;string&#93;$Thumbprint,

        &#91;Parameter(Mandatory = $true)&#93;
        &#91;string&#93;$FilePath
    )

    $text = (&amp; $RdpsignPath /sha256 $Thumbprint /l $FilePath 2&gt;&amp;1 | Out-String)
    $exitCode = $LASTEXITCODE

    $badPatterns = @(
        'could not be signed',
        'Unable locate the certificate specified',
        'A certificate needs to be specified'
    )

    $bad = $false
    foreach ($pattern in $badPatterns) {
        if ($text -match $pattern) {
            $bad = $true
            break
        }
    }

    &#91;PSCustomObject&#93;@{
        Ok       = ($exitCode -eq 0 -and -not $bad)
        ExitCode = $exitCode
        Output   = $text.Trim()
    }
}

# 1) Comprobaciones de entorno
$requiredCommands = @(
    'rdpsign.exe',
    'New-SelfSignedCertificate',
    'Export-Certificate',
    'Get-FileHash'
)

foreach ($cmd in $requiredCommands) {
    try {
        $null = Get-Command $cmd -ErrorAction Stop
    }
    catch {
        throw &quot;No encuentro '$cmd' en este equipo.&quot;
    }
}

if ($StoreScope -eq 'LocalMachine' -and -not (Test-IsAdministrator)) {
    throw &quot;Con -StoreScope LocalMachine debes ejecutar PowerShell como administrador.&quot;
}

try {
    $resolved = Resolve-Path -LiteralPath $Folder -ErrorAction Stop
}
catch {
    throw &quot;La carpeta '$Folder' no existe o no es accesible.&quot;
}

Throw-IfFalse (@($resolved).Count -eq 1) &quot;La ruta '$Folder' debe resolver a una sola carpeta.&quot;
$Folder = $resolved&#91;0&#93;.ProviderPath

Throw-IfFalse ((Test-Path -LiteralPath $Folder -PathType Container)) &quot;'$Folder' no es una carpeta.&quot;

# 2) Comprobar que hay .rdp
$rdpFiles = Get-ChildItem -LiteralPath $Folder -Filter '*.rdp' -File | Sort-Object Name
Throw-IfFalse ($rdpFiles.Count -gt 0) &quot;No hay archivos .rdp en '$Folder'.&quot;

# 3) Comprobar escritura en la carpeta
try {
    $writeProbe = Join-Path $Folder (&#91;System.IO.Path&#93;::GetRandomFileName())
    Set-Content -LiteralPath $writeProbe -Value '' -NoNewline -ErrorAction Stop
    Remove-Item -LiteralPath $writeProbe -Force -ErrorAction Stop
}
catch {
    throw &quot;No tengo permiso de escritura en '$Folder'.&quot;
}

# 4) Comprobar backups existentes
if (-not $TestOnly -and -not $NoBackup -and -not $OverwriteExistingBackups) {
    $existingBackups = foreach ($file in $rdpFiles) {
        $bak = $file.FullName + '.bak'
        if (Test-Path -LiteralPath $bak) {
            $bak
        }
    }

    if ($existingBackups) {
        $list = ($existingBackups | Sort-Object | ForEach-Object { &quot; - $_&quot; }) -join &#91;Environment&#93;::NewLine
        throw &quot;Ya existen backups .bak. Borralos o relanza con -OverwriteExistingBackups.`n$list&quot;
    }
}

# 5) Crear SIEMPRE un certificado NUEVO
$stamp     = Get-Date -Format 'yyyyMMdd-HHmmss'
$subject   = &quot;CN=$SubjectPrefix $stamp&quot;
$friendly  = &quot;RDP Signer $env:COMPUTERNAME $stamp&quot;
$storePath = &quot;Cert:\$StoreScope\My&quot;

$cert = New-SelfSignedCertificate `
    -Type CodeSigningCert `
    -Subject $subject `
    -FriendlyName $friendly `
    -CertStoreLocation $storePath `
    -KeySpec Signature `
    -KeyAlgorithm RSA `
    -KeyLength 2048 `
    -HashAlgorithm SHA256 `
    -KeyExportPolicy NonExportable `
    -NotAfter (Get-Date).AddYears($YearsValid)

Throw-IfFalse ($null -ne $cert) &quot;No se pudo crear el certificado.&quot;
Throw-IfFalse ($cert.HasPrivateKey) &quot;El certificado se creó sin clave privada.&quot;
Throw-IfFalse ($cert.NotAfter -gt (Get-Date)) &quot;El certificado ya aparece caducado.&quot;

# 6) Usar el Thumbprint del store, sin espacios
$thumb = $cert.Thumbprint.Replace(' ', '').ToUpperInvariant()

# 7) Exportar CER publico (sin clave privada) por si luego quieres confiarlo/importarlo
$cerPath = Join-Path $Folder (&quot;RdpPublisher-{0}-{1}.cer&quot; -f $thumb.Substring(0,8), $stamp)
Export-Certificate -Cert $cert -FilePath $cerPath | Out-Null

# 8) Probar rdpsign contra el primer archivo antes de tocar todo el lote
$probe = Test-RdpSignProbe -RdpsignPath (Get-Command rdpsign.exe).Source -Thumbprint $thumb -FilePath $rdpFiles&#91;0&#93;.FullName
if (-not $probe.Ok) {
    throw &quot;La prueba de rdpsign ha fallado.`nExitCode: $($probe.ExitCode)`n$($probe.Output)&quot;
}

# 9) Firmar
$rdpsignPath = (Get-Command rdpsign.exe).Source
$results = @()

foreach ($file in $rdpFiles) {
    $beforeHash = (Get-FileHash -LiteralPath $file.FullName -Algorithm SHA256).Hash
    $bakPath    = $file.FullName + '.bak'

    if (-not $TestOnly -and -not $NoBackup) {
        if ($OverwriteExistingBackups) {
            Copy-Item -LiteralPath $file.FullName -Destination $bakPath -Force
        }
        else {
            Copy-Item -LiteralPath $file.FullName -Destination $bakPath
        }
    }

    $args = @('/v', '/sha256', $thumb)
    if ($TestOnly) {
        $args += '/l'
    }
    $args += $file.FullName

    $text = (&amp; $rdpsignPath @args 2&gt;&amp;1 | Out-String)
    $exitCode = $LASTEXITCODE

    $bad = $text -match 'could not be signed|Unable locate the certificate specified|A certificate needs to be specified'
    if ($exitCode -ne 0 -or $bad) {
        throw &quot;Error firmando '$($file.FullName)'.`nExitCode: $exitCode`n$text&quot;
    }

    $afterHash = if ($TestOnly) {
        $beforeHash
    }
    else {
        (Get-FileHash -LiteralPath $file.FullName -Algorithm SHA256).Hash
    }

    $results += &#91;PSCustomObject&#93;@{
        File        = $file.FullName
        Backup      = if ($TestOnly -or $NoBackup) { $null } else { $bakPath }
        Mode        = if ($TestOnly) { 'TestOnly (/l)' } else { 'Signed' }
        Changed     = if ($TestOnly) { $null } else { ($beforeHash -ne $afterHash) }
    }
}

# 10) Resumen
Write-Host ''
Write-Host '================ RESUMEN ================'
Write-Host &quot;Carpeta            : $Folder&quot;
Write-Host &quot;Store certificado  : $storePath&quot;
Write-Host &quot;Cert path          : $storePath\$thumb&quot;
Write-Host &quot;Subject            : $($cert.Subject)&quot;
Write-Host &quot;Thumbprint SHA1    : $thumb&quot;
Write-Host &quot;CER publico        : $cerPath&quot;
Write-Host &quot;Archivos procesados: $($results.Count)&quot;
Write-Host &quot;Modo               : $(if ($TestOnly) { 'Prueba (/l)' } else { 'Firmado real' })&quot;
Write-Host ''
Write-Host 'Pega este Thumbprint en la policy de trusted .rdp publishers:'
Write-Host $thumb
Write-Host '========================================='
Write-Host ''

$results</pre>
</div>Ejemplos de uso:<br />
<br />
<div class="bbcode_container">
	<div class="bbcode_description">Código:</div>
	<pre class="bbcode_code notranslate" style="max-height:calc(30 *  + 2 * var(--bbcode-padding) + var(--h-scrollbar-allowance));"># Prueba: crea un cert NUEVO y valida la firma, pero no toca los .rdp
.\New-RdpPublisherAndSign.ps1 -Folder &quot;C:\carpeta_donde_esten_los_rdp&quot; -TestOnly</pre>
</div><div class="bbcode_container">
	<div class="bbcode_description">Código:</div>
	<pre class="bbcode_code notranslate" style="max-height:calc(30 *  + 2 * var(--bbcode-padding) + var(--h-scrollbar-allowance));"># Firma real, creando .bak
.\New-RdpPublisherAndSign.ps1 -Folder &quot;C:\carpeta_donde_esten_los_rdp&quot;</pre>
</div><div class="bbcode_container">
	<div class="bbcode_description">Código:</div>
	<pre class="bbcode_code notranslate" style="max-height:calc(30 *  + 2 * var(--bbcode-padding) + var(--h-scrollbar-allowance));"># Firma real sin backups
.\New-RdpPublisherAndSign.ps1 -Folder &quot;C:\carpeta_donde_esten_los_rdp&quot; -NoBackup</pre>
</div>Después de ejecutarlo, abrir gpedit.msc e ir a:<br />
<br />
Configuración de usuario &gt; Plantillas administrativas &gt; Componentes de Windows &gt; Servicios de Escritorio remoto &gt; Cliente de conexión a Escritorio remoto &gt; Specify SHA1 thumbprints of certificates representing trusted .rdp publishers<br />
<br />
Se habilita y pegar el thumbprint que te imprimió el script. Si se quisiera que sirviera para todos los usuarios del equipo, usar la misma policy en Configuración del equipo.<br />
<br />
Este script crea un certificado nuevo en `CurrentUser\My` por defecto, usa `CodeSigningCert`, exporta además el `.cer` público, valida `rdpsign` con `/l` antes de tocar todo el lote y luego firma cada `.rdp` por separado creando `.bak` salvo que le digamos lo contrario. `rdpsign` sobrescribe el archivo firmado, no acepta comodines, y Microsoft indica que el thumbprint debe sacarse del almacén de certificados y usarse sin espacios.<br />
<br />
Cuando acabe, quedarse con el `Thumbprint SHA1` que imprime. Ese es el valor que se debe pegar en la directiva **“Specify SHA1 thumbprints of certificates representing trusted .rdp publishers”**. Microsoft documenta que esa policy existe tanto en **User Configuration** como en **Computer Configuration**, y que si la huella coincide, el usuario no recibe warnings al abrir el `.rdp`.<br />
<br />
Si al ser autofirmado se quiere dejar además confiado en Windows, Microsoft indica que los certificados autofirmados deben estar en el **Trusted Root Certificates store**, e `Import-Certificate` permite importar el `.cer` al store que elijas con `-CertStoreLocation`.<br />
<br />
Detalle importante: cada ejecución de este script crea un certificado distinto, así que si se vuelve a lanzar más adelante se tendrá también un **thumbprint nuevo** y hay que actualizar esa policy con la nueva huella.]]></content:encoded>
			<category domain="https://jmtella.com/foro/forum/ejercicios-y-ejemplos"><![CDATA[TIP's, Ejercicios y Ejemplos]]></category>
			<dc:creator>jmtella</dc:creator>
			<guid isPermaLink="true">https://jmtella.com/foro/forum/ejercicios-y-ejemplos/57679-tip-en-las-ultimas-versiones-de-windows-11-y-server-2025-al-lanzar-un-archivo-rdp-para-conexión-remota-nos-pedirá-permisos-para-conectar-devices</guid>
		</item>
		<item>
			<title><![CDATA[TIP:  medir velocidad de red entre PC's  de la red local.]]></title>
			<link>https://jmtella.com/foro/forum/ejercicios-y-ejemplos/57604-tip-medir-velocidad-de-red-entre-pc-s-de-la-red-local</link>
			<pubDate>Fri, 10 Apr 2026 10:13:23 GMT</pubDate>
			<description><![CDATA[Hace unos dias alguien preguntó por alguna herramienta para medir velocidad entre PC's de la RED LOCAL. Creo que es muy util sobre todo para ver...]]></description>
			<content:encoded><![CDATA[Hace unos dias alguien preguntó por alguna herramienta para medir velocidad entre PC's de la RED LOCAL. Creo que es muy util sobre todo para ver estado del cableado y de los posibles switchs de red.<br />
<br />
He hecho esto en python. Leer las instrucciones del archivo leeme.txt.<br />
<br />
<br />
Notas:<br />
- El firewall del equipo servidor debe permitir el puerto configurado.]]></content:encoded>
			<category domain="https://jmtella.com/foro/forum/ejercicios-y-ejemplos"><![CDATA[TIP's, Ejercicios y Ejemplos]]></category>
			<dc:creator>jmtella</dc:creator>
			<guid isPermaLink="true">https://jmtella.com/foro/forum/ejercicios-y-ejemplos/57604-tip-medir-velocidad-de-red-entre-pc-s-de-la-red-local</guid>
		</item>
		<item>
			<title>TIP: ver la direccion de la ONT en routers movistar</title>
			<link>https://jmtella.com/foro/forum/ejercicios-y-ejemplos/57311-tip-ver-la-direccion-de-la-ont-en-routers-movistar</link>
			<pubDate>Mon, 16 Feb 2026 13:55:33 GMT</pubDate>
			<description>Por defecto la configuracion no la muestra, y es necesario saberla si queremos sustituir un rounter por otro de otros model con ONT incorporada o...</description>
			<content:encoded><![CDATA[Por defecto la configuracion no la muestra, y es necesario saberla si queremos sustituir un rounter por otro de otros model con ONT incorporada o bien queremos poner una ONT                     dun router aparte.<br />
<br />
La manera de ver la dioreccion es acceder al router pero en diredcto a laa pagina &quot;instalacion&quot;:<br />
<br />
<a href="https://192.168.1.1/instalacion" target="_blank">https://192.168.1.1/instalacion</a><br />
<br />
Esto nos mostrará la dir de la ONT. Si mustra más de 14 digitos, solo son validos los 14 primeros.]]></content:encoded>
			<category domain="https://jmtella.com/foro/forum/ejercicios-y-ejemplos"><![CDATA[TIP's, Ejercicios y Ejemplos]]></category>
			<dc:creator>jmtella</dc:creator>
			<guid isPermaLink="true">https://jmtella.com/foro/forum/ejercicios-y-ejemplos/57311-tip-ver-la-direccion-de-la-ont-en-routers-movistar</guid>
		</item>
	</channel>
</rss>
