Skip Ribbon Commands
Skip to main content

Ondrej Sevecek's English Pages

:

Engineering and troubleshooting by Directory Master!
MCM: Directory
Home
April 20
Disable Network Level Authentication (NLA) on RDP client side

In order to disable the use of Network Level Authentication (NLA) for RDP (Remote Desktop Protocol) client, you must create a new or edit an existing .RDP file on the client side and insert or change the following configuration value in the file. You cannot change the setting in GUI of the MSTSC client directly:

enablecredsspsupport:i:0

April 20
Windows OOBE hangs during "Just a moment" phase of SYSPREP
In my case, this happened when calling SYSPREP on Windows 11 while there still were some outstanding autologon registry values on the machine from my previous build process using the autologon technology.

The problem manifested itself by hanging OOBE phase after image deployment during the "Just a moment" phase. If I restarted the machine forcibly during the hang, the next boot failed autologging the defaultuser0 automatically. Which actually pointed me to the reason and so the solution.

It helped to simply remove all of the following registry values prior to starting SYSPREP:

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
  AutoAdminLogon
  AutoLogonCount
  AutoLogonSID
  DefaultDomainName
  DefaultPassword
  DefaultUserName

February 04
How to repair it after an in-place upgrade of the Windows OS under the Azure AD Connect

I just experienced a painful problem after in-place upgrading the operating system Windows Server 2012 R2 to Windows Server 2019 on a computer where Azure AD Connect (formerly known also as DirSync or AzureSync) was installed. The Azure AD Connect stopped working after the inplace upgrade of operating system. I needed to upgrade the OS first because a wannabe newer version of the Azure AD Connect was not willing to upgrade on the older Windows 2012 R2.

No console was willing to run after the OS upgrade although the Microsoft Azure AD Sync service (ADSync aka miisserver) was starting. Error messages ranged among all the AD Connect, Synchronization Rules Editor and Synchronization Service Manager:

The current user requires Admin access to the Microsoft Azure AD Sync.

The machine-default permission settings do not grant Local Activation permission
  for the COM Server application with CLSID {835BEE60-8731-4159-8BFF-941301D76D05}
  and APPID Unavailable to the user AAD_.

Retrieving the COM class factory for remote component
  with CLSID {835BEE60-8731-4159-8BFF-941301D76D05} failed. Error: 80070005.

Reason and solution

It appears that the inplace OS upgrade deleted COM registration of the Microsoft Azure AD Sync service from the HKEY_CLASSES_ROOT. So I solved it by exporting the registration keys from another AD Connect installation and imported them back to this failing system. You need the following two keys:

HKEY_CLASSES_ROOT\AppID\{835BEE60-8731-4159-8BFF-941301D76D05}
HKEY_CLASSES_ROOT\CLSID\{835BEE60-8731-4159-8BFF-941301D76D05}

Either copy what you find elsewhere or create a .REG file from the following and import it. Definitelly you will have to update the configuration to mention your own security groups in its DCOM config (see later):

[HKEY_CLASSES_ROOT\AppID\{835BEE60-8731-4159-8BFF-941301D76D05}]
"LocalService"="ADSync"
@="Microsoft Azure AD Sync"
"LaunchPermission"=hex:01,00,04,80,ec,00,00,00,08,01,00,00,00,00,00,00,14,00,\
  00,00,02,00,d8,00,06,00,00,00,00,00,18,00,1f,00,00,00,01,02,00,00,00,00,00,\
  05,20,00,00,00,20,02,00,00,00,00,24,00,0b,00,00,00,01,05,00,00,00,00,00,05,\
  15,00,00,00,cd,cd,31,ba,b5,9f,8b,ac,eb,d3,89,6e,e9,03,00,00,00,00,24,00,0b,\
  00,00,00,01,05,00,00,00,00,00,05,15,00,00,00,cd,cd,31,ba,b5,9f,8b,ac,eb,d3,\
  89,6e,ea,03,00,00,00,00,24,00,0b,00,00,00,01,05,00,00,00,00,00,05,15,00,00,\
  00,cd,cd,31,ba,b5,9f,8b,ac,eb,d3,89,6e,eb,03,00,00,00,00,28,00,1f,00,00,00,\
  01,06,00,00,00,00,00,05,50,00,00,00,17,87,75,c1,af,aa,67,da,bd,f2,93,2d,92,\
  92,46,95,83,11,c3,35,00,00,24,00,0b,00,00,00,01,05,00,00,00,00,00,05,15,00,\
  00,00,cd,cd,31,ba,b5,9f,8b,ac,eb,d3,89,6e,ec,03,00,00,01,05,00,00,00,00,00,\
  05,15,00,00,00,cd,cd,31,ba,b5,9f,8b,ac,eb,d3,89,6e,f4,01,00,00,01,02,00,00,\
  00,00,00,05,20,00,00,00,20,02,00,00
"AccessPermission"=hex:01,00,04,80,00,01,00,00,1c,01,00,00,00,00,00,00,14,00,\
  00,00,02,00,ec,00,07,00,00,00,00,00,18,00,07,00,00,00,01,02,00,00,00,00,00,\
  05,20,00,00,00,20,02,00,00,00,00,24,00,03,00,00,00,01,05,00,00,00,00,00,05,\
  15,00,00,00,cd,cd,31,ba,b5,9f,8b,ac,eb,d3,89,6e,e9,03,00,00,00,00,24,00,03,\
  00,00,00,01,05,00,00,00,00,00,05,15,00,00,00,cd,cd,31,ba,b5,9f,8b,ac,eb,d3,\
  89,6e,ea,03,00,00,00,00,14,00,07,00,00,00,01,01,00,00,00,00,00,05,12,00,00,\
  00,00,00,28,00,07,00,00,00,01,06,00,00,00,00,00,05,50,00,00,00,17,87,75,c1,\
  af,aa,67,da,bd,f2,93,2d,92,92,46,95,83,11,c3,35,00,00,24,00,03,00,00,00,01,\
  05,00,00,00,00,00,05,15,00,00,00,cd,cd,31,ba,b5,9f,8b,ac,eb,d3,89,6e,eb,03,\
  00,00,00,00,24,00,03,00,00,00,01,05,00,00,00,00,00,05,15,00,00,00,cd,cd,31,\
  ba,b5,9f,8b,ac,eb,d3,89,6e,ec,03,00,00,01,05,00,00,00,00,00,05,15,00,00,00,\
  cd,cd,31,ba,b5,9f,8b,ac,eb,d3,89,6e,f4,01,00,00,01,02,00,00,00,00,00,05,20,\
  00,00,00,20,02,00,00
"AuthenticationLevel"=dword:00000006

[HKEY_CLASSES_ROOT\CLSID\{835BEE60-8731-4159-8BFF-941301D76D05}]
"AppID"="{835BEE60-8731-4159-8BFF-941301D76D05}"
@="Microsoft Azure AD Sync"

[HKEY_CLASSES_ROOT\CLSID\{835BEE60-8731-4159-8BFF-941301D76D05}\InprocHandler32]
@="ole32.dll"

[HKEY_CLASSES_ROOT\CLSID\{835BEE60-8731-4159-8BFF-941301D76D05}\ProgID]
@="Microsoft.Metadirectory.Server.1"

[HKEY_CLASSES_ROOT\CLSID\{835BEE60-8731-4159-8BFF-941301D76D05}\VersionIndependentProgID]
@="Microsoft.Metadirectory.Server"

After importing the registry settings you need to start the Component Services MMC console and update you Security permissions according to the following procedure:

  • start Component Services console
  • expand the Component Services - Computers - My Computer - DCOM Config - Microsoft Azure AD Sync
  • open Properties - Security tab
  • update both the Launch and Activation Permissions and the Access Permissions to contain your security groups (replace it instead of the non-resolvable SIDs) such as your local groups FIMSyncAdmins, FIMSyncOperators, FIMSyncBrowse and FIMSyncPasswordSet, or the newer ADSyncAdmins, ADSyncBrowse, ADSyncOperators and ADSyncPasswordSet

 

April 27
How to create self-signed certificate from PowerShell without having PowerShell 5 cmdlets

Yes, it is possible to create self-signed certificates from command line on nearly any computer today even without having the PowerShell 5 installed. The PowerShell 5 comes with the all new New-SelfSignedCertificate cmdlet but apparently requires this newer version of the PowerShell which I often cannot rely on. While it is possible, since ever, to do the same with CERTREQ command line utility which is available built-in on all currently supported corporate editions of Windows.

I just wrapped the CERTREQ into the following powershell script. Yes, it does need PowerShell 2 only. The script simply compiles INF file for the CERTREQ. You can get documentation on the INF contents here.

