// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #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 { /// /// /// Implements operations of invoke-cimmethod cmdlet. /// /// internal sealed class CimInvokeCimMethod : CimAsyncOperation { /// /// Containing all necessary information originated from /// the parameters of /// internal class CimInvokeCimMethodContext : XOperationContextBase { /// /// /// Constructor /// /// /// /// /// internal CimInvokeCimMethodContext(string theNamespace, string theMethodName, CimMethodParametersCollection theCollection, CimSessionProxy theProxy) { this.proxy = theProxy; this.methodName = theMethodName; this.collection = theCollection; this.nameSpace = theNamespace; } /// /// namespace /// internal string MethodName { get { return this.methodName; } } private string methodName; /// /// parameters collection /// internal CimMethodParametersCollection ParametersCollection { get { return this.collection; } } private CimMethodParametersCollection collection; } /// /// /// Constructor /// /// public CimInvokeCimMethod() : base() { } /// /// /// Base on parametersetName to retrieve ciminstances /// /// /// object. public void InvokeCimMethod(InvokeCimMethodCommand cmdlet) { IEnumerable computerNames = ConstValue.GetComputerNames(cmdlet.ComputerName); string nameSpace; List proxys = new List(); 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; } } /// /// /// Invoke cimmethod on given /// /// /// 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 /// /// /// Set properties /// /// /// /// private void SetSessionProxyProperties( ref CimSessionProxy proxy, InvokeCimMethodCommand cmdlet) { proxy.OperationTimeout = cmdlet.OperationTimeoutSec; if (cmdlet.ResourceUri != null) { proxy.ResourceUri = cmdlet.ResourceUri; } } /// /// /// Create and set properties /// /// /// /// /// private CimSessionProxy CreateSessionProxy( string computerName, InvokeCimMethodCommand cmdlet) { CimSessionProxy proxy = CreateCimSessionProxy(computerName); SetSessionProxyProperties(ref proxy, cmdlet); return proxy; } /// /// /// Create and set properties /// /// /// /// /// /// private CimSessionProxy CreateSessionProxy( string computerName, CimInstance cimInstance, InvokeCimMethodCommand cmdlet) { CimSessionProxy proxy = CreateCimSessionProxy(computerName, cimInstance); SetSessionProxyProperties(ref proxy, cmdlet); return proxy; } /// /// Create and set properties. /// /// /// /// private CimSessionProxy CreateSessionProxy( CimSession session, InvokeCimMethodCommand cmdlet) { CimSessionProxy proxy = CreateCimSessionProxy(session); SetSessionProxyProperties(ref proxy, cmdlet); return proxy; } /// /// /// Create with given key properties. /// And/or object. /// /// /// /// /// /// /// /// See CimProperty.Create. /// CimProperty.Create. 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 /// /// Operation target. /// private const string targetClass = @"{0}"; /// /// Action. /// private const string actionTemplate = @"Invoke-CimMethod: {0}"; #endregion } }