locked
Issue assigning user to review activity using powershell RRS feed

  • Question

  • I have a powershell script to be run in a workflow, triggered when a change request of a specific templateId is created.  It should assign a review activity to a user.

    As I step through the script, it throws an exception, and does not add the reviewer to the RA.

    Exception calling "Commit" with "0" argument(s): "A discovery data item was rejected because the item is already bound to another Membership relationship."
    At D:\PS1\Update-ReviewActivityAssignedTO-New4.ps1:42 char:19
    +    $RAStep1.Commit <<<< ()
        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
        + FullyQualifiedErrorId : DotNetMethodException

    All of my varibles are valid, and are not NULL...  Not sure what the problem is?

    # Script Pre-reqs
    # Set execustion policy and import SMlets if not already imported.
     set-executionpolicy -executionPolicy ByPass 
     $a = (get-module|%{$_.name}) -join " "
     if(!$a.Contains("SMLets")){Import-Module SMLets -ErrorVariable err -Force}
    
    #Temporary CR assingment for testing, remove for full testing.
    $CRID = "CR611"
    $1stApprover = "UserID" # Only here for testing, when reading remove this line and uncomment theline below listed as 1stApprover.
    
    #Grab classes and relationships
     $ReviewerClass = get-scsmclass -name System.Reviewer$
     $UserClass = Get-SCSMClass -Name Microsoft.AD.User$
     $RAHasReviewerRel = get-scsmrelationshipclass -name System.ReviewActivityHasReviewer$
     $AssignedToRel = get-scsmrelationshipclass -name System.WorkItemAssignedToUser$
     $ReviewerIsUserRel = get-scsmrelationshipclass -name System.ReviewerIsUser$
     $WIContainsActivityRel = get-scsmrelationshipclass -name System.WorkItemContainsActivity$
    
    #Assign Reviewer to varible
    #$ApproversMatrix = Import-Csv \\server\share\file.csv
    #$1stApprover = $Approversmatrix | ? {$_.functionalarea -eq $area} | select "MinorChangeRequestApprover"
    #$2ndApprover = $Approversmatrix | ? {$_.functionalarea -eq $area} | select "AlternateMinorChangeApprover"
    
    $User1 = Get-SCSMObject -Class $UserClass –Filter "Username -eq $1stApprover"
    #$User2 = Get-SCSMObject -Class $UserClass –Filter "Username -eq $2ndApprover" 
    
    #Grab the ChangeRequest Object per the CR_ID provided as input parameter from SCSM.
    $CRObject = Get-SCSMObject -Class (Get-SCSMClass -name System.WorkItem.ChangeRequest$) -filter "ID -eq $CRID"
    
    #Grab the ReviewActivites for the above ChangeRequest
    $RActivities = Get-SCSMRelatedObject -SMObject $CRObject | ?{$_.displayname -like "RA*"}
    
    #Assign the Reviewer per the ApprovalMatrix
    $ReviewerArgs = @{ReviewerID = "$User1"; Mustvote = $true; Veto = $true}
    
     foreach ($RA in $RActivities)
      {
       $Reviewer = $null
       $Reviewer = new-scsmobject -class $ReviewerClass -propertyhashtable $ReviewerArgs -nocommit
       $RAStep1 = new-scsmrelationshipobject -nocommit -relation $RAHasReviewerRel -source $RA -target $Reviewer
       $RAStep2 = new-scsmrelationshipobject -nocommit -relation $ReviewerIsUserRel -source $reviewer -target $User1
       $RAStep1.Commit()
       $RAStep2.Commit()
      }
    

     


    Joshua Fuente

    Tuesday, November 20, 2012 2:43 AM

