2016-07-14 04:27:37 +02:00
|
|
|
/*============================================================================
|
|
|
|
* Copyright (C) Microsoft Corporation, All rights reserved.
|
|
|
|
*============================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
#region Using directives
|
|
|
|
|
|
|
|
using System;
|
|
|
|
using System.Collections;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Diagnostics;
|
|
|
|
using System.Globalization;
|
|
|
|
using System.Management.Automation;
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
namespace Microsoft.Management.Infrastructure.CimCmdlets
|
|
|
|
{
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Implements operations of invoke-cimmethod cmdlet.
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
internal sealed class CimInvokeCimMethod : CimAsyncOperation
|
|
|
|
{
|
|
|
|
/// <summary>
|
|
|
|
/// Containing all necessary information originated from
|
|
|
|
/// the parameters of <see cref="InvokeCimMethodCommand"/>
|
|
|
|
/// </summary>
|
|
|
|
internal class CimInvokeCimMethodContext : XOperationContextBase
|
|
|
|
{
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Constructor
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="theNamespace"></param>
|
|
|
|
/// <param name="theCollection"></param>
|
|
|
|
/// <param name="theProxy"></param>
|
|
|
|
internal CimInvokeCimMethodContext(string theNamespace,
|
|
|
|
string theMethodName,
|
|
|
|
CimMethodParametersCollection theCollection,
|
|
|
|
CimSessionProxy theProxy)
|
|
|
|
{
|
|
|
|
this.proxy = theProxy;
|
|
|
|
this.methodName = theMethodName;
|
|
|
|
this.collection = theCollection;
|
|
|
|
this.nameSpace = theNamespace;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
2016-08-26 22:46:03 +02:00
|
|
|
/// <para>namespace</para>
|
2016-07-14 04:27:37 +02:00
|
|
|
/// </summary>
|
|
|
|
internal string MethodName
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return this.methodName;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
private string methodName;
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>parameters collection</para>
|
|
|
|
/// </summary>
|
|
|
|
internal CimMethodParametersCollection ParametersCollection
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return this.collection;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
private CimMethodParametersCollection collection;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Constructor
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
public CimInvokeCimMethod()
|
|
|
|
: base()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Base on parametersetName to retrieve ciminstances
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="cmdlet"><see cref="GetCimInstanceCommand"/> object</param>
|
|
|
|
public void InvokeCimMethod(InvokeCimMethodCommand cmdlet)
|
|
|
|
{
|
|
|
|
IEnumerable<string> computerNames = ConstValue.GetComputerNames(cmdlet.ComputerName);
|
|
|
|
string nameSpace;
|
|
|
|
List<CimSessionProxy> proxys = new List<CimSessionProxy>();
|
|
|
|
string action = string.Format(CultureInfo.CurrentUICulture, actionTemplate, cmdlet.MethodName);
|
|
|
|
|
|
|
|
switch (cmdlet.ParameterSetName)
|
|
|
|
{
|
|
|
|
case CimBaseCommand.CimInstanceComputerSet:
|
|
|
|
foreach (string computerName in computerNames)
|
|
|
|
{
|
|
|
|
proxys.Add(CreateSessionProxy(computerName, cmdlet.CimInstance, cmdlet));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CimBaseCommand.ClassNameComputerSet:
|
|
|
|
case CimBaseCommand.CimClassComputerSet:
|
|
|
|
case CimBaseCommand.ResourceUriComputerSet:
|
|
|
|
case CimBaseCommand.QueryComputerSet:
|
|
|
|
foreach (string computerName in computerNames)
|
|
|
|
{
|
|
|
|
proxys.Add(CreateSessionProxy(computerName, cmdlet));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CimBaseCommand.ClassNameSessionSet:
|
|
|
|
case CimBaseCommand.CimClassSessionSet:
|
|
|
|
case CimBaseCommand.QuerySessionSet:
|
|
|
|
case CimBaseCommand.CimInstanceSessionSet:
|
|
|
|
case CimBaseCommand.ResourceUriSessionSet:
|
|
|
|
foreach (CimSession session in cmdlet.CimSession)
|
|
|
|
{
|
|
|
|
CimSessionProxy proxy = CreateSessionProxy(session, cmdlet);
|
|
|
|
proxys.Add(proxy);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
CimMethodParametersCollection paramsCollection =
|
|
|
|
CreateParametersCollection(cmdlet.Arguments, cmdlet.CimClass, cmdlet.CimInstance, cmdlet.MethodName);
|
|
|
|
|
|
|
|
// Invoke methods
|
|
|
|
switch (cmdlet.ParameterSetName)
|
|
|
|
{
|
|
|
|
case CimBaseCommand.ClassNameComputerSet:
|
|
|
|
case CimBaseCommand.ClassNameSessionSet:
|
|
|
|
case CimBaseCommand.ResourceUriSessionSet:
|
|
|
|
case CimBaseCommand.ResourceUriComputerSet:
|
|
|
|
{
|
|
|
|
string target = string.Format(CultureInfo.CurrentUICulture, targetClass, cmdlet.ClassName);
|
|
|
|
if(cmdlet.ResourceUri != null )
|
|
|
|
{
|
|
|
|
nameSpace = cmdlet.Namespace;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nameSpace = ConstValue.GetNamespace(cmdlet.Namespace);
|
|
|
|
}
|
|
|
|
foreach (CimSessionProxy proxy in proxys)
|
|
|
|
{
|
|
|
|
if (!cmdlet.ShouldProcess(target, action))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
proxy.InvokeMethodAsync(
|
|
|
|
nameSpace,
|
|
|
|
cmdlet.ClassName,
|
|
|
|
cmdlet.MethodName,
|
|
|
|
paramsCollection);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CimBaseCommand.CimClassComputerSet:
|
|
|
|
case CimBaseCommand.CimClassSessionSet:
|
|
|
|
{
|
|
|
|
string target = string.Format(CultureInfo.CurrentUICulture, targetClass, cmdlet.CimClass.CimSystemProperties.ClassName);
|
|
|
|
nameSpace = ConstValue.GetNamespace(cmdlet.CimClass.CimSystemProperties.Namespace);
|
|
|
|
foreach (CimSessionProxy proxy in proxys)
|
|
|
|
{
|
|
|
|
if (!cmdlet.ShouldProcess(target, action))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
proxy.InvokeMethodAsync(
|
|
|
|
nameSpace,
|
|
|
|
cmdlet.CimClass.CimSystemProperties.ClassName,
|
|
|
|
cmdlet.MethodName,
|
|
|
|
paramsCollection);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CimBaseCommand.QueryComputerSet:
|
|
|
|
case CimBaseCommand.QuerySessionSet:
|
|
|
|
nameSpace = ConstValue.GetNamespace(cmdlet.Namespace);
|
|
|
|
foreach (CimSessionProxy proxy in proxys)
|
|
|
|
{
|
|
|
|
// create context object
|
|
|
|
CimInvokeCimMethodContext context = new CimInvokeCimMethodContext(
|
|
|
|
nameSpace,
|
|
|
|
cmdlet.MethodName,
|
|
|
|
paramsCollection,
|
|
|
|
proxy);
|
|
|
|
proxy.ContextObject = context;
|
|
|
|
// firstly query instance and then invoke method upon returned instances
|
|
|
|
proxy.QueryInstancesAsync(nameSpace, ConstValue.GetQueryDialectWithDefault(cmdlet.QueryDialect), cmdlet.Query);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CimBaseCommand.CimInstanceComputerSet:
|
|
|
|
case CimBaseCommand.CimInstanceSessionSet:
|
|
|
|
{
|
|
|
|
string target = cmdlet.CimInstance.ToString();
|
|
|
|
if(cmdlet.ResourceUri != null )
|
|
|
|
{
|
|
|
|
nameSpace = cmdlet.Namespace;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nameSpace = ConstValue.GetNamespace(cmdlet.CimInstance.CimSystemProperties.Namespace);
|
|
|
|
}
|
|
|
|
foreach (CimSessionProxy proxy in proxys)
|
|
|
|
{
|
|
|
|
if (!cmdlet.ShouldProcess(target, action))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
proxy.InvokeMethodAsync(
|
|
|
|
nameSpace,
|
|
|
|
cmdlet.CimInstance,
|
|
|
|
cmdlet.MethodName,
|
|
|
|
paramsCollection);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Invoke cimmethod on given <see cref="CimInstance"/>
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="cimInstance"></param>
|
|
|
|
public void InvokeCimMethodOnCimInstance(CimInstance cimInstance, XOperationContextBase context, CmdletOperationBase operation)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx();
|
|
|
|
CimInvokeCimMethodContext cimInvokeCimMethodContext = context as CimInvokeCimMethodContext;
|
|
|
|
Debug.Assert(cimInvokeCimMethodContext != null, "CimInvokeCimMethod::InvokeCimMethodOnCimInstance should has CimInvokeCimMethodContext != NULL.");
|
|
|
|
|
|
|
|
string action = string.Format(CultureInfo.CurrentUICulture, actionTemplate, cimInvokeCimMethodContext.MethodName);
|
|
|
|
if (!operation.ShouldProcess(cimInstance.ToString(), action))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
CimSessionProxy proxy = CreateCimSessionProxy(cimInvokeCimMethodContext.Proxy);
|
|
|
|
proxy.InvokeMethodAsync(
|
|
|
|
cimInvokeCimMethodContext.Namespace,
|
|
|
|
cimInstance,
|
|
|
|
cimInvokeCimMethodContext.MethodName,
|
|
|
|
cimInvokeCimMethodContext.ParametersCollection);
|
|
|
|
}
|
|
|
|
|
|
|
|
#region private methods
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Set <see cref="CimSessionProxy"/> properties
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="proxy"></param>
|
|
|
|
/// <param name="cmdlet"></param>
|
|
|
|
private void SetSessionProxyProperties(
|
|
|
|
ref CimSessionProxy proxy,
|
|
|
|
InvokeCimMethodCommand cmdlet)
|
|
|
|
{
|
|
|
|
proxy.OperationTimeout = cmdlet.OperationTimeoutSec;
|
|
|
|
if(cmdlet.ResourceUri != null )
|
|
|
|
{
|
|
|
|
proxy.ResourceUri = cmdlet.ResourceUri;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Create <see cref="CimSessionProxy"/> and set properties
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="computerName"></param>
|
|
|
|
/// <param name="cmdlet"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
private CimSessionProxy CreateSessionProxy(
|
|
|
|
string computerName,
|
|
|
|
InvokeCimMethodCommand cmdlet)
|
|
|
|
{
|
|
|
|
CimSessionProxy proxy = CreateCimSessionProxy(computerName);
|
|
|
|
SetSessionProxyProperties(ref proxy, cmdlet);
|
|
|
|
return proxy;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Create <see cref="CimSessionProxy"/> and set properties
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="computerName"></param>
|
|
|
|
/// <param name="cimInstance"></param>
|
|
|
|
/// <param name="cmdlet"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
private CimSessionProxy CreateSessionProxy(
|
|
|
|
string computerName,
|
|
|
|
CimInstance cimInstance,
|
|
|
|
InvokeCimMethodCommand cmdlet)
|
|
|
|
{
|
|
|
|
CimSessionProxy proxy = CreateCimSessionProxy(computerName, cimInstance);
|
|
|
|
SetSessionProxyProperties(ref proxy, cmdlet);
|
|
|
|
return proxy;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Create <see cref="CimSessionProxy"/> and set properties
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="session"></param>
|
|
|
|
/// <param name="cmdlet"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
private CimSessionProxy CreateSessionProxy(
|
|
|
|
CimSession session,
|
|
|
|
InvokeCimMethodCommand cmdlet)
|
|
|
|
{
|
|
|
|
CimSessionProxy proxy = CreateCimSessionProxy(session);
|
|
|
|
SetSessionProxyProperties(ref proxy, cmdlet);
|
|
|
|
return proxy;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <para>
|
|
|
|
/// Create <see cref="CimMethodParametersCollection"/> with given key properties.
|
|
|
|
/// And/or <see cref="CimClass"/> object.
|
|
|
|
/// </para>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="parameters"></param>
|
|
|
|
/// <param name="cimClass"></param>
|
|
|
|
/// <param name="cimInstance"></param>
|
|
|
|
/// <param name="methodName"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
/// <exception cref="ArgumentNullException">See CimProperty.Create</exception>
|
|
|
|
/// <exception cref="ArgumentException">CimProperty.Create</exception>
|
|
|
|
private CimMethodParametersCollection CreateParametersCollection(
|
|
|
|
IDictionary parameters,
|
|
|
|
CimClass cimClass,
|
|
|
|
CimInstance cimInstance,
|
|
|
|
string methodName)
|
|
|
|
{
|
|
|
|
DebugHelper.WriteLogEx();
|
|
|
|
|
|
|
|
CimMethodParametersCollection collection = null;
|
|
|
|
if (parameters == null)
|
|
|
|
{
|
|
|
|
return collection;
|
|
|
|
}
|
|
|
|
else if (parameters.Count == 0)
|
|
|
|
{
|
|
|
|
return collection;
|
|
|
|
}
|
|
|
|
|
|
|
|
collection = new CimMethodParametersCollection();
|
|
|
|
IDictionaryEnumerator enumerator = parameters.GetEnumerator();
|
|
|
|
while (enumerator.MoveNext())
|
|
|
|
{
|
|
|
|
string parameterName = enumerator.Key.ToString();
|
|
|
|
|
|
|
|
CimFlags parameterFlags = CimFlags.In;
|
|
|
|
object parameterValue = GetBaseObject(enumerator.Value);
|
|
|
|
|
|
|
|
DebugHelper.WriteLog(@"Create parameter name= {0}, value= {1}, flags= {2}.", 4,
|
|
|
|
parameterName,
|
|
|
|
parameterValue,
|
|
|
|
parameterFlags);
|
|
|
|
|
|
|
|
CimMethodParameter parameter = null;
|
|
|
|
CimMethodDeclaration declaration = null;
|
|
|
|
string className = null;
|
|
|
|
if (cimClass != null)
|
|
|
|
{
|
|
|
|
className = cimClass.CimSystemProperties.ClassName;
|
|
|
|
declaration = cimClass.CimClassMethods[methodName];
|
|
|
|
if (declaration == null)
|
|
|
|
{
|
|
|
|
throw new ArgumentException(String.Format(
|
|
|
|
CultureInfo.CurrentUICulture, Strings.InvalidMethod, methodName, className));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (cimInstance != null)
|
|
|
|
{
|
|
|
|
className = cimInstance.CimClass.CimSystemProperties.ClassName;
|
|
|
|
declaration = cimInstance.CimClass.CimClassMethods[methodName];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (declaration != null)
|
|
|
|
{
|
|
|
|
CimMethodParameterDeclaration paramDeclaration = declaration.Parameters[parameterName];
|
|
|
|
if (paramDeclaration == null)
|
|
|
|
{
|
|
|
|
throw new ArgumentException(String.Format(
|
|
|
|
CultureInfo.CurrentUICulture, Strings.InvalidMethodParameter, parameterName, methodName, className));
|
|
|
|
}
|
|
|
|
parameter = CimMethodParameter.Create(
|
|
|
|
parameterName,
|
|
|
|
parameterValue,
|
|
|
|
paramDeclaration.CimType,
|
|
|
|
parameterFlags);
|
|
|
|
// FIXME: check in/out qualifier
|
|
|
|
// parameterFlags = paramDeclaration.Qualifiers;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (parameterValue == null)
|
|
|
|
{
|
|
|
|
// try the best to get the type while value is null
|
|
|
|
parameter = CimMethodParameter.Create(
|
|
|
|
parameterName,
|
|
|
|
parameterValue,
|
|
|
|
CimType.String,
|
|
|
|
parameterFlags);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CimType referenceType = CimType.Unknown;
|
|
|
|
object referenceObject = GetReferenceOrReferenceArrayObject(parameterValue, ref referenceType);
|
|
|
|
if (referenceObject != null)
|
|
|
|
{
|
|
|
|
parameter = CimMethodParameter.Create(
|
|
|
|
parameterName,
|
|
|
|
referenceObject,
|
|
|
|
referenceType,
|
|
|
|
parameterFlags);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
parameter = CimMethodParameter.Create(
|
|
|
|
parameterName,
|
|
|
|
parameterValue,
|
|
|
|
parameterFlags);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (parameter != null)
|
|
|
|
collection.Add(parameter);
|
|
|
|
}
|
|
|
|
return collection;
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region const strings
|
|
|
|
/// <summary>
|
|
|
|
/// operation target
|
|
|
|
/// </summary>
|
|
|
|
private const string targetClass = @"{0}";
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// action
|
|
|
|
/// </summary>
|
|
|
|
private const string actionTemplate = @"Invoke-CimMethod: {0}";
|
|
|
|
#endregion
|
|
|
|
}//End Class
|
|
|
|
}//End namespace
|