function global:Create-SelfSignedCert (
  [Parameter(Mandatory = $true)]                                                                                                                                 [string] $subject,
                                                                                                                                                                 [string] $friendlyName,
                                 [ValidateSet('md5', 'md4', 'md2', 'sha1', 'sha256', 'sha384', 'sha512')]                                                        [string] $hash = 'sha256',
                                 [ValidateScript({ $_ -gt 0 })]                                                                                                  [int] $keyLength = 2048,
                                 [ValidateSet('seconds', 'minutes', 'hours', 'days', 'weeks', 'months', 'years')]                                                [string] $validityUnit = 'Months',
                                 [ValidateScript({ $_ -gt 0 })]                                                                                                  [int] $validityLen = 3,
                                 [ValidateNotNullOrEmpty()]                                                                                                      [string] $provider = "Microsoft Software Key Storage Provider",
                                                                                                                                                                 [switch] $machineKey,
                                 [ValidateSet('ClientAuthentication', 'ServerAuthentication')]                                                                   [string[]] $eku = @('ClientAuthentication'),
                                 [ValidateSet('DigitalSignature', 'KeyEncipherment', 'NonRepudiation', 'CertificateSigning', 'CrlSigning', 'OfflineCrlSigning')] [string[]] $keyUsage = @('DigitalSignature')
  )
{
  # Note: the file really must contain the last empty line
  [string] $muster = @'

; Built with SAPHA toolkit - (C) Ondrej Sevecek, 2012-2020 - www.sevecek.com, ondrej@sevecek.com

[Version]
Signature = "$Windows NT$"

[NewRequest]
RequestType = Cert
Subject = "$subject$"
HashAlgorithm = $hash$
KeyLength = $keyLength$
KeySpec = $keySpec$
KeyUsage = $keyUsage$ ; CERT_DIGITAL_SIGNATURE_KEY_USAGE
ValidityPeriod = $validityUnit$
ValidityPeriodUnits = $validityLen$
ProviderName = "$provider$"
Silent = true
MachineKeySet = $machineKey$
Exportable = false
FriendlyName = "$friendlyName$"

[Extensions]
"2.5.29.37" = "{text}$eku$"

'@

  [hashtable] $ekuOIDs = @{
    ServerAuthentication = '1.3.6.1.5.5.7.3.1'
    ClientAuthentication = '1.3.6.1.5.5.7.3.2'
    }

  [hashtable] $keyUsages = @{
    DigitalSignature = 0x80
    KeyEncipherment = 0x20
    NonRepudiation = 0x40
    CertificateSigning = 0x04
    CrlSigning = 0x02
    OfflineCrlSigning = 0x02
    }

  [string] $thumbprint = $null

  [System.Management.Automation.ActionPreference] $local:errorActionInternalBackup = $global:errorActionPreference
  try { $global:errorActionPreference = [System.Management.Automation.ActionPreference]::Stop

    $muster = $muster.Replace('$subject$', $subject)
    $muster = $muster.Replace('$friendlyName$', $friendlyName)
    $muster = $muster.Replace('$hash$', $hash)
    $muster = $muster.Replace('$keyLength$', $keyLength)
    $muster = $muster.Replace('$validityUnit$', $validityUnit)
    $muster = $muster.Replace('$validityLen$', $validityLen)
    $muster = $muster.Replace('$provider$', $provider)
    $muster = $muster.Replace('$machineKey$', $machineKey)
    $muster = $muster.Replace('$eku$', (($eku | % { $ekuOIDs[$_] }) -join ','))

    [int] $keyUsageInt = 0
    foreach ($oneKeyUsage in $keyUsage) {

      $keyUsageInt = $keyUsageInt -bor $keyUsages[$oneKeyUsage]
    }

    $muster = $muster.Replace('$keyUsage$', ('0x{0:X2}' -f $keyUsageInt))

    if ($keyUsages -contains 'KeyEncipherment') {

      $muster = $muster.Replace('$keySpec$', 'AT_SIGNATURE')

    } else {

      $muster = $muster.Replace('$keySpec$', 'AT_KEYEXCHANGE')
    }
    
    [string] $infFile = Join-Path $env:TEMP ('sapha-self-signed-certificate-{0}.inf' -f ([DateTime]::Now.ToString('yyyyMMddHHmmss')))
    [string] $cerFile = [System.IO.Path]::ChangeExtension($infFile, '.cer')

    Write-Host ('Creat a self-signed certificate: {0} | {1} | {2}' -f $subject, $friendlyName, $provider)
    
    Write-Host ('Save certificate request file: {0}' -f $infFile)
    $muster.Split("`n") | % { $_.Trim() } | Out-File -FilePath $infFile -Encoding Unicode -Force

    Write-Host ('Create the certificate with CERTREQ: {0}' -f $cerFile)
    [Collections.ArrayList] $cmdOut = @()
    certreq -f -q -new $infFile $cerFile | % { [void] $cmdOut.Add($_) }
    [int] $cmdRes = $LASTEXITCODE
    if ($cmdRes -ne 0) { throw  ('CERTREQ error: 0x{0:X8} | {1}' -f $cmdRes, ($cmdOut -join "`r`n")) }
    if (-not (Test-Path $cerFile)) { throw  ('No certificate file created: {0}' -f $cerFile) }

    Write-Host ('Loading the created certificate from file: {0}' -f $cerFile)
    [Security.Cryptography.X509Certificates.X509Certificate2] $certificateLoaded = New-Object Security.Cryptography.X509Certificates.X509Certificate2
    $certificateLoaded.Import($cerFile)

    if ($certificateLoaded.Thumbprint -notmatch '\A[a-fA-F0-9]{40}\Z') { throw  ('Invalid certificate loaded: {0} | {1}' -f $cerFile, $certificateLoaded.Thumbprint) }

    if ($machineKey) {

      $certCreatePath = ('Cert:\LocalMachine\My\{0}' -f $certificateLoaded.Thumbprint)

    } else {

      $certCreatePath = ('Cert:\CurrentUser\My\{0}' -f $certificateLoaded.Thumbprint)
    }

    [Security.Cryptography.X509Certificates.X509Certificate2] $certificateCreated = Get-Item $certCreatePath
    if ([object]::Equals($certificateCreated, $null)) { throw  ('Cannot open the local certificate store: {0}' -f $certificateLoaded.Thumbprint) }

    Write-Host ('Certificate created: {0} | {1} | exp = {2} | {3} | provider = {4}' -f $certificateLoaded.SubjectName.Name, $certificateLoaded.Thumbprint, $certificateLoaded.NotAfter.ToString('yyyy-MM-dd HH:mm:ss'), $certCreatePath, $provider)

    if ($certificateLoaded.NotBefore -gt ([DateTime]::Now.AddMinutes(-10))) { throw  ('Weird certificate expiration date: {0}' -f $certificateLoaded.NotBefore.ToString('yyyy-MM-dd HH:mm:ss')) }

    $thumbprint = $certificateCreated.Thumbprint

  } finally { $global:errorActionPreference = $local:errorActionInternalBackup
  }

  return $thumbprint
}
April 01
LG smart TV not playing some DLNA movies correctly

