WindowsFirewallRuleset

Remoting help

This document briefly describes remoting commandlets, requirements, help notices and design used in this repository.

Table of Contents

Commandlets breakdown

A brief breakdown that is of interest, according to Microsoft docs.

Set-WSManQuickConfig

Reference

Set-WSManQuickConfig -UseSSL will not work if your certificate is self signed

Table of Contents

Enable-PSRemoting

This provides remote access to session configurations that were reserved for local use.
LocalAccountTokenFilterPolicy = 1 allows remote access to members of the Administrators group.

Reference
Table of Contents

Enable-PSSessionConfiguration

Does not remove or change the Network_Deny_All

Reference
Table of Contents

Disable-PSRemoting

Changes the security descriptor of all session configurations to block remote access

Will not undo the following:

LocalAccountTokenFilterPolicy = 0 blocks remote access to members of the Administrators group.

Because Deny_All was not added, loopback connections are still allowed, for requirements see WinRM on loopback

Reference
Table of Contents

Disable-PSSessionConfiguration

Table of Contents

WinRM on loopback

A loopback connection is created when the following conditions are met:

For loopback remoting reference see Disable-PSRemoting

Table of Contents

Security descriptor flags

For details see -AccessMode parameter description here AccessMode

To add or remove these flags to configurations manually use Set-PSSessionConfiguration

Table of Contents

SkipNetworkProfileCheck commandlets

-SkipNetworkProfileCheck switch parameter is available only by the following commandlets:

If you have Hyper-V installed that means some virtual switches will operate on public network even if you’re on private network profile, which means you won’t be able to configure all possible WinRM service options, except only with those commandlets listed above.

Disabling those virtual switches is required in that case, uninstalling Hyper-V is an alternative solution if disabling does not work.

Of course any remaining network adapters must operate on private network profile.

For reference see -SkipNetworkProfileCheck parameter description.

Table of Contents

Remote registry

In this repository for PowerShell [Microsoft.Win32.RegistryKey] class is used for remote registry.

For reference see RegistryKey

Table of Contents

Remote registry requirements in PowerShell

The following requirements apply to both endpoints involved (client and server computers):

To initiate remote registry connection you must authenticate to remote computer with username and password of the user account on remote computer that belongs to Administrators group.

[Microsoft.Win32.RegistryKey] does not provide any authentication methods, therefore to use it in PowerShell the solution is to open network drive as follows:

$RemoteComputer = "COMPUTERNAME"
$RemotingCredential = Get-Credential

