This document briefly describes remoting commandlets, requirements, help notices and design used in this repository.
- Remoting help
A brief breakdown that is of interest, according to Microsoft docs.
- Starts the WinRM service and sets startup type to automatic.
- Creates a listener to accept requests on any IP address, HTTP by default.
- Adds
Windows Remote Management
firewall rules to PersistentStore (required by WinRM)
Set-WSManQuickConfig -UseSSL
will not work if your certificate is self signed
- Runs the
Set-WSManQuickConfig
- Creates (or recreates) the default session configurations.
- Enables all session configurations, see Enable-PSSessionConfiguration
- Changes the security descriptor of all session configurations to allow remote access.
- Removes the
Deny_All
- Removes the
Network_Deny_All
- Removes the
- Sets the following registry key to
1
HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy
- Restarts the WinRM service
This provides remote access to session configurations that were reserved for local use.
LocalAccountTokenFilterPolicy = 1
allows remote access to members of the Administrators group.
- Removes the
Deny_All
setting from the security descriptor - Turns on the listener that accepts requests on any IP address
- Restarts the WinRM service
- Sets the value of the Enabled property of the session configuration in
WSMan:\<computer>\PlugIn\<SessionConfigurationName>\Enabled
to True.
Does not remove or change the Network_Deny_All
Changes the security descriptor of all session configurations to block remote access
- Adds the
Network_Deny_All
Will not undo the following:
- Stop and disable the WinRM service
- Delete the listener that accepts requests on any IP address
- Disable and remove
Windows Remote Management
firewall rules (including compatibility rules) - Add
Deny_All
if it was present previously - Restore the following registry value to
0
HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy
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
- Adds the
Deny_All
setting to the security descriptor - Sets the value of the Enabled property of the session configuration in
WSMan:\<computer>\PlugIn\<SessionConfigurationName>\Enabled
to False.
A loopback connection is created when the following conditions are met:
- The computer name to connect to is
localhost
- No credentials are passed in
- Current logged in user (implicit credentials) is used for the connection
- The
-EnableNetworkAccess
switch parameter is used withNew-PSSession
For loopback remoting reference see Disable-PSRemoting
Deny_All
block all users from using session configuration, both remote and localNetwork_Deny_All
allow only users of the local computer to use the session configuration, either loopback or trough network stack
For details see -AccessMode
parameter description here AccessMode
To add or remove these flags to configurations manually use Set-PSSessionConfiguration
-SkipNetworkProfileCheck
switch parameter is available only by the following commandlets:
Set-WSManQuickConfig
Enable-PSRemoting
Enable-PSSessionConfiguration
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 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.
In this repository for PowerShell [Microsoft.Win32.RegistryKey]
class is used for remote registry.
For reference see RegistryKey
Following requirements apply to both endpoints involved (client and server computers):
RemoteRegistry
service isRunning
and set toAutomatic
startup- Enable at a minimum following predefined (not custom) firewall rules:
File and Printer sharing
Network Discovery
- Network adapter is on
Private
orDomain
network profile.
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
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.
Following is an example that 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("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
Following link lists common troubleshooting with remoting About Remote Troubleshooting
Following section lists other not so common problems and how to resolve them.
TODO: missing resolutions for the following known problems:
- System cannot find file because it does not exist
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. Service is not listening 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
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
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.
Access is denied
If credentials are required, this may happend 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.
[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 -Remote, to fix this problem run in Windows PowerShell:
Set-PSSessionConfiguration -Name Microsoft.PowerShell -AccessMode Remote
Otherwise check following 3 things:
-
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 -
Verify access mode of the session PS configuration is set to
Remote
Set-PSSessionConfiguration -Name "NameOfTheSession" -AccessMode Remote
-
Verify
LocalAccountTokenFilterPolicy
is enabled (set to 1)Set-ItemProperty -Name LocalAccountTokenFilterPolicy -Value 1 ` -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
Following sections list CIM related errors and how to resolve them
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.
Hint:
Do not use -Shallow
parameter with Get-CimInstance
commandlet
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
For more information see WMI plug-in configuration notes
Most likely you need to specify credentials
See following link Troubleshooting Remote Registry