locked
Auto Assigning Change reviewers via powershell RRS feed

  • Question

  • I am looking to auto populate the reviewers for a specific type of change request.  I am thinking I need to do this as a powershell script.  I dont have Orchestrator available yet. 

    I have been looking at this post, http://social.technet.microsoft.com/Forums/en-US/administration/thread/a0ff1dfd-4058-450e-b58c-65df53e6de9a

    I am assuming this needs to run as a WF when this specific type of CR is submitted. (or a step to check the type of CR before it runs)

    I have my own logic of "IF THEN" statements to determine who the reviewer should be based on the application selected in the CR.

    So I will have the reviewers account name, and I assume I can get the CR from the current context somehow?

    I am still new to SCSM, so I am not really sure how I should go about the script itself, So far I have this, but I get an error on the last statement.

    Here I am trying to just assign a user to a review activity, I still need to figure out the CRActivity parts...


    $RA = 'RA126' 
     
    $Implementer = "Last, First"

    $RAclass = Get-SCSMClass -Name  System.WorkItem.Activity.ReviewActivity$

    $RAObject = Get-SCSMObject -Class $RAclass -Filter "ID -eq $RA"

    $UserClass = Get-SCSMClass -Name Microsoft.AD.User$

    $User = Get-SCSMObject -Class $UserClass –Filter "DisplayName -eq $Implementer"

    $ImplementerRelationship = Get-SCSMRelationshipClass -Name System.ReviewActivityHasReviewer$
    $WIContainsActivityRel = get-scsmrelationshipclass -name System.WorkItemContainsActivity$
    $AllSRActivities = get-scsmrelatedobject -SMObject $RAobject -Relationship $WIContainsActivityRel
    $RActivities = $AllSRActivities | where {$_.ClassName -eq "System.WorkItem.Activity.ReviewActivity"}

    #Create a new Relationship Object Manual Activity - User (Implementer)
    New-SCSMRelationshipObject -RelationShip $ImplementerRelationship -Source $RAObject -Target $User -Bulk

    ERROR:

    New-SCSMRelationshipObject : The object with ID 77c952fe-728a-5761-9589-f09f00b5a9d3 is not of a valid class fo
    r insertion.
    At D:\PS1\Update-ReviewActivityAssignedTO.ps1:20 char:27
    + New-SCSMRelationshipObject <<<<  -RelationShip $ImplementerRelationship -Source $RAObject -Target $User -Bulk
     
        + CategoryInfo          : InvalidOperation: (Microsoft.Enter...ationshipObject:CreatableEnterp...ationship
       Object) [New-SCSMRelationshipObject], ArgumentException
        + FullyQualifiedErrorId : TargetError,SMLets.NewSCSMRelationshipObject


    Joshua Fuente

    Thursday, November 15, 2012 4:31 PM

Answers

  • Hi Joshua,

    adding Reviewer relationship to a RA is slightly different than adding a normal user relationship to a MA for instance.

    You have to use the last part of the script I wrote to add create a Reviewer - RA relationship:

    $ReviewerArgs = @{ReviewerID = "{0}"; Mustvote = $true; Veto = $true}
    
    	foreach ($RA in $RActivities)
    	{
    		if ((Get-SCSMRelatedObject -SMObject $RA -Relationship $RAHasReviewerRel) -eq $null)
    		{
    			$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 $AssignedUser
    			$RAStep1.Commit()
    			$RAStep2.Commit()
    		}
    	}
    }
    

    Please see this thread where James explains how to deal with reviewer class and why it's different than a normal user relationship like 'AssignedTo'

    Hope it helps.

    Cheers

    Alex

    Friday, November 16, 2012 11:42 AM

