135 lines
5.9 KiB
PowerShell
135 lines
5.9 KiB
PowerShell
[CmdletBinding(SupportsShouldProcess)]
|
|
param(
|
|
[string]$RemoteDesktopPrincipal = 'LCI\SG-Laboratorio-Usuarios-RDP',
|
|
[switch]$EnableAdministrativeFirewallGroups
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
|
|
$principal = [Security.Principal.WindowsPrincipal]::new($identity)
|
|
if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
|
throw 'Run this script from an elevated Windows PowerShell session.'
|
|
}
|
|
|
|
$computer = Get-CimInstance Win32_ComputerSystem
|
|
if (-not $computer.PartOfDomain) {
|
|
throw 'Join the computer to the domain before enabling domain-scoped remote access.'
|
|
}
|
|
|
|
$remoteDesktopUsersSid = [Security.Principal.SecurityIdentifier]::new('S-1-5-32-555')
|
|
$remoteDesktopUsersGroup = ($remoteDesktopUsersSid.Translate([Security.Principal.NTAccount]).Value -split '\\', 2)[1]
|
|
$remoteDesktopPrincipalSid = ([Security.Principal.NTAccount]::new($RemoteDesktopPrincipal)).Translate(
|
|
[Security.Principal.SecurityIdentifier])
|
|
|
|
function Get-LocalGroupMemberSid {
|
|
param([Parameter(Mandatory)][string]$Name)
|
|
|
|
$group = [ADSI]("WinNT://$env:COMPUTERNAME/$Name,group")
|
|
foreach ($member in @($group.psbase.Invoke('Members'))) {
|
|
try {
|
|
$sidBytes = $member.GetType().InvokeMember('objectSid',
|
|
[Reflection.BindingFlags]::GetProperty, $null, $member, $null)
|
|
if ($sidBytes) {
|
|
([Security.Principal.SecurityIdentifier]::new([byte[]]$sidBytes, 0)).Value
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
}
|
|
|
|
if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, "Enable RDP and grant $RemoteDesktopPrincipal access")) {
|
|
function Invoke-PowerCfgBestEffort {
|
|
param([Parameter(Mandatory)][string[]]$Arguments)
|
|
|
|
# Start-Process keeps powercfg's policy-override diagnostic on its own
|
|
# stderr stream. In PowerShell 7, directly invoking that native command
|
|
# turns stderr into a terminating ErrorRecord under $ErrorActionPreference
|
|
# = 'Stop', which previously aborted this unrelated remediation work.
|
|
$process = Start-Process -FilePath "$env:SystemRoot\System32\powercfg.exe" `
|
|
-ArgumentList $Arguments -Wait -PassThru -WindowStyle Hidden
|
|
if ($process.ExitCode -ne 0) {
|
|
Write-Warning "powercfg $($Arguments -join ' ') returned exit code $($process.ExitCode); continuing enrollment repair."
|
|
}
|
|
}
|
|
|
|
foreach ($powerChange in @(
|
|
@('monitor-timeout-ac', '0'),
|
|
@('monitor-timeout-dc', '0'),
|
|
@('standby-timeout-ac', '0'),
|
|
@('standby-timeout-dc', '0'),
|
|
@('hibernate-timeout-ac', '0'),
|
|
@('hibernate-timeout-dc', '0'))) {
|
|
Invoke-PowerCfgBestEffort -Arguments @('/change', $powerChange[0], $powerChange[1])
|
|
}
|
|
Invoke-PowerCfgBestEffort -Arguments @('/hibernate', 'off')
|
|
|
|
Set-ItemProperty -LiteralPath 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' `
|
|
-Name fDenyTSConnections -Type DWord -Value 0
|
|
Set-ItemProperty -LiteralPath 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' `
|
|
-Name UserAuthentication -Type DWord -Value 1
|
|
|
|
Set-Service -Name TermService -StartupType Automatic
|
|
Start-Service -Name TermService
|
|
|
|
Get-NetFirewallRule -Name 'RemoteDesktop-UserMode-In-TCP','RemoteDesktop-UserMode-In-UDP' `
|
|
-ErrorAction SilentlyContinue |
|
|
Set-NetFirewallRule -Enabled True -Profile Domain
|
|
|
|
$existingMembers = @(Get-LocalGroupMemberSid -Name $remoteDesktopUsersGroup)
|
|
if ($existingMembers -notcontains $remoteDesktopPrincipalSid.Value) {
|
|
Add-LocalGroupMember -Group $remoteDesktopUsersGroup -Member $remoteDesktopPrincipalSid.Value
|
|
}
|
|
|
|
# Use Windows PowerShell so both the inbox and compatible remoting endpoints
|
|
# are configured even when this helper is launched from PowerShell 7.
|
|
$enableRemoting = Start-Process -FilePath "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe" `
|
|
-ArgumentList @('-NoLogo', '-NoProfile', '-NonInteractive', '-Command',
|
|
'Enable-PSRemoting -Force -SkipNetworkProfileCheck') `
|
|
-Wait -PassThru -WindowStyle Hidden
|
|
if ($enableRemoting.ExitCode -ne 0) {
|
|
throw "Enable-PSRemoting returned $($enableRemoting.ExitCode)."
|
|
}
|
|
|
|
Set-Service -Name WinRM -StartupType Automatic
|
|
Start-Service -Name WinRM
|
|
Get-NetFirewallRule -Name 'WINRM-HTTP-In-TCP','WINRM-HTTP-In-TCP-NoScope' `
|
|
-ErrorAction SilentlyContinue |
|
|
Set-NetFirewallRule -Enabled True -Profile Domain
|
|
Get-NetFirewallRule -Name 'WINRM-HTTP-In-TCP-PUBLIC' -ErrorAction SilentlyContinue |
|
|
Disable-NetFirewallRule
|
|
|
|
if ($EnableAdministrativeFirewallGroups) {
|
|
$administrativeRules = @(
|
|
'RemoteEventLogSvc-In-TCP',
|
|
'RemoteEventLogSvc-NP-In-TCP',
|
|
'RemoteEventLogSvc-RPCSS-In-TCP',
|
|
'RemoteSvcAdmin-In-TCP',
|
|
'RemoteSvcAdmin-NP-In-TCP',
|
|
'RemoteSvcAdmin-RPCSS-In-TCP',
|
|
'WMI-RPCSS-In-TCP',
|
|
'WMI-WINMGMT-In-TCP',
|
|
'WMI-ASYNC-In-TCP'
|
|
)
|
|
Get-NetFirewallRule -Name $administrativeRules -ErrorAction SilentlyContinue |
|
|
Set-NetFirewallRule -Enabled True -Profile Domain
|
|
}
|
|
}
|
|
|
|
$rdpMembers = @(Get-LocalGroupMemberSid -Name $remoteDesktopUsersGroup)
|
|
[pscustomobject]@{
|
|
ComputerName = $env:COMPUTERNAME
|
|
Domain = $computer.Domain
|
|
RemoteDesktopEnabled = (Get-ItemPropertyValue `
|
|
'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' `
|
|
-Name fDenyTSConnections) -eq 0
|
|
NetworkLevelAuthentication = (Get-ItemPropertyValue `
|
|
'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' `
|
|
-Name UserAuthentication) -eq 1
|
|
RemoteDesktopPrincipal = $RemoteDesktopPrincipal
|
|
PrincipalIsAuthorized = $rdpMembers -contains $remoteDesktopPrincipalSid.Value
|
|
TermService = (Get-Service TermService).Status
|
|
WinRM = (Get-Service WinRM).Status
|
|
FirewallProfile = 'Domain'
|
|
AlwaysOnPowerPolicyApplied = $true
|
|
}
|