#------------------------------------------------------------------------------------------------------------------------------------
#  Script:   Portal Software Request - Script 2
#  Author:   www.xapity.com
#  Date:     03-Dec-2016
#  Version:  1.0
#  Comments: Used in a Xapity PowerShell Activity to process a Portal Software Request
#            Script 2:
#                *  adds the Affected User to Software Deployment Group
#                *  adds software guides (from disk) to the  Xapity Notification activity which 
#                    then emails the affected user
#------------------------------------------------------------------------------------------------------------------------------------

Import-Module SMLets -Force
Import-Module ActiveDirectory -Force

#------------------------------------------------------------------------------------------------------------------------------------
#Define the Classes and Relationships that are required 
#     Note: $ParentID is a variable supplied by Xapity PowerShell and does not need to be defined
#------------------------------------------------------------------------------------------------------------------------------------
$ParentClass = Get-SCSMClass System.WorkItem.ServiceRequest$
$ParentObject = Get-SCSMObject -Class $ParentClass -Filter "ID -eq $ParentID"

$UserRelClass = Get-SCSMRelationshipClass -Name "System.WorkItemAffectedUser"
$UserObject = Get-SCSMRelatedObject -SMObject $ParentObject -Relationship $UserRelClass

$FileAttachmentClass = Get-SCSMClass -Name "System.FileAttachment"
$ManagementGroup =  new-object Microsoft.EnterpriseManagement.EnterpriseManagementGroup "localhost"
$FileAttachmentRel = Get-SCSMRelationshipClass "System.WorkItemHasFileAttachment"

#------------------------------------------------------------------------------------------------------------------------------------
#Function to Add Action Comment to SR 
#------------------------------------------------------------------------------------------------------------------------------------
function Add-ActionComment {
    param (
            [parameter(Mandatory=$true,Position=0)][Alias('Id')]$ParentWorkItemID,
            [parameter(Mandatory=$true,Position=1)][Alias('ActionType')][String]$ActionTypeData,
            [parameter(Mandatory=$true,Position=2)][Alias('Title')][String]$AddTitle,
            [parameter(Mandatory=$true,Position=3)][Alias('Comment')][String]$AddComment,
            [parameter(Mandatory=$true,Position=4)][Alias('EnteredBy')][String]$AddEnteredBy
          )

    #Check what type of WorkItem and set variables 
    If ($ParentWorkItemID -like "SR*") {
    $WorkItemClass = Get-SCSMClass System.WorkItem.ServiceRequest$
    $WorkItemTypeProjection = "System.WorkItem.ServiceRequestProjection" }

    ElseIf ($ParentWorkItemID -like "IR*") {
    $WorkItemClass = Get-SCSMClass System.WorkItem.Incident$
    $WorkItemTypeProjection = "Xapity.ActionLog.TypeProjection.Incident"}

    ElseIf ($ParentWorkItemID -like "PR*") {
    $WorkItemClass = Get-SCSMClass System.WorkItem.Problem$
    $WorkItemTypeProjection = "Xapity.ActionLog.TypeProjection.Problem"}

    Switch($ActionTypeData) 
    {
        EmailSent {$ActionType = "System.WorkItem.ActionLogEnum.EmailSent"}
        FileAttached {$ActionType = "System.WorkItem.ActionLogEnum.FileAttached"}
        FileDeleted {$ActionType = "System.WorkItem.ActionLogEnum.FileDeleted"}
        RecordAssigned {$ActionType = "System.WorkItem.ActionLogEnum.RecordAssigned"}
        RecordClosed {$ActionType = "System.WorkItem.ActionLogEnum.RecordClosed"}
        RecordDispatched {$ActionType = "System.WorkItem.ActionLogEnum.RecordDispatched"}
        RecordEscalated {$ActionType = "System.WorkItem.ActionLogEnum.RecordEscalated"}
        RecordOpened {$ActionType = "System.WorkItem.ActionLogEnum.RecordOpened"}
        Reopened {$ActionType = "System.WorkItem.ActionLogEnum.Reopened"}
        Resolved {$ActionType = "System.WorkItem.ActionLogEnum.Resolved"}
        SurveyCompleted {$ActionType = "System.WorkItem.ActionLogEnum.SurveyCompleted"}
        TaskExecuted {$ActionType = "System.WorkItem.ActionLogEnum.TaskExecuted"}
        TemplateApplied {$ActionType = "System.WorkItem.ActionLogEnum.TemplateApplied"}
     }


    $WorkItemObject = Get-SCSMObject -Class $WorkItemClass -Filter "Id -eq $ParentWorkItemID" 
    $NewGUID = ([guid]::NewGuid()).ToString()
    $Projection = @{__CLASS = $ProjectionClass;
                    __SEED = $WorkItemObject;
                    ActionLog = @{__CLASS = "System.WorkItem.TroubleTicket.ActionLog";
                                          __OBJECT = @{Id = $NewGUID;
                                                       DisplayName = $NewGUID;
                                                       ActionType = $ActionType;
                                                       Title = $AddTitle;
                                                       Description = $AddComment;
                                                       EnteredBy  = $AddEnteredBy;
                                                       EnteredDate = (Get-Date).ToUniversalTime();
                                                       IsPrivate = $false;
                                                      }
                                         }
                   }
    New-SCSMObjectProjection -Type $WorkItemTypeProjection -Projection $Projection
}