New-PSDrive -Credential $RemotingCredential -PSProvider FileSystem -Name RemoteRegistry `
    -Root \\$RemoteComputer\C$ -Description "Remote registry authentication" | Out-Null

Note that Registry provider -PSProvider Registry does not support specifying credentials but specifying FileSystem does the trick.

If New-PSDrive fails with “The network path was not found” try restarting fdphost service on both computers or reboot both computers.
Alternatively, creating a new remote share and authenticating to it instead of default C$ can help.

Table of Contents

Exception handling

Methods of the [Microsoft.Win32.RegistryKey] class may throw various exceptions but not all are handled in this repository except for initial registry authentication and root key access to avoid code bloat.

At a minimum you should handle OpenRemoteBaseKey and opening root key (but not subsequent subkeys) with OpenSubkey exceptions.

The following is an example which you can copy\paste to problem script to get detailed problem description.

try
{
    Write-Verbose -Message "[$($MyInvocation.InvocationName)] Accessing registry on computer: $RemoteComputer"
    $RemoteKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($RegistryHive, $RemoteComputer, $RegistryView)
}
catch [System.UnauthorizedAccessException]
{
    Write-Error -Category AuthenticationError -TargetObject $RegistryHive -Message $_.Exception.Message
    Write-Warning -Message "[$($MyInvocation.InvocationName)] Remote registry access was denied for $([Environment]::MachineName)\$([Environment]::UserName) by $RemoteComputer system"
    return
}
catch [System.Security.SecurityException]
{
    Write-Error -Category SecurityError -TargetObject $RegistryHive -Message $_.Exception.Message
    Write-Warning -Message "[$($MyInvocation.InvocationName)] $($RemotingCredential.UserName) does not have the requested ACL permissions for $RegistryHive hive"
    return
}
catch
{
    Write-Error -ErrorRecord $_
    return
}

try
{
    Write-Verbose -Message "[$($MyInvocation.InvocationName)] Opening root key: HKLM:\$HKLM"
    $RootKey = $RemoteKey.OpenSubkey($HKLM, $RegistryPermission, $RegistryRights)

    if (!$RootKey)
    {
        throw [System.Data.ObjectNotFoundException]::new("The following registry key does not exist: HKLM:\$HKLM")
    }
}
catch [System.Security.SecurityException]
{
    Write-Error -Category SecurityError -TargetObject $HKLM -Message $_.Exception.Message
    Write-Warning -Message "[$($MyInvocation.InvocationName)] $($RemotingCredential.UserName) does not have the requested ACL permissions for $HKLM key"
}
catch
{
    Write-Error -ErrorRecord $_
}
finally
{
    if ($RemoteKey)
    {
        $RemoteKey.Dispose()
    }

    Write-Error -ErrorRecord $_
    return
}

For additional breakdown of registry key naming convention and exceptions see NamingConvention.md

Table of Contents

Troubleshooting

The following link lists common issues with remoting and how to troubleshoot them About Remote Troubleshooting

The following section lists other not so common problems and how to resolve them.

Troubleshooting WinRM

TODO: missing resolutions for the following known problems:

Table of Contents

The WinRM client sent a request to an HTTP server and got a response saying the requested HTTP URL was not available

Connecting to remote server COMPUTERNAME failed with the following error message : The WinRM client sent a request to an HTTP server and got a response saying the requested HTTP URL was not available. This is usually returned by a HTTP server that does not support the WS-Management protocol.

When you specify computername, it is translated to private IP address for which listener must exist.
WinRM service is not listening on the translated IP address, to add listener for any IP address run:

New-Item -Path WSMan:\localhost\Listener -Address * -Transport HTTP -Enabled $true -Force | Out-Null

or alternatively:

New-WSManInstance -ResourceURI winrm/config/Listener -ValueSet @{ Enabled = $true } `
     -SelectorSet @{ Address = "*"; Transport = "HTTP" } | Out-Null

Table of Contents

“Negotiate” authentication is not enabled

Set-Item -Path WSMan:\localhost\Client\Auth\Negotiate -Value $true
Restart-Service -Name WinRM

If not working then:

Set-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WSMAN\Client\ `
     -Name auth_negotiate -Value ([int32] ($AuthenticationOptions["Negotiate"] -eq $true))
Restart-Service -Name WinRM

Table of Contents

Encountered an internal error in the SSL library

The server certificate on the destination computer (localhost) has the following errors: Encountered an internal error in the SSL library.

If using SSL on localhost, it would go trough network stack and for this you need authentication, which means specifying host name, user name and password.

Table of Contents

Access is denied (WinRM)

Access is denied

If credentials are required, this may happen due to invalid username\password.
It may also happen if the administrative account used to deploy firewall has no password set, in which case password must be set because WinRM doesn’t support passwordless authentication.
Although it should be possible for passwordless logon by configuring GPO on remote computer:
Computer Configuration/Windows Settings/Security Settings/Local Policies/Security Options/Accounts:
Limit local account use of blank passwords to console logon only

[localhost] Connecting to remote server localhost failed with the following error message: Access is denied.

If this happens in Initialize-WinSession it’s because session configuration was disabled in Windows PowerShell, ex. by using Reset-Firewall -Remoting, to fix this problem run in Windows PowerShell:

Set-PSSessionConfiguration -Name Microsoft.PowerShell -AccessMode Remote

Otherwise check the following 3 things:

  1. Verify PS session configuration which is being used is enabled

     Get-PSSessionConfiguration -Name "NameOfTheSession" | Enable-PSSessionConfiguration
    

    NOTE: To get Windows PowerShell session configurations use Get-PSSessionConfiguration in Windows PowerShell

  2. Verify access mode of the session PS configuration is set to Remote

     Set-PSSessionConfiguration -Name "NameOfTheSession" -AccessMode Remote
    
  3. Verify LocalAccountTokenFilterPolicy is enabled (set to 1)

     Set-ItemProperty -Name LocalAccountTokenFilterPolicy -Value 1 `
         -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
    
  4. Verify access permissions for user or group on remote host per session in question

     Set-PSSessionConfiguration -ShowSecurityDescriptorUI -Name NameOfTheSession
    

