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.

Requirements

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

Structure

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.

Functions!!

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:

DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK. IF YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING.

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!

function Get-LabFolder {
<#
	.SYNOPSIS
		Checks to see if Lab folder structure is present on the current machine.

	.DESCRIPTION
		Checks to see if the folders for Hyper-V test lab structure are present on the current machine.
		This includes folders for VHDs, VMs and ISOs.

	.PARAMETER Root
		Provide the root location of the folder structure.
    Default value of c:\Hyper-V

	.EXAMPLE
				PS C:\> Get-LabFolder

				Checks to see if Lab folder structure is present on the current machine on the default path of C:\Hyper-V

	.EXAMPLE
				PS C:\> Get-LabFolder -Root 'D:\'

				Checks to see if Lab folder structure is present on the current machine on the path D:\

	.EXAMPLE
				PS C:\> Get-LabFolder -Root 'C:\Lab'

				Checks to see if Lab folder structure is present on the current machine on the path C:\Lab

	.NOTES
		Default folder structure would be:
		C:\Hyper-V\VHD
		C:\Hyper-V\VHD\Template
		C:\Hyper-V\VM
		C:\Hyper-V\ISO

    Created by: Robert Prüst
    Blog: http://powershellpr0mpt.com
    Version: 1.0
    Module: PSP-VMLab

#>

  [CmdletBinding()]
  param
  (
	  [string]$Root = 'C:\Hyper-V'
  )

  process {
    Write-Verbose "Starting $($MyInvocation.Mycommand)"
    Write-Verbose "Root is set to '$Root'"
    Write-Verbose 'Testing main folder'

    if (!(Test-Path -Path $Root))
    {
	    Write-Output "$Root folder does not exist"
    }
    else
    {
	    Write-Verbose 'Main folder exists'
	    Write-Verbose 'Testing sub folders'
	    Write-Verbose 'Setting folder values for checkup'

	    $ISO = $true
	    $VHD = $true
	    $VHDTemplate = $true
	    $VM = $true

	    if (!(Test-Path -Path "$Root\ISO"))
		    {
		    Write-Output 'ISO Folder does not exist'
		    $ISO = $false
		    }
	    if (!(Test-Path -Path "$Root\VHD"))
		    {
		    Write-Output 'VHD Folder does not exist'
		    $VHD = $false
		    }
	    if (!(Test-Path -Path "$Root\VHD\Template"))
		    {
		    Write-Output 'VHD Template Folder does not exist'
		    $VHDTemplate = $false
		    }
	    if (!(Test-Path -Path "$Root\VM"))
		    {
		    Write-Output 'VM Folder does not exist'
		    $VM = $false
		    }
	    if (($ISO) -and ($VHD) -and ($VHDTemplate) -and ($VM))
	    {
		    Write-Output 'All folders exist'
	    }

    }
  }

}

