Skip Ribbon Commands
Skip to main content

Ondrej Sevecek's English Pages

:

Engineering and troubleshooting by Directory Master!
MCM: Directory

Quick Launch

Ondrej Sevecek's English Pages > Posts > Enabling remote WMI and PowerShell access over WinRM for non-administrators
April 26
Enabling remote WMI and PowerShell access over WinRM for non-administrators

Note: Czech version of the same article can be found here.

I have already published an article about how to enable remote WMI access for non-administrators, directly over the WMI's native DCOM interface. Yet, the DCOM is not the only transport for WMI. If you have Windows Management Framework (WMF) installed on a remote server, you can enable another transport over WinRM (Windows Remote Management).

WinRM, sometimes called WSMan as well, is a generic remote management technology which does little itself, but provides a standard HTTP SOAP transport for other management technologies, such as WMI or PowerShell remoting, Event Forwarding or even the notorious Server Manager. WinRM is just a protocol and server web service, which listens to remote management requests on its own HTTP, or encrypted HTTPS endpoints, and forwards the queries and commands to its local providers (or plugins). PowerShell, WMI or the Event Forwarding are all implemented as the WinRM providers.

If you were a software developer, you would be able to create your own WinRM provider (plugin) and enable your own server application to be managed remotelly. Yes, you could do it any other way, using either DCOM or your own HTTP web service. But WinRM is a standard framework, server administrators may be able to configure it more easily, than to learn another configuration of your own application.

WinRM also provides for standard user authentication over Windows integrated authentication methods such as Kerberos, Negotiate (plus NTLM) and Schannel (certificate authentication). As it uses normal HTTP, the clients can also authenticate using standard Basic or Digest authentication methods. This may be another reason for application developers to use WinRM services to transport their own management "protocols".

In case of WMI, the Windows Management Instrumentation service (winmgmt) can receive remote commands and queries (WQL) on its own DCOM interface and if enabled, also on WinRM interface as well. PowerShell on the other hand does not have its own "server". With PowerShell remoting, you can run commands on a remote machine using commandlets such as Enter-PSSession or Invoke-Command. As PowerShell does not have its own server service, it relies on WinRM to receive commands from remote clients. PowerShell then executes the commands locally on the server and WinRM returns their results to the client side.

Similarly, Server Manager works like the PowerShell remoting. Event Forwarding could have developed its own method of transport, because it actually has its own Windows Event Collector service (wecsvc), but Microsoft decided to use WinRM instead. Probably because of its standard and simple to implement HTTP SOAP protocol.

In all cases, WinRM runs the provider (plug-in) operations in context of the authenticated client identity leaving any security related controls to the normal Windows access control mechanisms.

WinRM is does not enable remote access by default on Windows 2008 R2 and older systems. Although you can easily enable it with the following command:

winrm quickconfig

With introduction of the new Server Manager on Windows 2012 and its strong remote management capabilities, WinRM is configured to listens for authenticated HTTP requests by default on Windows 2012.

Yet, in both cases, it enables only members of Administrators to connect remotely. Although you may have some local rights or may just like to query some information from a remote server, WinRM does not allow you to connect unless you are member of local Administrators group. It is similar to the case of administrative shares (the automatic disk$ shares) - these are also enabled by default, but restricted only to Administrators.

In secure environments with separated administrative tasks, if is often a requirement to have some "remote operators" or "audit only" users who can monitor remote systems, or perform some basic administrative tasks. So how to make WinRM connection possible for non-administrators. How to enable them to query WMI. How to allow non-administrators to run remote PowerShell commands?

In the following text, we will cover mainly WinRM 2.0, which is included with Windows 7 and Windows Server 2008 R2 while you can download it (as part of Windows Management Framework 2.0) for all other supported systems. Windows 2012 and Windows 8 come by default with WinRM 3.0 (Windows Management Framework 3.0). You can download it for Windows 7 and Windows Server 2008 as well, but I would rather not do it as it is not yet supported with Exchange 2012, SharePoint 2010 nor System Center 2012.

WinRM internals first

WinRM is a Windows service with the same name. It runs as NT AUTHORITY\NetworkService, so that it can accept authenticated client requests over Windows integrated authentication mechanisms such as the Negotiate, Kerberos, NTLM or Schannel (TLS client certificate authentication) protocols. On server editions, the service runs Automatically, while on client editions of operating system it is configured to start as Manual.