Table of Contents

Troubleshooting CIM

The following sections list CIM related errors and how to resolve them

WS-Management service does not support the specified polymorphism mode

Error description example:

Get-CimInstance: The WS-Management service does not support the specified polymorphism mode. Try changing the polymorphism mode specified, and try again.

Error resolution:

The Web Services Management Protocol Extensions for Windows Vista service MUST return instances of both base and derived classes. Each returned instance MUST contain the properties of the base class. Each returned instance MAY omit the properties from the derived classes and MAY set the instance type of derived classes to the base class.

PolymorphismMode

Hint: do not use -Shallow parameter with Get-CimInstance commandlet

The service is configured to reject remote connection requests for this plugin

The WS-Management service cannot process the request. The service is configured to reject remote connection requests for this plugin

You get this error when running Get-CimInstance -CimSession $CimServer where $CimServer is your already established remote CIM session.

First step is to harvest plugin status as follows:

Get-Item WSMan:\localhost\Plugin\* | ForEach-Object {
  $Enabled = Get-Item "WSMan:\localhost\Plugin\$($_.Name)\Enabled" |
  Select-Object -ExpandProperty Value

  [PSCustomObject] @{
    Name = $_.Name
    Enabled = $Enabled
    PSPath = $_.PSPath
  }
} | Sort-Object -Property Enabled -Descending | Format-Table -AutoSize

Sample output may look like this:

Name                          Enabled PSPath
----                          ------- ------
RemoteFirewall                True    Microsoft.WSMan.Management\WSMan::localhost\Plugin\RemoteFirewall
Microsoft.PowerShell          True    Microsoft.WSMan.Management\WSMan::localhost\Plugin\Microsoft.PowerShell
WMI Provider                  False   Microsoft.WSMan.Management\WSMan::localhost\Plugin\WMI Provider
Microsoft.PowerShell32        False   Microsoft.WSMan.Management\WSMan::localhost\Plugin\Microsoft.PowerShell32
Event Forwarding Plugin       False   Microsoft.WSMan.Management\WSMan::localhost\Plugin\Event Forwarding Plugin
Microsoft.Powershell.Workflow False   Microsoft.WSMan.Management\WSMan::localhost\Plugin\Microsoft.Powershell.Workflow

As you can see WMI Provider plugin is not enabled in this example which does the following:

WMI allows you to manage local and remote computers and models computer and network objects using an extension of the Common Information Model (CIM) standard

Since this plugin is required to run CIM commands against remote computer you enable it like this:

Set-Item -Path WSMan:\localhost\Plugin\"WMI Provider"\Enabled -Value $true
Restart-Service -Name WinRM

Table of Contents

For more information see WMI plug-in configuration notes

Access is denied (CIM)

Most likely you need to specify credentials

Table of Contents

Troubleshooting remote registry

See the following link Troubleshooting Remote Registry

Table of Contents

Remoting status

The following section lists module functions and scripts which support or do not support remoting by design, as well as functions which currently lack remoting implementation or are unfinished for remoting.

The following modules do no expose any remoting functionality at all by design

The following modules lack remoting functionality

Ruleset.Compatibility

The following functions support remoting but were not tested for remoting

The following functions do not implement remoting and it’s unclear if it’s needed

Ruleset.ComputerInfo

The following functions support remoting

The following functions lack remoting implementation

All other public functions do not support remoting by design

Ruleset.Firewall

The following functions support remoting

The following functions do not support remoting by design

All other public functions lack remoting implementation

Ruleset.ProgramInfo

The following functions do not support remoting by design

The following functions support remoting with PowerShell Core only

All other public functions support remoting

Ruleset.Remote

The following functions support remoting

All other functions do not implement remoting and it’s unclear if remoting is needed

Ruleset.UserInfo

The following functions do not support remoting by design

The following functions lack remoting implementation

The following functions support remoting but may fail

All other functions support remoting

Ruleset.Utility

The following functions support remoting

The following functions lack remoting implementation

All other functions do not support remoting by design

Scripts

The following scripts support remoting

The following scripts lack remoting implementation

All other scripts do not support remoting by design

Table of Contents