locked
Upload attachment to service request using powershell RRS feed

  • Question

  • Hi, i am trying to upload some attachements using powershell in service manager 2012 R2. I have solved it in the incident class but now i am trying to do the same with the service request class and here i can't get it to work. 

    On the incident part i used SMlets and the set-scsmincident cmdlets but there is no set-scsmservicerequest cmdlet and all other examples i have found is for the incident class none for service request. 

    Anyone know a way of achieving this?


    www.zgc.se - Sysadmin blog.

    Monday, August 18, 2014 1:19 PM

Answers

  • We managed to find a way. Here is the code if someone else has the same issue

    Function Insert-SRAttachment
    {
        [CmdletBinding( SupportsShouldProcess=$false )]
        Param(
            [Parameter( Mandatory = $true )]
            [string]$SCSMID,
            [Parameter( Mandatory = $true )]
            [string]$Directory
        )
        #Get management group
        $ManagementGroup = New-Object Microsoft.EnterpriseManagement.EnterpriseManagementGroup "localhost"
        #Init classes
        $FileAttachmentRel = Get-SCSMRelationshipClass -Name System.WorkItemHasFileAttachment$
        $FileAttachmentClass = Get-SCSMClass -Name System.FileAttachment$
        $ActionLogClass = Get-SCSMClass -Name System.WorkItem.TroubleTicket.ActionLog$
        $ActionLogRel = Get-SCSMRelationshipClass -Name System.WorkItemHasActionLog$
    
        #Get the file listing for the directory
        $AllFiles = Get-ChildItem $Directory
    
        #Check how many files were in the directory
        #Also check for any empty files?
    
        Foreach ( $FileObject in $AllFiles )
        {
            #Create a filestream 
            $FileMode = [System.IO.FileMode]::Open
            $fRead = New-Object System.IO.FileStream $FileObject.FullName, $FileMode
    
            #Create file object to be inserted
            $NewFileAttach = New-Object Microsoft.EnterpriseManagement.Common.CreatableEnterpriseManagementObject($ManagementGroup, $FileAttachmentClass)
            #Populate properties with info
            $SCSMGUID_Attachment = [Guid]::NewGuid().ToString()
            $NewFileAttach.Item($FileAttachmentClass, "Id").Value = $SCSMGUID_Attachment
            $NewFileAttach.Item($FileAttachmentClass, "DisplayName").Value = $FileObject.Name
            $NewFileAttach.Item($FileAttachmentClass, "Description").Value = $FileObject.Name
            $NewFileAttach.Item($FileAttachmentClass, "Extension").Value = $FileObject.Extension
            $NewFileAttach.Item($FileAttachmentClass, "Size").Value = $FileObject.Length
            $NewFileAttach.Item($FileAttachmentClass, "AddedDate").Value = [DateTime]::Now.ToUniversalTime()
            $NewFileAttach.Item($FileAttachmentClass, "Content").Value = $fRead
    
            #Init projection
            $ProjectionType = Get-SCSMTypeProjection -Name System.WorkItem.ServiceRequestProjection$
            $Projection = Get-SCSMObjectProjection -ProjectionName $ProjectionType.Name -Filter "ID -eq $SCSMID"
    
            #Attach file object to Service Manager
            $Projection.__base.Add($NewFileAttach, $FileAttachmentRel.Target)
            $Projection.__base.Commit()
    
            $SCSMGUID_ActionLog = [Guid]::NewGuid().ToString()
            $MP = Get-SCManagementPack -Name "System.WorkItem.Library"
            $ActionType = "System.WorkItem.ActionLogEnum.FileAttached"
            $NewLog = New-Object Microsoft.EnterpriseManagement.Common.CreatableEnterpriseManagementObject($ManagementGroup, $ActionLogClass)
    
            $NewLog.Item( $ActionLogClass, "Id").Value = $SCSMGUID_ActionLog
            $NewLog.Item( $ActionLogClass, "DisplayName").Value = $SCSMGUID_ActionLog
            $NewLog.Item( $ActionLogClass, "ActionType").Value = $MP.GetEnumerations().GetItem($ActionType)
            $NewLog.Item( $ActionLogClass, "Title").Value = "Attached File"
            $NewLog.Item( $ActionLogClass, "EnteredBy").Value = "SYSTEM"
            $NewLog.Item( $ActionLogClass, "Description").Value = $FileObject.Name
            $NewLog.Item( $ActionLogClass, "EnteredDate").Value = (Get-Date).ToUniversalTime()
    
            #Insert comment to action log
            $Projection.__base.Add($NewLog, $ActionLogRel.Target)
            $Projection.__base.Commit()
    
            #Cleanup
            $fRead.Close();
        }
    }


    www.zgc.se - Sysadmin blog.

    Thursday, August 28, 2014 8:53 AM
  • Resolved

    import-module SMlets
    $srClass = Get-SCSMClass -Name system.workitem.servicerequest$
    
    #$SRs = Get-SCSMObject -Class $srClass
    $DefaultDirPath = "C:\temp\import\";
    $ServiceRequestDirArray = get-childitem $DefaultDirPath | select Name
    
    if ($ServiceRequestDirArray.count -ne $NULL)
    {
    foreach ($ServiceRequestDir in $ServiceRequestDirArray)
    {
    $FullDirPath = $DefaultDirPath + $ServiceRequestDir.Name+"\";
    $AttachmentEntries = [IO.Directory]::GetFiles($FullDirPath); 
    $AttachmentArray = $AttachmentEntries.count;
                  if ($AttachmentArray -ne $NULL)
                  {
                  foreach($SingleAttachment in $AttachmentEntries) 
                  { 
                                 $AttachmentSingleName = split-path $SingleAttachment -leaf
                                 if ((Get-SCSMObject -Class $srClass -filter "Id -eq $ServiceRequestDir.Name" | where {$_.FileAttachment -like $AttachmentSingleName}) -eq $NULL)
                                 {
                                               Insert-SRAttachment -SCSMID $ServiceRequestDir.Name -Directory $SingleAttachment;
                                               write-host "$AttachmentSingleName from Folder $SingleAttachment has been uploaded to ServiceRequest with ID:" $ServiceRequestDir.Name 
                                } 
                  }
                  }
    }
    }         
    remove-module SMlets

    Friday, January 19, 2018 3:24 PM