Answers

  • Hi there,

    the reason for this is because you've specified a "hardcoded" value for the ReviewerID in the $ReviewerArgs hashtable. The ReviewerID though is an auto-increment property. You can see what properties details by running this cmd in powershell (smlets to be loaded before :))

    (get-scsmclass -name System.Reviewer$).PropertyCollection

    It seems SCSM creates, every time you choose a user as a reviewer, a new reviewer object, although a reviewer object for that particular user already exist (at least that's the behaviour in my environment :))

    You can validate that if you run this script:

    import-module smlets
    $reviewerclass = get-scsmclass -name System.Reviewer$
    $ReviewerIsUserRel = get-scsmrelationshipclass -name System.ReviewerIsUser$
    $AllReviewer = get-scsmobject -class $reviewerclass
    foreach ($Reviewer in $AllReviewer) {get-scsmrelatedobject -SMObject $Reviewer -relationship $ReviewerIsUserRel};

    In my case I receive an output which shows me that a reviewer object is created multiple times for a single user-object.

    Long story short, you have to modify this line

    $ReviewerArgs = @{ReviewerID = "$User1"; Mustvote = $true; Veto = $true}

    to this: $ReviewerArgs = @{ReviewerID = {0}; Mustvote = $true; Veto = $true}

    The RAStep2 command takes care that the reviewer object gets related to your user object.

    To be honest, I don't quite understand why multiple reviewer objects get created for single user objects. The relationship cardinality between a RA and a reviewer (ReviewActivityHasReviewer) at least allows almost infinite relationships which means a reviewer object can be related to more than one RA. I guess only MSFT knows :)

    Try to change the ReviewerArgs as mentioned and give it another try. Let me know if that helps.

    Cheers

    Alex


    Tuesday, November 20, 2012 10:13 AM

All replies

  • Hi there,

    the reason for this is because you've specified a "hardcoded" value for the ReviewerID in the $ReviewerArgs hashtable. The ReviewerID though is an auto-increment property. You can see what properties details by running this cmd in powershell (smlets to be loaded before :))

    (get-scsmclass -name System.Reviewer$).PropertyCollection

    It seems SCSM creates, every time you choose a user as a reviewer, a new reviewer object, although a reviewer object for that particular user already exist (at least that's the behaviour in my environment :))

    You can validate that if you run this script:

    import-module smlets
    $reviewerclass = get-scsmclass -name System.Reviewer$
    $ReviewerIsUserRel = get-scsmrelationshipclass -name System.ReviewerIsUser$
    $AllReviewer = get-scsmobject -class $reviewerclass
    foreach ($Reviewer in $AllReviewer) {get-scsmrelatedobject -SMObject $Reviewer -relationship $ReviewerIsUserRel};

    In my case I receive an output which shows me that a reviewer object is created multiple times for a single user-object.

    Long story short, you have to modify this line

    $ReviewerArgs = @{ReviewerID = "$User1"; Mustvote = $true; Veto = $true}

    to this: $ReviewerArgs = @{ReviewerID = {0}; Mustvote = $true; Veto = $true}

    The RAStep2 command takes care that the reviewer object gets related to your user object.

    To be honest, I don't quite understand why multiple reviewer objects get created for single user objects. The relationship cardinality between a RA and a reviewer (ReviewActivityHasReviewer) at least allows almost infinite relationships which means a reviewer object can be related to more than one RA. I guess only MSFT knows :)

    Try to change the ReviewerArgs as mentioned and give it another try. Let me know if that helps.

    Cheers

    Alex


    Tuesday, November 20, 2012 10:13 AM
  • To be honest, I don't quite understand why multiple reviewer objects get created for single user objects. The relationship cardinality between a RA and a reviewer (ReviewActivityHasReviewer) at least allows almost infinite relationships which means a reviewer object can be related to more than one RA. I guess only MSFT knows :)

    Just FYI, the "reviewer" object maintains a user's vote for a particular review activity. That's why you need one reviewer object per review activity per user. If you only had one reviewer object related to many review activities, then a single vote would apply to many review activity (which isn't ideal..but you could do it if you wanted to).

    As for wondering why the relationship is many-to-many, I'm assuming it's because, in Service Manager, 1-to-many and many-to-many are the same thing. (It's a drawback in the Service Manager framework. It does not respect a relationship source's max cardinality..it's always many).

    Tuesday, November 20, 2012 6:08 PM
  • Just FYI, the "reviewer" object maintains a user's vote for a particular review activity. That's why you need one reviewer object per review activity per user. If you only had one reviewer object related to many review activities, then a single vote would apply to many review activity (which isn't ideal..but you could do it if you wanted to).

    As for wondering why the relationship is many-to-many, I'm assuming it's because, in Service Manager, 1-to-many and many-to-many are the same thing. (It's a drawback in the Service Manager framework. It does not respect a relationship source's max cardinality..it's always many).

    Thanks Aaron, this does make sense! Haven't thought about the vote results. It was indeed the cardinality issue (or behaviour, call it what you want :)) you've mentioned which confused me.

    Regards

    Alex

    Wednesday, November 21, 2012 8:12 AM