Aidan Finn writes about Microsoft virtualization for the Petri IT Knowledgebase. He is a Microsoft Valuable Professional with the Virtual Machine (Hyper-V) expertise. Aidan has been working in IT infrastructure since 1996, and is the Technical Sales Lead for MicroWarehouse Ltd., a Microsoft value added distributor in Ireland. He runs the blog and has written or co-written books such as Windows Server 2012 Hyper-V Installation And Configuration Guide, Microsoft Private Cloud Computing, and Mastering Hyper-V Deployment.

Managing Windows Server Containers with PowerShell: Managing Containers

In this article series, I’m showing you how to manage Windows Server Containers on Windows Server 2016 (WS2016) Technical Preview 3 (TPv3) using PowerShell. I’ve already covered where the files are stored, what kinds of files are used, and how to create and start a new container. In this post, we’ll look at how we can manage a container, along with instructions on how to create a new container image.

This post is part of a series:

Remote Administration

What good is a container if you don’t install something to run inside of it? Normally with a machine you would log into that machine. But there is no such thing as logging into a container because it’s not a machine. But you can use PowerShell’s remote capabilities to configure a container.

If you want to have an interactive administration experience, then you can use Enter-PSSession to get a PowerShell session inside of a container. Enter-PSSession requires the unique ID of the container to create that session. That ID is easy to provide if you previously stored a pointer to the container using a variable (see $Container in Part 1). For example:

If you haven’t saved a pointer to the container, then you can run:

Entering a PowerShell remote session with a Windows Server Container (Image credit: Aidan Finn)
Entering a PowerShell remote session with a Windows Server Container (Image credit: Aidan Finn)

If you run Enter-PSSession too soon after starting a container, then you will get the following misleading error:

Enter-PSSession : The term ‘Measure-Object’ is not recognized as the name of a cmdlet, function, script file, or operable program.

The advantage of Enter-PSSession is that it allows you to get quite a bit of manual work done inside of a container. However, it is an interactive-only approach, and it is not suitable for remote scripting.

If you want to run a single command against a container, or if you want to script administrative tasks inside of a container, then you should use Invoke-Command. Invoke-Command allows you to execute a script block against a machine or a container; the example below will send a script block to retrieve the IPv4 address of a container, which we might later use to create NAT rules on a VM host.

Using Invoke-Command to run a script block in a container (Image credit: Aidan Finn)
Using Invoke-Command to run a script block in a container (Image credit: Aidan Finn)

Customizing a Container

The reason we use containers is to deploy services, so we need to install some software. Not every application is suitable for containerization; remember that containers are designed for born-in-the-cloud services. I had no joy with running IIS in more than one container on a VM host in my testing with TPv3; this might be why Microsoft documented the process for deploying the nginx web server instead.

One task you might find tricky with containers is getting the application setup files into the container, as containers do not support domain membership because of their intended short lives. The method most are using is to share the files on a web server and use wget to download the zip file into the container. The following example is run inside of a container to download the setup files for nginx into a container:

You can install and customize your software as required, and then we’ll create a reusable image.

Creating a Container Image

The goal of containers is to create a golden image that you can deploy repeatedly and get identical results every time. Once you have prepped your first container, you can start the image creation process. The first step is to stop the container:

Next you will create a new container image, stored in the repository from the customized container. This is a non-destructive process:

If we query the resulting new container image using Get-ContainerImage, then we can see there is a link between the new image and WindowsServerCore. Deploying a new container from DemoImage1 will cause WindowsServerCore to be used as a dependency.

Querying the parentage or dependencies of a container image (Image credit: Aidan Finn)
Querying the parentage or dependencies of a container image (Image credit: Aidan Finn)

You now have an image that you can deploy to rapidly create lots of identical containers. I’ll show you how to do that in the next post in this series, along with steps on how to configure network address translation (NAT) for containers on NAT-enabled VM hosts.

Related Topics:

  • Windows Server 2016

    Don't have a login but want to join the conversation? Sign up for a Petri Account