Welcome to Foxite.COM Community Weblog Sign in | Join | Help

Remote connections to Windows Server 2003 using WinRM

WinRM by default only allows remote connections via a secured connection using SSL (HTTPS). It can be configured to allow connections via HTTP, but as the documentation says, unless you are using IPSec to secure the connection between your client and server then the credentials used to adminster the server are sent in plaintext.

Configuring client and server (Windows Server 2003)

This code returns the current configuration for WS2003R2 (see here for the Vista config schema and what you need to do to access it: I will cover remote connections to/from Vista in another article) To configure WinRM, use the Put method, passing XML returned by the Get on the Config objects with the appropriate attributes set as required.
* Access config XML (Win 2003 Server)
oWsman = createobject("WSMAN.Automation") with oWsman.CreateSession()
cXML = .get("wsman:microsoft.com/wsman/2005/06/config")
messagebox(cXML)
endwith
The default configuration for a Windows 2003 server is below: because the WinRM client and service have basic authentication disabled remote connections via HTTP cannot be attempted or accepted.
Config
    MaxEnvelopeSizekb = 50
    MaxTimeoutms = 60000
    MaxBatchItems = 20
    SoapTraceEnabled = false
    MaxProviderRequests = 25
    Client
        NetworkDelayms = 5000
        URLPrefix = wsman
        HTTP
            Port = 80
            Unencrypted
                Basic = false
                Digest = false
                Negotiate = false
        HTTPS
            Port = 443
            Basic = true
            Digest = true
            Negotiate = true
    Service
        RootSDDL = O:NSG:BAD:P(A;;GA;;;BA)S:P(AU;FA;GA;;;WD)(AU;SA;GWGX;;;WD)
        MaxConcurrentOperations = 100
        EnumerationTimeoutms = 60000
        MaxClientCertInfoSize = 16384
        MaxConnections = 5
        HTTP
            Unencrypted
                Basic = false
                Negotiate = false
        HTTPS
            Basic = true
            Negotiate = true

Server configuration

From this output the XML containing the properties to be modified can be extracted and the new values substituted. This example XML could be used to allow basic authentication on inbound HTTP connections in WS2003:
<cfg:Config xmlns:cfg="wsman:microsoft.com/wsman/2005/06/config.xsd">
<cfg:Service>
<cfg:HTTP>
<cfg:Unencrypted>
<cfg:Basic>true</cfg:Basic>
</cfg:Unencrypted>
</cfg:HTTP>
</cfg:Service>
</cfg:Config>

Client configuration

HTTP authentication has to be explicitly allowed on the client as well: this is for WS2003 as well.
<cfg:Config xmlns:cfg="wsman:microsoft.com/wsman/2005/06/config.xsd">
<cfg:Client>
<cfg:HTTP>
<cfg:Unencrypted>
<cfg:Basic>true</cfg:Basic>
</cfg:Unencrypted>
</cfg:HTTP>
</cfg:Client>
</cfg:Config>
To set the configuration, pass the XML via the Put method (to the appropriate config URI). If successful, the new configuration is returned, otherwise XML indicating fault or failure. The session object's Error method will have details of the problem:
cResultXML = oSession.put("wsman:microsoft.com/wsman/2005/06/config", cConfigXML)

Creating a Listener

Once this has been done - or if you intend to connect using HTTPS - one or more listeners must be created on the target system. Listeners must be created and adminstered locally using WinRM.

This example code illustrates creating a listener, enumerating it, and finally deleting it. You will have to specify the IP address and hostname in the appropriate functions:
oWsman = createobject("WSMAN.Automation")
oSession = oWsman.CreateSession()
cSchema = "wsman:microsoft.com/wsman/2005/06/"

cResource = cSchema + "config/Listener?IP="
cResource = cResource + GetIPAddress() + "+Port=" + GetPort()

cXML = [<cfg:Listener xmlns:cfg="] + cSchema + [config/listener.xsd">]
cXML = cXML + "<cfg:Hostname>" + GetComputerName() + "</cfg:Hostname>"
cXML = cXML + "<cfg:Transport>" + GetTransport() + "</cfg:Transport>"
cXML = cXML + "</cfg:Listener>"

* Create the listener
cResponse = oSession.create(cResource, cXML)
messagebox(cResponse)

* Enumerate it:
cResponse = oSession.Enumerate(cSchema + "config/Listener").ReadItem()
messagebox(cResponse)

* Now delete it: there is no response to this operation if it is successful
cResponse = oSession.Delete(cResource)

function GetComputerName
return "VMAC"

function GetIPAddress
return "192.161.1.240"

function GetPort
return "80"

function GetTransport
return "HTTP"
The winrm command line would generally be used to do these operations on servers.
winrm put wsman:microsoft.com/wsman/2005/06/config -file:c:\config.xml
winrm create wsman:microsoft.com/wsman/2005/06/config/Listener?IP=192.168.1.240+Port=80 @{Hostname="VMAC";Transport="http"}
winrm enumerate wsman:microsoft.com/wsman/2005/06/config/Listener
You can check the connection using a command like the following. It doesn't appear possible to pass the required parameters to the automation session's Get method, as unfortunately the resource locator object is missing in WS2003R2 (it is available in Vista)
winrm get wsman:system/2005/06/this -machine:vmac -transport:http -username:stuart -password:helloworld

Establishing the remote connection to WMI

The WSMan.Automation object has a CreateConnectionsObject method which returns an object to whose properties are assigned the credentials to be used for the connection, and this object is passed to the CreateSession method with the appropriate connection flags. On my home network I have been unable to connect by IP address - the session object's error method returns <h1>Bad Request (Invalid Hostname)</h1> - and I have been unable to connect through the Windows Firewall.
#DEFINE WSManFlagCredUsernamePassword	4096
#DEFINE WSManFlagUseDigest	65536	
#DEFINE WSManFlagUseNegotiate	131072	
#DEFINE WSManFlagUseBasic	262144		

oWSMan = createobject("wsman.automation")

oCredentials = oWSMan.CreateConnectionOptions
oCredentials.username = "username"
oCredentials.password = "password"

cAddress = "http://VMAC"

* Use WSManFlagUseNegotiate instead of WSManFlagUseBasic for domain credentials
oSession = oWSMan.CreateSession ;
	(cAddress, WSManFlagUseBasic + WSManFlagCredUsernamePassword, oCredentials)

cSchema =  "http://schemas.microsoft.com/wsman/2005/06/"
cNamespace = "wmi/root/cimv2/"
cClass = "Win32_ComputerSystem"

cResource = cSchema + cNamespace + cClass

oItems = oSession.Enumerate(cResource)
messagebox(oItems.ReadItem())
Published Monday, April 10, 2006 11:17 PM by stuartd
Filed Under:

Comments

Anonymous comments are disabled