All replies

  • get-scsmincident would be the same as get-scsmobject -class (get-scsmclass system.workitem.incident$)

    then you get it as an scsmobject and can use set-scsmobject on it. should be pretty straight forward from there.


    http://codebeaver.blogspot.dk/

    Tuesday, August 19, 2014 6:59 AM
  • In the set-scsmincident there is a flag -AttachmentPath. I can't seem to figure out how i can replicate that flag so i can upload the attachments. 

    www.zgc.se - Sysadmin blog.

    Tuesday, August 19, 2014 8:54 AM
  • the incident commandlets cheat. they do a lot of work behind the scenes to make it look easy. the actual structure is that the work item is related to a System.FileAttachment object by System.WorkItemHasFileAttachment. this object has a property Content which is a Microsoft.EnterpriseManagement.Common.ServerBinaryStream. 

    i posted something about that here recently, but i'm having trouble finding the reference right now. i'll post it back if i can locate it. 

    Thursday, August 21, 2014 4:02 AM
  • We managed to find a way. Here is the code if someone else has the same issue

    Function Insert-SRAttachment
    {
        [CmdletBinding( SupportsShouldProcess=$false )]
        Param(
            [Parameter( Mandatory = $true )]
            [string]$SCSMID,
            [Parameter( Mandatory = $true )]
            [string]$Directory
        )
        #Get management group
        $ManagementGroup = New-Object Microsoft.EnterpriseManagement.EnterpriseManagementGroup "localhost"
        #Init classes
        $FileAttachmentRel = Get-SCSMRelationshipClass -Name System.WorkItemHasFileAttachment$
        $FileAttachmentClass = Get-SCSMClass -Name System.FileAttachment$
        $ActionLogClass = Get-SCSMClass -Name System.WorkItem.TroubleTicket.ActionLog$
        $ActionLogRel = Get-SCSMRelationshipClass -Name System.WorkItemHasActionLog$
    
        #Get the file listing for the directory
        $AllFiles = Get-ChildItem $Directory
    
        #Check how many files were in the directory
        #Also check for any empty files?
    
        Foreach ( $FileObject in $AllFiles )
        {
            #Create a filestream 
            $FileMode = [System.IO.FileMode]::Open
            $fRead = New-Object System.IO.FileStream $FileObject.FullName, $FileMode
    
            #Create file object to be inserted
            $NewFileAttach = New-Object Microsoft.EnterpriseManagement.Common.CreatableEnterpriseManagementObject($ManagementGroup, $FileAttachmentClass)
            #Populate properties with info
            $SCSMGUID_Attachment = [Guid]::NewGuid().ToString()
            $NewFileAttach.Item($FileAttachmentClass, "Id").Value = $SCSMGUID_Attachment
            $NewFileAttach.Item($FileAttachmentClass, "DisplayName").Value = $FileObject.Name
            $NewFileAttach.Item($FileAttachmentClass, "Description").Value = $FileObject.Name
            $NewFileAttach.Item($FileAttachmentClass, "Extension").Value = $FileObject.Extension
            $NewFileAttach.Item($FileAttachmentClass, "Size").Value = $FileObject.Length
            $NewFileAttach.Item($FileAttachmentClass, "AddedDate").Value = [DateTime]::Now.ToUniversalTime()
            $NewFileAttach.Item($FileAttachmentClass, "Content").Value = $fRead
    
            #Init projection
            $ProjectionType = Get-SCSMTypeProjection -Name System.WorkItem.ServiceRequestProjection$
            $Projection = Get-SCSMObjectProjection -ProjectionName $ProjectionType.Name -Filter "ID -eq $SCSMID"
    
            #Attach file object to Service Manager
            $Projection.__base.Add($NewFileAttach, $FileAttachmentRel.Target)
            $Projection.__base.Commit()
    
            $SCSMGUID_ActionLog = [Guid]::NewGuid().ToString()
            $MP = Get-SCManagementPack -Name "System.WorkItem.Library"
            $ActionType = "System.WorkItem.ActionLogEnum.FileAttached"
            $NewLog = New-Object Microsoft.EnterpriseManagement.Common.CreatableEnterpriseManagementObject($ManagementGroup, $ActionLogClass)
    
            $NewLog.Item( $ActionLogClass, "Id").Value = $SCSMGUID_ActionLog
            $NewLog.Item( $ActionLogClass, "DisplayName").Value = $SCSMGUID_ActionLog
            $NewLog.Item( $ActionLogClass, "ActionType").Value = $MP.GetEnumerations().GetItem($ActionType)
            $NewLog.Item( $ActionLogClass, "Title").Value = "Attached File"
            $NewLog.Item( $ActionLogClass, "EnteredBy").Value = "SYSTEM"
            $NewLog.Item( $ActionLogClass, "Description").Value = $FileObject.Name
            $NewLog.Item( $ActionLogClass, "EnteredDate").Value = (Get-Date).ToUniversalTime()
    
            #Insert comment to action log
            $Projection.__base.Add($NewLog, $ActionLogRel.Target)
            $Projection.__base.Commit()
    
            #Cleanup
            $fRead.Close();
        }
    }


    www.zgc.se - Sysadmin blog.

    Thursday, August 28, 2014 8:53 AM
  • I apologize for my ignorance but what is the usage?  I am currently using this for incident requests but need the equivalent for service requests:

    import-module SMlets
    $DefaultDirPath = "C:\temp\import\";
    $IncidentDirArray = get-childitem $DefaultDirPath | select Name
    
    if ($IncidentDirArray.count -ne $NULL)
    {
    foreach ($IncidentDir in $IncidentDirArray)
    {
    $FullDirPath = $DefaultDirPath + $IncidentDir.Name+"\";
    $AttachmentEntries = [IO.Directory]::GetFiles($FullDirPath); 
    $AttachmentArray = $AttachmentEntries.count;
    	if ($AttachmentArray -ne $NULL)
    	{
    	foreach($SingleAttachment in $AttachmentEntries) 
    	{ 
        		$AttachmentSingleName = split-path $SingleAttachment -leaf
        		if ((get-scsmincident -ID $IncidentDir.Name | where {$_.FileAttachment -like $AttachmentSingleName}) -eq $NULL)
        		{
        			set-scsmincident -ID $IncidentDir.Name -attachmentpath $SingleAttachment;
        			write-host "$AttachmentSingleName from Folder $SingleAttachment has been uploaded to Incident with ID:" $IncidentDir.Name 
       	 	} 
    	}
    	}
    }
    }         
    remove-module SMlets

    Thursday, January 18, 2018 10:40 PM
  • Resolved

    import-module SMlets
    $srClass = Get-SCSMClass -Name system.workitem.servicerequest$
    
    #$SRs = Get-SCSMObject -Class $srClass
    $DefaultDirPath = "C:\temp\import\";
    $ServiceRequestDirArray = get-childitem $DefaultDirPath | select Name
    
    if ($ServiceRequestDirArray.count -ne $NULL)
    {
    foreach ($ServiceRequestDir in $ServiceRequestDirArray)
    {
    $FullDirPath = $DefaultDirPath + $ServiceRequestDir.Name+"\";
    $AttachmentEntries = [IO.Directory]::GetFiles($FullDirPath); 
    $AttachmentArray = $AttachmentEntries.count;
                  if ($AttachmentArray -ne $NULL)
                  {
                  foreach($SingleAttachment in $AttachmentEntries) 
                  { 
                                 $AttachmentSingleName = split-path $SingleAttachment -leaf
                                 if ((Get-SCSMObject -Class $srClass -filter "Id -eq $ServiceRequestDir.Name" | where {$_.FileAttachment -like $AttachmentSingleName}) -eq $NULL)
                                 {
                                               Insert-SRAttachment -SCSMID $ServiceRequestDir.Name -Directory $SingleAttachment;
                                               write-host "$AttachmentSingleName from Folder $SingleAttachment has been uploaded to ServiceRequest with ID:" $ServiceRequestDir.Name 
                                } 
                  }
                  }
    }
    }         
    remove-module SMlets

    Friday, January 19, 2018 3:24 PM
  • Expanded this for use with Config Items and all Out of the Box WorkItem Classes.

    Function Add-SCSMFileAttachment
    {
        <#
        .SYNOPSIS
            Add one or more file attachments to an SCSMObject (WorkItem or ConfirItem)
    
        .DESCRIPTION
            Add one or more file attachments to an SCSMObject (WorkItem or ConfirItem)
    
        .PARAMETER <ParameterName>
            <Parameter Decription>
        
        .EXAMPLE
            #Files to Objects
            Add-SCSMFileAttachment -SMObject $SMObject -Path E:\File.csv
    
            #Attach to objects via pipline
            $SMObject | Add-SCSMFileAttachment -Path E:\File.csv
    
            #Attach Files via GUID
            Add-SCSMFileAttachment -ID "3df4b654-f230-bd4a-528a-7c0df4f5f23b" -Path E:\File.csv
    
            #Attach Files in Folder
            Add-SCSMFileAttachment -SMObject $SMObject -Path E:\Folder
    
            #Attache Multiple Files or Folders (not Recusive)
            Add-SCSMFileAttachment -SMObject $SMObject -Path E:\File.csv, E:\Folder, E:\File2.csv
        
        .NOTES
    
        .LINK
    #>
    
    [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='Low')]
    param
    (
        <#
        [parameter(
            Mandatory=$false,
            ValueFromPipeline=$false,
            ValueFromPipelibebyPropertyName=$false,
            Position=0,
            ParameterSetName='Set1',
            HelpMessage="Enter Managment Server Computer Name")]
            [Microsoft.EnterpriseManagement.Common.EnterpriseManagementObject]
        [ValidateSet("Value1","Value2")] 
            $Example,       
        #>
        
        [parameter(
            ParameterSetName="Object",
            ValueFromPipeline=$true,
            Mandatory=$true)]
            [Microsoft.EnterpriseManagement.Common.EnterpriseManagementObject]
            $SMObject,
    
        [parameter(
            ParameterSetName="GUID",
            ValueFromPipeline=$true,
            Mandatory=$true)]
            [System.Guid]
            $ID,
    
        [parameter( 
            Mandatory = $true )]
            [string[]]$Path,
    
        [parameter(
            HelpMessage="Enter Managment Server Computer Name")]
            [string]
            $ComputerName
    
    
    )#end param
    BEGIN 
    { 
        #Set SMDefaultComputer
        If ($ComputerName)  
        { 
            $SMDefaultComputer = $ComputerName 
        }
        if(!$SMDefaultComputer)
        {
            Write-Error '$SMDefaultComputer is null in the current session and no -ComputerName parameter was passed to this function. Please specify one or the other.' -ErrorAction Stop
            break
        }
    
    } #End BEGIN
    
    PROCESS
    {
        if ($PSCmdlet.ParameterSetName -eq "GUID")
        {
            $SMObject = Get-SCSMObject -Id $ID
        }
    
        if ($SMObject.ClassName -match "workitem") {
            $RelationshipClassName = "System.WorkItemHasFileAttachment"
            $ProjectionName =        "System.WorkItem.Projection"
            $ObjID =                    $SMObject.ID
            $ActionLogClass =        Get-SCSMClass -Name System.WorkItem.TroubleTicket.ActionLog$
            $ActionLogRel =          Get-SCSMRelationshipClass -Name System.WorkItemHasActionLog$
        } else {
            $RelationshipClassName = "System.ConfigItemHasFileAttachment"
            $ProjectionName =        "System.ConfigItem.Projection"
            $ObjID =                    $SMObject.Id
        }
    
        $ManagementGroup = New-Object Microsoft.EnterpriseManagement.EnterpriseManagementGroup $SMDefaultComputer
        $FileAttachmentRel = Get-SCSMRelationshipClass -Name $RelationshipClassName
        $FileAttachmentClass = Get-SCSMClass -Name System.FileAttachment$
        
    
        #Get the all files
        $AllFiles = $Path |%{Get-ChildItem $_}
    
        #Check how many files were in the directory
        #Also check for any empty files?
    
        Foreach ( $FileObject in $AllFiles ){
            #Create a filestream 
            $FileMode = [System.IO.FileMode]::Open
            $fRead = New-Object System.IO.FileStream $FileObject.FullName, $FileMode
    
            #Create file object to be inserted
            $NewFileAttach = New-Object Microsoft.EnterpriseManagement.Common.CreatableEnterpriseManagementObject($ManagementGroup, $FileAttachmentClass)
            #Populate properties with info
            $SCSMGUID_Attachment = [Guid]::NewGuid().ToString()
            $NewFileAttach.Item($FileAttachmentClass, "Id").Value = $SCSMGUID_Attachment
            $NewFileAttach.Item($FileAttachmentClass, "DisplayName").Value = $FileObject.Name
            $NewFileAttach.Item($FileAttachmentClass, "Description").Value = $FileObject.Name
            $NewFileAttach.Item($FileAttachmentClass, "Extension").Value = $FileObject.Extension
            $NewFileAttach.Item($FileAttachmentClass, "Size").Value = $FileObject.Length
            $NewFileAttach.Item($FileAttachmentClass, "AddedDate").Value = [DateTime]::Now.ToUniversalTime()
            $NewFileAttach.Item($FileAttachmentClass, "Content").Value = $fRead
    
            #Init projection
            $ProjectionType = Get-SCSMTypeProjection -Name $ProjectionName
            $Projection = Get-SCSMObjectProjection -Projection $ProjectionType -Filter "ID -eq $ObjID"
    
    
            #Attach file object to Service Manager
            $Projection.__base.Add($NewFileAttach, $FileAttachmentRel.Target)
            $Projection.__base.Commit()
    
            if ($SMObject.ClassName -match "workitem") {
                $SCSMGUID_ActionLog = [Guid]::NewGuid().ToString()
                $MP = Get-SCSMManagementPack -Name "System.WorkItem.Library"
                $ActionType = "System.WorkItem.ActionLogEnum.FileAttached"
                $NewLog = New-Object Microsoft.EnterpriseManagement.Common.CreatableEnterpriseManagementObject($ManagementGroup, $ActionLogClass)
    
                $NewLog.Item( $ActionLogClass, "Id").Value = $SCSMGUID_ActionLog
                $NewLog.Item( $ActionLogClass, "DisplayName").Value = $SCSMGUID_ActionLog
                $NewLog.Item( $ActionLogClass, "ActionType").Value = $MP.GetEnumerations().GetItem($ActionType)
                $NewLog.Item( $ActionLogClass, "Title").Value = "Attached File"
                $NewLog.Item( $ActionLogClass, "EnteredBy").Value = "SYSTEM"
                $NewLog.Item( $ActionLogClass, "Description").Value = $FileObject.Name
                $NewLog.Item( $ActionLogClass, "EnteredDate").Value = (Get-Date).ToUniversalTime()
    
                #Insert comment to action log
                $Projection.__base.Add($NewLog, $ActionLogRel.Target)
                $Projection.__base.Commit()
            }
    
            #Cleanup
            $fRead.Close();
        }
    
    }#end PROCESS
    
    END
    {  }#end END
    
    }

    Tuesday, October 30, 2018 4:35 PM