You list some basic service info from command line by using SC command and its parameters such as QUERY, QC or QSIDTYPE as in the following output:

C:\sc query winrm

SERVICE_NAME: winrm
        STATE              : 4  RUNNING

C:\sc qc winrm

[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: winrm
        TYPE               : 20  WIN32_SHARE_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : C:\Windows\System32\svchost.exe -k NetworkService
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : Windows Remote Management (WS-Management)
        DEPENDENCIES       : RPCSS
                           : HTTP
        SERVICE_START_NAME : NT AUTHORITY\NetworkService

C:\sc qsidtype winrm

[SC] QueryServiceConfig2 SUCCESS

SERVICE_NAME: winrm
SERVICE_SID_TYPE:  UNRESTRICTED

Note: the SID type of the service shows as unrestricted, which means that it actually has (although it is "unrestricted", it is not "none") its own service SID and you might configure some permissions for its service identity of NT SERVICE\winrm. Don't know what I am talking about? Just forget.

We said that WinRM is a HTTP web service. But the WinRM service does not listen to HTTP requests directly. It may collide with other HTTP services on the same server, such as IIS or SQL Reporting Services or Hyper-V replication. For this reason, it uses the built-in HTTP.SYS driver the same ways as the other mentioned services.

HTTP.SYS is a Kernel mode driver that listens for HTTP and HTTPS requests and when one comes, it parses some of its headers and mainly the URL and distributes the request to one of its user mode client applications. HTTP.SYS is present by default and does not depend on IIS installation. For instance, if you install IIS, it only registeres its URL namespaces with HTTP.SYS. When HTTP.SYS receives an HTTP request for some IIS managed URL, it forwards the request to respective W3SVC worker process if one already runs - or instructs Windows Process Activation Service (WAS) to start a new one.

Similarly, SQL Server Reporting Services does not need IIS to work. The Report Server only registers with HTTP.SYS (its URL paths are /Reports and /ReportServer) and does not need to bother with the rest. Another example of HTTP.SYS listener application is SSTP VPN server. It registers URI of /sra_{BA195980-CD49-458b-9E23-C84EE0ADCD75}. IPHTTPS tunnel server registers /IPHTTPS URI.

All the same, WinRM registers /WSMan URI with HTTP.SYS. By default on a TCP port number different than the standard 80, but you can also create a listener on the common TCP port 80 if you need it.

HTTP.SYS listening technology is the very important part of WinRM operation, so you should be able to query and verify its state before we proceed with actual WinRM configuration:

C:\netsh http show servicestate

Snapshot of HTTP service state (Server Session View):
-----------------------------------------------------

Server session ID: FF00000320000001
    Version: 1.0
    State: Active
    Properties:
        Max bandwidth: 4294967295
        Timeouts:
            Entity body timeout (secs): 120
            Drain entity body timeout (secs): 120
            Request queue timeout (secs): 120
            Idle connection timeout (secs): 120
            Header wait timeout (secs): 120
            Minimum send rate (bytes/sec): 150
    URL groups:
    URL group ID: FE00000340000001
        State: Active
        Request queue name: Request queue is unnamed.
        Properties:
            Max bandwidth: inherited
            Max connections: inherited
            Timeouts:
                Timeout values inherited
            Number of registered URLs: 1
            Registered URLs:
                HTTP://+:47001/WSMAN/

Request queues:
    Request queue name: Request queue is unnamed.
        Version: 1.0
        State: Active
        Request queue 503 verbosity level: Basic
        Max requests: 1000
        Number of active processes attached: 1
        Process IDs:
            152

The previous output shows the default WinRM configuration which you will find on Windows 2008 R2 (be patient, the defaults for Windows 2012 come shortly). WinRM and its /WSMan URI is bound to port TCP 47001 by default. You can also see the number among listening ports when you query NETSTAT:

C:\netstat -ano | findstr :47001

  TCP    0.0.0.0:47001          0.0.0.0:0              LISTENING       4
  TCP    [::]:47001             [::]:0                 LISTENING       4

Does it mean that WinRM is remotelly accessible on this port? What if you opened a firewall exception for the port (which is not present by default)? Nothing would happen. Although HTTP.SYS accept requests on the port number and forwards them to WinRM, WinRM in turn checks whether the client is local or remote and if it is a remote connection, it rejects it with HTTP error status 404 Not Found.

But yes, WinRM accepts local requests on the port TCP 47001. It is actually the reason for having the port opened by default. To receive local WinRM requests.

As we said before, Windows 2012 enable remote WinRM access by default (you will see a key stating AllowRemoteAccess = true in the following command output). The following output shows the default port TCP 5985 which accepts even remote HTTP requests. The output also shows the previously mentioned port TCP 47001 which has the same function as on Windows 2008 R2 and older systems. Not only Windows 2012 have the WinRM listener enabled, they also have a firewall exception for the port opened by default.

C:\netsh http show servicestate

Snapshot of HTTP service state (Server Session View):
-----------------------------------------------------

Server session ID: FF00000120000001
    Version: 1.0
    State: Active
    Properties:
        Max bandwidth: 4294967295
        Timeouts:
            Entity body timeout (secs): 120
            Drain entity body timeout (secs): 120
            Request queue timeout (secs): 120
            Idle connection timeout (secs): 120
            Header wait timeout (secs): 120
            Minimum send rate (bytes/sec): 150
    URL groups:
    URL group ID: FE00000140000001
        State: Active
        Request queue name: Request queue is unnamed.
        Properties:
            Max bandwidth: inherited
            Max connections: inherited
            Timeouts:
                Timeout values inherited
            Number of registered URLs: 2
            Registered URLs:
                HTTP://+:5985/WSMAN/
                HTTP://+:47001/WSMAN/

Request queues:
    Request queue name: Request queue is unnamed.
        Version: 1.0
        State: Active
        Request queue 503 verbosity level: Basic
        Max requests: 1000
        Number of active processes attached: 1
        Process IDs:
            960

Yes, I call it a small security issue. It is just not nice. The same way as it is with administrative shares which I would rather have disabled.

Small interruption - sorry for not mentioning it yet. I wanted to make it as simple as possible. What we have discussed here yet was called WinRM Service Hosting Model. It means that WinRM windows service is actually listening for the WinRM requests. But it is only a single service, single process, also sharing its process with other windows services. For large, heavily loaded, server deployments it may not be too scalable. Thus, there is also another method how to make WinRM accessible. You may install WinRM Extension for IIS. If WinRM runs as a virtual directory inside IIS, it may be configured to run in a separate worker process (W3SVC), have its own resource qoutas etc. For example, Exchange 2010 uses this hosting model called WinRM IIS Extension Hosting Model. If you run Exchange PowerShell commands remotely, it goes into the Exchange's IIS first, from there into WinRM and yet from there to the server's local PowerShell. But we are not particually intersted with the IIS WinRM Extension here, so forget about it.

We have just investigated the HTTP.SYS configuration. To understand WinRM listeners completelly, we must proceed with WinRM own configuration. You would see the following output on default installation of Windows 2008 R2:

C:\winrm get winrm/config

Config
    MaxEnvelopeSizekb = 150
    MaxTimeoutms = 60000
    MaxBatchItems = 32000
    MaxProviderRequests = 4294967295
    Client
        NetworkDelayms = 5000
        URLPrefix = wsman
        AllowUnencrypted = false
        Auth
            Basic = true
            Digest = true
            Kerberos = true
            Negotiate = true
            Certificate = true
            CredSSP = false
        DefaultPorts
            HTTP = 5985
            HTTPS = 5986
        TrustedHosts
    Service
        RootSDDL = O:NSG:BAD:P(A;;GA;;;BA)S:P(AU;FA;GA;;;WD)(AU;SA;GWGX;;;WD)
        MaxConcurrentOperations = 4294967295
        MaxConcurrentOperationsPerUser = 15
        EnumerationTimeoutms = 60000
        MaxConnections = 25
        MaxPacketRetrievalTimeSeconds = 120
        AllowUnencrypted = false
        Auth
            Basic = false
            Kerberos = true
            Negotiate = true
            Certificate = false
            CredSSP = false
            CbtHardeningLevel = Relaxed
        DefaultPorts
            HTTP = 5985
            HTTPS = 5986
        IPv4Filter = *
        IPv6Filter = *
        EnableCompatibilityHttpListener = false
        EnableCompatibilityHttpsListener = false
        CertificateThumbprint
    Winrs
        AllowRemoteShellAccess = true
        IdleTimeout = 180000
        MaxConcurrentUsers = 5
        MaxShellRunTime = 2147483647
        MaxProcessesPerShell = 15
        MaxMemoryPerShellMB = 150
        MaxShellsPerUser = 5

Also note some minor changes of the default settings on Windows 2012. Especially mind the RootSDDL which we will research shortly and which is crucial for out non-administrators access:

Config
    MaxEnvelopeSizekb = 500
    MaxTimeoutms = 60000
    MaxBatchItems = 32000
    MaxProviderRequests = 4294967295
    Client
        NetworkDelayms = 5000
        URLPrefix = wsman
        AllowUnencrypted = false
        Auth
            Basic = true
            Digest = true
            Kerberos = true
            Negotiate = true
            Certificate = true
            CredSSP = false
        DefaultPorts
            HTTP = 5985
            HTTPS = 5986
        TrustedHosts
    Service
        RootSDDL = O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;IU)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
        MaxConcurrentOperations = 4294967295
        MaxConcurrentOperationsPerUser = 1500
        EnumerationTimeoutms = 240000
        MaxConnections = 300
        MaxPacketRetrievalTimeSeconds = 120
        AllowUnencrypted = false
        Auth
            Basic = false
            Kerberos = true
            Negotiate = true
            Certificate = false
            CredSSP = false
            CbtHardeningLevel = Relaxed
        DefaultPorts
            HTTP = 5985
            HTTPS = 5986
        IPv4Filter = *
        IPv6Filter = *
        EnableCompatibilityHttpListener = false
        EnableCompatibilityHttpsListener = false
        CertificateThumbprint
        AllowRemoteAccess = true
    Winrs
        AllowRemoteShellAccess = true
        IdleTimeout = 7200000
        MaxConcurrentUsers = 10
        MaxShellRunTime = 2147483647
        MaxProcessesPerShell = 25
        MaxMemoryPerShellMB = 1024
        MaxShellsPerUser = 30

