<#
  .Notes
	Copyright (c) 2013-2014, Intel Corporation. All rights reserved.
  .Synopsis 
	Sets the data of the specified attribute or feature of the specified solution component
  .Description
	Sets the data of the specified attribute or feature of the specified solution component
  .Example
	.\SCS-SetAttribute -ComputerName MyHost.Domain.com -Component 0b93a9cb-64b1-43ed-bc33-e5b0b8692694 -Attribute "AttributeName" -Value "123" -Type 1
  .Outputs
	The cmdlet outputs the attribute objects in the form: { Tag, Type, Value }
#>
[CmdletBinding()]
Param(
	[string]$bad_param,
	[Parameter(Position=0, Mandatory=$True, HelpMessage='Fully qualified component identifer of the solution component on which to perform the operation')][string]$Component,
	[Parameter(Mandatory=$False, HelpMessage='Address of the computer on which to perform the operation (default: localhost)')][string]$ComputerName = $env:ComputerName,
	[Parameter(Mandatory=$False, HelpMessage='Credentials to use for authenticating to the Solutions Framework (default: current user)')][Object]$Credential = $null,
	[Parameter(Position=1, Mandatory=$False, HelpMessage='Name of the attribute for which to set the data')][string]$Attribute,
	[Parameter(Position=2, Mandatory=$False, HelpMessage='Value to be set in the attribute. Must be a string, integer, boolean, or byte array.')][Object]$Value,
	[Parameter(Position=3, Mandatory=$False, HelpMessage='Data type of the attribute')][int32]$Type = 0,
	[Parameter(Mandatory=$False, ValueFromPipeline=$True)][Object]$AttrObjects
)

if ($bad_param) {
	Write-Host "Invalid positional parameter"
	exit 5
}

$filter = $(
	if ($Component -Match '%') {
		"ComponentID LIKE ""$Component"""
	} else {
		"ComponentID = ""$Component"""
	}
)

if ($attrObjects) {

	$SCS_ManagedElement = $( # Retrieve the specified ManagedElement
		if ($Credential) {
			Get-WMIObject -Computer $ComputerName -Credential $cred -Authentication 6 -Errorvariable err -Namespace Root\Intel_SCS_Framework -Class SCS_ManagedElement -Filter $filter
		} else {
			Get-WMIObject -Computer $ComputerName -Authentication 6 -Errorvariable err -Namespace Root\Intel_SCS_Framework -Class SCS_ManagedElement -Filter $filter
		}
	) | Select -First 1 # If the filter returns multiple components, the cmdlet will run on only the first component

	if ($SCS_ManagedElement -eq $null) {
		if($err.Count -gt 0) {$mg=$err[0];} else { $mg="";}
		Write-Error "Failed to load component $Component with error: $mg"		
		exit 1
	}

	$method = "SetAttribute"
	$params = $SCS_ManagedElement.GetMethodParameters($method)

	$attrObjects | %{
		if (!$_.Attribute) {
			Write-Error "Invalid attribute name"
			return
		}
		if (!$_.Value) {
			$_.Value = [byte[]]@()
		}
		$params.TagName = $_.Attribute
		$params.Data = $_.Value
		$params.DataType = $_.Type
		try {
			$ret = $SCS_ManagedElement.InvokeMethod($method, $params, $null)
		} catch [Exception] {
			Write-Error "Failed to execute the $method command with message: $_.Exception.Message"
			Write-Host "Please check the event log for more details"			
			exit $_.Exception.ErrorCode
		}
		if ($ret.ReturnValue -ne 0) {
			@{ Tag = $params.TagName; Error = $ret.ReturnValue }
		}
	}
} else {
	if (!$Attribute) {
		Write-Error "Invalid attribute name"		 
		exit 1
	}
	if (!$Value) {
		$Value = [byte[]]@()
	}

	$SCS_ManagedElement = $( # Retrieve the specified ManagedElement
		if ($Credential) {
			Get-WMIObject -Computer $ComputerName -Credential $cred -Authentication 6 -Errorvariable err -Namespace Root\Intel_SCS_Framework -Class SCS_ManagedElement -Filter $filter
		} else {
			Get-WMIObject -Computer $ComputerName -Authentication 6 -Errorvariable err -Namespace Root\Intel_SCS_Framework -Class SCS_ManagedElement -Filter $filter
		}
	) | Select -First 1 # This cmdlet supports running only one operation

	if ($SCS_ManagedElement -eq $null) {
		if($err.Count -gt 0) {$mg=$err[0];} else { $mg="";}
		Write-Error "Failed to load component $Component with error: $mg"
		exit $_.Exception.ErrorCode
	}

	$method = "SetAttribute"
	$params = $SCS_ManagedElement.GetMethodParameters($method)


	$params.TagName = $Attribute
	$params.Data = $Value
	$params.DataType = $Type
	try {
		$ret = $SCS_ManagedElement.InvokeMethod($method, $params, $null)
	} catch [Exception] {
		Write-Error "Failed to execute the $method command with message: $_.Exception.Message"
		Write-Host "Please check the event log for more details."		
		exit $_.Exception.ErrorCode
	}
	if ($ret.ReturnValue -ne 0) {
		@{ Tag = $Attribute; Error = $ret.ReturnValue }
		exit $ret.ReturnValue
	}
}
