Skip to content

Instantly share code, notes, and snippets.

@JaekelEDV
Created February 19, 2018 18:58
Show Gist options
  • Save JaekelEDV/fe7c65ce8ffa185c3d3588b34165e38e to your computer and use it in GitHub Desktop.
Save JaekelEDV/fe7c65ce8ffa185c3d3588b34165e38e to your computer and use it in GitHub Desktop.
Powershell Script to export VMs with dynamic parameters
<#
.SYNOPSIS
The Function Export-MyVM extends the standard cmdlet Export-VM with dynamic parameters.
.DESCRIPTION
The Script makes the search for the VMs and the Export-Destination-Drive dynamic.
You can simply tab through the two mandatory parameters to get (a) all VMs on the Hyper-V-Host and (b) all connected drives.
Frankly, the main purpose was to learn dynamic parameters.
.PARAMETER VMName
Tab out all VMs on the Hyper-V-Host.
It's a positional (1) and mandatory parameter.
.PARAMETER Disk
Tab out all Disks on the Hyper-V-Host to find your preferred backup-destination
It's a positional (2) and mandatory parameter.
.EXAMPLE
Export-MyVM -VMName <Value> -Disk <Value>
.NOTES
Author: Oliver Jäkel | oj@jaekel-edv.de | @JaekelEDV
#>
function Export-MyVM
{
#region Parameter Section
[CmdletBinding(
SupportsShouldProcess = $true
)]
Param()
DynamicParam
{ #Dynamic Parameters require 4 objects:
#1 - Runtime defined Parameter Dictionary
#2 - Attribute Collection
#3 - ParamaterAttribute
#4 - Runtime Defined Parameter
#Declare the first dynamic parameter
$ParameterName1 = 'VMName'
#1 - Create the dictionary, i.e. a container where the dynamic parameters will be stored
$RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
#2 - Create the collection of attributes, i.e. a container where System.Attribute objects will be stored
$AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
#3a - Create and set the parameters' attributes
$ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
$ParameterAttribute.Mandatory = $true
$ParameterAttribute.Position = 1
#3b - Add the attributes to the attributes collection
$AttributeCollection.Add($ParameterAttribute)
#3c - Create and set the ValidateSet, i.e. the dynamically values our parameters might have
$arrSet = Get-VM | Select-Object -ExpandProperty Name
$ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet)
# Add the ValidateSet to the attributes collection
$AttributeCollection.Add($ValidateSetAttribute)
#4 - Now it's time to create the dynamic parameters and put them in the dictionary
$RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName1, [string], $AttributeCollection)
$RuntimeParameterDictionary.Add($ParameterName1, $RuntimeParameter)
#And now the ugly part of this solution: for a second dynamic parameter you'll have to start all over...
#Declare the second dynamic parameter
$ParameterName2 = 'Disk'
$AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
$ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
$ParameterAttribute.Mandatory = $true
$ParameterAttribute.Position = 2
$AttributeCollection.Add($ParameterAttribute)
$arrSet = Get-CimInstance -ClassName Win32_LogicalDisk | Select-Object -ExpandProperty DeviceID
$ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet)
$AttributeCollection.Add($ValidateSetAttribute)
$RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName2, [string], $AttributeCollection)
$RuntimeParameterDictionary.Add($ParameterName2, $RuntimeParameter)
return $RuntimeParameterDictionary
#endregion
}
begin
#region Check and import Hyper-V Module
{
$LoadedModules = (Get-Module).Name
if ($LoadedModules -notcontains 'Hyper-V')
{Import-Module Hyper-V
}
else
{write-host 'Hyper-V Module already loaded' -ForegroundColor Yellow
}
#endregion
}
process
#region Export-VM
{ $VMName = $PsBoundParameters[$ParameterName1]
$Disk = $PsBoundParameters[$ParameterName2]
Export-VM -Name $VMName -Path $Disk
}
#endregion
end
{
#no end processing needed
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment