Exploring Windows Remote Management and CIM

Every IT professional is interested in managing their servers remotely. It would be better if we can achieve our tasks on remote machines from our desk than having to travel to a data center (unless there's a physical failure).

Remoting is the key feature of Windows PowerShell. However, most security administrators consider this to be a security risk. This is not completely true; Windows PowerShell remoting works based on a two-way authentication (a mutual authentication), and this inherits the feature of the Active Directory Kerberos protocol. This applies only for domain-joined machines.

We will cover the following topics:

  • Understanding WS-Management cmdlets
  • The HTTP listener
  • The HTTPS listener
  • Exploring the CIM commands
  • Exploring the CIM methods
  • Querying the remote machines using CIM

Windows PowerShell remoting

The Windows PowerShell remoting feature makes it richer, and this works based on the WS-Management protocol and the Windows Remote Management (WinRM) service. From Windows PowerShell 3.0 onward, the WS-Management configurations can be manipulated using the PowerShell provider, which is the WSMan drive.

WS-Management is a SOAP-based protocol for servers and is according to the DMTF open-based standard. Following are the standard abilities of DMTF Web Services Management (WSMan):

  • It gets, puts (updates), creates, and deletes individual resource instances, such as settings and dynamic values
  • It enumerates the contents of the containers and collections, such as large tables and logs
  • It subscribes to the events emitted by the managed resources
  • It executes the specific management methods with strongly typed input and output parameters

The WinRM service processes the request sent by WSMan over the network and the listening happens through the HTTP.sys driver.

Exploring WSMan cmdlets

WSMan cmdlets are used to manage WSMan protocols. These commands are organized in the Microsoft.WSMan.Management module. Run the following command:

Get-Command -Module Microsoft.WSMan.Management

The output is as shown in the following image:

Exploring WSMan cmdlets

Note

For more information, refer to the following link:

https://technet.microsoft.com/en-us/library/hh849876.aspx

In this exercise, let's take a look at how we can change the maximum session configurations. Let's consider the current maximum allowed connections.

Using the native PowerShell Get-Item command, execute the following code and refer to the following image:

CD WSMAN:WMF5Node03ShellMaxShellsPerUser
Exploring WSMan cmdlets

Let us see the result of the following code:

Set-Item WSMan:wmf5node03ShellMaxShellsPerUser -Value 30
Exploring WSMan cmdlets

Using the WSMan cmdlets, we can manage the session's timeout period. Run the following command:

$Time = New-WSManSessionOption -operationtimeout 3000
Connect-WSMan -computer WMF5Node02 -sessionoption $Time

We can call Disconnect-WSMan to disconnect the client from the WinRM service. Once this is executed, we don't see the remote computer in the WSMan drive.

Now, let's establish a connection with the remote LYNC 2013 server using the WSManConnectionInfo class using C# and PowerShell. Following is a sample code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;
using System.Management.Automation.Remoting;
using System.Management.Automation.Runspaces;
using System.Security;
using System.Collections.ObjectModel;
using System.Text;

namespace Office365
{
    class Program
    {
        static void Main(string[] args)
        {
            string username = "DSCDEMOLAB\SKBAdminID";
            string password = "SecureString";
            System.Security.SecureString securepassword = new System.Security.SecureString();
            foreach (char c in password)
            {
                securepassword.AppendChar(c);
            }
            PSCredential credential = new PSCredential(username, securepassword);
            WSManConnectionInfo connectioninfo = new WSManConnectionInfo(new Uri("https://RemoteServer/OcsPowershell"), "http://schemas.microsoft.com/powershell/Microsoft.PowerShell", credential);
            connectioninfo.AuthenticationMechanism = AuthenticationMechanism.Default;
            connectioninfo.SkipCACheck = true;
            connectioninfo.SkipCNCheck = true;
            //connectioninfo.AuthenticationMechanism = AuthenticationMechanism.Basic;
            connectioninfo.MaximumConnectionRedirectionCount = 2;
            //connectioninfo.MaximumConnectionRedirectionCount = 2;
            using (Runspace runspace = RunspaceFactory.CreateRunspace(connectioninfo))
            {
                runspace.Open();
                using (PowerShell powershell = PowerShell.Create())
                {
                    powershell.Runspace = runspace;
                    //Create the command and add a parameter
                    powershell.AddCommand("Get-CsUser");
                    Collection<PSObject> results = powershell.Invoke();
                    foreach (PSObject result in results)
                    {
                        Console.WriteLine(result.Properties["SamaccountName"].Value.ToString());
                        Console.ReadLine();
                    }
                }
            }
        }
    }
}

Refer to the following image:

Exploring WSMan cmdlets

We used the WSManConnectionInfo class, which provides us with the connection information that is needed to connect to a remote runspace. Windows PowerShell uses a WinRM connection to connect to the computer on which the remote runspace is opened. Execute the following code:

WSManConnectionInfo connectioninfo = new WSManConnectionInfo(new Uri("https://RemoteServer/OcsPowershell"), "http://schemas.microsoft.com/powershell/Microsoft.PowerShell", credential);
"https://RemoteServer/OcsPowershell"

This is our remote Skype for Business server URL using which we can explore Skype for Business Web Front End Server (IIS). Using the preceding code, we can establish the connection and query information from the remote servers.

The same can be achieved using PowerShell. Execute the following code:

$cred = Get-Credential "DomainSKBAdmin"
$session = New-PSSession -ConnectionURI "https://RemoteServer/OcsPowershell" -Credential $cred
Import-PsSession $session
Error: Access denied due to incorrect credentials (401 status code)

The output of the code we just saw is shown in the following image:

Exploring WSMan cmdlets

For learning purpose, we can get the certificate information and add it to Current User | Trusted Root Certification Authorities and execute the PowerShell code—Yes! Connection establishes as expected.

To get the certificate information, you can go to the site, https://RemoteServer/OCSPowerShell. Take a look at the following image:

Exploring WSMan cmdlets

Click on the Lock button in your browser and get the information.

HTTP/HTTPS Listener

To configure the HTTP or HTTPS Listener, we need to ensure that the ports, 5985 and 5986, are opened. The transport happens through the respective ports. Using PowerShell, we can easily enable the HTTP listener. Run the following command:

Set-WSManQuickConfig
HTTP/HTTPS Listener

To avoid the access denied error, ensure that PowerShell is running as Administrator. This is applicable for Win 7 and 2008 server OS. The command works without elevated privileges if you run it under the local admin account. Take a look at the following image:

HTTP/HTTPS Listener

The output is as follows:

PS C:Windowssystem32> Winrm Enumerate Winrm/config/Listener
Listener
    Address = *
    Transport = HTTP
    Port = 5985
    Hostname
    Enabled = true
    URLPrefix = wsman
    CertificateThumbprint
    ListeningOn = <IPS>

By default, the HTTP listener will be created to enable HTTPS; we need to use the switch, –UseSSL.

Let's give it a try with the following command:

Set-WSManQuickConfig -UseSSL

The error is self-explanatory. This is the really cool stuff in Windows PowerShell. Take a look at the following image:

HTTP/HTTPS Listener

To overcome this, we can use the following code. You can check with your certification authority (CA) administrator for the certificate-related query:

$Cert = Get-ChildItem Cert:LocalMachineMy | where {$_.Subject -match $env:COMPUTERNAME}
"The installed SSL certificate: " + $Cert.Subject
$CertPrivKey = $Cert.PrivateKey
$KeyCertFile = Get-Item -path "$ENV:ProgramDataMicrosoftCryptoRSAMachineKeys*" | where {$_.Name -eq $CertPrivKey.CspKeyContainerInfo.UniqueKeyContainerName}
$KeyAcl = (Get-Item -Path $KeyCertFile.FullName).GetAccessControl("Access")
$perm = "NT AUTHORITYNETWORK SERVICE","Read","Allow"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $perm
$KeyAcl.AddAccessRule($accessRule)
Set-Acl $KeyCertFile.FullName $KeyAcl

Now, the following code will work:

Set-WSManQuickConfig -UseSSL

The output is as shown in the following code:

Listener
    Address = *
    Transport = HTTPS
    Port = 5986
    Hostname
    Enabled = true
    URLPrefix = wsman
    CertificateThumbprint = D3438E6116227BA1459434943DB723C2C5D50C7C
    ListeningOn = <IPS>

In case this is a workgroup, we can add trusted hosts to accept the connections. This way, we can have more control in remoting. Your client accepts the connection only if it's listed in the trusted hosts.

Exploring CIM commands

We have covered a few basic examples of CIM and WMI in Chapter 2, Unleashing Development Skills Using Windows PowerShell 5.0; let's take a quick review here and proceed with a few more examples using PowerShell and C#.

You may wonder, why do we need CIM, and why not WMI? In this topic, we'll discover how CIM helps IT professionals.

  • Common Information Model (CIM) is the DMTF standard [DSP0004] for describing the structure and behavior of managed resources such as storage, network, or software components
  • Windows Management Instrumentation (WMI) is a CIM server that implements the CIM standard on Windows
  • The WS-Management (WSMan) protocol is a SOAP-based, firewall-friendly protocol for management clients to communicate with CIM servers
  • Windows Remote Management (WinRM) is the Microsoft implementation of the WSMan protocol on Windows.

CIM provides a rich experience in PowerShell and supports standard compliance—yes; CIM does work in Windows- and nonWindows-based machines.

CIM is introduced in Windows PowerShell 3.0 with the 2012 server by default, but this is limited; it supports down-level OS as well.

To know all the available CIM cmdlets, use the following code:

Get-Command -Module CimCmdlets | Select Name

Following is a list of available CIM cmdlets:

  • Export-BinaryMiLog
  • Get-CimAssociatedInstance
  • Get-CimClass
  • Get-CimInstance
  • Get-CimSession
  • Import-BinaryMiLog
  • Invoke-CimMethod
  • New-CimInstance
  • New-CimSession
  • New-CimSessionOption
  • Register-CimIndicationEvent
  • Remove-CimInstance
  • Remove-CimSession
  • Set-CimInstance

Take a look at the following image:

Exploring CIM commands

CIM cmdlets have auto tab completion, so it involves little typing and coding. Do remember that the default namespace is root/cimv2.

Now, let's take a look at the list of CIM classes:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Management.Automation;
using System.Management.Automation.Host;
using System.Collections.ObjectModel;

namespace CIM_Exercise
{
    class Program
    {
        static void Main(string[] args)
        {
            using (PowerShell PowerShellInstance = PowerShell.Create())
            {
                PowerShellInstance.AddCommand("Get-CimClass");
                Collection<PSObject> result = PowerShellInstance.Invoke();
                foreach (PSObject r in result)
                {
                    Console.WriteLine(r);
                    Console.ReadKey();
                }
            }
        }
    }
}

Ensure that you call a property that exists. If we don't use an existing property, the following error will appear:

Exploring CIM commands

After a successful execution, we will obtain the list as shown in the following image:

Exploring CIM commands

Using help commands, we can explore all the CIM commands.

Exploring CIM methods

Using the Invoke-CimMethod cmdlet, we can perform operations such as creating, terminating, restarting, and so on.

In this exercise, let's consider the basic example of opening a notepad. Yes! We can simply type the word notepad in PowerShell, and this will do it. But we will explore the CIM methods using the Invoke-CimMethod cmdlet and its parameters.

The following is a single line of code in PowerShell that uses the Invoke-CimMethod cmdlet:

Invoke-CimMethod -ClassName Win32_Process -MethodName "Create" -Arguments @{Commandline = "notepad.exe"}

The following is a single line of code in PowerShell that uses the [WMICLASS] type accelerator:

([wmiclass]"rootcimv2:Win32_Process").Create('notepad.exe');

So, how do we find out the parameters of the methods? Run the following command and refer to the following image:

(Get-CimClass -ClassName Win32_Process).CimClassMethods
Exploring CIM methods

For each method name, we can see the parameters. It's easy to explore and use as required.

Now, let's create a small Windows form application and take note of the execution of CIM methods.

Following is the code used for this:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
namespace CIM_Exercise
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            using(PowerShell PowerShellInstance = PowerShell.Create())
            {
                PowerShellInstance.AddScript("Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine = notepad.exe}");
                PowerShellInstance.Invoke();
            }
        }
        private void button2_Click(object sender, EventArgs e)
        {
            using (PowerShell PowerShellInstance = PowerShell.Create())
            {
                PowerShellInstance.AddScript("Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine = calc.exe}");
                PowerShellInstance.Invoke();
            }
        }
    }
}

