[CmdletBinding(SupportsShouldProcess)] param( [ValidateNotNullOrEmpty()] [string[]]$AllowedRemoteAddress = @('LocalSubnet') ) $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.' } $operatingSystem = Get-CimInstance Win32_OperatingSystem if ([int]$operatingSystem.ProductType -eq 1) { throw 'This helper is for Windows Server. Use Enable-LabRemoteAccess.ps1 on a Windows client.' } if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, 'Enable secure administrative RDP and PowerShell Remoting')) { 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'))) { & powercfg.exe /change $powerChange[0] $powerChange[1] if ($LASTEXITCODE -ne 0) { throw "powercfg /change $($powerChange[0]) failed with exit code $LASTEXITCODE." } } & powercfg.exe /hibernate off if ($LASTEXITCODE -ne 0) { throw "powercfg /hibernate off failed with exit code $LASTEXITCODE." } 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 $remoteDesktopRules = @(Get-NetFirewallRule ` -Name 'RemoteDesktop-UserMode-In-TCP','RemoteDesktop-UserMode-In-UDP' ` -ErrorAction SilentlyContinue) $remoteDesktopRules | Set-NetFirewallRule -Enabled True -Profile Any $remoteDesktopRules | Get-NetFirewallAddressFilter | Set-NetFirewallAddressFilter -RemoteAddress $AllowedRemoteAddress | Out-Null $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 $winRmRules = @(Get-NetFirewallRule ` -Name 'WINRM-HTTP-In-TCP','WINRM-HTTP-In-TCP-NoScope' ` -ErrorAction SilentlyContinue) $winRmRules | Set-NetFirewallRule -Enabled True -Profile Any $winRmRules | Get-NetFirewallAddressFilter | Set-NetFirewallAddressFilter -RemoteAddress $AllowedRemoteAddress | Out-Null Get-NetFirewallRule -Name 'WINRM-HTTP-In-TCP-PUBLIC' -ErrorAction SilentlyContinue | Disable-NetFirewallRule $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' ) $enabledAdministrativeRules = @(Get-NetFirewallRule ` -Name $administrativeRules -ErrorAction SilentlyContinue) $enabledAdministrativeRules | Set-NetFirewallRule -Enabled True -Profile Any $enabledAdministrativeRules | Get-NetFirewallAddressFilter | Set-NetFirewallAddressFilter -RemoteAddress $AllowedRemoteAddress | Out-Null } [pscustomobject]@{ ComputerName = $env:COMPUTERNAME 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 TermService = (Get-Service TermService).Status WinRM = (Get-Service WinRM).Status FirewallProfile = 'Any' AllowedRemoteAddress = $AllowedRemoteAddress AdministrativeAccessOnly = $true AlwaysOnPowerPolicyApplied = $true }