#------------------------------------------------------------------------------------------------------------------------------------
#Get a list of the Activities on the ParentObject. Recursive to find Activities in PA or SA containers. Filtered to Xapity WorkItem Activity
#------------------------------------------------------------------------------------------------------------------------------------
$NotificationActivities = Get-SCSMRelatedObject -SMObject $ParentObject -Depth Recursive  | ?{$_.TypeName -like "Xapity.WorkItem.Activity.*"}

#------------------------------------------------------------------------------------------------------------------------------------
#Loop through the Notification Activities and upload the software guides based on what software the user choose
#------------------------------------------------------------------------------------------------------------------------------------
foreach ($ACActivity in $NotificationActivities)
  {
    If ($ACActivity.Title -like "*Software Guide Email*")
        {
        $SourceFolder  = "C:\Temp\Attachments\"+$ParentObject.SRString
        $SRComment = ""
        
        #Retrieve all the files in the Source folder. All files will be attached to the work item
        $SourceFiles = Get-ChildItem $SourceFolder
        Write-Host "Source Folder: $SourceFolder"

        #Loop through each file and add it to the work item
        Foreach ( $File in $SourceFiles )
            {
                #Create a filestream 
                $FileMode = [System.IO.FileMode]::Open
                $FileStreamRead = New-Object System.IO.FileStream $File.FullName, $FileMode

                #Create file object to be attached
                $Attachment = New-Object Microsoft.EnterpriseManagement.Common.CreatableEnterpriseManagementObject($ManagementGroup, $FileAttachmentClass)
        
               #Populate properties of the file object
                $NewGUID_Attachment = [Guid]::NewGuid().ToString()
                $Attachment.Item($FileAttachmentClass, "Id").Value = $NewGUID_Attachment
                $Attachment.Item($FileAttachmentClass, "DisplayName").Value = $File.Name
                $Attachment.Item($FileAttachmentClass, "Description").Value = $File.Name
                $Attachment.Item($FileAttachmentClass, "Extension").Value = $File.Extension
                $Attachment.Item($FileAttachmentClass, "Size").Value = $File.Length
                $Attachment.Item($FileAttachmentClass, "AddedDate").Value = [DateTime]::Now.ToUniversalTime()
                $Attachment.Item($FileAttachmentClass, "Content").Value = $FileStreamRead

                #Intialise projection. This is hard coded to the Notification Activity. This would need to change for other activity types
                $ProjectionType = Get-SCSMTypeProjection -Name Xapity.NotificationActivity.Form.ProjectionType$
                $Projection = Get-SCSMObjectProjection -ProjectionName $ProjectionType.Name -Filter "ID -eq $($ACActivity.ID)"

                #Attach file to the work item
                $Projection.__base.Add($Attachment, $FileAttachmentRel.Target)
                $Projection.__base.Commit()
                Write-Host "Attached file: $File.Name"        
                $SRComment += "Uploaded attachment: $File.Name `n"
               
                #Close the file stream
                $FileStreamRead.Close();

           } #End ForEach file in Sourcefiles

        #Examples using each Work Item type
        Add-ActionComment -Id $ParentID -ActionType "FileAttached"  -Title "File Uploaded" -Comment $SRComment -EnteredBy "PowerShell Activity"


        }#End If Software Guide Email
    }#End ForEach Notification Activity

#------------------------------------------------------------------------------------------------------------------------------------
#Add the user to the software based deployment group
#       Note the Software name was stored in the SRstring field (a Custom extension to the SR Class)
#------------------------------------------------------------------------------------------------------------------------------------
$ADGroup = "SCCM-Software-" + $ParentObject.SRString
Add-ADGroupMember -Identity $ADGroup -Member $UserObject.DistinguishedName

$ADcomment = "User $($UserObject.DisplayName) was added to AD Group $ADGroup)"
Write-Host "User $($UserObject.DisplayName) was added to AD Group $ADGroup)"

Add-ActionComment -Id $ParentID -ActionType "TaskExecuted"  -Title "AD Group Updated" -Comment $ADcomment -EnteredBy "PowerShell Activity"

#------------------------------------------------------------------------------------------------------------------------------------
Write-host "Script Complete"
#------------------------------------------------------------------------------------------------------------------------------------