321 lines
11 KiB
C#
321 lines
11 KiB
C#
// 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
|
|
{
|
|
/// <summary>
|
|
/// Containing all necessary information originated from
|
|
/// the parameters of <see cref="InvokeCimMethodCommand"/>
|
|
/// </summary>
|
|
internal class CimSetCimInstanceContext : XOperationContextBase
|
|
{
|
|
/// <summary>
|
|
/// <para>
|
|
/// Constructor
|
|
/// </para>
|
|
/// </summary>
|
|
/// <param name="theNamespace"></param>
|
|
/// <param name="theCollection"></param>
|
|
/// <param name="theProxy"></param>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>property value</para>
|
|
/// </summary>
|
|
internal IDictionary Property
|
|
{
|
|
get
|
|
{
|
|
return this.property;
|
|
}
|
|
}
|
|
|
|
private IDictionary property;
|
|
|
|
/// <summary>
|
|
/// <para>parameter set name</para>
|
|
/// </summary>
|
|
internal string ParameterSetName
|
|
{
|
|
get
|
|
{
|
|
return this.parameterSetName;
|
|
}
|
|
}
|
|
|
|
private string parameterSetName;
|
|
|
|
/// <summary>
|
|
/// <para>PassThru value</para>
|
|
/// </summary>
|
|
internal bool PassThru
|
|
{
|
|
get
|
|
{
|
|
return this.passThru;
|
|
}
|
|
}
|
|
|
|
private bool passThru;
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>
|
|
/// Implements operations of set-ciminstance cmdlet.
|
|
/// </para>
|
|
/// </summary>
|
|
internal sealed class CimSetCimInstance : CimGetInstance
|
|
{
|
|
/// <summary>
|
|
/// <para>
|
|
/// Constructor
|
|
/// </para>
|
|
/// </summary>
|
|
public CimSetCimInstance()
|
|
: base()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>
|
|
/// Base on parametersetName to set ciminstances
|
|
/// </para>
|
|
/// </summary>
|
|
/// <param name="cmdlet"><see cref="SetCimInstanceCommand"/> object.</param>
|
|
public void SetCimInstance(SetCimInstanceCommand cmdlet)
|
|
{
|
|
IEnumerable<string> computerNames = ConstValue.GetComputerNames(
|
|
GetComputerName(cmdlet));
|
|
List<CimSessionProxy> proxys = new List<CimSessionProxy>();
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// <para>
|
|
/// Set <see cref="CimInstance"/> with properties specified in cmdlet
|
|
/// </para>
|
|
/// </summary>
|
|
/// <param name="cimInstance"></param>
|
|
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
|
|
|
|
/// <summary>
|
|
/// <para>
|
|
/// Set the properties value to be modified to the given
|
|
/// <see cref="CimInstance"/>
|
|
/// </para>
|
|
/// </summary>
|
|
/// <param name="properties"></param>
|
|
/// <param name="cimInstance"></param>
|
|
/// <param name="terminationMessage"></param>
|
|
/// <returns></returns>
|
|
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
|
|
/// <summary>
|
|
/// Action.
|
|
/// </summary>
|
|
private const string action = @"Set-CimInstance";
|
|
#endregion
|
|
}
|
|
}
|