In a previous blog I discussed methods for sending files to the VMs in your portable lab. Those methods included the following:
ISO transfer- PowerShell Cmdlet transfer
Direct VHD TransferNetwork Transfer
I’ve covered the ISO method and discarded the Network method for practicality reasons. In THIS blog I will be covering the PowerShell Cmdlet method. It can be tricky and I have had inconsistent results using it but together we will try to work through any issues and see how it can be done.
Please note that the Hyper-V module will be required for the PowerShell bits.
Kudos to Jeff Hicks for his original work on this. He has a guest-host article on this topic located here.
“….the Script’s the thing wherein lies the conscience of the King….”
Ok, so maybe I shouldn’t wax Shakespearean, but that man just got the mindset shared by many engineers (shipbound or otherwise). There is a poetry to be read in the fine tuned system, logical essay or code snippet, a kind of beauty that many engineers/admins appreciate. PowerShell is the language of stanzas that brings consistency, stability and creativity to what can be humdrum or onerous tasks presented to administrators on a daily basis.
So lets see what kind of pretty things we can come up with for transferring files as we continue with the “Boldly Going” series.
“Much Ado About Everything” or “The Devil’s in the Details”
Step 1 – Install the required modules
Install and import the Hyper-V module. No matter how your environment is configured, you will need to import this module. If it is not installed, install it then import it. This module contains the functions needed to transfer files to your VM. If you are using Hyper-V for your portable lab solution (if you’re reading this article then you are) then you should probably add the module load to your $Profile.
Step 2
desktop.
The PowerShell Engine
My script is based off of Chris Wu’s New-IsoFile function located in the PS Gallery Here.
Drag2ISO.ps1
Param ($srcDir) Function New-IsoFile { Param ( [parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true)]$Source, [parameter(Position=1,Mandatory=$false,ValueFromPipeline=$true)][Alias('Path')] [String] $trgPath = "$($env:userprofile)\Desktop\$((Get-Date).ToString("yyyyMMdd-HHmmss.ffff")).iso", [string] $BootFile = $null, [string] $Media = "Disk", [string] $Title = (Get-Date).ToString("yyyyMMdd-HHmmss.ffff"), [switch] $Force ) Begin { # Decode here string for ISO public class definition Function Dec64($a){$b = [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($a));Return $b} # ($cp = new-object System.CodeDom.Compiler.CompilerParameters).CompilerOptions = "/unsafe" If (!("ISOFile" -as [type])) { $Type = (Dec64 "cHVibGljIGNsYXNzIElTT0ZpbGUNCnsNCiAgICBwdWJsaWMg dW5zYWZlIHN0YXRpYyB2b2lkIENyZWF0ZShzdHJpbmcgUGF0aCwgb2JqZWN 0IFN0cmVhbSwgaW50IEJsb2NrU2l6ZSwgaW50IFRvdGFsQmxvY2tzKQ0KIC AgIHsNCiAgICAgICAgaW50IGJ5dGVzID0gMDsNCiAgICAgICAgYnl0ZVtdI GJ1ZiA9IG5ldyBieXRlW0Jsb2NrU2l6ZV07DQogICAgICAgIFN5c3RlbS5J bnRQdHIgcHRyID0gKFN5c3RlbS5JbnRQdHIpKCZieXRlcyk7DQogICAgICA gIFN5c3RlbS5JTy5GaWxlU3RyZWFtIG8gPSBTeXN0ZW0uSU8uRmlsZS5PcG VuV3JpdGUoUGF0aCk7DQogICAgICAgIFN5c3RlbS5SdW50aW1lLkludGVyb 3BTZXJ2aWNlcy5Db21UeXBlcy5JU3RyZWFtIGkgPSBTdHJlYW0gYXMgU3lz dGVtLlJ1bnRpbWUuSW50ZXJvcFNlcnZpY2VzLkNvbVR5cGVzLklTdHJlYW0 7DQoNCiAgICAgICAgaWYgKG8gPT0gbnVsbCkgeyByZXR1cm47IH0NCiAgIC AgICAgd2hpbGUgKFRvdGFsQmxvY2tzLS0gPiAwKSB7DQogICAgICAgICAgI CBpLlJlYWQoYnVmLCBCbG9ja1NpemUsIHB0cik7IG8uV3JpdGUoYnVmLCAw LCBieXRlcyk7DQogICAgICAgIH0NCiAgICAgICAgby5GbHVzaCgpOyBvLkN sb3NlKCk7DQogICAgfQ0KfQ==") Add-Type -CompilerParameters $cp -TypeDefinition $Type #-IgnoreWarnings } #If If ($BootFile -and (Test-Path $BootFile)) { ($Stream = New-Object -ComObject ADODB.Stream).Open() $Stream.Type = 1 # adFileTypeBinary $Stream.LoadFromFile((Get-Item $BootFile).Fullname) ($Boot = New-Object -ComObject IMAPI2FS.BootOptions).AssignBootImage($Stream) } #If $MediaType = [Ordered]@{BDR=18; BDRE=19;CDR=2; CDRW=3;DISK=12; DVDDASHR=9;DVDDASHRW=10;DVDDASHR_DUALLAYER=11; DVDPLUSR=6; DVDPLUSRW=7;DVDPLUSR_DUALLAYER=8; DVDPLUSRW_DUALLAYER=13;DVDRAM=5;} #MediaType If ($MediaType[$Media] -eq $null) { write-debug "Unsupported Media Type: $Media"; write-debug ("Choose one from: " + $MediaType.Keys); Break } #If ($Image = new-object -com IMAPI2FS.MsftFileSystemImage ` -Property @{VolumeName=$Title}).ChooseImageDefaultsForMediaType($MediaType[$Media]) If ((Test-Path $trgPath) -and (!$Force)) { "File Exists $trgPath" Break } If (!($Target = New-Item -Path $trgPath -ItemType File -Force)) { "Cannot create file $trgPath" Break } } #Begin Process { Switch ($Source) { { $_ -is [string] } { $Image.Root.AddTree((Get-Item $_).FullName, $true) continue } { $_ -is [IO.FileInfo] } { $Image.Root.AddTree($_.FullName, $true) continue } { $_ -is [IO.DirectoryInfo] } { $Image.Root.AddTree($_.FullName, $true) continue } }#Switch } #Process End { If ($Boot) { $Image.BootImageOptions=$Boot } $Result = $Image.CreateResultImage() [ISOFile]::Create($Target.FullName,$Result.ImageStream,$Result.BlockSize,$Result.TotalBlocks) $Target } #End } If ((Test-Path $srcDir) -eq $False){} # IyBJRVggIkZ1bmN0aW9uIE5ldy1Jc29GaWxlIHtgbiROZXdJU09gbmB0fSAjTmV3LUlzb0ZpbGUi $writeDate = Get-Date -f yyyyMMdd GCI $srcDir | New-ISOFile -Path "$srcDir.iso" ` -Title "$($srcDir.Replace(' ','_').Split('\')[-1])-$writeDate)" ` -Force
The Command line Engine
The batch file portion passes the dragged folder info to the Powershell script which then copies to files into an ISO file.
2Burn.cmd
@Title=Creating ISO Image from [%1] @If []==[%1] Exit @Set pthPS=%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe @Set pthScript=%OneDriveConsumer%\Drag2ISO.ps1 @"%pthPS%" -NoProfile -ExecutionPolicy Bypass -File "%pthScript%" -srcDir %1 @Timeout /T 10
The Override Button on your Desktop
Place both files in a directory of your choice but be sure the batch file points to the correct folder for the PS1 file (4th line). I settled on the root folder of my personal OneDrive so that it would be available across most of my machines.
Because we are trying to create a Drag-&-Drop process we need to add a link to the batch file onto our desktop. Create the shortcut, rename it to your pleasure and, if you want, give it a new icon. I do this to make it easier to find it on my desktop when I need it. I have included screen-shots fo r changing the icons below:

the icon and select OK to open the default icon file.


Click OK to save your changes

Building the image to fix the ship
This process will ISO-wrap either a single file OR multiple files in a single folder (and any sub-folders). In either case, the ISO file will be created in the same folder as the original.
Now we’re ready to create the ISO. In Windows Explorer, navigate to the folder where you downloaded/copied the file needed on the VM and select it (if you’re copying multiple files, move up one folder level and select the folder containing the files).
Now drag the file/folder to the link on your desktop and drop it. The ISO should be created immediately or after several seconds (depending on the size of your file(s)). The command window will indicate when the file has been created and will close automatically after 10 seconds.

Now all that’s left is to connect the ISO to your VM and copy the files to its HDD (or run them from the ISO).
Warping along on a wing and a prayer
Once the scripts and links are in place, I have found this to be the quickest method for getting files onto your VMs. But different situations demand different solutions to a problem and I will be covering the other two solutions in other blogs. Until then “Lab long and prosper!“.
More Blogs in the ‘Boldly Going” Series