Подключение файлов VHD в Hyper-V


Многие знают, что в Virtual Server 2005 существовала утилита vhdmount.exe. Она позволяла подключать образы жестких дисков формата VHD в виде каталога на разделе NTFS или отдельного диска.


В Hyper-V такой возможности нет. В связи с чем возникают больные вопросы — «доколе?» и «что делать?».


Выход из этой ситуации, конечно, есть. Точнее несколько выходов. Все они основаны на богатых возможностях управления Hyper-V через репозиторий WMI. Я приведу примеры подключения образов VHD для C#, VBScript и PowerShell. Если тема программного управления VM интересна, могу привести другие примеры.


PowerShell


#Specify the VHD to be mounted


$VHDName = “F:\Windows.vhd”


   


#Get the MSVM_ImageManagementService


$VHDService = get-wmiobject -class “Msvm_ImageManagementService” -namespace “root\virtualization” -computername “.”


   


#Mount the VHD


$Result = $VHDService.Mount($VHDName)


Это, конечно, очень простой пример. Он использует готовый объект MSVM_ImageManagementService, который создается при установке роли Hyper-V, и вызывает для него метод Mount. Для отключения, что логично, используется метод UnMount.


Обратите внимание, что для успешного подключения образа виртуального диска требуется, чтобы он в данный момент не использовался запущенными виртуальными машинами. Иначе попытка подключения завершится ошибкой.


Более того — диск просто подключится к системе, но будет находиться в отключенном состоянии (offline). Перевести его в состояние online можно из оснастки Disk Management, которая входит в Server Manager. Затем там же потребуется присвоить диску букву или подключить в пустой каталог.


VBScript


Option Explicit


   


Dim WMIService


Dim VHDService


Dim VHD


   


‘Specify the VHD to be mounted


VHD = “F:\Windows.vhd”


   


‘Get instance of ‘virtualization’ WMI service on the local computer


Set WMIService = GetObject(“winmgmts:\\.\root\virtualization”)


   


‘Get the MSVM_ImageManagementService


Set VHDService = WMIService.ExecQuery(“SELECT * FROM Msvm_ImageManagementService”).ItemIndex(0)


   


‘Mount the VHD


VHDService.Mount(VHD)


Приведу также пример на C#. Но это немного сложнее, так что не обессудьте за большой объем кода. Я и так для облегчения восприятия убрал всевозможные необходимые в реальной жизни проверки ошибок.


C#




using System;


using System.Collections.Generic;


using System.Text;


using System.Management;


using System.IO;


using System.Security.AccessControl;


using Microsoft.Virtualization.Test.Utilities.CommandLineParser;


 


public static class Class1


{


    private static ManagementClass mVhdSvc;


    public static void Main(string[] args)


    {


        OpenVirtualization(“localhost”);


        MountVHD(“F:\\Windows.vhd”);


    }


    static void OpenVirtualization(string ComputerName)


    {


        ManagementPath path = new ManagementPath();


        path.Server = mHostName;


        path.NamespacePath = @”root\virtualization”;


        path.ClassName = “Msvm_VirtualSystemManagementService”;


        ManagementClass vsManagementService = new ManagementClass(path);


        foreach (ManagementObject vs in vsManagementService.GetInstances())


        {


            mVirtualization = vs;


            break;


        }


        path.ClassName = “Msvm_ImageManagementService”;


        ManagementClass vhdSvc = new ManagementClass(path);


        foreach (ManagementObject vhdsvc in vhdSvc.GetInstances())


        {


            mVhdSvc = vhdsvc;


            break;


        }


    }


    static void WaitForWmiComplete(string Task, string ErrorDescription, uint Result)


    {


        if (Result != 0 && Result != 4096)


        {


            throw new ManagementException(ErrorDescription + ” Error=” + Result);


        }


        else if (Result == 4096)


        {


            VMTask task = new VMTask(new ManagementObject(Task));


            task.WaitForCompletion(-1);


            if (task.Status != VMTaskStatus.CompletedSuccessfully)


            {


                throw new ManagementException(


                ErrorDescription + ” Error Code: “ + task.ErrorCode + “.” +


                “Error Description: “ + task.ErrorDescription + “.”


                );


            }


        }


    }


    static void MountVHD(String VHDPath)


    {


        object[] arguments = new object[] { vhdPathInfo.FullName, null };


        uint result = 0;


        result = (uint)mVhdSvc.InvokeMethod(“Mount”, arguments);


        WaitForWmiComplete((string)arguments[1], “Failed to mount VHD”, result);


    }


}

Comments (5)

  1. Anonymous says:

    спасает команда diskpart

    а в ней:

    подключение:

    select vdisk file "d:file.vhdx"

    attach vdisk

    назначение буквы: list disk, определяем наш диск (предположим это диск 2)

    select disk 2

    assign letter=Z

    отключение:

    select vdisk file "d:file.vhdx"

    detach vdisk

  2. Alexandr Belov says:

    Привет.

    А как можно с помощью powershell изменять параметры "resource control" в hyper-v?

    Александр Белов.

  3. Белов Александр says:

    Прошлый комент можно проигнорить нашёл решщение.

    Другой Вопрос: Как узнать букву примонтированного VHD диска? для дальнейшего использования в скрипте.

  4. Anonymous says:

    Всем привет! Подскажите в какой кодировке смотреть страницы – везде вместо русского текста знаки вопросов.

  5. Не прошло и месяца. Поддержка блогов пофиксила проблемы с кодировкой.

Skip to main content