VM Lab – Lab Folders

Lets get started…

First of all, I always prefer my lab to have the same layout and tend to use the same solutions, since they’re either best practice or the most logical approach for me.
Now in a Lab environment, this starts at the basics, creating a folder structure to put everything in, from VHDs, VMs to ISO files and templates.


For my Lab I always want it to have the same folder structure.

This structure is as follows:

  • $Root\ISO
  • $Root\VHD
  • $Root\VHD\Template
  • $Root\VM


Now I wanted to have the following “solutions” for this requirement:

  • Get-LabFolder
    To see if the current folder [including all sub folders] actually already exists.
    The most annoying bit was to check if all the sub folders actually existed, which I bet can be done more elegantly, but I’ll need to check that at a later point.
  • New-LabFolder
    Create a new set of Lab folders in the provided Root.
  • Remove-LabFolder
    Take a wild guess 😉
    Mostly for my testing purposes, since I’ve not yet done Pester tests for all my scripts.

While it seems very basic, making tiny building blocks out of every solution, makes it so I can re-use these solutions at a later point.
This isn’t a “hard” solution, but for me the most important bit was getting the structure done right, making sure everything has a proper help function and is somewhat well documented/scripted.

In the process I also used a handy trick for a confirmation pop-up on the deletion, to let someone confirm they want to remove the folder structure, because gone = gone.


Here’s what most people come for.


These functions are meant for a test environment.
I’ve borrowed Jeffery Hicks‘ disclaimer, because it simply says it all:


I’ve set the scripts to a max height as to not flood the page, but rest assured, everything’s there.
Please do note that functions might refer to other functions, this is intended as a complete toolset, not just 1 piece.

If you have questions on the techniques used or suggestions on how to improve something, please let me know in the comment section!






VM Lab – Introduction

Hey guys,

It’s been a bit quiet lately, some holiday time and most importantly a change of jobs!
As of July 1st I now work for OSC as an Infrastructure Specialist and will hopefully have more time to expand my knowledge and share this with the community.

The last few weeks I’ve been busy playing around with a solution in order to quickly create a Lab with VM’s.

While I know how to manually set them up and create machines, I had a somewhat ‘ideal’ method in mind and didn’t really want to stray from that idea.

I will finish up the solution this week hopefully, but already have a Proof Of Concept [POC] solution working as intended.
While this sounds all fancy, basically I have all the tiny building blocks ready as scripts.
It means I will need to finish writing all the help files, modifying them from scripts to functions and putting them all in a single module.

What does the solution do?

Here’s a quick overview of what my solution does:

  • Create [or checks if it exists] a default Hyper-V folder structure in place where you can store everything you require for your Lab
  • Create a default Hyper-V infrastructure in place which you can utilize for your Lab
  • Creates template VHD files on which you can base your Lab VM’s.
    This solution provides templates for the following Operating Systems:

    • Windows 8.1
    • Windows 10
    • Windows Server 2008R2 [Core + GUI]
    • Windows Server 2012R2 [Core + GUI]
    • Windows Server 2016 TP5 [Core + GUI]
  • Creates differencing disks based on the above template VHDs, which are ‘enhanced’ by custom Unattend.xml files specifying:
    • ComputerName
    • UserName
    • Password
    • Organization
    • IP Address
    • DNS Server Address
    • Gateway Address

Once you have the template VHD files created [this takes the longest and only needs to be done once], it takes SECONDS to configure and start up your custom Lab VM


What next?

As mentioned above, I will need to update the help files, fine tune certain bits and convert the solution from separate scripts to functions in a module.
Now I’m not expecting this to take ages, but I want to make sure I don’t accidentally break my current solution.

In the coming time I will try and break down all created functions and provide the entire code.

To be continued! 🙂


Lab: Configure PowerShell WebAccess for management

Now that I have my Lab configured and set up to accept remoting from my Client machine, I want to set up a small Hyper-V lab onto this Host.

Since my goal is to manage as much as possible through PowerShell, my current setup will run into the following problem:
I can remote into my lab host, but due to single-hop remoting, it is not recommended to daisy chain sessions.

In case you DO want this, you can look at the following articles that will give you more insight on multihop remoting.
A small insight on what is required:

What is the goal and what is required?

The goals I have are quite simple:

  • PowerShell access to my Host machine
  • PowerShell access to my Guest VM’s
  • It has to be secure, following Best Practice

In order to obtain these goals I first have to figure out what the best practice is, since I can already access Host machine.

According to a PowerPoint presentation made by  Lee Holmes [part of the PowerShell team since v.1] CredSSP should only be used in case of Highly Trusted Servers, because otherwise

‘This opens you up to credential theft, so is disabled by default on both the client and the server’

Ok, so I need another way to get access to my Hosts, which allows access to my Guest VM’s without having to multihop remote or RDP to my Host machine.

In comes PowerShell WebAccess!
This allows us to connect to the Host machine as console and through that session I can remote onto my Guest VM’s!

The Code

Getting this all done required 4 steps that can easily be done through PowerShell:

  • Install PowerShell WebAccess
  • Configure the PowerShell WebAccess Web Application – Gateway
  • Configure a restrictive authorization rule
  • Use PowerShell WebAccess

Installing PowerShell Web Access

To install PowerShell WebAccess is quite simple, but first let’s check if it’s not already installed or perhaps requires source media:

In my case this has not been done yet, so we’ll go ahead and install this.
Do note that PowerShell WebAccess required IIS as Web Server, so this will also get installed.

Reboot the machine if required, but normally you should be ready to continue.

Configure the PowerShell WebAccess Web Application – Gateway

Now that we have PowerShell WebAccess installed, we need to configure it for usage.
We can do this using

As the added parameter implies, this will set up a self signed certificate which is recommended for test environments only.
The certificate will expire in 90 days after which you should re-assign a new self-signed certificate.
When setting up a secure production environment be sure to use a valid certificate signed by a CA.

This  command will configure a few things for you:

  • Install the PSWA Web Application
  • Install the PSWA Application Pool
  • Install PSWA within the IIS Default Web Site container
  • Automatically configures IIS to run on the default website under https://[servername]/pswa
  • Bind a self signed certificate to the PSWA Web Application

In case you want to set up a valid certificate, use the following command

And configure the certificate through bindings on IIS Manager.

Configure a restrictive authorization rule

Now that we have the Role installed and the Gateway configured, we need to define who is actually allowed to access PowerShell WebAccess on this machine.
We can do this by explicitly granting access to users through the following commands.
Do note, there is no GUI alternative to add or manage there permissions, PowerShell will be required!

Now in case of a test environment, you won’t to be too picky on who can access your machine, but in case of production you should make sure to configure these settings with care!

As the command implies, all users, connecting to all computers, are allowed granted access to all configurations.

In case you want to restrict this access a little bit more, you can do this by simply defining the provided parameters with more detail.
For my environment I personally restricted the UserName to the local administrator, just because I can 🙂

Use PowerShell WebAccess

Now that everything’s configured, let’s give it a test run!

Open your browser to the server’s name or FQDN


To log in there’s one tiny thing to keep in mind:

In the User name field, be sure to provide it in the format you’ve defined your PswaAuthorizationRule, so in my case CONTOSO-SRV001\administrator instead of simply Administrator.



You have full [secure] access to your Host VM, providing access to all Cmdlets, tab-completion etc. and you can now securely remote onto your Guest VM’s.


Happy scripting! 🙂