Home Cireson Uploads
image


IT Monkey will place code here as examples of what Cireson's consulting team has to offer as well as examples for public consumption to benefit the Microsoft System Center community as a whole.

DISCLAIMER

All files and projects located here come as is and without any warranty or support. We will attempt to improve the projects as time goes on based on customer and community demand. Comments and improvements are welcome as well as customization requests. Your use of these Cireson Uploads is subject to our Terms of Use.


Cireson's support team has no information on these projects outside of what you have available and will not provide support for these enhancements, extensions, and scripts.

Dont forget to checkout solutions uploaded by our customers, partners and community members here.

Locking the work item

john_doylejohn_doyle Cireson Support Ninja IT Monkey ✭✭✭✭
This is my attempt to prevent analysts from losing work because more than one of them has accessed the same work item. It won't stop work items being updated by e-mail or by work flows. It also will not stop someone from updating a work item through the SCSM Console.

What it does:

  • User opens workitem
  • Checks if there is an object with the same ID in the work item lock class
  • If there is none, a new entry is created for this workitem. The lock is then updated every 30 seconds.
  • If a lock is found, the code checks if the lock belongs to this user, or if it is older than 35 seconds. In this case the lock is updated with the current time and the details of the user. The lock is then updated every 30 seconds.
  • If the lock is found but the lock is held by a different user and was last updated less than 35 seconds ago, the user is alerted that the work item is being edited by the user holding the lock and the Save and Apply buttons are disabled.

Installation:

  1. Unzip the attached file.
  2. Import the Management Pack into the SCSM Console
  3. Run the PowerShell script to give End Users create/edit rights to the Work Item Lock class
  4. Add the JavaScript code in the custom.js file to the same file in C:\intepub\CiresonPortal\CustomSpace folder.


N.B. This has not been tested in a production environment. Please test it thoroughly before implementing it. I am sure it needs more error checking code before it is ready for use.

