MegaBites-AI/Windows-powershell
0372
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4#region Using directives5 6using System;7using System.Collections;8using System.Collections.Generic;9using System.Diagnostics;10using System.Globalization;11 12#endregion13 14namespace Microsoft.Management.Infrastructure.CimCmdlets15{16 /// <summary>17 /// <para>18 /// Implements operations of invoke-cimmethod cmdlet.19 /// </para>20 /// </summary>21 internal sealed class CimInvokeCimMethod : CimAsyncOperation22 {23 /// <summary>24 /// Containing all necessary information originated from25 /// the parameters of <see cref="InvokeCimMethodCommand"/>26 /// </summary>27 internal class CimInvokeCimMethodContext : XOperationContextBase28 {29 /// <summary>30 /// Initializes a new instance of the <see cref="CimInvokeCimMethodContext"/> class.31 /// </summary>32 /// <param name="theNamespace"></param>33 /// <param name="theCollection"></param>34 /// <param name="theProxy"></param>35 internal CimInvokeCimMethodContext(string theNamespace,36 string theMethodName,37 CimMethodParametersCollection theCollection,38 CimSessionProxy theProxy)39 {40 this.proxy = theProxy;41 this.MethodName = theMethodName;42 this.ParametersCollection = theCollection;43 this.nameSpace = theNamespace;44 }45 46 /// <summary>47 /// <para>namespace</para>48 /// </summary>49 internal string MethodName { get; }50 51 /// <summary>52 /// <para>parameters collection</para>53 /// </summary>54 internal CimMethodParametersCollection ParametersCollection { get; }55 }56 57 /// <summary>58 /// Initializes a new instance of the <see cref="CimInvokeCimMethod"/> class.59 /// </summary>60 public CimInvokeCimMethod()61 : base()62 {63 }64 65 /// <summary>66 /// <para>67 /// Base on parametersetName to retrieve ciminstances68 /// </para>69 /// </summary>70 /// <param name="cmdlet"><see cref="GetCimInstanceCommand"/> object.</param>71 public void InvokeCimMethod(InvokeCimMethodCommand cmdlet)72 {73 IEnumerable<string> computerNames = ConstValue.GetComputerNames(cmdlet.ComputerName);74 string nameSpace;75 List<CimSessionProxy> proxys = new();76 string action = string.Format(CultureInfo.CurrentUICulture, actionTemplate, cmdlet.MethodName);77 78 switch (cmdlet.ParameterSetName)79 {80 case CimBaseCommand.CimInstanceComputerSet:81 foreach (string computerName in computerNames)82 {83 proxys.Add(CreateSessionProxy(computerName, cmdlet.CimInstance, cmdlet));84 }85 86 break;87 case CimBaseCommand.ClassNameComputerSet:88 case CimBaseCommand.CimClassComputerSet:89 case CimBaseCommand.ResourceUriComputerSet:90 case CimBaseCommand.QueryComputerSet:91 foreach (string computerName in computerNames)92 {93 proxys.Add(CreateSessionProxy(computerName, cmdlet));94 }95 96 break;97 case CimBaseCommand.ClassNameSessionSet:98 case CimBaseCommand.CimClassSessionSet:99 case CimBaseCommand.QuerySessionSet:100 case CimBaseCommand.CimInstanceSessionSet:101 case CimBaseCommand.ResourceUriSessionSet:102 foreach (CimSession session in cmdlet.CimSession)103 {104 CimSessionProxy proxy = CreateSessionProxy(session, cmdlet);105 proxys.Add(proxy);106 }107 108 break;109 default:110 break;111 }112 113 CimMethodParametersCollection paramsCollection =114 CreateParametersCollection(cmdlet.Arguments, cmdlet.CimClass, cmdlet.CimInstance, cmdlet.MethodName);115 116 // Invoke methods117 switch (cmdlet.ParameterSetName)118 {119 case CimBaseCommand.ClassNameComputerSet:120 case CimBaseCommand.ClassNameSessionSet:121 case CimBaseCommand.ResourceUriSessionSet:122 case CimBaseCommand.ResourceUriComputerSet:123 {124 string target = string.Format(CultureInfo.CurrentUICulture, targetClass, cmdlet.ClassName);125 if (cmdlet.ResourceUri != null)126 {127 nameSpace = cmdlet.Namespace;128 }129 else130 {131 nameSpace = ConstValue.GetNamespace(cmdlet.Namespace);132 }133 134 foreach (CimSessionProxy proxy in proxys)135 {136 if (!cmdlet.ShouldProcess(target, action))137 {138 return;139 }140 141 proxy.InvokeMethodAsync(142 nameSpace,143 cmdlet.ClassName,144 cmdlet.MethodName,145 paramsCollection);146 }147 }148 149 break;150 case CimBaseCommand.CimClassComputerSet:151 case CimBaseCommand.CimClassSessionSet:152 {153 string target = string.Format(CultureInfo.CurrentUICulture, targetClass, cmdlet.CimClass.CimSystemProperties.ClassName);154 nameSpace = ConstValue.GetNamespace(cmdlet.CimClass.CimSystemProperties.Namespace);155 foreach (CimSessionProxy proxy in proxys)156 {157 if (!cmdlet.ShouldProcess(target, action))158 {159 return;160 }161 162 proxy.InvokeMethodAsync(163 nameSpace,164 cmdlet.CimClass.CimSystemProperties.ClassName,165 cmdlet.MethodName,166 paramsCollection);167 }168 }169 170 break;171 case CimBaseCommand.QueryComputerSet:172 case CimBaseCommand.QuerySessionSet:173 nameSpace = ConstValue.GetNamespace(cmdlet.Namespace);174 foreach (CimSessionProxy proxy in proxys)175 {176 // create context object177 CimInvokeCimMethodContext context = new(178 nameSpace,179 cmdlet.MethodName,180 paramsCollection,181 proxy);182 proxy.ContextObject = context;183 // firstly query instance and then invoke method upon returned instances184 proxy.QueryInstancesAsync(nameSpace, ConstValue.GetQueryDialectWithDefault(cmdlet.QueryDialect), cmdlet.Query);185 }186 187 break;188 case CimBaseCommand.CimInstanceComputerSet:189 case CimBaseCommand.CimInstanceSessionSet:190 {191 string target = cmdlet.CimInstance.ToString();192 if (cmdlet.ResourceUri != null)193 {194 nameSpace = cmdlet.Namespace;195 }196 else197 {198 nameSpace = ConstValue.GetNamespace(cmdlet.CimInstance.CimSystemProperties.Namespace);199 }200 201 foreach (CimSessionProxy proxy in proxys)202 {203 if (!cmdlet.ShouldProcess(target, action))204 {205 return;206 }207 208 proxy.InvokeMethodAsync(209 nameSpace,210 cmdlet.CimInstance,211 cmdlet.MethodName,212 paramsCollection);213 }214 }215 216 break;217 default:218 break;219 }220 }221 222 /// <summary>223 /// <para>224 /// Invoke cimmethod on given <see cref="CimInstance"/>225 /// </para>226 /// </summary>227 /// <param name="cimInstance"></param>228 public void InvokeCimMethodOnCimInstance(CimInstance cimInstance, XOperationContextBase context, CmdletOperationBase operation)229 {230 DebugHelper.WriteLogEx();231 CimInvokeCimMethodContext cimInvokeCimMethodContext = context as CimInvokeCimMethodContext;232 Debug.Assert(cimInvokeCimMethodContext != null, "CimInvokeCimMethod::InvokeCimMethodOnCimInstance should has CimInvokeCimMethodContext != NULL.");233 234 string action = string.Format(CultureInfo.CurrentUICulture, actionTemplate, cimInvokeCimMethodContext.MethodName);235 if (!operation.ShouldProcess(cimInstance.ToString(), action))236 {237 return;238 }239 240 CimSessionProxy proxy = CreateCimSessionProxy(cimInvokeCimMethodContext.Proxy);241 proxy.InvokeMethodAsync(242 cimInvokeCimMethodContext.Namespace,243 cimInstance,244 cimInvokeCimMethodContext.MethodName,245 cimInvokeCimMethodContext.ParametersCollection);246 }247 248 #region private methods249 250 /// <summary>251 /// <para>252 /// Set <see cref="CimSessionProxy"/> properties253 /// </para>254 /// </summary>255 /// <param name="proxy"></param>256 /// <param name="cmdlet"></param>257 private static void SetSessionProxyProperties(258 ref CimSessionProxy proxy,259 InvokeCimMethodCommand cmdlet)260 {261 proxy.OperationTimeout = cmdlet.OperationTimeoutSec;262 if (cmdlet.ResourceUri != null)263 {264 proxy.ResourceUri = cmdlet.ResourceUri;265 }266 }267 268 /// <summary>269 /// <para>270 /// Create <see cref="CimSessionProxy"/> and set properties271 /// </para>272 /// </summary>273 /// <param name="computerName"></param>274 /// <param name="cmdlet"></param>275 /// <returns></returns>276 private CimSessionProxy CreateSessionProxy(277 string computerName,278 InvokeCimMethodCommand cmdlet)279 {280 CimSessionProxy proxy = CreateCimSessionProxy(computerName);281 SetSessionProxyProperties(ref proxy, cmdlet);282 return proxy;283 }284 285 /// <summary>286 /// <para>287 /// Create <see cref="CimSessionProxy"/> and set properties288 /// </para>289 /// </summary>290 /// <param name="computerName"></param>291 /// <param name="cimInstance"></param>292 /// <param name="cmdlet"></param>293 /// <returns></returns>294 private CimSessionProxy CreateSessionProxy(295 string computerName,296 CimInstance cimInstance,297 InvokeCimMethodCommand cmdlet)298 {299 CimSessionProxy proxy = CreateCimSessionProxy(computerName, cimInstance);300 SetSessionProxyProperties(ref proxy, cmdlet);301 return proxy;302 }303 304 /// <summary>305 /// Create <see cref="CimSessionProxy"/> and set properties.306 /// </summary>307 /// <param name="session"></param>308 /// <param name="cmdlet"></param>309 /// <returns></returns>310 private CimSessionProxy CreateSessionProxy(311 CimSession session,312 InvokeCimMethodCommand cmdlet)313 {314 CimSessionProxy proxy = CreateCimSessionProxy(session);315 SetSessionProxyProperties(ref proxy, cmdlet);316 return proxy;317 }318 319 /// <summary>320 /// <para>321 /// Create <see cref="CimMethodParametersCollection"/> with given key properties.322 /// And/or <see cref="CimClass"/> object.323 /// </para>324 /// </summary>325 /// <param name="parameters"></param>326 /// <param name="cimClass"></param>327 /// <param name="cimInstance"></param>328 /// <param name="methodName"></param>329 /// <returns></returns>330 /// <exception cref="ArgumentNullException">See CimProperty.Create.</exception>331 /// <exception cref="ArgumentException">CimProperty.Create.</exception>332 private CimMethodParametersCollection CreateParametersCollection(333 IDictionary parameters,334 CimClass cimClass,335 CimInstance cimInstance,336 string methodName)337 {338 DebugHelper.WriteLogEx();339 340 CimMethodParametersCollection collection = null;341 if (parameters == null)342 {343 return collection;344 }345 else if (parameters.Count == 0)346 {347 return collection;348 }349 350 collection = new CimMethodParametersCollection();351 IDictionaryEnumerator enumerator = parameters.GetEnumerator();352 while (enumerator.MoveNext())353 {354 string parameterName = enumerator.Key.ToString();355 356 const CimFlags parameterFlags = CimFlags.In;357 object parameterValue = GetBaseObject(enumerator.Value);358 359 DebugHelper.WriteLog(@"Create parameter name= {0}, value= {1}, flags= {2}.", 4,360 parameterName,361 parameterValue,362 parameterFlags);363 364 CimMethodParameter parameter = null;365 CimMethodDeclaration declaration = null;366 string className = null;367 if (cimClass != null)368 {369 className = cimClass.CimSystemProperties.ClassName;370 declaration = cimClass.CimClassMethods[methodName];371 if (declaration == null)372 {373 throw new ArgumentException(string.Format(374 CultureInfo.CurrentUICulture, CimCmdletStrings.InvalidMethod, methodName, className));375 }376 }377 else if (cimInstance != null)378 {379 className = cimInstance.CimClass.CimSystemProperties.ClassName;380 declaration = cimInstance.CimClass.CimClassMethods[methodName];381 }382 383 if (declaration != null)384 {385 CimMethodParameterDeclaration paramDeclaration = declaration.Parameters[parameterName];386 if (paramDeclaration == null)387 {388 throw new ArgumentException(string.Format(389 CultureInfo.CurrentUICulture, CimCmdletStrings.InvalidMethodParameter, parameterName, methodName, className));390 }391 392 parameter = CimMethodParameter.Create(393 parameterName,394 parameterValue,395 paramDeclaration.CimType,396 parameterFlags);397 // FIXME: check in/out qualifier398 // parameterFlags = paramDeclaration.Qualifiers;399 }400 else401 {402 if (parameterValue == null)403 {404 // try the best to get the type while value is null405 parameter = CimMethodParameter.Create(406 parameterName,407 parameterValue,408 CimType.String,409 parameterFlags);410 }411 else412 {413 CimType referenceType = CimType.Unknown;414 object referenceObject = GetReferenceOrReferenceArrayObject(parameterValue, ref referenceType);415 if (referenceObject != null)416 {417 parameter = CimMethodParameter.Create(418 parameterName,419 referenceObject,420 referenceType,421 parameterFlags);422 }423 else424 {425 parameter = CimMethodParameter.Create(426 parameterName,427 parameterValue,428 parameterFlags);429 }430 }431 }432 433 if (parameter != null)434 collection.Add(parameter);435 }436 437 return collection;438 }439 #endregion440 441 #region const strings442 /// <summary>443 /// Operation target.444 /// </summary>445 private const string targetClass = @"{0}";446 447 /// <summary>448 /// Action.449 /// </summary>450 private const string actionTemplate = @"Invoke-CimMethod: {0}";451 #endregion452 }453}454 