Our new LG smart TV (actually the 43UM7100PLB) connected over WiFi network to NAS device (network attached storage) of Western Digital (WD) MyCloud Ex2 which supports DLNA (digital living network alliance). Some movies were not playing on the TV correctly. The stated error message was Unable to play. This file can't be recognized. Which was weird because they actually were playing for several seconds and their library thumbnails were displaying ok. If I put the movie file on a USB they were playing well too.

It turned out that encoding of the video or its format was not a problem. I tried to connect the LG smart TV to the WiFi router and thus to the NAS over network cable instead of WiFi which solved it. I suppose the problem was slow or failing and unstable WiFi connection, because the problem arrised mainly with larger video files.

February 28
Microsoft NLB is incompatible with SR-IOV hardware acceleration on Hyper-V

If you plan to use Microsoft NLB (Network Load Balancing) in unicast mode in Hyper-V virtual machines, these VMs must not use any Hyper-V virtual switch configured for SR-IOV (single root IO virtualization). Otherwise the virtual machine does not receive any traffic on the virtual NLB MAC address.

The unicast mode of NLB uses a virtual unicast MAC address. The problem with SR-IOV though is that it needs the virtual machines to register all their unicast MAC addresses with the physical network adapter in order to have the hardware acceleration.

The SR-IOV is a technology supported by server hardware NIC (network interface cards) which can distribute network traffic directly to the virtual machines (VMs) according to either their destination MAC address or their assigned VLAN ID. In order to tell the SR-IOV NIC the actual MAC address of a VM the hosting Hyper-V must know the MAC address of the virtual machine. In case of NLB the virtual MAC address is managed dynamically by the NLB driver inside the VM and the hypervizor does not know anything about it.

