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.Globalization;10 11#endregion12 13namespace Microsoft.Management.Infrastructure.CimCmdlets14{15 /// <summary>16 /// Containing all necessary information originated from17 /// the parameters of <see cref="InvokeCimMethodCommand"/>18 /// </summary>19 internal class CimSetCimInstanceContext : XOperationContextBase20 {21 /// <summary>22 /// Initializes a new instance of the <see cref="CimSetCimInstanceContext"/> class.23 /// </summary>24 /// <param name="theNamespace"></param>25 /// <param name="theCollection"></param>26 /// <param name="theProxy"></param>27 internal CimSetCimInstanceContext(string theNamespace,28 IDictionary theProperty,29 CimSessionProxy theProxy,30 string theParameterSetName,31 bool passThru)32 {33 this.proxy = theProxy;34 this.Property = theProperty;35 this.nameSpace = theNamespace;36 this.ParameterSetName = theParameterSetName;37 this.PassThru = passThru;38 }39 40 /// <summary>41 /// <para>property value</para>42 /// </summary>43 internal IDictionary Property { get; }44 45 /// <summary>46 /// <para>parameter set name</para>47 /// </summary>48 internal string ParameterSetName { get; }49 50 /// <summary>51 /// <para>PassThru value</para>52 /// </summary>53 internal bool PassThru { get; }54 }55 56 /// <summary>57 /// <para>58 /// Implements operations of set-ciminstance cmdlet.59 /// </para>60 /// </summary>61 internal sealed class CimSetCimInstance : CimGetInstance62 {63 /// <summary>64 /// Initializes a new instance of the <see cref="CimSetCimInstance"/> class.65 /// </summary>66 public CimSetCimInstance()67 : base()68 {69 }70 71 /// <summary>72 /// <para>73 /// Base on parametersetName to set ciminstances74 /// </para>75 /// </summary>76 /// <param name="cmdlet"><see cref="SetCimInstanceCommand"/> object.</param>77 public void SetCimInstance(SetCimInstanceCommand cmdlet)78 {79 IEnumerable<string> computerNames = ConstValue.GetComputerNames(80 GetComputerName(cmdlet));81 List<CimSessionProxy> proxys = new();82 switch (cmdlet.ParameterSetName)83 {84 case CimBaseCommand.CimInstanceComputerSet:85 foreach (string computerName in computerNames)86 {87 // create CimSessionProxySetCimInstance object internally88 proxys.Add(CreateSessionProxy(computerName, cmdlet.CimInstance, cmdlet, cmdlet.PassThru));89 }90 91 break;92 case CimBaseCommand.CimInstanceSessionSet:93 foreach (CimSession session in GetCimSession(cmdlet))94 {95 // create CimSessionProxySetCimInstance object internally96 proxys.Add(CreateSessionProxy(session, cmdlet, cmdlet.PassThru));97 }98 99 break;100 default:101 break;102 }103 104 switch (cmdlet.ParameterSetName)105 {106 case CimBaseCommand.CimInstanceComputerSet:107 case CimBaseCommand.CimInstanceSessionSet:108 string nameSpace = ConstValue.GetNamespace(GetCimInstanceParameter(cmdlet).CimSystemProperties.Namespace);109 string target = cmdlet.CimInstance.ToString();110 foreach (CimSessionProxy proxy in proxys)111 {112 if (!cmdlet.ShouldProcess(target, action))113 {114 return;115 }116 117 Exception exception = null;118 CimInstance instance = cmdlet.CimInstance;119 // For CimInstance parameter sets, Property is an optional parameter120 if (cmdlet.Property != null)121 {122 if (!SetProperty(cmdlet.Property, ref instance, ref exception))123 {124 cmdlet.ThrowTerminatingError(exception, action);125 return;126 }127 }128 129 proxy.ModifyInstanceAsync(nameSpace, instance);130 }131 132 break;133 case CimBaseCommand.QueryComputerSet:134 case CimBaseCommand.QuerySessionSet:135 GetCimInstanceInternal(cmdlet);136 break;137 default:138 break;139 }140 }141 142 /// <summary>143 /// <para>144 /// Set <see cref="CimInstance"/> with properties specified in cmdlet145 /// </para>146 /// </summary>147 /// <param name="cimInstance"></param>148 public void SetCimInstance(CimInstance cimInstance, CimSetCimInstanceContext context, CmdletOperationBase cmdlet)149 {150 DebugHelper.WriteLog("CimSetCimInstance::SetCimInstance", 4);151 152 if (!cmdlet.ShouldProcess(cimInstance.ToString(), action))153 {154 return;155 }156 157 Exception exception = null;158 if (!SetProperty(context.Property, ref cimInstance, ref exception))159 {160 cmdlet.ThrowTerminatingError(exception, action);161 return;162 }163 164 CimSessionProxy proxy = CreateCimSessionProxy(context.Proxy, context.PassThru);165 proxy.ModifyInstanceAsync(cimInstance.CimSystemProperties.Namespace, cimInstance);166 }167 168 #region private members169 170 /// <summary>171 /// <para>172 /// Set the properties value to be modified to the given173 /// <see cref="CimInstance"/>174 /// </para>175 /// </summary>176 /// <param name="properties"></param>177 /// <param name="cimInstance"></param>178 /// <param name="terminationMessage"></param>179 /// <returns></returns>180 private bool SetProperty(IDictionary properties, ref CimInstance cimInstance, ref Exception exception)181 {182 DebugHelper.WriteLogEx();183 if (properties.Count == 0)184 {185 // simply ignore if empty properties was provided186 return true;187 }188 189 IDictionaryEnumerator enumerator = properties.GetEnumerator();190 while (enumerator.MoveNext())191 {192 object value = GetBaseObject(enumerator.Value);193 string key = enumerator.Key.ToString();194 DebugHelper.WriteLog("Input property name '{0}' with value '{1}'", 1, key, value);195 196 try197 {198 CimProperty property = cimInstance.CimInstanceProperties[key];199 // modify existing property value if found200 if (property != null)201 {202 if ((property.Flags & CimFlags.ReadOnly) == CimFlags.ReadOnly)203 {204 // can not modify ReadOnly property205 exception = new CimException(string.Format(CultureInfo.CurrentUICulture,206 CimCmdletStrings.CouldNotModifyReadonlyProperty, key, cimInstance));207 return false;208 }209 // allow modify the key property value as long as it is not readonly,210 // then the modified ciminstance is stand for a different CimInstance211 DebugHelper.WriteLog("Set property name '{0}' has old value '{1}'", 4, key, property.Value);212 property.Value = value;213 }214 else // For dynamic instance, it is valid to add a new property215 {216 CimProperty newProperty;217 if (value == null)218 {219 newProperty = CimProperty.Create(220 key,221 value,222 CimType.String,223 CimFlags.Property);224 }225 else226 {227 CimType referenceType = CimType.Unknown;228 object referenceObject = GetReferenceOrReferenceArrayObject(value, ref referenceType);229 if (referenceObject != null)230 {231 newProperty = CimProperty.Create(232 key,233 referenceObject,234 referenceType,235 CimFlags.Property);236 }237 else238 {239 newProperty = CimProperty.Create(240 key,241 value,242 CimFlags.Property);243 }244 }245 246 try247 {248 cimInstance.CimInstanceProperties.Add(newProperty);249 }250 catch (CimException e)251 {252 if (e.NativeErrorCode == NativeErrorCode.Failed)253 {254 string errorMessage = string.Format(CultureInfo.CurrentUICulture,255 CimCmdletStrings.UnableToAddPropertyToInstance,256 newProperty.Name,257 cimInstance);258 exception = new CimException(errorMessage, e);259 }260 else261 {262 exception = e;263 }264 265 return false;266 }267 268 DebugHelper.WriteLog("Add non-key property name '{0}' with value '{1}'.", 3, key, value);269 }270 }271 catch (Exception e)272 {273 DebugHelper.WriteLog("Exception {0}", 4, e);274 exception = e;275 return false;276 }277 }278 279 return true;280 }281 282 #endregion283 284 #region const strings285 /// <summary>286 /// Action.287 /// </summary>288 private const string action = @"Set-CimInstance";289 #endregion290 }291}292 