Cómo administrar y acceder a la información de un servidor de virtualización VMware ESXi o a un clúster de servidores VMware ESXi con VMware vCenter Server. Mostramos cómo realizar tareas habituales (encender, apagar, reiniciar, resetear, snapshot, cambiar nombre, etc) a máquinas virtuales mediante VMware vSphere PowerCLI y una aplicación completa en C# C Sharp para ejemplo de uso de VMware VIX API, con el código fuente incluido: AjpdSoft Gestión VMware ESXi y vCenter.
- Videotutorial AjpdSoft Acceso VMware ESXi y vCenter en funcionamiento.
- Requisitos para usar VMware PowerCLI y VIX API con C# C Sharp.
- Descarga e instalación de VMware vSphere PowerCLI y VIX API.
- Cómo usar PowerCLI para obtener datos y cómo realizar tareas en servidor VMware ESXi y vCenter Server.
- Cómo usar VMware VIX API para desarrollar aplicación Visual Studio .NET C# C Sharp para administrar ESXi y vCenter.
- Anexo: listado código fuente completo de apliación de ejemplo VIX API en C Sharp.
- Notas sobre la última versión de PowerCLI y algunos cambios en el código fuente para la conexión.
Videotutorial AjpdSoft Acceso VMware ESXi y vCenter en funcionamiento
AjpdSoft Gestión VMware ESXi y vCenter, aplicación desarrollada en Visual Studio .NET 2013 (C# CSharp) con código fuente incluido 100% open source totalmente gratuito.
AjpdSoft Gestión VMware ESXi y vCenter permite acceder a servidores de virtualización ESXi y clúster de servidores ESXi con VMware vCenter y permite obtener las máquinas virtuales (aplicando filtros) con sus datos básicos: nombre, poweredstate, tiempo inicio, estado, vRAM, vCPU, vCores, estado Vmware Tools, hostname, IP, sistema operativo, UUID, path, ficheros, alarmas, anotaciones, número de discos, etc. La aplicación también permite (si disponemos de la licencia de VMware ESXi apropiada) realizar acciones sobre las máquinas virtuales: encender, apagar, pausar, snapshot de máquina virtual, apagar, reiniciar el sistema operativo, instalar VMware Tools, montar y desmontar CD VMware Tools, cambiar nombre de máquina virtual, exportar resultados a CSV.
A continuación mostramos un videotutorial sobre el uso y funcionamiento de AjpdSoft Gestión VMware ESXi y vCenter:
Requisitos para usar VMware PowerCLI y VIX API con C# C Sharp
En este tutorial explicaremos paso a paso cómo usar VMware vSphere PowerCLI para acceder a servidores VMware ESXi y VMware vCenter Server. A continuación detallamos los requisitos para poder usar esta aplicación:
- Un equipo cliente con sistema operativo Microsoft Windows 7, Windows 8, Windows 10 con acceso a la misma red que los servidores de virtualización ESXi.
- Servidor de virtualización VMware ESXi o bien grupo de servidores de virtualización en clúster con VMware vCenter Server: Instalar VMware ESXi 5.
Descarga e instalación de VMware vSphere PowerCLI y VIX API
En primer lugar descargaremos el software gratuito VMware vSphere PowerCLI, que nos permitirá acceder a un servidor VMware ESXi o un clúster de servidores VMware vCenter Server, con esta herramienta de la línea de comandos podremos realizar cualquier acción sobre una máquina virtual: encenderla, detenerla, reiniciarla, crear un snapshot, etc. y podremos obtener datos de las las máquinas virtuales: snapshot, listado de máquinas virtuales, sistema operativo, IP, vRAM y vCPU asignadas, etc.
Para descargar VMware PowerCLI accederemos a la web oficial de VMware, necesitaremos ser usuario registrado de VMware (es gratuito). Accederemos a la URL correspondiente para la descarga de VMware vShere PowerCLI:
https://www.vmware.com/support/developer/PowerCLI
En nuestro caso descargaremos VMware vSphere PowerCLI 5.5.0, pulsaremos en «Download Now»:
Leeremos los términos de licencia para VMware vSphere Software Developmen Kit (SDK), si estamos de acuerdo marcaremos «I agree to the terms and conditions outlined in the End User License Agreement» y pulsaremos «Accept»:
Descargaremos el fichero «VMware-PowerCLI-5.5.0-1295336.exe»:
Una vez descargado el fichero lo ejecutaremos para iniciar la instalación de VMware vSphere Software Development Kit SDK (vSphere PowerCLI y VIX API):
Pulsaremos en «Ejecutar»:
El asistente para instalar VMware vSphere PowerCLI nos indicará que se requieren los componentes VMware Remote Console Plug-in 5.1 y VMware VIX 1.12.1, pulsaremos «Install» para instalarlos:
Se iniciará el asistente para instalar VMware Remote Console Plug-in, pulsaremos «Next»:
Pulsaremos «Install»
La instalación de VMware Remote Console Plug-in concluirá, pulsaremos «Finish»:
Se iniciará ahora la instalación de VMware VIX API, pulsaremos «Next»:
Leeremos los términos de licencia para VMware Software Development Kit (SDK), para Vmware VIX Application Programming Interface (VIX API), si estamos de acuerdo marcaremos «I accept the terms in the license agreement» y pulsaremos «Next»:
Indicaremos la carpeta donde se instalará VMware VIX API, pulsaremos «Next»:
Pulsaremos «Install»:
La instalación de VMware VIX API concluirá, pulsaremos «Finish»:
A continuación el asistente para instalar VMware vSphere PowerCLI nos indicará que se requiere una política de ejecución «RemoteSigned» para poder usar PowerCLI, posteriormente indicaremos cómo habilitarla, pulsaremos «Continue»:
Con el texto: The PowerShell execution policy of this computer is not set to «RemoteSigned». This prevents execution of PowerShell scripts on your computer and will result in error when VMware vSphere PowerCLI is invoked. It is recommended that you set the execution policy to «RemoteSigned» in order to ve able to execute scripts. This can be done by invoking the command «Set-ExecutionPolicy RemoteSigned» from a PowerShell prompt. Press Continue to skip and continue install or Cancel to exit the installation.
Se iniciará el asistente para instalar VMware vSphere PowerCLI, pulsaremos «Next»:
Leeremos los términos de licencia de VMware vSphere PowerCLI, si estamos de acuerdo marcaremos «I accept the terms in the license agreement» y pulsaremos «Next»:
Se instalará vSphere PowerCLI y vCloud Director PowerCLI, pulsaremos «Next»:
Pulsaremos «Install»:
Tras la instalación, el asistente nos indicará que ha concluido satisfactoriamente, pulsaremos «Finish»:
De esta sencilla forma ya tendremos disponibles las PowerCLI para administrar y consultar servidores VMware ESXi y VMware vCenter Server:
Cómo usar PowerCLI para obtener datos y realizar tareas en servidor VMware ESXi y vCenter Server
Una vez instaladas las VMware vSphere PowerCLI (como indicamos aquí), pulsaremos en el botón Inicio de Windows, en la carpeta «VMware vSphere PowerCLI» ejecutaremos «VMware vSphere PowerCLI»:
En el primer inicio de las shell de la línea de comandos de las PowerCLI nos indicará que debemos activar «RemoteSigned» para poder usarlas:
Con el texto: No se puede cargar el archivo c:/Program Files (x86)/VMware/Infrastructure/vSphere PowerCLI/Scripts/Initialize-PowerCLIEnvironment.ps1 porque en el sistema está deshabilitada la ejecución de scripts. Vea «get-help about_signing» para obtener más información. En línea: 1 Carácter 2. CategoryInfo; NotSpecified, PSSecurityException. FullQualifiedErrorId: RuntimeException.
Para activar RemoteSigned ejecutaremos el comando:
1 |
set-executionpolicy remotesigned |
Nos avisará de que se va a cambiar una directiva de ejecución, introduciremos «s» y pulsaremos INTRO:
Con el texto: Cambio de directiva de ejecución. La directiva de ejecución le ayuda a protegerse de scripts en los que no confía. Si cambia dicha directiva podría exponerse a los riesgos de seguridad descritos en el tema de la Ayuda about_Execution_Policies. ¿Desea cambiar la directiva de ejecución?
Si la directiva se aplica correctamente se inciará el shel de comandos VMware vSphere PowerCLI:
Con el texto:
Welcome to the VMware vSphere PowerCLI.
Log in to a vCenter Server or ESX host: Connect-VIServer.
To find out what commands are available, type: Get-VICommand
To show searchable help for all PowerCLI commands: Get-PowerCLIHelp
Once you’ve connected, display all virtual machines: Get-VM
If you need more help, visit the PowerCLI community: Get-PowerCLICommunity
Lo primero que haremos será conectarnos a nuestro servidor VMware ESXi o bien a nuestro clúster de servidores VMware vCenter Server, para ello necesitaremos saber la IP de dicho servidor y un usuario y contraseña con permisos suficientes. El parámetro a ejecutar para establecer la conexión será:
1 |
Connect-VIServer -Server 192.168.1.101 -User root -Password xxx |
Donde:
- 192.168.1.101: será la IP de nuestro servidor VMware ESXi o la IP del servidor vCenter Server.
- root: será el usuario con el que nos conectaremos al servidor de virtualización VMware.
- xxx: será la contraseña del usuario anterior.
Si queremos usar el protocolo https y un puerto diferente, podremos ejecutar el comando:
1 |
Connect-VIServer -Server 192.168.1.101 -Protocol https -Port 9245 -User "root" -Password "xxx" |
Si todo es correcto el shell PowerCLI nos mostrará un mensaje indicando que se ha establecido la conexión con el servidor. Es posible que nos muestre alguna advertencia referente al certificado de seguridad:
A partir de ahora podremos ejecutar comandos que serán lanzados contra el servidor ESXi o vCenter al que estemos conectados. Por ejemplo, para obtener todas las máquinas virtuales del servidor (tanto las iniciadas como las apagadas) ejecutaremos el comando:
1 |
Get-VM |
Nos mostrará el nombre de la máquina virtual, el estado (PowerState), el número de vCPU asignados y la cantidad de vRAM asignada:
Podremos hacer filtros, por ejemplo para mostrar sólo las máquinas virtuales encendidas (con PowerState = PoweredOn) ejecutaremos:
1 |
Get-VM | where {$_.PowerState -eq "PoweredOn"} |
Para mostrar solo las máquinas virtuales apagadas:
1 |
Get-VM | where {$_.PowerState -eq "PoweredOff"} |
Además de obtener datos también podremos interactuar con las máquinas virtuales. Por ejemplo, para iniciar una máquina virtual detenida ejecutaremos el comando:
1 |
Start-VM -VM "Ubuntu 10" -RunAsync |
El comando anterior iniciará la máquina virtual con nombre «Ubuntu 10»:
Nota importante: hay que tener en cuenta que las interacciones con las máquinas virtuales desde PowerCLI requieren de licencia en el servidor VMware ESXi, si tenemos licencia Free (gratuita) no podremos ejecutar comandos que realicen acciones sobre las máquinas virtuales (iniciarlas, pararlas, detenerlas, crear máquinas virtuales, eliminar máquinas virtuales, resetearlas, crear snapshot, eliminar snapshot, etc.). En caso de no disponer de la licencia adecuada en el servidor ESXi o vCenter al que estemos conectados, al ejecutar cualquier comando que la requiere mostrará el mensaje:
Fault.RestrictedVersion.summary.
CategoryInfo: NotSpecified, RestrictiveVersion
FullQualifiedErrorId: Client20_VMServiceImpl_StartVM_ViError,VMware.VimAutomation.ViCore.Cmdlets.Commands.StartVM
Para detener una máquina virtual ejecutaremos el comando:
1 |
Stop-VM -VM "XPDelphi" |
Donde «XPDelphi» será el nombre de la máquina virtual a detener. Dependiendo de la acción puede que nos pida confirmación, de ser así introduciremos «s» y pulsaremos INTRO:
Otros ejemplos para obtener datos estadísticos, por ejemplo para obtener métricas de acceso a disco desde una fecha a una fecha, para una máquina virtual (por ejempo «SRVPROYECTOA», ejecutaremos el comando:
1 |
Get-Stat -Entity SRVPROYECTOA -Start 01/03/2014 -Finish 01/03/2014 -Disk |
Para métricas de memoria RAM:
1 |
Get-Stat -Entity SRVPROYECTOA -Start 01/03/2014 -Finish 01/03/2014 -Memory |
Para métricas de CPU:
1 |
Get-Stat -Entity SRVPROYECTOA -Start 01/03/2014 -Finish 01/03/2014 -Cpu |
Para obtener todos los snapshot realizados a una máquina virtual ejecutaremos el comando:
1 |
Get-Snapshot -VM SRVPROYECTOA |
Donde «SRVPROYECTOA» será la máquina virtual de la que mostraremos los snapshots realizados:
Si queremos desactivar los mensajes de aviso (warnings) al ejecutar determinados comandos ejecutaremos este otro comando:
1 |
Set-PowerCLIConfiguration -DisplayDeprecationWarnigs 0 |
Los resultados de la ejecución de comandos que devuelven datos se pueden formatear y personalizar. Por ejemplo, para mostrar los datos de los snapshot de una máquina virtual en forma de detalle ejecutaremos el comando:
1 |
Get-Snapshot -VM SRVPROYECTOA | Format-List |
Para mostrar todos los snapshots de todas las máqunias virtuales del servidor al que estamos conectados, mostrando las columnas vm, name, iscurrent, sizegb:
1 |
Get-VM | Get-Snapshot | Format-List vm, name, iscurrent, sizegb |
Para mostrar los snapshots de las máquinas virtuales de un Resource Pool determinado ejecutaremos el comando:
1 |
Get-VM -Location "Uniland" | Get-Snapshot | Format-List vm, name, iscurrent, sizegb |
Donde «Uniland» será el nombre del Resource Pool.
También podremos guardar los resultados en un ficheor de texto. Por ejemplo, para guardar las máquinas virtuales del servidor al que estamos conectados en un fichero de texto ejecutaremos:
1 |
Get-VM | Out-File c:/vm.txt |
Nos guardará los datos en un fichero de texto plano:
Para guardar más datos de las máquinas virtuales (nombre, estado, vCPU, vRAM, espacio aprovisionado, espacio usado, notas, versión):
1 |
Get-VM | Format-List name, powerstate, numcpu, memorygb, provisionedspacegb, usedspacegb,notes,version | Out-File c:/mv.txt |
Nos habrá guardado algo así en el fichero de salida:
PowerCLI es una herramienta muy potente que nos permitirá realizar cualquier acción sobre un servidor VMware ESXi, sobre un grupo de servidores vCenter Server y sobre cualquiera de sus máquinas virtuales. Otro ejemplo, para eliminar un snapshot especificado de una máquina virtual determinada, sin que pida confirmación, ejecutaremos el siguiente comando PowerCLI:
1 |
Get-VM -Name SRVCERCO | Get-Snapshot | Where {$_.Name -eq "Antes de Service Pack 2"} | Remove-Snapshot -confirm:$false |
El comando anterior eliminará el snapshot con descripción «Antes de Service Pack 2» de la máquina virtual «SRVCERCO»:
Cómo usar VMware VIX API para desarrollar aplicación Visual Studio .NET C# C Sharp para administrar ESXi y vCenter
VMware nos proporciona, junto con las VMware vSphere PowerCLI las VMware VIX API, que básicamente son los mismos comandos disponibles en las PowerCLI pero para plataformas .NET. Con VMware VIX API podremos desarrollar nuestras propias aplicaciones para gestión y administración de nuestros servidores VMware ESXi y VMware vCenter Server. A continuación mostraremos una aplicación completa con código fuente disponible (gratuito) como ejemplo de uso de VMware VIX API.
En primer lugar deberemos disponer de Microsoft Visual Studio .NET en alguna de sus versiones. A continuación mostramos alguinos tutoriales sobre cómo instalarlo y crear una aplicación con Visual Studio .NET:
- Instalar Visual Studio .Net 2012 Windows 8, primera aplicación CSharp.
- Instalar Visual Studio 2010 y desarrollar aplicación con acceso a PostgreSQL.
Abriremos Microsoft Visual Studio .NET, en nuestro caso usaremos la versión 2013, y crearemos un nuevo proyecto C# C Sharp (el procedimiento será el mismo para Visual Basic VB.NET). En los tutoriales anteriores explicamos cómo crear un nuevo proyecto paso a paso.
Una vez creado el proyecto Visual Studio .Net (C#), agregaremos la referencia correspondiente a VMware VIX API. Para ello pulsaremos en el menú «PROYECTO» – «Agregar referencia»:
Pulsaremos en «Examinar»:
Accederemos a la carpeta de instalación de VMware VIX API, por defecto en:
C:/Archivos de programa (x86)/VMware/Infrastructure/vSphere PowerCLI
Y seleccionaremos la librería dll «VMware.Vim.dll», pulsaremos «Agregar»:
Accederemos al código de nuestro formulario principal, donde usaremos VIX API, y añadiremos el using siguiente:
using VMware.Vim;
A partir de ahora ya podremos usar VMware VIX API para gestionar y acceder a servidores VMware ESXi y VMware vCenter Server desde nuestra aplicación C# .NET. Como ejemplo hemos desarrollado una aplicación completa que permite obtener todas las máquinas virtuales (y realizar filtros) y muchos datos como: nombre máquina virtual, estado (PowerState), tiempo de inicio, estado conexión, vRAM, vCPU, cores por socket, estado VMware Tools, hostname, IP, sistema operativo , ruta ficheros MV, ID Guest, Uuid, WWN, anotaciones, número de discos, tamaño, ficheros que componen la MV, alarmas, etc.
Esta aplicación también permite realizar acciones sobre máquinas virtuales tales como: iniciar máquina virtual, apagar, pausar, resetear, reiniciar sistema operativo, apagar sistema operativo, actualizar VMware Tools, instalar VMware Tools, desmontar CD VMware Tools, cambiar nombre a máquina virtual, crear snapshot, etc.
Los componentes que usaremos para realizar la aplicación AjpdSoft Gestión VMware ESXi y vCenter:
El enlace para descargar la aplicación completa con el código fuente en Visual C# .NET 2013:
La aplicación AjpdSoft Gestión VMware ESXi y vCenter en funcionamiento:
Anexo: listado código fuente completo de apliación de ejemplo VIX API en C Sharp
A continuación mostramos el código fuente (source code) completo de la aplicación AjpdSoft Gestión VMware ESXi y vCenter:
- Formulario formAjpdSoftVMwareESX.cs:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 |
using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using System.Net; using System.Text; using System.Windows.Forms; using VMware.Vim; namespace AjpdSoftAccesoVMwareESX { public partial class formAjpdSoftVMwareESX : Form { public VimClientImpl accesoESX = new VimClientImpl(); public formAjpdSoftVMwareESX() { InitializeComponent(); } public bool ampliarTamanoDiscoVirtual(string nombreVM, int numeroDisco, int nuevoTamanoBytes) { NameValueCollection filter = new NameValueCollection(); filter.Add("Summary.vm", nombreVM); VirtualMachine vm = (VirtualMachine)accesoESX.FindEntityView(typeof(VirtualMachine), null, filter, null); try { NameValueCollection nvc = new NameValueCollection(); nvc.Add("name", "Datacenter"); Datacenter dc = (Datacenter)accesoESX.FindEntityView(typeof(Datacenter), null, nvc, null); VirtualDiskManager vdm = new VirtualDiskManager(accesoESX, new ManagedObjectReference()); vdm.ExtendVirtualDisk_Task(vm.Layout.Disk[numeroDisco].DiskFile[0].ToString(), dc.MoRef, nuevoTamanoBytes * 1024 * 1024, false); return true; } catch (Exception errorC) { MessageBox.Show("Ha habido un error:" + Environment.NewLine + Environment.NewLine + errorC.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return false; } } private void btPowerOn_Click(object sender, EventArgs e) { string mvSel; if (lsMVESX.SelectedItems.Count > 0) { mvSel = lsMVESX.SelectedItems[0].Text; if (MessageBox.Show("¿Está seguro que desea encender la máquina virtual " + mvSel + "?", "Encender máquina virtual", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes) { ManagedObjectReference _svcRef = new ManagedObjectReference(); _svcRef.Type = "ServiceInstance"; _svcRef.Value = "ServiceInstance"; try { NameValueCollection filterForVM = new NameValueCollection(); filterForVM.Add("Name", mvSel); VirtualMachine vm = (VirtualMachine)accesoESX.FindEntityView(typeof(VirtualMachine), null, filterForVM, null); vm.PowerOnVM(vm.Runtime.Host); } catch (Exception errorC) { MessageBox.Show("Ha habido un error:" + Environment.NewLine + Environment.NewLine + errorC.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } } else MessageBox.Show("Debe seleccionar la máquina virtual a encender.", "Encender máquina virtual", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } private void formAjpdSoftVMwareESX_FormClosed(object sender, FormClosedEventArgs e) { GuardarConfiguracion proUtilidades = new GuardarConfiguracion(); proUtilidades.guardarValorConfiguracion("URL Servidor ESX vCenter", txtURLESX.Text); proUtilidades.guardarValorConfiguracion("Usuario", txtUsuarioESX.Text); proUtilidades.guardarValorConfiguracion("Filtrar por", lsFiltrarPor.Text); proUtilidades.guardarValorConfiguracion("Valor filtro", lsValorFiltro.Text); //guardar contraseña cifrada cifrarAES cifradoAES = new cifrarAES(); proUtilidades.guardarValorConfiguracion("Contraseña", cifradoAES.cifrarTextoAES(txtContrasenaESX.Text, "AjpdSoft_Frase_Encriptado", "AjpdSoft_Frase_Encriptado", "MD5", 22, "1234567891234567", 128)); try { //Cerramos la conexión con el servidor ESX accesoESX.Disconnect(); } catch { } } private void btPowerOff_Click(object sender, EventArgs e) { string mvSel; if (lsMVESX.SelectedItems.Count > 0) { mvSel = lsMVESX.SelectedItems[0].Text; if (MessageBox.Show("¿Está seguro que desea apagar la máquina virtual " + mvSel + "?", "Apagar máquina virtual", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes) { ManagedObjectReference _svcRef = new ManagedObjectReference(); _svcRef.Type = "ServiceInstance"; _svcRef.Value = "ServiceInstance"; try { NameValueCollection filterForVM = new NameValueCollection(); filterForVM.Add("Name", mvSel); VirtualMachine vm = (VirtualMachine)accesoESX.FindEntityView(typeof(VirtualMachine), null, filterForVM, null); vm.PowerOffVM(); } catch (Exception errorC) { MessageBox.Show("Ha habido un error:" + Environment.NewLine + Environment.NewLine + errorC.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } } else MessageBox.Show("Debe seleccionar la máquina virtual a apagar.", "Apagar máquina virtual", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } private void btRenombrarMV_Click(object sender, EventArgs e) { string mvSel; if (lsMVESX.SelectedItems.Count > 0) { if (txtNombreVM.Text == "") { MessageBox.Show("Debe indicar el nuevo nombre de la máquina virtual.", "Renombrar máquina virtual", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } else { mvSel = lsMVESX.SelectedItems[0].Text; if (MessageBox.Show("¿Está seguro que desea renombrar la máquina virtual [" + mvSel + "] por [" + txtNombreVM.Text + "]?", "Renombrar máquina virtual", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes) { ManagedObjectReference _svcRef = new ManagedObjectReference(); _svcRef.Type = "ServiceInstance"; _svcRef.Value = "ServiceInstance"; try { NameValueCollection filterForVM = new NameValueCollection(); filterForVM.Add("Name", mvSel); VirtualMachine vm = (VirtualMachine)accesoESX.FindEntityView(typeof(VirtualMachine), null, filterForVM, null); VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec(); vmConfigSpec.Name = txtNombreVM.Text; // Cambiar nombre a MV vm.ReconfigVM_Task(vmConfigSpec); } catch (Exception errorC) { MessageBox.Show("Ha habido un error:" + Environment.NewLine + Environment.NewLine + errorC.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } } } else MessageBox.Show("Debe seleccionar la máquina virtual a renombrar.", "Renombrar máquina virtual", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } private void btReiniciarGuest_Click(object sender, EventArgs e) { string mvSel; if (lsMVESX.SelectedItems.Count > 0) { mvSel = lsMVESX.SelectedItems[0].Text; if (MessageBox.Show("¿Está seguro que desea reiniciar el sistema operativo " + "de la máquina virtual [" + mvSel + "]?", "Reiniciar sistema operativo", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes) { ManagedObjectReference _svcRef = new ManagedObjectReference(); _svcRef.Type = "ServiceInstance"; _svcRef.Value = "ServiceInstance"; try { NameValueCollection filterForVM = new NameValueCollection(); filterForVM.Add("Name", mvSel); VirtualMachine vm = (VirtualMachine)accesoESX.FindEntityView(typeof(VirtualMachine), null, filterForVM, null); vm.RebootGuest(); } catch (Exception errorC) { MessageBox.Show("Ha habido un error:" + Environment.NewLine + Environment.NewLine + errorC.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } } else MessageBox.Show("Debe seleccionar la máquina virtual a reiniciar.", "Reiniciar máquina virtual", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } private void btExportarCSV_Click(object sender, EventArgs e) { dlGuardar.Filter = "Fichero CSV (*.csv)|*.csv"; dlGuardar.FileName = "Máquinas virtuales ESX"; dlGuardar.Title = "Exportar a CSV"; if (dlGuardar.ShowDialog() == DialogResult.OK) { StringBuilder csvMemoria = new StringBuilder(); foreach (ColumnHeader columnasLista in lsMVESX.Columns) { csvMemoria.Append(String.Format("\"{0}\";", columnasLista.Text)); } csvMemoria.AppendLine(); foreach (ListViewItem elementosLista in lsMVESX.Items) { foreach (ListViewItem.ListViewSubItem lvs in elementosLista.SubItems) { if (lvs.Text.Trim() == string.Empty) csvMemoria.Append("\"\";"); else csvMemoria.Append(String.Format("\"{0}\";", lvs.Text)); } csvMemoria.AppendLine(); } System.IO.StreamWriter sw = new System.IO.StreamWriter(dlGuardar.FileName, false, System.Text.Encoding.Default); sw.Write(csvMemoria.ToString()); sw.Close(); } } private void btSuspender_Click(object sender, EventArgs e) { string mvSel; if (lsMVESX.SelectedItems.Count > 0) { mvSel = lsMVESX.SelectedItems[0].Text; if (MessageBox.Show("¿Está seguro que desea suspender la " + "máquina virtual [" + mvSel + "]?", "Suspender MV", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes) { ManagedObjectReference _svcRef = new ManagedObjectReference(); _svcRef.Type = "ServiceInstance"; _svcRef.Value = "ServiceInstance"; try { NameValueCollection filterForVM = new NameValueCollection(); filterForVM.Add("Name", mvSel); VirtualMachine vm = (VirtualMachine)accesoESX.FindEntityView(typeof(VirtualMachine), null, filterForVM, null); vm.SuspendVM(); } catch (Exception errorC) { MessageBox.Show("Ha habido un error:" + Environment.NewLine + Environment.NewLine + errorC.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } } else MessageBox.Show("Debe seleccionar la máquina virtual a suspender.", "Reiniciar máquina virtual", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } private void btActualizarVMwareTools_Click(object sender, EventArgs e) { string mvSel; if (lsMVESX.SelectedItems.Count > 0) { mvSel = lsMVESX.SelectedItems[0].Text; if (MessageBox.Show("¿Está seguro que desea actualizar las VMware Tools de la " + "máquina virtual [" + mvSel + "]?", "Actualizar VMware Tools", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes) { ManagedObjectReference _svcRef = new ManagedObjectReference(); _svcRef.Type = "ServiceInstance"; _svcRef.Value = "ServiceInstance"; try { NameValueCollection filterForVM = new NameValueCollection(); filterForVM.Add("Name", mvSel); VirtualMachine vm = (VirtualMachine)accesoESX.FindEntityView(typeof(VirtualMachine), null, filterForVM, null); vm.UpgradeTools(""); } catch (Exception errorC) { MessageBox.Show("Ha habido un error:" + Environment.NewLine + Environment.NewLine + errorC.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } } else MessageBox.Show("Debe seleccionar la máquina virtual a actualizar las VMware Tools.", "Actualizar VMware Tools", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } private void btInstalarVMwareTools_Click(object sender, EventArgs e) { string mvSel; if (lsMVESX.SelectedItems.Count > 0) { mvSel = lsMVESX.SelectedItems[0].Text; if (MessageBox.Show("¿Está seguro que desea instalar las VMware Tools en la " + "máquina virtual [" + mvSel + "]?", "Instalar VMware Tools", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes) { ManagedObjectReference _svcRef = new ManagedObjectReference(); _svcRef.Type = "ServiceInstance"; _svcRef.Value = "ServiceInstance"; try { NameValueCollection filterForVM = new NameValueCollection(); filterForVM.Add("Name", mvSel); VirtualMachine vm = (VirtualMachine)accesoESX.FindEntityView(typeof(VirtualMachine), null, filterForVM, null); vm.MountToolsInstaller(); } catch (Exception errorC) { MessageBox.Show("Ha habido un error:" + Environment.NewLine + Environment.NewLine + errorC.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } } else MessageBox.Show("Debe seleccionar la máquina virtual para instalar las VMware Tools.", "Instalar VMware Tools", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } private void btApagarSO_Click(object sender, EventArgs e) { string mvSel; if (lsMVESX.SelectedItems.Count > 0) { mvSel = lsMVESX.SelectedItems[0].Text; if (MessageBox.Show("¿Está seguro que desea apagar el sistema operativo " + "de la máquina virtual [" + mvSel + "]?", "Apagar sistema operativo", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes) { ManagedObjectReference _svcRef = new ManagedObjectReference(); _svcRef.Type = "ServiceInstance"; _svcRef.Value = "ServiceInstance"; try { NameValueCollection filterForVM = new NameValueCollection(); filterForVM.Add("Name", mvSel); VirtualMachine vm = (VirtualMachine)accesoESX.FindEntityView(typeof(VirtualMachine), null, filterForVM, null); vm.ShutdownGuest(); } catch (Exception errorC) { MessageBox.Show("Ha habido un error:" + Environment.NewLine + Environment.NewLine + errorC.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } } else MessageBox.Show("Debe seleccionar la máquina virtual a apagar el sistema operativo.", "Apagar Sistema Operativo", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } private void formAjpdSoftVMwareESX_Load(object sender, EventArgs e) { //Establecemos las propiedades del ListView lsMVESX.View = System.Windows.Forms.View.Details; lsMVESX.GridLines = true; lsMVESX.FullRowSelect = true; //Añadimos las columnas al ListView lsMVESX.Columns.Add("MV", 130); lsMVESX.Columns.Add("PW Estado", 70); lsMVESX.Columns.Add("Tiempo inicio", 110); lsMVESX.Columns.Add("Estado", 70); lsMVESX.Columns.Add("vRAM", 60); lsMVESX.Columns.Add("vCPU", 60); lsMVESX.Columns.Add("Cores x socket", 80); lsMVESX.Columns.Add("Estado Tools", 100); lsMVESX.Columns.Add("Hostname", 80); lsMVESX.Columns.Add("IP", 100); lsMVESX.Columns.Add("SO", 150); lsMVESX.Columns.Add("Path", 150); lsMVESX.Columns.Add("ID Guest", 80); lsMVESX.Columns.Add("Uuid", 80); lsMVESX.Columns.Add("WWN", 80); lsMVESX.Columns.Add("Anotaciones", 80); lsMVESX.Columns.Add("Nº Discos MV", 50); lsMVESX.Columns.Add("Tamaño Discos MV", 50); lsMVESX.Columns.Add("Nº Discos Guest", 50); lsMVESX.Columns.Add("Tamaño Discos Guest", 80); lsMVESX.Columns.Add("Ficheros MV", 80); lsMVESX.Columns.Add("Alarma", 80); GuardarConfiguracion proUtilidades = new GuardarConfiguracion(); txtURLESX.Text = proUtilidades.leerValorConfiguracion("URL Servidor ESX vCenter"); txtUsuarioESX.Text = proUtilidades.leerValorConfiguracion("Usuario"); lsFiltrarPor.Text = proUtilidades.leerValorConfiguracion("Filtrar por"); lsValorFiltro.Text = proUtilidades.leerValorConfiguracion("Valor filtro"); //leer contraseña cifrada cifrarAES cifradoAES = new cifrarAES(); string contrasenaCifrada = ""; contrasenaCifrada = proUtilidades.leerValorConfiguracion("Contraseña"); txtContrasenaESX.Text = cifradoAES.descifrarTextoAES(contrasenaCifrada, "AjpdSoft_Frase_Encriptado", "AjpdSoft_Frase_Encriptado", "MD5", 22, "1234567891234567", 128); } private void lsMVESX_SelectedIndexChanged(object sender, EventArgs e) { if (lsMVESX.SelectedItems.Count > 0) txtNombreVM.Text = lsMVESX.SelectedItems[0].Text; } private void btSnapshot_Click(object sender, EventArgs e) { string mvSel; if (lsMVESX.SelectedItems.Count > 0) { if (txtSnapshotNombre.Text == "") { MessageBox.Show("Debe indicar el nombre del snapshot que se creará.", "Snapshot máquina virtual", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } else { mvSel = lsMVESX.SelectedItems[0].Text; if (MessageBox.Show("¿Está seguro que desea crear un snapshot del momento actual para la MV [" + mvSel + "]?", "Snapshot máquina virtual", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes) { ManagedObjectReference _svcRef = new ManagedObjectReference(); _svcRef.Type = "ServiceInstance"; _svcRef.Value = "ServiceInstance"; try { NameValueCollection filterForVM = new NameValueCollection(); filterForVM.Add("Name", mvSel); VirtualMachine vm = (VirtualMachine)accesoESX.FindEntityView(typeof(VirtualMachine), null, filterForVM, null); vm.CreateSnapshot(txtSnapshotNombre.Text, txtSnapshotDescripcion.Text, opSnapshotMemoria.Checked, opSnapshotQuiesceFileSystem.Checked); } catch (Exception errorC) { MessageBox.Show("Ha habido un error:" + Environment.NewLine + Environment.NewLine + errorC.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } } } else MessageBox.Show("Debe seleccionar la máquina virtual a renombrar.", "Renombrar máquina virtual", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } private void btDesconectarESXvCenter_Click(object sender, EventArgs e) { try { accesoESX.Disconnect(); } catch (Exception errorC) { MessageBox.Show("Ha habido un error:" + Environment.NewLine + Environment.NewLine + errorC.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } private void btConectarESXvCenter_Click(object sender, EventArgs e) { if (!opLimpiarLista.Checked) lsMVESX.Items.Clear(); try { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; ServicePointManager.ServerCertificateValidationCallback += delegate { return true; }; // Conectamos con vSphere ESX - vCenter servicio web string puerto = txtPuerto.Text; if (puerto == "") puerto = "443"; string protocolo = lsProtocolo.Text; if (protocolo != "") { if (protocolo == "HTTP") accesoESX.Connect(txtURLESX.Text, CommunicationProtocol.Http, Convert.ToUInt16(puerto)); else accesoESX.Connect(txtURLESX.Text, CommunicationProtocol.Https, Convert.ToUInt16(puerto)); } else accesoESX.Connect(txtURLESX.Text); // Iniciamos sesión en el servidor VMware ESX - vCenter con usuario y contraseña accesoESX.Login(txtUsuarioESX.Text, txtContrasenaESX.Text); //Filtramos las máquinas virtuales (por el campo y valor que queramos) NameValueCollection filter = new NameValueCollection(); if (opAplicarFiltro.Checked) filter.Add(lsFiltrarPor.Text, lsValorFiltro.Text); IList<EntityViewBase> vmList = accesoESX.FindEntityViews(typeof(VirtualMachine), null, filter, null); //datos de conexión a VMware ESX - vCenter txtInfoServerESX.Text = accesoESX.ServiceContent.About.FullName + " " + accesoESX.ServiceContent.About.ApiType + " " + accesoESX.ServiceContent.About.LicenseProductName + " " + accesoESX.ServiceContent.About.OsType + " " + accesoESX.ServiceContent.IpPoolManager + " " + accesoESX.ServiceContent.About.Vendor + " " + accesoESX.ServiceUrl; //accesoESX.ServiceUrl + " " + //accesoESX.ServiceContent.About.DynamicProperty; //datos de licencia VMware ESX - vCenter LicenseManager licenciaESXvCenter = (LicenseManager)accesoESX.GetView(accesoESX.ServiceContent.LicenseManager, null); LicenseManagerLicenseInfo[] licencia = licenciaESXvCenter.Licenses; string tipoLicenciaESX = ""; string claveLicenciaESX = ""; foreach (LicenseManagerLicenseInfo lic in licencia) { tipoLicenciaESX = lic.Name.ToString(); claveLicenciaESX = lic.LicenseKey.ToString(); } txtLicenciaESX.Text = tipoLicenciaESX + " Key: " + claveLicenciaESX; //Añadimos los elementos (filas) al ListView string[] elementosFila = new string[22]; ListViewItem elementoListView; string ficherosMV = ""; // Recorremos todas las máquinas virtuales del ESX que cumplan el filtro foreach (VirtualMachine vm in vmList) { elementosFila[0] = vm.Name; elementosFila[1] = Convert.ToString(vm.Runtime.PowerState); elementosFila[2] = Convert.ToString(vm.Runtime.BootTime); elementosFila[3] = Convert.ToString(vm.Runtime.ConnectionState); elementosFila[4] = Convert.ToString(vm.Config.Hardware.MemoryMB); elementosFila[5] = Convert.ToString(vm.Config.Hardware.NumCPU); elementosFila[6] = Convert.ToString(vm.Config.Hardware.NumCoresPerSocket); elementosFila[7] = Convert.ToString(vm.Guest.ToolsStatus); elementosFila[8] = Convert.ToString(vm.Guest.HostName); elementosFila[9] = Convert.ToString(vm.Guest.IpAddress); elementosFila[10] = Convert.ToString(vm.Guest.GuestFullName); elementosFila[11] = Convert.ToString(vm.Config.Files.VmPathName); elementosFila[12] = Convert.ToString(vm.Config.GuestId); elementosFila[13] = Convert.ToString(vm.Config.Uuid); elementosFila[14] = Convert.ToString(vm.Config.NpivPortWorldWideName); elementosFila[15] = Convert.ToString(vm.Config.Annotation); if (vm.Layout.Disk != null) { elementosFila[16] = Convert.ToString(vm.Layout.Disk.Count()); //Tamaño de los discos duros virtuales de la máquina virtual long tamano = 0; string discosTamano = ""; foreach (VirtualDevice dispositivo in vm.Config.Hardware.Device) { if (dispositivo.GetType() == typeof(VirtualDisk)) { VirtualDisk disco = new VirtualDisk(); if (discosTamano == "") discosTamano = disco.DiskObjectId + " -> " + Convert.ToString(disco.CapacityInKB / 1024 / 1024) + "GB"; else discosTamano = discosTamano + " || " + disco.DiskObjectId + " -> " + Convert.ToString(disco.CapacityInKB / 1024 / 1024) + "GB"; tamano = tamano + disco.CapacityInKB / 1024 / 1024; } } elementosFila[17] = Convert.ToString(tamano) + " " + discosTamano; ficherosMV = ""; //Obtener todos los ficheros que componen la máquina virtual for (int i = 0; i < vm.Layout.Disk.Count(); i++) { for (int j = 0; j < vm.Layout.Disk[i].DiskFile.Count(); j++) { ficherosMV = ficherosMV + " || " + vm.Layout.Disk[i].DiskFile[j]; } } elementosFila[20] = ficherosMV; } else { elementosFila[16] = "--"; elementosFila[17] = "--"; } if (vm.Guest.Disk != null) { elementosFila[18] = Convert.ToString(vm.Guest.Disk.Count()); long? tamanoDiscos = 0; for (int i = 0; i < vm.Guest.Disk.Count(); i++) { tamanoDiscos = tamanoDiscos + vm.Guest.Disk[i].Capacity; } elementosFila[19] = Convert.ToString(tamanoDiscos / 1024 / 1024 / 1024); } else { elementosFila[18] = "--"; elementosFila[19] = "--"; } //obtenemos las posibles alarmas activas para la máquina virtual VMware.Vim.AlarmState[] alarmaMV = vm.TriggeredAlarmState; string alarmasMV = ""; foreach (AlarmState alarma in alarmaMV) { alarmasMV = alarmasMV + alarma.Alarm.Value + " || "; } elementosFila[21] = alarmasMV; elementoListView = new ListViewItem(elementosFila); lsMVESX.Items.Add(elementoListView); } } catch (Exception errorC) { MessageBox.Show("Ha habido un error:" + Environment.NewLine + Environment.NewLine + errorC.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } private void btResetearMV_Click(object sender, EventArgs e) { string mvSel; if (lsMVESX.SelectedItems.Count > 0) { mvSel = lsMVESX.SelectedItems[0].Text; if (MessageBox.Show("¿Está seguro que desea resetear la " + "máquina virtual [" + mvSel + "]?", "Resetear MV", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { ManagedObjectReference _svcRef = new ManagedObjectReference(); _svcRef.Type = "ServiceInstance"; _svcRef.Value = "ServiceInstance"; try { NameValueCollection filterForVM = new NameValueCollection(); filterForVM.Add("Name", mvSel); VirtualMachine vm = (VirtualMachine)accesoESX.FindEntityView(typeof(VirtualMachine), null, filterForVM, null); vm.ResetVM(); } catch (Exception errorC) { MessageBox.Show("Ha habido un error:" + Environment.NewLine + Environment.NewLine + errorC.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } } else MessageBox.Show("Debe seleccionar la máquina virtual a resetear.", "Resetear máquina virtual", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } private void btMontarVMwareTools_Click(object sender, EventArgs e) { string mvSel; if (lsMVESX.SelectedItems.Count > 0) { mvSel = lsMVESX.SelectedItems[0].Text; if (MessageBox.Show("¿Está seguro que desea desmontar el CD de las VMware Tools en la " + "máquina virtual [" + mvSel + "]?", "Desmontar CD VMware Tools", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { ManagedObjectReference _svcRef = new ManagedObjectReference(); _svcRef.Type = "ServiceInstance"; _svcRef.Value = "ServiceInstance"; try { NameValueCollection filterForVM = new NameValueCollection(); filterForVM.Add("Name", mvSel); VirtualMachine vm = (VirtualMachine)accesoESX.FindEntityView(typeof(VirtualMachine), null, filterForVM, null); vm.UnmountToolsInstaller(); } catch (Exception errorC) { MessageBox.Show("Ha habido un error:" + Environment.NewLine + Environment.NewLine + errorC.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } } else MessageBox.Show("Debe seleccionar la máquina virtual para desmontar las VMware Tools.", "Desmontar VMware Tools", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } private void btObtenerUltimaTarea_Click(object sender, EventArgs e) { /* TaskHistoryCollector tareas; TaskFilterSpec filtroTareas = new TaskFilterSpec(); filtroTareas.Time.BeginTime = DateTime.Now; tareas = vm.GetAllTasksView(filtroTareas); tareas.ReadNextTasks(1); foreach (TaskInfo tarea in tareas) { elementosFila[21] = tarea.Description.Message; } */ /* ManagedObjectReference _svcRef = new ManagedObjectReference(); _svcRef.Type = "ServiceInstance"; _svcRef.Value = "ServiceInstance"; try { NameValueCollection filterForVM = new NameValueCollection(); filterForVM.Add("Name", mvSel); VirtualMachine vm = (VirtualMachine)accesoESX.FindEntityView(typeof(VirtualMachine), null, filterForVM, null); vm.UnmountToolsInstaller(); } catch (Exception errorC) { MessageBox.Show("Ha habido un error:" + Environment.NewLine + Environment.NewLine + errorC.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } } else MessageBox.Show("Debe seleccionar la máquina virtual para desmontar las VMware Tools.", "Desmontar VMware Tools", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); */ } private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { System.Diagnostics.Process.Start("https://proyectoa.com"); } } } |
- GuardarConfiguracion.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Configuration; using System.Windows.Forms; namespace AjpdSoftAccesoVMwareESX { class GuardarConfiguracion { //leer valor de configuración del fichero app.config public string leerValorConfiguracion(string clave) { try { string resultado = ConfigurationManager.AppSettings[clave].ToString(); return resultado; } catch { return ""; } } //escribir valor de configuración en fichero app.config public void guardarValorConfiguracion(string clave, string valor) { try { Configuration ficheroConfXML = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath); //eliminamos la clave actual (si existe), si no la eliminamos //los valores se irán acumulando separados por coma ficheroConfXML.AppSettings.Settings.Remove(clave); //asignamos el valor en la clave indicada ficheroConfXML.AppSettings.Settings.Add(clave, valor); //guardamos los cambios definitivamente en el fichero de configuración ficheroConfXML.Save(ConfigurationSaveMode.Modified); } catch { /* MessageBox.Show("Error al guardar valor de configuración: " + System.Environment.NewLine + System.Environment.NewLine + ex.GetType().ToString() + System.Environment.NewLine + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);*/ } } } } |
- CifrarAES.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
using System; using System.Security.Cryptography; using System.Text; using System.IO; namespace AjpdSoftAccesoVMwareESX { class cifrarAES { public string cifrarTextoAES(string textoCifrar, string palabraPaso, string valorRGBSalt, string algoritmoEncriptacionHASH, int iteraciones, string vectorInicial, int tamanoClave) { try { byte[] InitialVectorBytes = Encoding.ASCII.GetBytes(vectorInicial); byte[] saltValueBytes = Encoding.ASCII.GetBytes(valorRGBSalt); byte[] plainTextBytes = Encoding.UTF8.GetBytes(textoCifrar); PasswordDeriveBytes password = new PasswordDeriveBytes(palabraPaso, saltValueBytes, algoritmoEncriptacionHASH, iteraciones); byte[] keyBytes = password.GetBytes(tamanoClave / 8); RijndaelManaged symmetricKey = new RijndaelManaged(); symmetricKey.Mode = CipherMode.CBC; ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, InitialVectorBytes); MemoryStream memoryStream = new MemoryStream(); CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write); cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); cryptoStream.FlushFinalBlock(); byte[] cipherTextBytes = memoryStream.ToArray(); memoryStream.Close(); cryptoStream.Close(); string textoCifradoFinal = Convert.ToBase64String(cipherTextBytes); return textoCifradoFinal; } catch { return null; } } public string descifrarTextoAES(string textoCifrado, string palabraPaso, string valorRGBSalt, string algoritmoEncriptacionHASH, int iteraciones, string vectorInicial, int tamanoClave) { try { byte[] InitialVectorBytes = Encoding.ASCII.GetBytes(vectorInicial); byte[] saltValueBytes = Encoding.ASCII.GetBytes(valorRGBSalt); byte[] cipherTextBytes = Convert.FromBase64String(textoCifrado); PasswordDeriveBytes password = new PasswordDeriveBytes(palabraPaso, saltValueBytes, algoritmoEncriptacionHASH, iteraciones); byte[] keyBytes = password.GetBytes(tamanoClave / 8); RijndaelManaged symmetricKey = new RijndaelManaged(); symmetricKey.Mode = CipherMode.CBC; ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, InitialVectorBytes); MemoryStream memoryStream = new MemoryStream(cipherTextBytes); CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read); byte[] plainTextBytes = new byte[cipherTextBytes.Length]; int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); memoryStream.Close(); cryptoStream.Close(); string textoDescifradoFinal = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount); return textoDescifradoFinal; } catch { return null; } } } } |
Notas sobre la última versión de PowerCLI y algunos cambios en el código fuente para la conexión
En la última versión de las librerías de PowerCLI, las que se usan en este proyecto, hay que modificar la línea de código:
1 |
public VimClient accesoESX = new VimClient(); |
Por esta otra línea:
1 |
public VimClientImpl accesoESX = new VimClientImpl(); |
Dado que en esta última versión, VimClient ya no es una clase, es una interfaz, y por lo tanto no sirve la declaración anterior.
En caso de no hacer este cambio y de usar la versión 7.0 de las librerías de PowerCLI, en Visual Studio .Net C# se mostrará este error:
Error CS0144 No se puede crear una instancia de la interfaz o el tipo abstracto «VimClient»
Para la línea de código:
1 |
public VimClient accesoESX = new VimClient(); |
Además de esto, en el código fuente se han tenido que añadir unas líneas para ignorar los mensajes de error de certificado:
Quedando el código fuente de conexión como sigue:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
if (!opLimpiarLista.Checked) lsMVESX.Items.Clear(); try { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; ServicePointManager.ServerCertificateValidationCallback += delegate { return true; }; // Conectamos con vSphere ESX - vCenter servicio web string puerto = txtPuerto.Text; if (puerto == "") puerto = "443"; string protocolo = lsProtocolo.Text; if (protocolo != "") { if (protocolo == "HTTP") accesoESX.Connect(txtURLESX.Text, CommunicationProtocol.Http, Convert.ToUInt16(puerto)); else accesoESX.Connect(txtURLESX.Text, CommunicationProtocol.Https, Convert.ToUInt16(puerto)); } else accesoESX.Connect(txtURLESX.Text); // Iniciamos sesión en el servidor VMware ESX - vCenter con usuario y contraseña accesoESX.Login(txtUsuarioESX.Text, txtContrasenaESX.Text); |
Habiendo añadido las líneas:
1 2 3 |
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; ServicePointManager.ServerCertificateValidationCallback += delegate { return true; }; |
En caso de no aplicar estos cambios, al conectar a un servidor VMware ESXi o clúster vCenter, podría mostrar el error:
No se pudo establecer una relación de confianza para el canal seguro SSL/TLS con la autoridad ‘192.168.1.100’.
Por otro lado, si la aplicación muestra un error como el siguiente al abrirse:
Error
Error al iniciar la aplicación:
No se puede cargar el archivo o ensamblado ‘VMware.Vim, Version=7.0.1.3060, Culture=neutral, PublicKeyToken=null’ ni una de sus dependencias. El sistema no puede encontrar el archivo especificado.
Es debido a que falta alguna de las librerías DLL de PowerCLI necesarias, que son las siguientes (se incluyen en esta descarga):
- VMware.Vim.dll
- VMware.Binding.WsTrust.dll
- VMware.Binding.Wcf.dll
- InternalVimService50.Wcf.dll
- InternalVimService70.Wcf.dll
- InventoryService55.Wcf.dll
- VimService.dll
- Newtonsoft.Json.dll