```


## New-LabFolder

function New-LabFolder {
<#
	.SYNOPSIS
		Creates a Lab folder structure on the current machine.

	.DESCRIPTION
		Creates a Lab folder structure on the current machine.
		This includes folders for VHDs, VMs and ISOs.

	.PARAMETER Root
		Provide the root location of the folder structure.
    Default value of c:\Hyper-V

	.EXAMPLE
				PS C:\> New-LabFolders

				Creates a new Lab folder structure on the current machine on the default path of C:\Hyper-V

	.EXAMPLE
				PS C:\> New-LabFolders -Root 'D:\'

				Creates a new Lab folder structure on the current machine on the path D:\

	.EXAMPLE
				PS C:\> New-LabFolders -Root 'C:\Lab'

				Creates a new Lab folder structure on the current machine on the path C:\Lab

	.NOTES
		Default folder structure would be:
		C:\Hyper-V\VHD
		C:\Hyper-V\VHD\Template
		C:\Hyper-V\VM
		C:\Hyper-V\ISO

    Created by: Robert Prüst
    Blog: http://powershellpr0mpt.com
    Version: 1.0
    Module: PSP-VMLab

#>


  [CmdletBinding()]
  param
  (
	  [string]$Root = 'C:\Hyper-V'
  )


  process {
    Write-Verbose "Starting $($MyInvocation.Mycommand)"
    Write-Verbose "Root is set to '$Root'"
    Write-Verbose 'Checking current status of Lab folders'

    $Check = Get-LabFolder -Root $Root

    if ($Check = "$Root folder does not exist") {

    mkdir "$Root" | Out-Null
    mkdir "$Root\ISO" | Out-Null
    mkdir "$Root\VHD" | Out-Null
    mkdir "$Root\VHD\Template" | Out-Null
    mkdir "$Root\VM" | Out-Null

    Write-Output 'Full folder structure created'

    }
    elseif ($Check -contains 'ISO Folder does not exist') {

    mkdir "$Root\ISO" | Out-Null
    Write-Output 'ISO folder created'

    }

      elseif ($Check -contains 'VHD Folder does not exist') {

    mkdir "$Root\VHD" | Out-Null
    mkdir "$Root\VHD\Template" | Out-Null
    Write-Output 'VHD folders created'

    }

    elseif ($Check -contains 'VHD Template Folder does not exist') {

    mkdir "$Root\VHD\Template" | Out-Null
    Write-Output 'VHD Template folder created'

    }

    elseif ($Check -contains 'VM Folder does not exist') {

    mkdir "$Root\VM" | Out-Null
    Write-Output 'VM folder created'

    }
  }

}

```


## Remove-LabFolder

function Remove-LabFolder {

<#
	.SYNOPSIS
		Removes the Lab folder structure on the current machine.

	.DESCRIPTION
		Removes the Lab folder structure on the current machine.
    Will automatically check if the folder actually exists.
    Prompts a warning screen for the user to actually confirm deletion.

	.PARAMETER Root
		Provide the root location of the folder structure.
    Default value of c:\Hyper-V

	.EXAMPLE
				PS C:\> Remove-LabFolder

				Removes the Lab folder structure on the current machine on the default path of C:\Hyper-V

	.EXAMPLE
				PS C:\> Remove-LabFolder -Root 'D:\'

				Removes the Lab folder structure on the current machine on the path D:\

	.EXAMPLE
				PS C:\> Remove-LabFolder -Root 'C:\Lab'

				Removes the Lab folder structure on the current machine on the path C:\Lab

	.NOTES
		Default folder structure would be:
		C:\Hyper-V\VHD
		C:\Hyper-V\VHD\Template
		C:\Hyper-V\VM
		C:\Hyper-V\ISO

    Created by: Robert Prüst
    Blog: http://powershellpr0mpt.com
    Version: 1.0
    Module: PSP-VMLab

#>

  [CmdletBinding()]
  param (
    [ValidateScript({Test-Path -Path $_})]
    [string]$Root = 'C:\Hyper-V'
  )

  process {
    Write-Verbose "Starting $($MyInvocation.Mycommand)"
    Write-Verbose "Root is set to '$Root'"
    Write-Verbose 'Setting up confirmation dialog'

    $Title = 'Delete Files'
    $Message = "Are you sure you want to delete all files, folders and subfolders under $Root ?"

    $Yes = New-Object System.Management.Automation.Host.ChoiceDescription '&Yes', 'Deletes all the files in the folder.'

    $No = New-Object System.Management.Automation.Host.ChoiceDescription '&No', 'Retains all the files in the folder.'

    $Options = [System.Management.Automation.Host.ChoiceDescription[]]($Yes, $No)

    $Result = $Host.ui.PromptForChoice($Title, $Message, $Options, 0)

    $Delete = $false

    switch ($Result)
        {
            0 {$Delete = $true}
            1 {Write-Output "Files will not be deleted, ending script"; return}
        }


      if ($Delete) {
        Remove-Item -Path $Root -Recurse
      }
  }
}

```