This function depends on the virtual switch being configured as non-SR-IOV. It does not matter if you enable the SR-IOV in the properties of the VM's network port. You must not have the SR-IOV enabled on the external virtual switch.

January 31
Assign RDP server certificate by using PowerShell

The following script finds the best certificate for RDP in the local machine certificate Personal (MY) store and assigns it for the use by the RDP server. Note that it prefers the Remote Desktop Authentication EKU (Enhanced Key Usage, 1.3.6.1.4.1.311.54.1.2). The certificate must be valid and have private key available, the script selects the certificate which is valid for the longest time. The script also makes sure that the Network Service account is granted read permission to the certificate private key.

[object[]] $validCerts = dir cert:\LocalMachine\My | ? { $_.HasPrivateKey -and $_.NotBefore -le ([DateTime]::Now) -and $_.NotAfter -gt ([DateTime]::Now)} | sort -Descending NotAfter
$certRDP = $null
$certTLS = $null

if ($validCerts.Length -gt 0) { foreach ($oneValidCert in $validCerts) {

  [string[]] $ekus = $oneValidCert.Extensions['2.5.29.37'].EnhancedKeyUsages | select -Expand Value
  if (($ekus -contains '1.3.6.1.4.1.311.54.1.2') -and ([object]::Equals($certRDP, $null))) {

    $certRDP = $oneValidCert
    Write-Host ('Found best RDP certificate: {0} | {1} | {2}' -f $certRDP.Subject, $certRDP.NotAfter.ToString('yyyy-MM-dd HH:mm:ss'), $certRDP.Thumbprint)

  } elseif (($ekus -contains '1.3.6.1.5.5.7.3.1') -and ([object]::Equals($certTLS, $nullo))) {

    $certTLS = $oneValidCert
    Write-Host ('Found best TLS certificate: {0} | {1} | {2}' -f $certTLS.Subject, $certTLS.NotAfter.ToString('yyyy-MM-dd HH:mm:ss'), $certTLS.Thumbprint)
  }
}}

$certBest = $null

if (-not ([object]::Equals($certRDP, $null))) {

  $certBest = $certRDP

} elseif (-not ([object]::Equals($certTLS, $null))) {

  $certBest = $certTLS
}

if ([object]::Equals($certBest, $null)) {

  throw ('Cannot find any suitable RDP certificate')
}

$thumbBytes = New-Object byte[] 20
for ($i = 0; $i -lt 20; $i ++) {

  $oneByte = $certBest.Thumbprint.SubString(($i * 2), 2)
  $thumbBytes[$i] = [Convert]::ToByte($oneByte, 16)
}

Write-Host ('Selected: thumbprint = {0} | {1}' -f $certBest.Thumbprint, ([BitConverter]::ToString($thumbBytes)))
Write-Host ('Selected: subject = {0}' -f $certBest.Subject)
Write-Host ('Selected: SAN = {0}' -f ($certBest.DnsNameList -join ','))
Write-Host ('Selected: expires = {0}' -f $certBest.NotAfter.ToString('yyyy-MM-dd HH:mm:ss'))
Write-Host ('Selected: issuer = {0}' -f $certBest.Issuer)

Remove-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations' SelfSignedCertifi -Force -EA SilentlyContinue
Set-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' SSLCertificateSHA1Hash $thumbBytes -Type Binary

# Note: RDP requires the private key to be accessible by Network Service
certutil -repairstore my $certBest.Thumbprint 'D:P(A;;0x80120089;;;NS)(A;;0xd01f01ff;;;SY)(A;;0xd01f01ff;;;BA)'

Restart-Service SessionEnv -Force
December 04
How to remove expired user certificates from Active Directory user accounts using PowerShell

The certification authority software of Active Directory Certificate Services (ADCS) running in the enterprise installation mode (AD integrated CA) can publish user certificates which it generates into the respective AD user account so that other users can find the certificates for their colleagues and use them for encryption. This function is usually completely unnecessary because only few environments use user certificates for any data encryption at all.

But yes, the default User certificate template has the setting called Publish certificate in Active Directory enabled by default which is then also the case for all duplicates created from this default User template.

The issued certificates get published in their DER binary form into the userCertificate multivalued attribute of their respective AD user object. Expired certificates are not removed automatically. If you want to find all user accounts in the local AD domain and remove any expired certificates from the accounts, you can use the following PowerShell script. The script not only deletes the expired certificate from the user account, it also saves the certificate into TEMP if that was for anything.

Note that the script handles only the published certificates stored in the userCertificate attribute (public certificates without private keys). It does not clean the certificates nor their private keys from the private credentials roaming msPKI attributes.

$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop

[object[]] $usersWithCerts = Get-ADUser -LDAPFilter '(userCertificate=*)' -Properties userCertificate

Write-Host ('Found user accounts with any certificate: #{0}' -f $usersWithCerts.Length)
foreach ($oneUserWithCert in $usersWithCerts) {

  Write-Host ('One user: {0} | certs = #{1} | {2}' -f $oneUserWithCert.sAMAccountName, $oneUserWithCert.userCertificate.Count, $oneUserWithCert.distinguishedName)

  foreach ($oneCertBin in $oneUserWithCert.userCertificate) {

    $oneCert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
    $oneCert.Import($oneCertBin)

    $isExpired = $oneCert.NotAfter -lt ([DateTime]::Now)
    Write-Host ('  certificate: {0} | expires = {1} (valid = {2}) | usage = {3}' -f $oneCert.Subject, $oneCert.NotAfter.ToString('yyyy-MM-dd HH:mm:ss'), (-not $isExpired), ($oneCert.EnhancedKeyUsageList -join ', '))

    if ($isExpired) {

      $saveExpired = Join-Path $env:TEMP ('expired-cert-{0}-exp{1}-{2}.cer' -f $oneUserWithCert.sAMAccountName, $oneCert.NotAfter.ToString('yyyy-MM-dd-HH-mm-ss'), $oneCert.Thumbprint)
      [void] ([System.IO.File]::WriteAllBytes($saveExpired, $oneCert.Export('Cert')))
      Write-Host ('  removing: saved = {0}' -f $saveExpired)

      Set-ADUser -Identity $oneUserWithCert -Certificates @{ Remove = $oneCert }
    }
  }
}

 

July 24
How to disable Windows Admin Center pop-up in Server Manager in registry

The Server Manager console on Windows Server 2019 now pop-ups by default with an annoying dialog box offering the option ty Try managing servers with Windows Admin Center (WindowsAdminCenter). If you want to disable this message by using registry key somewhat centrally, you can set the following registry value DoNotPopWACConsoleAtSMLaunch to 1:

HKLM\SOFTWARE\Microsoft\ServerManager
DoNotPopWACConsoleAtSMLaunch = DWORD = 1
May 27
Users get error message when connecting to RDP host using RemoteGuard

RemoteGuard is a fine new technology for RDP running to and from Windows 2016 and Window 10.1607 which allows for some basic credential protection of users' NTLM password hashes and TGT tickets. In order to use the remote guard feature you must either start mstsc client with /remoteGuard command line switch or have that feature enforced by a client machine group policy setting.

It is a documented fact that the sole use of the /remoteGuard switch requires the connecting user to be member of local Administrators group on the remote RDP host. In case the user is not member of the local Administrators group on the remote RDP host machine, the user receives the following error message displayed on the remote desktop screen after connecting:

The requested session access is denied

If you want your users to connect while not being members of local Administrators group on the remote RDP server then you have to enforce the RemoteGuard use on the client side by using group policy (local or GPO) setting:

Computer Configuration
  Policies
    Administrative Templates
      System
        Credentials Delegation

Restrict delegation of credentials to remote servers
    Enabled + Require Remote Credential Guard

Yes, weirdly enough, but really the /remoteGuard command line switch is apparently different from the GPO setting. And yes, both are client side matters. The only thing that you need to enable on the RDP server host is the DisableRestrictedAdmin registry value which is the same for both remote guard and restricted admin features.

HKLM\System\CurrentControlSet\Control\LSA
DisableRestrictedAdmin = DWORD = 0
1 - 10Next
 

 About this blog

 
Ondrej Sevecek 

Ondrej Sevecek is technical consultant, writer and speaker specialising in network security, PKI, identity management and Active Directory on Microsoft Windows platform. Ondrej is Microsoft Certified Master (MCM:Directory and MCSM:Directory) and the  Most Valuable Professional (MVP: Enterprise Security). He also maintains his CISA and CHFI:Computer Hacking Forensic Investigator and CEH:Certified Ethical Hacker certifications.

Ondrej is also MCT and gives lectures in the greatest of European training centers GOPAS.