Home > Powershell > Creating Hyper-V Symbolic Links using Powershell

Creating Hyper-V Symbolic Links using Powershell

As an MCT I’m required to download preconfigured VM’s and supporting VHD’s from Microsoft which are then imported into base images running Server 2008 R2 and HyperV.  Prior to importing the VM’s, symbolic links need to be created in each VM’s root Virutal Hard Disk folder.  Symbolic links are shortcuts that are associated with base or middle tier VHD’s.  Microsoft even includes a .bat file that automates their creation.  An example of one of these .bat files is below:

@ECHO Creating Symlinks necessary to import VM’s
rem ************  to create Symlink for Base Image
rem ************substitute VHDName.vhd with the name of the base image needed
mklink “Path:\Source.vhd” “Path:\Base.vhd”

So it occurred to me that if a .bat file could automate the creation of one or more symbolic links, then perhaps a Powershell script could automate the execution of one or more individual .bat files.  Creating these symbolic links is a repetitive act of having to browse to each root VM’s folder, execute the .bat file and then close the corresponding cmd prompt.  This is surely another instance where time could be better spent elsewhere and so I turn to my old friend Powershell for a script to automate this mundane task.

The first step is define the path to the root VM folders.

$path = "C:\Program Files\Microsoft Learning\6419\Drives\"

Now we run Get-ChildItem on the folder using the -Include parameter to filter for .bat files only and then -Recurse to browse sub folders and files.   These results are then placed into the $vhds array variable.

$vhds = Get-ChildItem $path -Include *.bat -Recurse

The next step is to execute the .bat files by piping the $vhds array containing the required .bat files to Start-Process.  One of the problems I encountered was that, although Start-Process was able to execute the .bat files it wasn’t passing it’s results down the pipeline.  Most cmdlets do return output but on occasion certain cmdlets needs to be encouraged to do this using the -PassThru  parameter.

$vhds | %{ start-process "$_" -PassThru |

These results are then pipelined to Foreach-Object where I found it necessary to pause the script and allow the .bat file to properly execute using Start-Sleep 1.  Without the pause there is a quick blip on the screen and then the .bat file exists.  I remember reading a script in a recent blog article by Greg Caporale regarding printing .pdf’s where he incorporated Start-Sleep ( or it’s alias sleep ) to provide enough time for the .pdf files to print before closing Adobe Reader.   The Foreach-Object also passes down the pipline each individually open cmd process to Stop-Process which exits the open cmd prompt.

$vhds | %{ Start-Process "$_" -PassThru |
        %{ Start-Sleep 1 ; $_} | Stop-Process }

I then wrapped the whole thing into a function called it Import-SymbolicLinks and defined a $Path parameter to make the script that much more flexible by accepting parameter input. Below if the final script.

Function Create-SymbolicLinks {            

  $path = "C:\Program Files\Microsoft Learning\6419\Drives\"

 $vhds = Get-ChildItem $path -Include *.bat -Recurse
 $vhds | %{ Start-Process "$_" -PassThru |
            %{ Start-Sleep 1 ; $_} | Stop-Process }


The obvious next step is to script the import of these VM’s as well as create snapshots.

Categories: Powershell Tags: ,
  1. No comments yet.
  1. February 2, 2012 at 6:52 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: