Ampliación de Hyper-V con PowerShell
Últimamente he estado escribiendo sobre mi uso de extensiones de tipo PowerShell como una forma de hacer más cosas rápidamente. O al menos dame la información que quiero con el mínimo esfuerzo. Utilizo mucho Hyper-V y los cmdlets de Hyper-V son invaluables. Y aunque un comando como Get-VM proporciona mucha información, parece que siempre quiero más, así que pensé en compartir con ustedes mis extensiones de tipo relacionadas con Hyper-V. Incluso si no necesita ni utiliza Hyper-V, mis técnicas pueden resultarle útiles.
El tipo de objeto para una máquina virtual Hyper-V es Microsoft.HyperV.PowerShell.VirtualMachine, que puede obtener fácilmente ejecutando Get-VM y conectándolo a Get-Member. Al utilizar Update-TypeData, hay varias propiedades de secuencia de comandos que quiero definir. Estas son propiedades donde el valor se calcula mediante un bloque de script de PowerShell. Por ejemplo, quiero poder ver rápidamente si a una máquina virtual le falta alguno de sus archivos de disco configurados. Podría ejecutar un comando como este:
Pero si quiero esta información con frecuencia, es escribir demasiado. Entonces puedo crear una propiedad de script con este bloque de script. Esta versión tiene en cuenta que la máquina virtual puede tener varios discos, de los cuales es posible que falten uno o más.
{
if ($this.HardDrives) {
#test if there are any false results
if ( ($this | Get-VMHardDiskDrive | Test-Path) -contains $False ) {
$False
}
else {
$True
}
}
else {
#no hard drive files configured or found
$false
}
}
En una nota relacionada, me gustaría saber cuánto espacio en disco consume la máquina virtual.
{
$stat = Get-VMHardDiskDrive -VMName $this.vmname | Get-Item | Measure-Object -Property length -sum
[math]::Round($stat.sum/1GB,2)
}
También me gusta saber la ruta al archivo de configuración. Este será un archivo vmcx con un nombre de archivo que coincida con el ID de la máquina virtual.
Join-path -Path "$($this.configurationLocation)\Virtual Machines" -ChildPath "$($this.vmid).vmcx" -Resolve
Para definir estos y algunos otros, uso código como este en mi script de perfil de PowerShell.
Defino una tabla hash donde la clave será el nombre de la propiedad y el valor es el bloque de script que usaré.
$extensions = @{
TestVHD = {
if ($this.HardDrives) {
#test if there are any false results
if ( ($this | Get-VMHardDiskDrive | Test-Path) -contains $False ) {
$False
}
else {
$True
}
}
else {
#no hard drive files configured or found
$false
}
}
ConfigurationFile = {
Join-path -Path "$($this.configurationLocation)\Virtual Machines" -ChildPath "$($this.vmid).vmcx" -Resolve
}
Diskpath = {$this.Harddrives.path}
Running = { if ($this.state -eq 'Running') {$True} else { $False}}
SizeGB = {
$stat = Get-VMHardDiskDrive -VMName $this.vmname | Get-Item | Measure-Object -Property length -sum
[math]::Round($stat.sum/1GB,2)
}
}
A continuación, defino una tabla hash de parámetros que agregaré Update-TypeData.
$params = @{
TypeName = 'Microsoft.HyperV.PowerShell.VirtualMachine'
MemberType = 'ScriptProperty'
MemberName = ''
Value = ''
Force = $True
}
El último paso es enumerar las extensiones y actualizar los datos del tipo.
$extensions.GetEnumerator() | foreach {
$params.memberName = $_.key
$params.value = $_.value
# Write-Host "Creating script property $($_.key)" -ForegroundColor cyan
Update-Typedata @params
}
Al usar tablas hash, mi código está organizado y es más fácil de leer.
Y ahora puedo ejecutar comandos como este:
Me encanta que PowerShell proporciona la flexibilidad para satisfacer mis necesidades. Como siempre, comentarios y sugerencias son bienvenidos.