Also note the DefaultPorts setting. It is really just default ports. Not that it would mean the HTTP 5985 listener is created on Windows 2008 by default. The HTTPS 5986 is not created by default even on Windows 2012.

A note about encryption: it may look like Windows 2012 do not enable encryption by default, because they listen to HTTP only. Although the transport is not directly encrypted with TLS/SSL then, WinRM itself encrypts its communications (see the AllowUnencrypted = false key) with keys derived from the default Windows authentication method. So we are still kind of safe, except we are do not follow some government encryption standards.

These were just default port configurations. To listen for remote queries actually, WinRM needs to have an explicit listener. Take a look at the default listener config on Windows 2012. You would also get the same output on Windows 2008 R2 and older system if you enabled remote access with the winrm qc (or exactly winrm quickconfig):

C:\winrm enumerate winrm/config/listener

Listener
    Address = *
    Transport = HTTP
    Port = 5985
    Hostname
    Enabled = true
    URLPrefix = wsman
    CertificateThumbprint
    ListeningOn = 10.10.0.12

Once again, if you want to enable remote access to your WinRM server on a specific TCP HTTPS port, you can do it just like me. You should only have a valid TLS server certificate with the machine's name ready in the local computer certificate store:

winrm create winrm/config/listener?Address=*+Transport=HTTPS @{Port="30000"}

Recap - if you have a WinRM listener, you will see a HTTP.SYS binding and URI registration as mentioned previously.

About WinRM plugins or providers

As I said, WinRM is just an easy transport worker and host for generic remote administration applications. Examples I have already mentioned are WMI, PowerShell, event forwarding or server manager. Every developer can create his own plugin or provider and register it with WinRM subsystem.

WinRM provider plug-in is just a DLL. You can list all listeners currently registered with WinRM if you want (and if you have read up to this point, you want probably) to investigate:

C:\winrm enumerate winrm/config/plugin -format:pretty

 Event Forwarding Plugin (wevtfwd.dll)
 URI: http://schemas.microsoft.com/wbem/wsman/1/windows/EventLog
 SDDL: O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;ER)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)

 microsoft.powershell (pwrshplugin.dll)
 URI: http://schemas.microsoft.com/powershell/microsoft.powershell
 SDDL: O:NSG:BAD:P(A;;GA;;;BA)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
 
 microsoft.servermanager (pwrshplugin.dll)
 URI: http://schemas.microsoft.com/powershell/microsoft.servermanager
 SDDL: O:NSG:BAD:P(A;;GA;;;BA)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)

 SEL Plugin (wsmselpl.dll)
 URI: http://schemas.microsoft.com/wbem/wsman/1/logrecord/sel
 SDDL: O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;S-1-5-80-4059739203-877974739-1245631912-527174227-2996563517)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)

 WMI Provider (wsmwmipl.dll)
 URI: http://schemas.microsoft.com/wbem/wsman/1/wmi
 URI: http://schemas.dmtf.org/wbem/wscim/1/cim-schema
 URI: http://schemas.dmtf.org/wbem/wscim/1/*

With Windows 2012 and its Windows Management Framework 3.0 we have more providers. To us here, only the small differences in SDDL matter:

 Event Forwarding Plugin (wevtfwd.dll)
 URI: http://schemas.microsoft.com/wbem/wsman/1/windows/EventLog
 SDDL: O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;ER)S:P(AU;FA;GA;;;WD)(AU;SA;GWGX;;;WD)

 microsoft.powershell (pwrshplugin.dll)
 URI: http://schemas.microsoft.com/powershell/microsoft.powershell
 SDDL: O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;RM)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
 
 microsoft.powershell.workflow (pwrshplugin.dll)
 URI: http://schemas.microsoft.com/powershell/microsoft.powershell.workflow
 SDDL: O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;RM)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)

 microsoft.powershell32 (pwrshplugin.dll)
 URI: http://schemas.microsoft.com/powershell/microsoft.powershell32
 SDDL: O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;RM)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)

 microsoft.windows.servermanagementworkflows (pwrshplugin.dll)
 URI: http://schemas.microsoft.com/powershell/microsoft.windows.servermanagerworkflows
 SDDL: O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;IU)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)

 SEL Plugin (wsmselpl.dll)
 URI: http://schemas.microsoft.com/wbem/wsman/1/logrecord/sel
 SDDL: O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;S-1-5-80-4059739203-877974739-1245631912-527174227-2996563517)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)

 WMI Provider (wsmwmipl.dll)
 URI: http://schemas.microsoft.com/wbem/wsman/1/wmi
 SDDL: O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;IU)(A;;GA;;;RM)(A;;GA;;;S-1-5-21-3411848436-3231049841-1657526397-1000)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
 URI: http://schemas.dmtf.org/wbem/wscim/1/cim-schema
 SDDL: O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;IU)(A;;GA;;;RM)(A;;GA;;;S-1-5-21-3411848436-3231049841-1657526397-1000)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
 URI: http://schemas.dmtf.org/wbem/wscim/1/*
 SDDL: O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;IU)(A;;GA;;;RM)(A;;GA;;;S-1-5-21-3411848436-3231049841-1657526397-1000)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
 URI: http://schemas.dmtf.org/wbem/cim-xml/2/cim-schema/2/*
 SDDL: O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;IU)(A;;GA;;;RM)(A;;GA;;;S-1-5-21-3411848436-3231049841-1657526397-1000)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)

Notably take a look at the WMI Provider. It has its own SDDL on Windows 2012 while there is no SDDL on Windows 2008 R2. If a provider does not have its own SDDL, it uses the RootSDDL which you saw in the output of winrm get winrm/config commands.

What the hell is SDDL?

That is exactly what controls access to WinRM and its providers in the first place. It is moniker for Security Descriptor Definition Language. Just a textual writedown of generic Windows security descriptor which you can find everywhere - on NTFS files and folders, in registry, on WMI namespaces or exactly here with WinRM.

WinRM does not allow just anybody to connect. It first authenticates the user and verify the SDDL for the particular provider before forwarding requests to the provider at all. There is either a certain SDDL on a provider or the provider defaults to the RootSDDL. Note that RootSDDL is not used as a "pre-filter". It has a meaning only as a default SDDL for providers which do not specify their own SDDL explicitly.

We must research the SDDLs slightly. If you want a precise reference for SDDL you can find it tady and tady and tady. Simple format is as follows:

O:<owner>D:P<permissions>S:P<auditing>

We are then interested in the section starting with D:P. Is is comprised of several bracketed sections. Each block represents an ACE (Access Control Entry). The letter A means Allow ACE, while D would mean Deny ACE. Here, we cope with Allow ACEs only, as you may verify. The middle part of every ACE specifies access level granted or denied:

GA = Generic All (Full Control)
GR = Generic Read
GW = Generic Write
GX = Generic Execute

The last thing in every ACE is either SID of a particular user or group (rather call it security principal) or a predefined SID:

BA = BUILTIN\Administrators
WD = Everyone
ER = BUILTIN\Event Log Readers
IU = NT AUTHORITY\Interactive
RM = BUILTIN\Remote Management Users
S-1-5-21-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-1000 = WinRMRemoteWMIUsers__

Lets investigate RootSDDL of the Windows 2008 R2 WinRM server. Yes, it is actually the SDDL which applies for its WMI provider:

O:NSG:BAD:P(A;;GA;;;BA)S:P(AU;FA;GA;;;WD)(AU;SA;GWGX;;;WD)

Its only ACE (the rest is just auditing) says Allow, Generic All to BUILTIN\Administrators. This is the exact reason, why you cannot access WMI remotelly over WinRM unless you are member of local Administrators group on the target server.

On Windows 2012, the SDDL is present explicitly on WMI provider, so that RootSDDL is ignored. It reads:

O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;IU)(A;;GA;;;RM)(A;;GA;;;S-1-5-21-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx-1000)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)

You can see four ACEs here. Everything is Allow, Generic All. The first ACE is for Administrators again. The second one is for INTERACTIVE, while the third allows Remote Management Users group and the fourth ACE means WinRMRemoteWmiUsers__. Ok. So it looks like on Windows 2012 you can add your accounts into Remote Management Users or WinRMRemoteWMIUsers__ and would have a remote WMI access.

No, it is not enough.

Why? Take your time. We first try it and investigate the failure

Just try a remote WMI over WinRM query for something simple, for instance spooler service:

winrm get wmicimv2/Win32_Service?Name=spooler –remote:srv-data1

Note that you must use server name for the -remote parameter. It does not work for IP addresses for me, although I don't know why :-) If your client uses a different TCP port number than the client is configured to use, specify it as well like -remote:srv-data1:30000.

If you tried the previous access under a member of Administrators group, the output would be ok. But if you try it under non-administrator, you would end up with the following error:

WSManFault
    Message = Access is denied.

Error number:  -2147024891 0x80070005
Access is denied.

It means, the remote WinRM serer knows immediatelly tha tyou do not have access. So add yourself into the Remote Management Users or the WinRMRemoteWMIUsers__ and try it again:

Fault
    Code
        Value = s:Receiver
        Subcode
            Value = w:InternalError
    Reason
        Text = The WS-Management service cannot process the request. The WMI service returned an 'access denied' error.

    Detail
        MSFT_WmiError
            CIMStatusCode = 2
            CIMStatusCodeDescription = null
            ErrorSource = null
            ErrorSourceFormat = 0
            ErrorType = 0
            Message = The WS-Management service cannot process the request. The WMI service returned an 'access denied' error.
            MessageID = HRESULT 0x80338104
            OtherErrorSourceFormat = null
            OtherErrorType = null
            OwningEntity = null
            PerceivedSeverity = 0
            ProbableCause = 0
            ProbableCauseDescription = null
            error_Category = 18
            error_Code = 2150859012
            error_Type = HRESULT
            error_WindowsErrorMessage = The WS-Management service cannot process the request. The WMI service returned an 'access denied' error.

Error number:  -2147023537 0x8007054F
An internal error occurred.

Once again an Access Denied error. But now not directly from WinRM, but rather from the WMI itself. What this means? It means that you were able to pass the first access control layer successfully, but failed at the second one. The first layer is WinRM's own provider SDDL. The second are WMI namespace permissions.

Futher investigating WinRM activity and errors

You can use Event Viewer to obtain trace logs for WinRM:

Event Viewer
  Application and Service Logs
    Microsoft
      Windows Remote Management
        right-click View - Show Analytic and Debug Logs
          right-click Analytic - Enable Log

If you checked the trace log events after the previous excercise, you would see something similar to the following:

User ... authenticated successfuly using Kerberos authentication
Authorizing the user
Updating quota for the user
The authorization of the user was done successfully

If you went up to this point, it means you passed SDDL of the WinRM service. If you didn't pass, the second message wouuld say Access denied already.

