<#
  .Notes
	Copyright (c) 2014, Intel Corporation. All rights reserved.
  .Synopsis 
	Manages the WMI, DCOM, and folder permissions required to manage a solution using the Solutions Framework
  .Description
	Manages the WMI, DCOM, and folder permissions required to manage a solution using the Solutions Framework.
	These are the permissons that are managed by this script:
		1) WMI permissions for the Intel_SCS_Framework namespace
		2) DCOM permissions for the SFPluginWrapper.exe COM object
		3) Permissions for these folders:
				* The folder containing the HostSolutionManager.dll file
				* The folder containing the solution host plugin DLL file
	For more information, refer to the "Required Permissions" section of the Intel(R)_Solutions_Framework.pdf.
	
	The value supplied in the Operation parameter defines which task the script will perform.
	Valid values:
	Add - This value calls the AddPermissions method for a managed solution. The AddPermissions method gives a specified user or group account all the necessary WMI, DCOM, and folder permissions required to manage a solution.
	Remove - This value calls the RemovePermissions method for a managed solution. The RemovePermissions method removes the WMI, DCOM, and folder permissions required to manage a solution from a specified user or group account. If you specify $True in the JustSolution parameter the user will only lose access to this specific solution. If you set JustSolution to $False the user will lose access to all of the Solutions Framework.
	Show - This value calls the EnumeratePermissions method of a managed solution. The EnumeratePermissions method returns all the users and group accounts that have permissions on the solution.

  .Example
	.\SCS-Permissions.ps1 -ComputerName MyHost.Domain.com -Component 0b93a9cb-64b1-43ed-bc33-e5b0b8692694 -Operation Add -NameOrSID "MyUserGroup"
  .Example
	.\SCS-Permissions.ps1 0b93a9cb-64b1-43ed-bc33-e5b0b8692694 Add "MyUserGroup"
  .Example
	.\SCS-Permissions.ps1 -ComputerName MyHost.Domain.com -Component 0b93a9cb-64b1-43ed-bc33-e5b0b8692694 -Operation Show
  .Example
	.\SCS-Permissions.ps1 0b93a9cb-64b1-43ed-bc33-e5b0b8692694 Show
  .Example
	.\SCS-Permissions.ps1 -ComputerName MyHost.Domain.com -Component 0b93a9cb-64b1-43ed-bc33-e5b0b8692694 -Operation Remove -NameOrSID "MyUserGroup" -JustSolution $false
  .Example
	.\SCS-Permissions.ps1 0b93a9cb-64b1-43ed-bc33-e5b0b8692694 Remove "MyUserGroup" $true

  .Outputs
	For the Show value: 
		A list of all the users and group accounts that have permissions on the solution
#>
[CmdletBinding(DefaultParameterSetName='None')]
Param(
	[Parameter(Position=0, Mandatory=$True, HelpMessage='Fully qualified component identifer of the solution component on which to perform the operation')][string]$Component,
	[Parameter(Position=1, Mandatory=$True, HelpMessage='The type of permissions Operation that you want to execute. Valid values: "Add", "Remove" or "Show"')][string]$Operation = "Show",
	[Parameter(Position=2, Mandatory=$False,  HelpMessage='The Name or SID of the user or group for which you want to apply the Operation. Not required when Operation is "Show". ')][string]$NameOrSID,
	[Parameter(Position=3, Mandatory=$False,  HelpMessage='Indicates if you want to remove permissions just for this managed solution(True) or for the entire Solutions Framework(False). This is relevant only when the value of Operation is "Remove". ')][bool]$JustSolution = $True,
	[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
) 
# Validation of input
$op = 0
if ("Show" -ieq $Operation){
    $op = 1
    }
if ("Remove" -ieq $Operation){
    $op = 2
    }
if ("Add" -ieq $Operation){
    $op = 3
    }
if ($op -lt 1 -or $op -gt 3) {
	Write-Error "An invalid operation flag was supplied. Valid values: Show, Add, and Remove ($Operation)."
	Write-Host "Please correct the commandline arguments and retry."
	exit 3
}

if ($op -gt 1 -and $NameOrSID -eq $null) {
	Write-Error "An invalid Name or SID was supplied."
	Write-Host "Please correct the commandline arguments and retry."
	exit 4
}

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

$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"
	Write-Host "Please check the event log for more details."
	exit 1
}

if($op -eq 3)
{
    $method = "AddPermissions"
    $params = $SCS_ManagedElement.GetMethodParameters($method)
    $params.NameOrSID = $NameOrSID
} elseif($op -eq 2) 
{
    $method = "RemovePermissions"
    $params = $SCS_ManagedElement.GetMethodParameters($method)
    $params.NameOrSID = $NameOrSID
    $params.JustPluginPermissions = $JustSolution
} elseif($op -eq 1)
{
    $method = "EnumeratePermissions"
    $params = $SCS_ManagedElement.GetMethodParameters($method)
}

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
}
$exitcode = $ret.ReturnValue
Write-Host "Finished operation with returned value $exitcode. "
Write-Host $ret.Description
if($op -eq 1)
{
   Write-Host $ret.NameOrSID
}
exit $exitcode
