Getting server roles and features using WMI on Windows Server 2012 and 2012R2 using the MSFT_ServerManagerDeploymentTasks method GetServerComponentsAsync
I've recently been trying to understand what's happened to the Win32_ServerFeature which Microsoft appear to have ditched in Windows Server 2012.
What's happened seems indicative of Microsoft's current attitude towards half finished products and documentation so I'm going to try and help clarify what has happened.
Win32_ServerFeature is still available on Windows Server 2012 and R2 however new server features that have been added to the operating system will not appear in the results.
The replacement is the GetServerComponentsAsync() method of the MSFT_ServerManagerDeploymentTasks class
Unfortunately Microsoft haven't actually bothered to document any of these methods. More scarily they seem to have written incorrect documentation stating that parameters are Strings for example, when they clearly aren't.
I've put together a quick WMI call to get the Windows server roles and features using WMI on Windows Server 2012 and above.
A few caveats
1. This is quick coding... I will finalise this at some point.
2. The method is called async but I'm calling it synchronously. I'm not sure why you need to be forced to call the method async, it's not like it's going to be returning terrabytes of data. Also calling it async seems to product AccessDenied errors.
Please let me know if this helps. If you're looking at documenting your servers please take a look at XIA Configuration Server our Network Documentation Tool
/// <summary>
/// Represents the state of a request to the
Server Manager.
/// </summary>
enum ServerManagerRequestState
: byte
{
/// <summary>
/// The request is in
progress.
/// </summary>
InProgress = 0,
/// <summary>
/// The request has completed.
/// </summary>
Completed
= 1,
/// <summary>
/// The request has failed.
/// </summary>
Failed =
2,
}
/// <summary>
/// Represents the installation state of a
component (server role or feature).
/// </summary>
enum ServerManagerInstalledState
: byte
{
/// <summary>
/// The component is not
installed.
/// </summary>
NotInstalled = 0,
/// <summary>
/// The component is
installed.
/// </summary>
Installed
= 1,
/// <summary>
/// The component has been
installed but requires a reboot to complete.
/// </summary>
RebootRequired = 3,
}
/// <summary>
/// Queries the state of the Windows server
components.
/// </summary>
public void Query()
{
Query(Environment.MachineName);
}
/// <summary>
/// Queries the state of the Windows server
components.
/// </summary>
/// <param name="Machinename">The name of the
machine to query.</param>
public void Query(String Machinename)
{
ConnectionOptions Options = new ConnectionOptions();
ManagementScope Scope = new
ManagementScope(String.Format(@"\\{0}\root\Microsoft\Windows\ServerManager",
Machinename), Options);
ManagementClass Tasks = new
ManagementClass(Scope, new ManagementPath(@"MSFT_ServerManagerDeploymentTasks"), null);
ManagementClass RequestGuid = new ManagementClass(Scope,
new ManagementPath(@"MSFT_ServerManagerRequestGuid"), null);
RequestGuid.Properties["HighHalf"].Value
= 0;
RequestGuid.Properties["LowHalf"].Value
= 0;
ManagementBaseObject Parameters =
Tasks.GetMethodParameters("GetServerComponentsAsync");
Parameters["RequestGuid"] =
RequestGuid;
ManagementBaseObject Results = Tasks.InvokeMethod("GetServerComponentsAsync", Parameters, null);
ManagementBaseObject EnumerationState = (ManagementBaseObject)Results.Properties["EnumerationState"].Value;
ServerManagerRequestState RequestState = (ServerManagerRequestState)EnumerationState.Properties["RequestState"].Value;
if (RequestState != ServerManagerRequestState.Completed)
{ throw new InvalidOperationException(String.Format("Could not determine the installed server components
- state {0}.", RequestState)); }
ManagementBaseObject[] ServerComponents = (ManagementBaseObject[])Results.Properties["ServerComponents"].Value;
Log(ServerComponents.Length.ToString());
foreach (ManagementBaseObject
ServerComponent in ServerComponents)
{
String DisplayName = (String)ServerComponent.Properties["Displayname"].Value;
ServerManagerInstalledState Installed = (ServerManagerInstalledState)ServerComponent.Properties["Installed"].Value;
Log(DisplayName + " " +
Installed.ToString());
}
}
/// <summary>
/// Writes the specified message.
/// </summary>
/// <param name="Message">The message to log.</param>
private void Log(String Message)
{
textBox1.AppendText(Message + Environment.NewLine);
}
Comments
Post a Comment