SOAP listener receiving
Processing client request for operation GET
The WinRM service loaded the following plugin: WMI Provider (WsmWmiPl.dll)
Entering plugin for operation Get with Resource URI of ...
Authorizing the user

If you end up at this point, you passed WinRM provider permissions but faild at WMI namespace security.

Plugin reporting data object for operation Get
SOAP listener sending
Plugin reporting operation complete for Get

How to enable remote WMI access over WinRM to non-administrators on Windows 2012?

It is just this simple. First add your group or account into the Remote Management Users or WinRMRemoteWMIUsers__ group.

Only then you need to adjust WMI namespace security. I am doing it on the Root namespace so that the ACEs can propagate down the whole tree. You may configure it on a particular namespace if you like, for example CIMv2 is the most commonly queried namespace:

You must add the Remote Enable permission. The rest should be there on the Authenticated Users ACE. Or you may like to be more precise and copy it as well if you please:

Now you can try it!

But how to achieve the same on Windows 2008 R2 and older systems?

In addtion to the previous steps, we must update the RootSDDL of WinRM service as well. In order to do it, you must determine your account's or group's SID (security ID). Go for command line and obtain it from output of WHOAMI /ALL command:

S-1-5-21-3412575342-4025462326-617077526-1002

And then you can modify the RootSDDL of WinRM finally.

winrm set winrm/config/service @{RootSDDL="O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;S-1-5-21-3412575342-4025462326-617077526-1002)S:P(AU;FA;GA;;;WD)(AU;SA;GWGX;;;WD)"}

Do you understand the SDDL string? I have just added one ACE block for my group. Rather do it with your own RootSDDL than just copy my my. Your machines may have different RootSDDL from mine, so take the time and do it yourself instead of copying my own.

Runniiiiing!

What about PowerShell Remoting finally?

Go up and take a look at the SDDL for plug-in called microsoft.powershell (pwrshplugin.dll) and its URI http://schemas.microsoft.com/powershell/microsoft.powershell. What do you see there?

On Windows 2008 R2 it looks like this:

O:NSG:BAD:P(A;;GA;;;BA)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)

As you should see now, only local Administrators can access PowerShell remoting by default.

While on Windows 2012 you can see something else:

O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;RM)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)

From which you could see Administrators again, and the Remote Management Users (RM moniker). The other (weird name) group called WinRMRemoteWMIUsers__ is not present there. Which gives us a single option - if you want to access PowerShell remotely, such as with Enter-PSSession or Invoke-Command, just add you account or group in remote server's Remote Management Users group. The weird group called WinRMRemoteWMIUsers__ is not useful here.

I actually don't understand, why the group WinRMRemoteWMIUsers__ exists at all. It is probably because of the nature of the two groups. The Remote Management Users group is BUILTIN group with a special SID which has been added on Windows 2012 only. If you install Windows Management Framework 3.0 on Windows 2008 R2, there is no built-in group called Remote Management Users and WMF 3.0 so installs the WinRMRemoteWMIUsers__ group manually. Maybe it remained in Windows 2012 to maintain backward compatibility.

Finally, how do we enable PowerShell remoting for non-administrative users on Windows 2008 R2 and older?

On Windows 2008 R2 it is a matter of modifying SDDL of microsoft.powershell and microsoft.powershell32 WinRM providers. You must first enable remoting system-wide with Enable-PSRemoting. The command enables default WinRM remote access, just like you would achieve with the notorious winrm qc. The second thing Enable-PSRemoting cmdlet does is that it registers microsoft.powershell32 WinRM provider (plug-in):

microsoft.powershell32 (pwrshplugin.dll)
URI: http://schemas.microsoft.com/powershell/microsoft.powershell32
SDDL: -

So what next? We must modify the SDDL of the two providers. Fortunatelly, PowerShell comes with a builtin cmdlet to achieve the task:

Set-PSSessionConfiguration -name Microsoft.PowerShell -ShowSecurityDescriptorUI
Set-PSSessionConfiguration -name Microsoft.PowerShell32 -ShowSecurityDescriptorUI

Finished. Cheers!

Comments

There are no comments for this post.

Add Comment

Title


You do not need to provide any value this column. It will automatically fill with the name of the article itself.

Author *


Body *


Type number two as digit *


This simple antispam field seems to work well. Just put here the number.

Attachments