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())