[Webinar] Learn how to a build a cloud-first strategyRegister Now

  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 739
  • Last Modified:

Integrating PowerShell Script in C# Assembly Code

Basically, we have help desk analysts who generate the incidents. SOMETIMES, they may have a need to generate an RMA (Return Merchandise Authorization, if you don't know what that means, just know that it is another form they need to fill out), and that RMA needs to be associated with an incident. An incident does not REQUIRE to have an RMA, but every RMA needs to be attached to its appropriate parent incident.

To do this I created a new class called Flexity.RMA.Class, created a new form from scratch in Visual Studio, and packaged the MP (Management Pack) XML and form assembly (.dll) into an MPB (management pack bundle).
I uploaded this to the console, and created a new console task called "Create RMA" that became visible when selecting the incident module.

This task would launch my PowerShell script, which in turn would take the ID of the incident selected or opened, create an RMA object, and associate the RMA object created with the ID # of the Incident (allowing it to be seen later in the "Related Items" Tab of the incident).
However, I ran into a problem here. I create the linking functionality correctly, but I cannot get the RMA form to automatically open up after it is created. Instead, when the task is run, it creates the object and saves it, but the analyst has to close the incident and reopen it to refresh the new data, navigate to the "Related Items" tab, and select the newly created RMA to open it up and fill out the form. This is alot of extra work and should be eliminated.
The correct functionality should be to create the RMA form, associate it with the open/selected incident, and launch the RMA form it just created to allow the analyst to fill in its details.

Apparently there is no function to call/launch the form directly from the console task. It seems I must modify the assembly code directly to be able to access the SCSM SDK (the layer I need to be working in). This is where I am lost - I have no idea how to convert my PowerShell script to C# Assembly code. Any help would be greatly appreciated.

I have provided my existing code below:

PowerShell Script:
#Script that does the linking and renaming:

# Creates a variable called IncidentID and points Incident # to it for use within the script

# Load the SMlets module
Import-Module SMlets 

# Get the Incident Class
$IncClass = Get-SCSMClass -Name System.WorkItem.Incident$

# Get the RMA Class
$RMAClass = Get-SCSMClass -Name Flexity.RMA.Class

# Build the Filter String
$FilterStr = "ID -eq " + $IncidentID

# Find the Incident we need to link to an RMA
$Inc = Get-SCSMObject -Class $IncClass -Filter $FilterStr
$RMAIncText = "[Linked to Incident " + $Inc.ID + "]"
$RMADescription = $RMAIncText 
New-SCSMObject -Class $RMAClass -PropertyHashtable (@{Title = $Inc.Title; Description = $RMADescription})

# Find the new RMA to be linked
$FilterStr = "Description -eq '$RMADescription'"
$RMA = Get-SCSMObject -Class $RMAClass -Filter $FilterStr

#Set RMA Number Variable
$RMANumber = $RMA.RMA_ID; 
#Clean up DisplayName, Title and Description  
$RMA | Set-SCSMObject -PropertyHashtable @{"DisplayName"  =  $RMANumber; "Title" =  $RMANumber; "Description" =  $RMANumber;   }

## Create an Incident Related Items instance referencing the new RMA
$RWIClass = Get-SCSMRelationshipClass -Name System.WorkItemRelatesToWorkItem$
New-SCSMRelationshipObject -Relationship $RWIClass -Source $Inc -Target $RMA -Bulk

# Unload the SMlets module
Remove-Module SMlets

Open in new window

Assembly Code:
public class RMATask : ConsoleCommand
        public RMATask()
        public override void ExecuteCommand(IList<NavigationModelNodeBase> nodes, NavigationModelNodeTask task, ICollection<string> parameters)
            IManagementGroupSession session = (IManagementGroupSession)FrameworkServices.GetService<IManagementGroupSession>();
            EnterpriseManagementGroup emg = session.ManagementGroup;

            ManagementPack mp = emg.ManagementPacks.GetManagementPack(new Guid("a82d62c5-ece0-35fd-a266-9afa246dea78"));
            ManagementPackClass mpc = emg.EntityTypes.GetClass(new Guid("4b081ab1-f48e-9c62-77bc-76bc31349030"));
            ManagementPackObjectTemplate mpt = emg.Templates.GetObjectTemplate(new Guid("92ed7c4d-aff5-819e-90f8-c92064c50cd6"));

            NavigationModelNodeBase nodeIn = nodes[0];

            NavigationModelNodeBase nmnbNew;
            NavigationModelNodeTask nmntNew = NavigationTasksHelper.CreateNewInstanceLink(mpc, mpt);
            Microsoft.EnterpriseManagement.GenericForm.GenericCommon.MonitorCreatedForm(nodeIn, nmntNew, out nmnbNew);

Open in new window

If you need any other info from me please don't hesitate to ask. Thanks in advance to all those who can help.
Sir Learnalot
Sir Learnalot
  • 3
1 Solution
Sir LearnalotAuthor Commented:
If anyone is looking for some code to use as reference, I am not sure but I THINK this may help, refer to the second post down (the marked answer to the question):

Sir LearnalotAuthor Commented:
I have solved my own question. Here is the code for those interested:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
/// using System.Threading.Tasks; <- .NET 4.5 only
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.EnterpriseManagement;
using Microsoft.EnterpriseManagement.Common;
using Microsoft.EnterpriseManagement.Configuration;
using Microsoft.EnterpriseManagement.ConnectorFramework;
// using Microsoft.EnterpriseManagement.UI.Core;
using Microsoft.EnterpriseManagement.UI.Extensions.Shared;
using Microsoft.EnterpriseManagement.UI.FormsInfra;
using Microsoft.EnterpriseManagement.UI.Core.Connection;
using Microsoft.EnterpriseManagement.UI.DataModel;
using Microsoft.EnterpriseManagement.UI.SdkDataAccess;
using Microsoft.EnterpriseManagement.UI.SdkDataAccess.DataAdapters;
using Microsoft.EnterpriseManagement.UI.WpfWizardFramework;
using Microsoft.EnterpriseManagement.ServiceManager.Application.Common;
using Microsoft.EnterpriseManagement.ConsoleFramework;
using Microsoft.EnterpriseManagement.GenericForm;
// using System.Management.Automation;
[assembly: CLSCompliant(true)]

namespace Flexity.RMA
    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>

    class RMATask : CreateWithLinkHandler
        public RMATask()

                // Sealed RMA Class GUID
                this.createClassGuid = new Guid("9ebd95da-1b16-b9ea-274d-6b0c16ce1bf3");
                this.classToDelegate = new Dictionary<Guid, CreateLinkHelperCallback>()
                    { ApplicationConstants.WorkItemTypeId, new CreateLinkHelperCallback (this.WorkItemCallback) }
            catch (Exception exc1)
                MessageBox.Show(exc1.Message, "Exception", MessageBoxButton.OK, MessageBoxImage.Error);

        public void WorkItemCallback(IDataItem RMAForm, IDataItem IncidentForm)
                // Note to self: RelatedWorkItems should be in MP XML as alias under TypeProjections
                if (RMAForm != null && RMAForm.HasProperty("RelatedWorkItems"))
                    // Perform Linking
                    RMAForm["RelatedWorkItems"] = IncidentForm;
                    // Copy Incident Title to RMA Title
                    RMAForm["Title"] = IncidentForm["Title"];
                    // Copy Incident Description to RMA Description
                    RMAForm["Description"] = IncidentForm["Description"];
            catch (Exception exc2)
                MessageBox.Show(exc2.Message, "Exception", MessageBoxButton.OK, MessageBoxImage.Error);
    public partial class WITemplate: UserControl
        private readonly RelatedItemsPane _relatedItemsPane;
        public WITemplate()
            var paneConfig = new WorkItemRelatedItemsConfiguration("RelatedWorkItems", "RelatedWorkItemSource",
                                                               "RelatedConfigItems", "RelatedKnowledgeArticles",
            _relatedItemsPane = new RelatedItemsPane(paneConfig);
            tabItemRelItems.Content = _relatedItemsPane;

Open in new window

Sir LearnalotAuthor Commented:
Will improve with more error correction. If anyone interested leave a message and Ill post the modifications as they come

Featured Post

Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now