To avoid overuse of Add parameters in the PowerShell instance, we used the type accelerator method. The Windows form provides the options of Open Notepad, which opens the Notepad application, and Open Calc, which opens the Calculator application, as shown in the following screenshot:

Exploring CIM methods

Querying the remote machines using CIM

As we have previously seen, CIM supports down-level OS. You may wonder, can we not use CIM commands in servers running Windows 2008 with PowerShell 2.0? Not really, but we can establish a remote session and execute the CIM commands.

Consider a scenario where we need to query the OS-installed date on remote machines. WMI will do it, but we need to add a snippet of code for creating the time format, which is as follows:

(Get-WmiObject -Class Win32_operatingSystem –ComputerName "Remote").InstallDate
#20140326181309.000000+060
(Get-CimInstance -ClassName CIM_OperatingSystem –ComputerName "Remote").InstallDate
#Wednesday, March 26, 2014 6:13:09 PM

Which one of these would our configuration management team prefer? Of course, they would prefer the one with the well-formatted date. Indeed, we can do this in WMI as well by adding a snippet of code as follows:

$os = (Get-WmiObject -Class Win32_operatingSystem)
[management.managementDateTimeConverter]::ToDateTime($os.InstallDate)

There are always multiple ways of doing things in PowerShell, and we can choose the one that best suits our requirement.

In this exercise, let's consider using the server remotely with PowerShell 2.0, and execute the CIM commands:

Test-WSMan -ComputerName RemoteServer
wsmid           : http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd
ProtocolVersion : http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd
ProductVendor   : Microsoft Corporation
ProductVersion  : OS: 0.0.0 SP: 0.0 Stack: 2.0

OS: 0.0.0 SP: 0.0 Stack: 2.0 proves that the remote machine is PowerShell 2.0.

So now, let's establish a session using the following code and get the OS-installed date:

$Dcom = New-CimSessionOption -Protocol Dcom
$session = New-CimSession -ComputerName RemoteServer -SessionOption $Dcom
(Get-CimInstance -CimSession $session -ClassName Win32_OperatingSystem).InstallDate

In this chapter, we explored the basics of Windows Remote Management; in the next chapter, we will discuss how to create DSC with MOF using class, deploying configuration, and the types of deployment modes.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset