// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft. All rights reserved.
namespace Microsoft.Samples.HyperV.ResourcePools
{
using System;
using System.Collections;
using System.Globalization;
using System.Management;
using Microsoft.Samples.HyperV.Common;
///
/// Utilities to allow access to the Msvm_ResourcePoolConfigurationService service,
/// which allow for the creation, modication, and deletion of resource pools.
/// For the ModifyPoolResource, ModifyPoolSettings, and DeletePool methods, there are
/// three ways that a resource pool can be referenced: by WMI reference path,
/// by a resource pool managment object (MOB), and by resource type and pool ID.
///
static class MsvmResourcePoolConfigurationService
{
///
/// Returns the Msvm_ResourcePoolConfigurationService MOB.
///
/// The ManagementScope to use to connect to WMI.
/// The resource pool configuration service MOB.
internal static ManagementObject
GetResourcePoolConfigurationService(
ManagementScope scope)
{
using (ManagementClass resourcePoolConfigurationServiceClass =
new ManagementClass("Msvm_ResourcePoolConfigurationService"))
{
resourcePoolConfigurationServiceClass.Scope = scope;
//
// Msvm_ResourcePoolConfigurationService is a singleton object.
//
ManagementObject resourcePoolConfigurationService =
WmiUtilities.GetFirstObjectFromCollection(
resourcePoolConfigurationServiceClass.GetInstances());
return resourcePoolConfigurationService;
}
}
///
/// Creates a resource pool and returns its associated CIM_ResourcePool MOB.
///
/// The ManagementScope to use to connect to WMI.
/// service management object.
/// The resource pool configuration.
/// The resource type to assign.
/// The resource subtype to assign.
/// The pool ID to assign.
/// The pool name to assign.
/// An array of strings that specify the parent
/// pool IDs.
/// An array of string arrays that represent the host
/// resources.
/// A Msvm_ResourcePool object.
internal static ManagementObject
CreatePoolHelper(
ManagementScope scope,
ManagementObject rPConfigurationService,
string resourceType,
string resourceSubType,
string childPoolId,
string childPoolName,
string[] parentPoolIdArray,
string[][] parentHostResourcesArray)
{
if (parentPoolIdArray.Length == 0)
{
throw new ManagementException(string.Format(
CultureInfo.CurrentCulture,
@"At least one parent pool must be specified when creating a
child resource pool (PoolId ""{0}"")", childPoolId));
}
if (parentPoolIdArray.Length != parentHostResourcesArray.Length)
{
throw new ManagementException(string.Format(
CultureInfo.CurrentCulture,
@"When creating a child resource pool, a host resource must be
specified for each parent pool. Shared allocations are not
supported (PoolId ""{0}"")", childPoolId));
}
string resourcePoolSettingData =
MsvmResourcePoolSettingData.GetSettingsForPool(
scope,
resourceType,
resourceSubType,
childPoolId,
childPoolName);
string[] parentPoolPathArray =
ResourcePoolUtilities.GetParentPoolArrayFromPoolIds(
scope,
resourceType,
resourceSubType,
parentPoolIdArray);
string[] resourceAllocationSettingDataArray =
MsvmResourceAllocationSettingData.GetNewPoolAllocationSettingsArray(
scope,
resourceType,
resourceSubType,
parentPoolIdArray,
parentHostResourcesArray);
using (ManagementBaseObject inParams =
rPConfigurationService.GetMethodParameters(
"CreatePool"))
{
inParams["PoolSettings"] = resourcePoolSettingData;
inParams["ParentPools"] = parentPoolPathArray;
inParams["AllocationSettings"] = resourceAllocationSettingDataArray;
using (ManagementBaseObject outParams =
rPConfigurationService.InvokeMethod(
"CreatePool",
inParams,
null))
{
if (WmiUtilities.ValidateOutput(outParams, scope, true, true))
{
string poolPath = outParams["Pool"].ToString();
return new ManagementObject(
scope,
new ManagementPath(poolPath),
null);
}
else
{
return null;
}
}
}
}
///
/// Creates a resource pool.
///
/// The display name of the resource type.
/// The pool ID to assign.
/// The pool name to assign.
/// A delimited string that specifies the parent
/// pool IDs.
/// A delimited string that represents the host
/// resources for each parent pool.
internal static void
CreatePool(
string resourceDisplayName,
string childPoolId,
string childPoolName,
string parentPoolIdsString,
string parentHostResourcesString)
{
Console.WriteLine(
"Creating a resource pool:\n" +
"\tPool Id: " + childPoolId +
"\n\tPool Name: " + childPoolName);
ResourceUtilities.DisplayResourceInformation(
resourceDisplayName);
ResourcePoolUtilities.DisplayPoolIdAndHostResources(
parentPoolIdsString,
parentHostResourcesString);
string[] poolDelimter = { "[p]" };
//
// Pool IDs are delimted by "[p], e.g.
// "[p]Child Pool A[p][p]Child Pool B[p]"
//
string[] parentPoolIdArray = ResourcePoolUtilities.GetOneDimensionalArray(
parentPoolIdsString,
poolDelimter);
string[] hostResourceDelimter = { "[h]" };
//
// Parent pool host resources are specified by a 2-D array. Each pool is delimited
// by a "[p]"; Each host resource is delimited by a "[h]". For example,
// "[p][h]Child A, Resource 1[h][h]Child A, Resource 2[h][p][p][h]Child B, Resource 1[h][p]"
//
string[][] parentHostResourcesArray = ResourcePoolUtilities.GetTwoDimensionalArray(
parentHostResourcesString,
poolDelimter,
hostResourceDelimter);
ManagementScope scope = ResourcePoolUtilities.GetManagementScope();
using (ManagementObject rPConfigurationService =
MsvmResourcePoolConfigurationService.GetResourcePoolConfigurationService(
scope))
{
CreatePoolHelper(
scope,
rPConfigurationService,
ResourceUtilities.GetResourceType(resourceDisplayName),
ResourceUtilities.GetResourceSubType(resourceDisplayName),
childPoolId,
childPoolName,
parentPoolIdArray,
parentHostResourcesArray);
}
}
///
/// Modifies the host resources assigned to a resource pool.
///
/// The ManagementScope to use to connect to WMI.
/// service management object.
/// The resource pool configuration
/// The resource type to assign.
/// The resource subtype to assign.
/// The reference path to a resource pool.
/// An array of strings that specify the parent
/// pool IDs.
/// An array of string arrays that represent the host
/// resources
internal static void
ModifyPoolResourcesByPath(
ManagementScope scope,
ManagementObject rPConfigurationService,
string resourceType,
string resourceSubType,
string poolPath,
string[] parentPoolIdArray,
string[][] parentHostResourcesArray)
{
if (parentPoolIdArray.Length == 0)
{
throw new ManagementException(string.Format(
CultureInfo.CurrentCulture,
@"At least one parent pool must be specified when modifying a
resource pool's host resources (poolPath ""{0}"")", poolPath));
}
if (parentPoolIdArray.Length != parentHostResourcesArray.Length)
{
throw new ManagementException(string.Format(
CultureInfo.CurrentCulture,
@"When modifying a child resource pool's host resources, a host
resource must be specified for each parent pool. Shared allocations
are not supported (poolPath ""{0}"")",
poolPath));
}
string[] parentPoolPathArray =
ResourcePoolUtilities.GetParentPoolArrayFromPoolIds(
scope,
resourceType,
resourceSubType,
parentPoolIdArray);
string[] resourceAllocationSettingDataArray =
MsvmResourceAllocationSettingData.GetNewPoolAllocationSettingsArray(
scope,
resourceType,
resourceSubType,
parentPoolIdArray,
parentHostResourcesArray);
using (ManagementBaseObject inParams =
rPConfigurationService.GetMethodParameters(
"ModifyPoolResources"))
{
inParams["ChildPool"] = poolPath;
inParams["ParentPools"] = parentPoolPathArray;
inParams["AllocationSettings"] = resourceAllocationSettingDataArray;
using (ManagementBaseObject outParams =
rPConfigurationService.InvokeMethod(
"ModifyPoolResources",
inParams,
null))
{
WmiUtilities.ValidateOutput(outParams, scope, true, true);
}
}
}
///
/// Modifies the host resources assigned to a resource pool.
///
/// The ManagementScope to use to connect to WMI.
/// service management object.
/// The resource pool configuration
/// The resource type to assign.
/// The resource subtype to assign.
/// The pool ID of a resource pool.
/// An array of strings that specify the parent
/// pool IDs.
/// An array of string arrays that represent the host
/// resources
internal static void
ModifyPoolResourcesHelper(
ManagementScope scope,
ManagementObject rPConfigurationService,
string resourceType,
string resourceSubType,
string poolId,
string[] parentPoolIdArray,
string[][] parentHostResourcesArray)
{
string poolPath =
MsvmResourcePool.GetResourcePoolPath(
scope,
resourceType,
resourceSubType,
poolId);
ModifyPoolResourcesByPath(
scope,
rPConfigurationService,
resourceType,
resourceSubType,
poolPath,
parentPoolIdArray,
parentHostResourcesArray);
}
///
/// Modifies the host resources assigned to a resource pool.
///
/// The display name of the resource type.
/// The pool ID of the pool to modify.
/// A delimited string that specifies the parent
/// pool IDs.
/// A delimited string that represents the host
/// resources for each parent pool.
internal static void
ModifyPoolResources(
string resourceDisplayName,
string poolId,
string parentPoolIdsString,
string parentHostResourcesString)
{
Console.WriteLine(
"Modifying a resource pool's host resources:\n" +
"\tPool ID: " + poolId);
ResourceUtilities.DisplayResourceInformation(
resourceDisplayName);
ResourcePoolUtilities.DisplayPoolIdAndHostResources(
parentPoolIdsString,
parentHostResourcesString);
string[] poolDelimiter = { "[p]" };
string[] hostResourceDelimter = { "[h]" };
string[] parentPoolIdArray = ResourcePoolUtilities.GetOneDimensionalArray(
parentPoolIdsString,
poolDelimiter);
string[][] parentHostResourcesArray = ResourcePoolUtilities.GetTwoDimensionalArray(
parentHostResourcesString,
poolDelimiter,
hostResourceDelimter);
ManagementScope scope = ResourcePoolUtilities.GetManagementScope();
using (ManagementObject rPConfigurationService =
MsvmResourcePoolConfigurationService.GetResourcePoolConfigurationService(
scope))
{
ModifyPoolResourcesHelper(
scope,
rPConfigurationService,
ResourceUtilities.GetResourceType(resourceDisplayName),
ResourceUtilities.GetResourceSubType(resourceDisplayName),
poolId,
parentPoolIdArray,
parentHostResourcesArray);
}
}
///
/// Modifies the resource pool's settings.
///
/// The ManagementScope to use to connect to WMI.
/// service management object.
/// The resource pool configuration
/// The reference path to a resource pool.
/// An embedded instance string of a
/// Msvm_ResourcePoolSettingData object.
/// A Msvm_ResourcePool object.
internal static void
ModifyPoolSettingsByPath(
ManagementScope scope,
ManagementObject rPConfigurationService,
string poolPath,
string resourcePoolSettingData)
{
using (ManagementBaseObject inParams =
rPConfigurationService.GetMethodParameters(
"ModifyPoolSettings"))
{
inParams["ChildPool"] = poolPath;
inParams["PoolSettings"] = resourcePoolSettingData;
using (ManagementBaseObject outParams =
rPConfigurationService.InvokeMethod(
"ModifyPoolSettings",
inParams,
null))
{
WmiUtilities.ValidateOutput(outParams, scope, true, true);
}
}
}
///
/// Modifies the resource pool's settings.
///
/// The ManagementScope to use to connect to WMI.
/// service management object.
/// The resource pool configuration
/// The resource type to assign.
/// The resource subtype to assign.
/// The pool ID of a resource pool.
/// An embedded instance string of a
/// Msvm_ResourcePoolSettingData object.
/// A Msvm_ResourcePool object.
internal static void
ModifyPoolSettingsHelper(
ManagementScope scope,
ManagementObject rPConfigurationService,
string resourceType,
string resourceSubType,
string poolId,
string resourcePoolSettingData)
{
string poolPath =
MsvmResourcePool.GetResourcePoolPath(
scope,
resourceType,
resourceSubType,
poolId);
ModifyPoolSettingsByPath(
scope,
rPConfigurationService,
poolPath,
resourcePoolSettingData);
}
///
/// Modifies the resource pool's settings.
///
/// The display name of the resource type.
/// The pool ID of a resource pool.
/// The new pool ID of the resource pool.
/// The new pool Name of the resource pool.
internal static void
ModifyPoolSettings(
string resourceDisplayName,
string poolId,
string newPoolId,
string newPoolName)
{
Console.WriteLine(
"Modifying a resource pool's settings:\n" +
"\tPool ID: " + poolId + " (change to " + newPoolId + ")\n" +
"\tPool Name: (change to " + newPoolName + ")");
ResourceUtilities.DisplayResourceInformation(
resourceDisplayName);
ManagementScope scope = ResourcePoolUtilities.GetManagementScope();
using (ManagementObject rPConfigurationService =
MsvmResourcePoolConfigurationService.GetResourcePoolConfigurationService(
scope))
{
string resourcePoolSettingData =
MsvmResourcePoolSettingData.GetSettingsForPool(
scope,
ResourceUtilities.GetResourceType(resourceDisplayName),
ResourceUtilities.GetResourceSubType(resourceDisplayName),
newPoolId,
newPoolName);
ModifyPoolSettingsHelper(
scope,
rPConfigurationService,
ResourceUtilities.GetResourceType(resourceDisplayName),
ResourceUtilities.GetResourceSubType(resourceDisplayName),
poolId,
resourcePoolSettingData);
}
}
///
/// Delete a resource pool.
///
/// The ManagementScope to use to connect to WMI.
/// service management object.
/// The resource pool configuration.
/// The resource type to assign.
/// The resource subtype to assign.
/// The pool ID to assign.
internal static void
DeletePoolHelper(
ManagementScope scope,
ManagementObject rPConfigurationService,
string resourceType,
string resourceSubType,
string poolId)
{
string poolPath =
MsvmResourcePool.GetResourcePoolPath(
scope,
resourceType,
resourceSubType,
poolId);
using (ManagementBaseObject inParams =
rPConfigurationService.GetMethodParameters(
"DeletePool"))
{
inParams["Pool"] = poolPath;
using (ManagementBaseObject outParams =
rPConfigurationService.InvokeMethod(
"DeletePool",
inParams,
null))
{
WmiUtilities.ValidateOutput(outParams, scope, true, true);
}
}
}
///
/// Delete a resource pool.
///
/// The display name of the resource type to assign.
/// The pool ID to assign.
internal static void
DeletePool(
string resourceDisplayName,
string poolId)
{
Console.WriteLine(
"Deleting a resource pool:\n" +
"\tPool Id: " + poolId);
ResourceUtilities.DisplayResourceInformation(
resourceDisplayName);
ManagementScope scope = ResourcePoolUtilities.GetManagementScope();
using (ManagementObject rPConfigurationService =
MsvmResourcePoolConfigurationService.GetResourcePoolConfigurationService(
scope))
{
DeletePoolHelper(
scope,
rPConfigurationService,
ResourceUtilities.GetResourceType(resourceDisplayName),
ResourceUtilities.GetResourceSubType(resourceDisplayName),
poolId);
}
}
}
}