Comments

  • john_doylejohn_doyle Cireson Support Ninja IT Monkey ✭✭✭✭
    Oops, I meant to credit Marcel Zehner for the PowerShell script. It is not mine I got it from his blog.

  • john_doylejohn_doyle Cireson Support Ninja IT Monkey ✭✭✭✭
    Has anyone implemented this in their Portal? Just curious to see if it has been beneficial to anyone.
  • Justin_WorkmanJustin_Workman Cireson Support Super IT Monkey ✭✭✭✭✭
    I put it in my lab.  It works well! :)
  • Jeff_LangJeff_Lang Customer Ninja IT Monkey ✭✭✭✭
    heh we have been discussing something similar here recently, but i had missed this being uploaded.

    now that i've seen this one here i will be putting it into our dev environment for testing, and if it works well moving to production
  • Oskar_PittersOskar_Pitters Customer IT Monkey ✭
    Hi,
    running the powershell script I get the following error:
    Can you please help me
    Exception calling "GetClass" with "1" argument(s): "An object of class ManagementPackClass with ID<br>7e6f57b1-a805-182c-392c-f73a2f387c5d was not found."<br>At C:\Users\cobpio0\Desktop\WorkItemLock\Give end users permissions to write a work item lock..ps1:10 char:1<br>+ $class_cwl = $emg.EntityTypes.GetClass("7e6f57b1-a805-182c-392c-f73a2f387c5d")<br>+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>&nbsp;&nbsp;&nbsp; + CategoryInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : NotSpecified: (:) [], MethodInvocationException<br>&nbsp;&nbsp;&nbsp; + FullyQualifiedErrorId : ObjectNotFoundException<p></p><p>New-Object : Cannot find an overload for "OperationImplicitScope" and the argument count: "4".<br>At C:\Users\cobpio0\Desktop\WorkItemLock\Give end users permissions to write a work item lock..ps1:18 char:13<br>+ $oiobject = New-Object $oiscope -ArgumentList @($class_cwl.id,$emptyguid,$emptyg ...<br>+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>&nbsp;&nbsp;&nbsp; + CategoryInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : InvalidOperation: (:) [New-Object], MethodException<br>&nbsp;&nbsp;&nbsp; + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand</p><p>Exception calling "Update" with "0" argument(s): "Object reference not set to an instance of an object."<br>At C:\Users\cobpio0\Desktop\WorkItemLock\Give end users permissions to write a work item lock..ps1:20 char:1<br>+ $prof_eu.Update()<br>+ ~~~~~~~~~~~~~~~~~<br>&nbsp;&nbsp;&nbsp; + CategoryInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : NotSpecified: (:) [], MethodInvocationException<br>&nbsp;&nbsp;&nbsp; + FullyQualifiedErrorId : NullReferenceException</p><p>New-Object : Cannot find an overload for "OperationImplicitScope" and the argument count: "4".<br>At C:\Users\cobpio0\Desktop\WorkItemLock\Give end users permissions to write a work item lock..ps1:23 char:13<br>+ $oiobject = New-Object $oiscope -ArgumentList @($class_cwl.id,$emptyguid,$emptyg ...<br>+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>&nbsp;&nbsp;&nbsp; + CategoryInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : InvalidOperation: (:) [New-Object], MethodException<br>&nbsp;&nbsp;&nbsp; + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand</p><p>Exception calling "Update" with "0" argument(s): "Object reference not set to an instance of an object."<br>At C:\Users\cobpio0\Desktop\WorkItemLock\Give end users permissions to write a work item lock..ps1:25 char:1<br>+ $prof_eu.Update()<br>+ ~~~~~~~~~~~~~~~~~<br>&nbsp;&nbsp;&nbsp; + CategoryInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : NotSpecified: (:) [], MethodInvocationException<br>&nbsp;&nbsp;&nbsp; + FullyQualifiedErrorId : NullReferenceException</p>
  • Justin_WorkmanJustin_Workman Cireson Support Super IT Monkey ✭✭✭✭✭
    @Oskar_Pitters - this script is assuming SCSM 2016.  Are you in SCSM 2016 or 2012?
  • Oskar_PittersOskar_Pitters Customer IT Monkey ✭

    Okay, I have SCSM 2012 R2 installed.

    But the scripts seems to work in my Test environment. I get a flag that the ticket ist currently edited by User X, and I can not make any changes on the Ticket.

    That's great work. I will test it the next day in our live environment.

  • Justin_WorkmanJustin_Workman Cireson Support Super IT Monkey ✭✭✭✭✭
    @Oskar_Pitters Also, did you import the MP before running the Powershell?  I'm trying it in my 2012 lab now and if you run the script before importing the MP, the Cireson WorkItem Lock class doesn't exist which is the first failure you're seeing.
  • Oskar_PittersOskar_Pitters Customer IT Monkey ✭
    @Justin_Workman I did the installation step by step as it is described. Imported the *.mp then updated the path variable in the powershell script to my installation path of SCSM. Script runs and throws the exceptions I posted above.

    I think that the Class ID in SCSM 2012 is different to SCSM 2016. Maybe you can tell me the Class ID.

    $class_cwl = $emg.EntityTypes.GetClass("7e6f57b1-a805-182c-392c-f73a2f387c5d")

    But it seems to work properly in my TEST environment.

  • Tom_HendricksTom_Hendricks Customer Super IT Monkey ✭✭✭✭✭
    I get a different type of error when running the script (on 2016):
    Exception calling "Update" with "0" argument(s): "The operation 7d6e1092-6ddc-4da1-a947-18fe5d538a69 in the profile <br>523382b8-c524-4641-a2e7-cfdfb4b6eb34 is already restricted to the same type or its base type. Hence there is no need to restrict it to the specified <br>type."<br>At C:\[PATH]\Give end users permissions to write a work item lock.ps1:20 char:1<br>+ $prof_eu.Update()<br>+ ~~~~~~~~~~~~~~~~~<br>    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException<br>    + FullyQualifiedErrorId : ProfileOperationImplicitScopeAlreadyExistsException<br> <br>Exception calling "Update" with "0" argument(s): "The operation 7d6e1092-6ddc-4da1-a947-18fe5d538a69 in the profile <br>523382b8-c524-4641-a2e7-cfdfb4b6eb34 is already restricted to the same type or its base type. Hence there is no need to restrict it to the specified <br>type."<br>At C:\[PATH]\Give end users permissions to write a work item lock.ps1:25 char:1<br>+ $prof_eu.Update()<br>+ ~~~~~~~~~~~~~~~~~<br>    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException<br>    + FullyQualifiedErrorId : ProfileOperationImplicitScopeAlreadyExistsException

    I am not quite sure how to interpret this message.
  • Jeff_LangJeff_Lang Customer Ninja IT Monkey ✭✭✭✭
    @Tom_Hendricks can you try running the script again, but output $prof_eu to check it has been set correctly, you should get output for it similar to the below
    >$prof_eu<br><br>Name                     : EndUser<br>DisplayName              : End User<br>Description              : End Users can use the self-service portal to create incidents, request software installation, <br>                           view announcements, and search the knowledge base.<br>HasSingleUserRole        : False<br>IsImplicitProfile        : False<br>ImplicitRelationship     : 00000000-0000-0000-0000-000000000000<br>IsImplicitEndpointSource : False<br>Operations               : {TypeProjection__Get, TypeCache__Get, Image__Get, User_Identity__Get...}<br>Scope                    : 515<br>Id                       : 523382b8-c524-4641-a2e7-cfdfb4b6eb34<br>ManagementGroup          : XXXXXXXX<br>ManagementGroupId        : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br>

  • Tom_HendricksTom_Hendricks Customer Super IT Monkey ✭✭✭✭✭
    I do get very similar output.  If I grab $prof_eu.Operations.ImplicitScopes, I do see two identical items that suggest that I already have this in place (maybe from what I thought was an unsuccessful run?):

    Shortcut to this: $prof_eu.Operations.ImplicitScopes | ? { $_.Class -eq '7e6f57b1-a805-182c-392c-f73a2f387c5d'}<br><br>Class                : 7e6f57b1-a805-182c-392c-f73a2f387c5d<br>Property             : 00000000-0000-0000-0000-000000000000<br>Relationship         : 00000000-0000-0000-0000-000000000000<br>RelationshipEndpoint : 2<br>IsCustomized         : True<br>ManagementGroup      : <br>ManagementGroupId    : 00000000-0000-0000-0000-000000000000
    These are actual values, not sanitized.

    Does it matter that I use a custom End User role instead of the OOB one?  The OOB role does exist, obviously, but it has no explicit members.  I attempted to add the internal name of my role on line 8 (also by ID and display name) but I got a bunch of nulls throughout the script that caused different errors.  So I have reverted back to this, to keep troubleshooting simple for now.
  • Jeff_LangJeff_Lang Customer Ninja IT Monkey ✭✭✭✭
    @Tom_Hendricks  This should work if added to the OOB End User Role, i ran it myself again, and didn't get those errors, even with it already setup, did you change the where{$_.name -eq "EndUser"} or leave it as is?

    we also don't use the OOB End User Role, but one based off it, and running the script with the only change being the path to the dll works every time here (SCSM 2016, SQL 2016, Server 2012R2)

  • Tom_HendricksTom_Hendricks Customer Super IT Monkey ✭✭✭✭✭
    @Jeff_Lang I believe you are correct.  I am testing it with an end user and it is working out great.  Our test environments are identical in terms of SCSM / SQL / OS, for what that is worth.

    I had originally changed that line to match my end user role, then changed it back and ran again.  I will run it clean in the next environment.

    But the good news is that this appears to be working fine in spite of the errors.

    @john_doyleI absolutely love this! 

    I modified mine to have a persistent message at the top-right of the page, but I want to live with it for a while and get extra opinions before actually sharing it as a suggestion.  Your way might be the right one--my way is just more similar to the way our old system worked.

    I do plan to run a workflow to clean out "old" locks, potentially...but I want to test the usefulness of keeping them first.  I did create a CI view of them so that I can see where this goes.
  • Jeff_LangJeff_Lang Customer Ninja IT Monkey ✭✭✭✭
    @Tom_Hendricks glad to hear it is working now, have been testing this a bit, and made some slight modifications to suit our environment a bit more, hopefully we'll be able to add this to production within the next week or 2.

    Like you we'll also be adding something to clear out old items, not sure if we'll have it clear out items older than a day or week etc yet though
  • Tom_HendricksTom_Hendricks Customer Super IT Monkey ✭✭✭✭✭
    I just wanted to provide an update.  We have rolled a slightly modified version of this all the way through our environments to production, and it is working extremely well. 

    Although I am still testing this in lower environments, initial testing is showing that we can "safely" disable the concurrency check without losing updates made by the system account, as a result.  If my last batch of tests works out, that will be a HUGE win, as the "data conflict error" is one of the most-complained-about "features."  Even if that does not work out, this is still providing benefit.

    I have the success block of the lock object commit creating an object in the view model, so that other functions of mine can A.) know that there is a lock, B.) know whether it belongs to the current user or someone else, outside of the scope of this code, and C.) I can run other functions based on whether the current user is locked out, such as removing certain tasks.  I have a message right below the title that indicates if the current user has the lock, or if someone else does.  If someone else, their name is a clickable link that opens a Skype IM.

    You are a hero, @john_doyle
  • Mike_LineMike_Line Customer IT Monkey ✭

    We installed this feature, and did not receive any errors. We are running SCSM 2016,on portal version 9.4.5.

    Although when I'm in the portal trying to test how it works, it does not.

    The IE Dev tools, shows a problem with this line: in the custom.js file

    Uncaught SyntaxError: Invalid or unexpected token - "TimeAdded": "0001-01-03T00:00:00.000Z"

    Any thoughts?

  • john_doylejohn_doyle Cireson Support Ninja IT Monkey ✭✭✭✭
    The most likely reason is that the comma at the end of the line before that one in custom.js file is missing.
  • Mike_LineMike_Line Customer IT Monkey ✭

    Hi @john_doyle

    I suspected that also, and have already tried this. Dev tools shows an error on that line with or without a comma at the end.

    I kept the comma at the end, and removed a space after "TimeAdded": and it is now working.

    Thanks for your quick response. Hopefully this helps others.

    Mike

  • john_doylejohn_doyle Cireson Support Ninja IT Monkey ✭✭✭✭

    Glad to hear it is sorted.

  • Sean_TerrySean_Terry Customer Advanced IT Monkey ✭✭✭

    Is this being used with the 9.4.11? Looking to implement this into Dev to test it. Not getting much luck so far from following the install instructions. MP in, PowerShell run ok and code added to .js file

  • Mike_LineMike_Line Customer IT Monkey ✭

    Could you assist with removing the ability to lock work items for a specific role, End Users.


    I have it applied to our analysts role, but do not want the end users to have this ability, it has been causing issues where they keep the incidents locked all day, and we cannot make changes to the incident.

Sign In or Register to comment.