Lability tutorial

A tutorial for working with Lability

View project on GitHub

Chapter 5: Simple private network

Build a simple private network, with two VMs who can talk to each other, but cannot talk to the Hyper-V host or the Internet.

Last tested: NEVER

On this page

Defining multiple nodes in configuration data

If you look at the configuration data for this chapter, you will find three entries under AllNodes -

  1. NodeName = '*'
  2. NodeName = 'CLIENT1'
  3. NodeName = 'CLIENT2'

The first entry, NodeName = '*', is special - rather than defining a node named *, it actually sets default values for all nodes. (Nodes can override these defaults.) This is a useful way to avoid heavy repetition that might otherwise be unavoidable when configuring multiple similar nodes.

The lab network

In the non-node data, we declare a private Hyper-V network, like so:

Network = @(
    @{ Name = 'CORP'; Type = 'Private'; }
)

A private switch allows VMs to communicate only with each other - not the Internet or even with the host machine. In this chapter, we will not be connecting the VMs to the Internet, or even connecting to a host network. The only way to interact with VMs on a private network is to use the Hyper-V console.

Declaring switches that already exist

Previously, we have declared the use of a switch which we first created by hand on the Hyper-V host, such that when it is referenced, that switch already exists.

We can also declare use of switches which do not yet exist on the host. If that switch is defined in NonNodeData, then the definition laid out in that section is used. If it isn’t, then Lability creates a new internal Hyper-V switch.

More information on Hyper-V switch types

See Hyper-V switch types for more information about different switch types.

Lab exercises and files

  1. Deploy the lab with Deploy-SIMPLENET.ps1

  2. Log in to one of the servers using the Hyper-V management console.

    • Ping the other server by its IP address
    • Use Enter-PSSession to connect to the other server - this requires understanding Powershell Remoting, including setting TrustedHosts and ensuring the firewall allows access.
  3. Run Get-NetIpAddress on your lab host and try to understand each network device that it returns.

    Observe that there is no network device on the private network, and therefore no way for you to RDP or Enter-PSSession to the VMs from your host.

  4. Change the network from “private” to “internal” and redeploy.

    Run Get-NetIpAddress again and see a new IP address on the new internal Hyper-V switch.

  5. Open Hyper-V Manager, click on Virtual Switch Manager, and delete any switches you don’t need.

    (If you fail to delete internal or external switches that are no longer in use, useful information in output of Get-NetIpAddress can get drowned in noise from old networks.)

ConfigurationData.SIMPLENET.psd1

@{
    AllNodes = @(
        @{
            NodeName                    = '*';
            InterfaceAlias              = 'Ethernet';
            AddressFamily               = 'IPv4';
            Lability_SwitchName         = "Wifi-HyperV-VSwitch";
            Lability_Media              = 'WIN10_x64_Enterprise_EN_Eval';
            Lability_ProcessorCount     = 1;
            Lability_StartupMemory      = 2GB;
            PSDscAllowPlainTextPassword = $true;
        }
        @{
            NodeName                    = 'CLIENT1';
            Role                        = 'CLIENT';
            IPAddress                   = '10.0.0.1/24';
        }
        @{
            NodeName                    = 'CLIENT2';
            Role                        = 'CLIENT';
            IPAddress                   = '10.0.0.2/24';
        }
    );
    NonNodeData = @{
        Lability = @{
            EnvironmentPrefix = 'SIMPLENET-';
            Network = @(
                @{ Name = 'CORP'; Type = 'Private'; }
            )
            DSCResource = @(
                @{ Name = 'xComputerManagement'; RequiredVersion = '4.1.0.0'; }
                @{ Name = 'xNetworking'; RequiredVersion = '5.7.0.0'; }
            );
        };
    };
};

Configure.SIMPLENET.ps1

Configuration SimpleNetworkConfig {
    param ()

    Import-DscResource -Module PSDesiredStateConfiguration

    Import-DscResource -Module xComputerManagement -ModuleVersion 4.1.0.0
    Import-DscResource -Module xNetworking -ModuleVersion 5.7.0.0

    # Common configuration for all nodes
    node $AllNodes.Where({$_.Role -in 'CLIENT'}).NodeName {

        LocalConfigurationManager {
            RebootNodeIfNeeded   = $true;
            AllowModuleOverwrite = $true;
            ConfigurationMode    = 'ApplyOnly';
        }

        xFirewall 'FPS-ICMP4-ERQ-In' {
            Name        = 'FPS-ICMP4-ERQ-In';
            DisplayName = 'File and Printer Sharing (Echo Request - ICMPv4-In)';
            Description = 'Echo request messages are sent as ping requests to other nodes.';
            Direction   = 'Inbound';
            Action      = 'Allow';
            Enabled     = 'True';
            Profile     = 'Any';
        }

        xFirewall 'FPS-ICMP6-ERQ-In' {
            Name        = 'FPS-ICMP6-ERQ-In';
            DisplayName = 'File and Printer Sharing (Echo Request - ICMPv6-In)';
            Description = 'Echo request messages are sent as ping requests to other nodes.';
            Direction   = 'Inbound';
            Action      = 'Allow';
            Enabled     = 'True';
            Profile     = 'Any';
        }

        xIPAddress 'PrimaryIPAddress' {
            IPAddress      = $node.IPAddress
            InterfaceAlias = $node.InterfaceAlias
            AddressFamily  = $node.AddressFamily
        }

        xComputer 'Hostname' {
            Name = $node.NodeName;
        }

    }

}

Deploy-SIMPLENET.ps1

[CmdletBinding()] Param(
    [SecureString] $AdminPassword = (Read-Host -AsSecureString -Prompt "Admin password"),
    [string] $ConfigurationData = (Join-Path -Path $PSScriptRoot -ChildPath ConfigurationData.SIMPLENET.psd1),
    [string] $ConfigureScript = (Join-Path -Path $PSScriptRoot -ChildPath Configure.SIMPLENET.ps1),
    [string] $DscConfigName = "SimpleNetworkConfig",
    [switch] $IgnorePendingReboot
)

$ErrorActionPreference = "Stop"

. $ConfigureScript
& $DscConfigName -ConfigurationData $ConfigurationData -OutputPath $env:LabilityConfigurationPath -Verbose
Start-LabConfiguration -ConfigurationData $ConfigurationData -Path $env:LabilityConfigurationPath -Verbose -Password $AdminPassword -IgnorePendingReboot:$IgnorePendingReboot
Start-Lab -ConfigurationData $ConfigurationData -Verbose