Integrating PowerShell Script in C# Assembly Code

Posted on 2014-08-22
Last Modified: 2014-08-27
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.
Question by:Sir Learnalot
    LVL 5

    Author Comment

    by:Sir Learnalot
    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):
    LVL 5

    Accepted Solution

    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

    LVL 5

    Author Closing Comment

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

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Live - One-on-One C# Help from Top Experts

    Solve your toughest problems, fast.
    C# experts are online now and ready to help you.

    Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
    Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
    Internet Business Fax to Email Made Easy - With eFax Corporate (, you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
    Here's a very brief overview of the methods PRTG Network Monitor ( offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

    779 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    10 Experts available now in Live!

    Get 1:1 Help Now