Answered by:
Upload attachment to service request using powershell

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.
- Marked as answer by Thomas Strömberg Thursday, August 28, 2014 8:53 AM
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
- Proposed as answer by Herb Winhoven Friday, January 19, 2018 3:24 PM
- Marked as answer by Andreas BaumgartenMVP Monday, January 22, 2018 9:09 PM
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.
- Marked as answer by Thomas Strömberg Thursday, August 28, 2014 8:53 AM
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
- Proposed as answer by Herb Winhoven Friday, January 19, 2018 3:24 PM
- Marked as answer by Andreas BaumgartenMVP Monday, January 22, 2018 9:09 PM
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 }
- Proposed as answer by Andreas BaumgartenMVP Tuesday, October 30, 2018 6:43 PM
Tuesday, October 30, 2018 4:35 PM