// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #region Using directives using System.Collections; using System; using System.Collections.Generic; using System.Globalization; using System.Management.Automation; #endregion namespace Microsoft.Management.Infrastructure.CimCmdlets { /// /// Containing all necessary information originated from /// the parameters of /// internal class CimSetCimInstanceContext : XOperationContextBase { /// /// /// Constructor /// /// /// /// /// internal CimSetCimInstanceContext(string theNamespace, IDictionary theProperty, CimSessionProxy theProxy, string theParameterSetName, bool passThru) { this.proxy = theProxy; this.property = theProperty; this.nameSpace = theNamespace; this.parameterSetName = theParameterSetName; this.passThru = passThru; } /// /// property value /// internal IDictionary Property { get { return this.property; } } private IDictionary property; /// /// parameter set name /// internal string ParameterSetName { get { return this.parameterSetName; } } private string parameterSetName; /// /// PassThru value /// internal bool PassThru { get { return this.passThru; } } private bool passThru; } /// /// /// Implements operations of set-ciminstance cmdlet. /// /// internal sealed class CimSetCimInstance : CimGetInstance { /// /// /// Constructor /// /// public CimSetCimInstance() : base() { } /// /// /// Base on parametersetName to set ciminstances /// /// /// object. public void SetCimInstance(SetCimInstanceCommand cmdlet) { IEnumerable computerNames = ConstValue.GetComputerNames( GetComputerName(cmdlet)); List proxys = new List(); switch (cmdlet.ParameterSetName) { case CimBaseCommand.CimInstanceComputerSet: foreach (string computerName in computerNames) { // create CimSessionProxySetCimInstance object internally proxys.Add(CreateSessionProxy(computerName, cmdlet.CimInstance, cmdlet, cmdlet.PassThru)); } break; case CimBaseCommand.CimInstanceSessionSet: foreach (CimSession session in GetCimSession(cmdlet)) { // create CimSessionProxySetCimInstance object internally proxys.Add(CreateSessionProxy(session, cmdlet, cmdlet.PassThru)); } break; default: break; } switch (cmdlet.ParameterSetName) { case CimBaseCommand.CimInstanceComputerSet: case CimBaseCommand.CimInstanceSessionSet: string nameSpace = ConstValue.GetNamespace(GetCimInstanceParameter(cmdlet).CimSystemProperties.Namespace); string target = cmdlet.CimInstance.ToString(); foreach (CimSessionProxy proxy in proxys) { if (!cmdlet.ShouldProcess(target, action)) { return; } Exception exception = null; CimInstance instance = cmdlet.CimInstance; // For CimInstance parameter sets, Property is an optional parameter if (cmdlet.Property != null) { if (!SetProperty(cmdlet.Property, ref instance, ref exception)) { cmdlet.ThrowTerminatingError(exception, action); return; } } proxy.ModifyInstanceAsync(nameSpace, instance); } break; case CimBaseCommand.QueryComputerSet: case CimBaseCommand.QuerySessionSet: GetCimInstanceInternal(cmdlet); break; default: break; } } /// /// /// Set with properties specified in cmdlet /// /// /// public void SetCimInstance(CimInstance cimInstance, CimSetCimInstanceContext context, CmdletOperationBase cmdlet) { DebugHelper.WriteLog("CimSetCimInstance::SetCimInstance", 4); if (!cmdlet.ShouldProcess(cimInstance.ToString(), action)) { return; } Exception exception = null; if (!SetProperty(context.Property, ref cimInstance, ref exception)) { cmdlet.ThrowTerminatingError(exception, action); return; } CimSessionProxy proxy = CreateCimSessionProxy(context.Proxy, context.PassThru); proxy.ModifyInstanceAsync(cimInstance.CimSystemProperties.Namespace, cimInstance); } #region private members /// /// /// Set the properties value to be modified to the given /// /// /// /// /// /// /// private bool SetProperty(IDictionary properties, ref CimInstance cimInstance, ref Exception exception) { DebugHelper.WriteLogEx(); if (properties.Count == 0) { // simply ignore if empty properties was provided return true; } IDictionaryEnumerator enumerator = properties.GetEnumerator(); while (enumerator.MoveNext()) { object value = GetBaseObject(enumerator.Value); string key = enumerator.Key.ToString(); DebugHelper.WriteLog("Input property name '{0}' with value '{1}'", 1, key, value); try { CimProperty property = cimInstance.CimInstanceProperties[key]; // modify existing property value if found if (property != null) { if ((property.Flags & CimFlags.ReadOnly) == CimFlags.ReadOnly) { // can not modify ReadOnly property exception = new CimException(string.Format(CultureInfo.CurrentUICulture, Strings.CouldNotModifyReadonlyProperty, key, cimInstance)); return false; } // allow modify the key property value as long as it is not readonly, // then the modified ciminstance is stand for a different CimInstance DebugHelper.WriteLog("Set property name '{0}' has old value '{1}'", 4, key, property.Value); property.Value = value; } else // For dynamic instance, it is valid to add a new property { CimProperty newProperty; if (value == null) { newProperty = CimProperty.Create( key, value, CimType.String, CimFlags.Property); } else { CimType referenceType = CimType.Unknown; object referenceObject = GetReferenceOrReferenceArrayObject(value, ref referenceType); if (referenceObject != null) { newProperty = CimProperty.Create( key, referenceObject, referenceType, CimFlags.Property); } else { newProperty = CimProperty.Create( key, value, CimFlags.Property); } } try { cimInstance.CimInstanceProperties.Add(newProperty); } catch (CimException e) { if (e.NativeErrorCode == NativeErrorCode.Failed) { string errorMessage = string.Format(CultureInfo.CurrentUICulture, Strings.UnableToAddPropertyToInstance, newProperty.Name, cimInstance); exception = new CimException(errorMessage, e); } else { exception = e; } return false; } DebugHelper.WriteLog("Add non-key property name '{0}' with value '{1}'.", 3, key, value); } } catch (Exception e) { DebugHelper.WriteLog("Exception {0}", 4, e); exception = e; return false; } } return true; } #endregion #region const strings /// /// Action. /// private const string action = @"Set-CimInstance"; #endregion } }