All replies

  • Hi Joshua,

    adding Reviewer relationship to a RA is slightly different than adding a normal user relationship to a MA for instance.

    You have to use the last part of the script I wrote to add create a Reviewer - RA relationship:

    $ReviewerArgs = @{ReviewerID = "{0}"; Mustvote = $true; Veto = $true}
    
    	foreach ($RA in $RActivities)
    	{
    		if ((Get-SCSMRelatedObject -SMObject $RA -Relationship $RAHasReviewerRel) -eq $null)
    		{
    			$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 $AssignedUser
    			$RAStep1.Commit()
    			$RAStep2.Commit()
    		}
    	}
    }
    

    Please see this thread where James explains how to deal with reviewer class and why it's different than a normal user relationship like 'AssignedTo'

    Hope it helps.

    Cheers

    Alex

    Friday, November 16, 2012 11:42 AM
  • Thanks, I knew there was something I was missing about the RAs.  The link you gave looks like its exactly what I am looking to do...

    With that in mind, how should I go about having this run?  I have a change template called "minorchangetemplate".  I would like this to run only on those templates.

    I am figuring I need to have a workflow that runs when any changerequest is created, use an If-Else statement to determine if the change templateId is "minorchangetemplate" and if so, run this script with the proper parameters.  If not, it stops.

    Seems straight forward?

    1. I have a matrix of approvers to use based the application selected in the change request. How can I incorporate that?

     - or would I need a script for each possibly combination? Or a big set of nested IfElse's?

    2. How do I grab the context of the current CRs review activity? (I need that as a parameter)

    - I am thinking I need a "pre" script to run and use get-scsmrelatedobject to get the current CR's review activity? (sound right? any better way?)

    Also, where is that "$AssignedUser" variable coming from in your example, what type of object does it need to be?


    Joshua Fuente


    • Edited by NachoScript Friday, November 16, 2012 8:01 PM added details
    Friday, November 16, 2012 7:42 PM
  • It seems you need to create custom workflows using the Authoring Tool for this. Here you probably need to create two workflows - one which triggers when a new CR is created and one when an existing CR is updated (it depends tough if you allow your change managers to apply your 'minorchangetemplate' template on existing CRs).

    Use the 'Additional Criteria' button to add a specific workflow trigger condition. Template ID as the workflow trigger property would probably make the most sense - via PowerShell and SMlets you should be able to retrieve the Template ID for your template. Maybe it's not even necessary - If I look in the history of any of our CRs the value of Template ID is everytime a string value (name of the template) and not the GUID which I'd actually expect for a property called Template ID (but I'd test it anyway with both to see when the workflow fires).

    In your custom workflow select a PSscript activity and drag it to the workflow sequence. Now add you code in the script body property of the PSscript activity. In the script parameter property you can specify the variables used by your script which are context related (like the CR ID). I'd recommend to specify the CR ID in this case as script parameter (see some information here), this way the script knows the distinct workitem and you don't have to get the workitem during script execution. The rest of the properties you may need during script execution can then be retrieved using the WorkItem properties and relationships to other classes (like for Review Activities).

    Regarding question 1:

    It's probably more efficient to use switch statements instead of nested if-else clauses. I've had a similar requirement for dynamic incident dispatching (location, department and busines unit of the affected user were relevant for the condition matrix). I've automated the dispatching by using a switch statement in powershell withing an Orchestrator Runbook. Based on the result of the switch statement the choosen group was set as "Assigned To" for the specific incident. The good thing about the switch statement is that you can define a default value when noone of your condition matches, this way you can define something like a "fallback approver" and your review activities have an appropriate reviewer assigned in any case. Since it's not possible to add groups to review activities you need to think how you can group your approvers together (in case you have more than one approver per application). Maybe it would make sense to group them in an AD group and then add each of the group members as reviewer using a foreach loop. Let me know if you need more information.

    Regarding question 2:

    Since you have the CR ID supplied by the SCSM workflow engine you can retrieve the relevant Review Activites using the get-scsmrelatedobject cmdlet as you've mentioned. This however does not necessarily needs to be a different script, I wouldn't exclude this at least...

    The $AssignedUser variable from my script is the user which is specified as "Assigned to" in the parent SR. This line fills the variable:

    $AssignedUser = Get-SCSMRelatedObject -SMObject $SR -Relationship $AssignedToRel

    The type of the var is "EnterpriseManagementObject". To get such an object from a string value you can use the get-scsmobject cmdlet and use the -Filter parameter (get-scsmobject -class (get-scsmclass -name System.Domain.User$) -Filter "DisplayName -eq MyString")

    Hope it helps.

    Cheers

    Alex

    Monday, November 19, 2012 10:59 AM
  • Thanks for the awesome reply!...  I have been able to create the script as described.  But I think I am having a type mismatch error, but I am going to start another thread for that.  Thanks for all the help.

    http://social.technet.microsoft.com/Forums/en-us/administration/thread/f4b98993-d70c-4216-b92c-2d9c61449d40


    Joshua Fuente

    Tuesday, November 20, 2012 2:53 AM