Home Powershell
Options

Quick assign to analyst, SMLets?

_ABIM_Support_ABIM_Support Customer IT Monkey ✭
edited April 3 in Powershell

I posted this in the SMLets thread but didn't want to clog it up asking for additional help. I am trying to figure out a way to be able to forward an email and have it quick create and assign to a specific analyst. This can be via the email emailed or the subject or body. So far I have been trying to do it with the recipient email, but without making 20 mailboxes that all have individual redirect rules (which DOES work with SMLets Multi Mailbox feature I am just trying to do it without maintaining a bunch of mailboxes). Using transport rules though it is not possible to handle BCC because it is not written to a header and therefore cannot be matched by SMLets.

After much research it seems like the custom events script might be able to do what I want via subject or body. I think I just need a little help with the steps (I am not an SCSM guy)

-Copy smletsExchangeConnector_customEvents.ps1 somewhere to server and .dot source it into the SMLets config page under DLL

-Add some code to Invoke-AfterCreateSR (we only use SRs pretty much) function within the customEvents script, something like below (ripped from another thread and modified). Would this work? Is $newWorkItem.ID correct? If nothing hits in this switch statement would it then proceed normally or do I need to account for that? Are there other good examples floating around I could copy? I am also open to other ways to do it.

function Invoke-AfterCreateIR {
# This function occurs after a new incident work item is created. 

    $ID = $NewWorkItem.ID ### I am guessing here based off custom events examples
    $SRClass = Get-SCSMClass -name System.WorkItem.ServiceRequest$
    $UserClass = Get-SCSMClass -name System.Domain.User$
    $AssignedToUserRelClass  = Get-SCSMRelationshipClass -Name System.WorkItemAssignedToUser$
    $ServiceRequest = Get-SCSMObject -Class $SRClass -Filter "ID -eq $ID"
    #Maybe I could use $newWorkItem instead of doing the $serviceRequest lookup on the ID?
   
    Switch -wildcard $email.Subject {
        '*[USER1]*' {
            try {
                $User = Get-SCSMObject -Class $UserClass -Filter "Username -eq 'USER1'"
                New-SCSMRelationshipObject -RelationShip $AssignedToUserRelClass -Source $Incident -Target $User -Bulk
        }
        catch { $logMessage = $_.Exception.Message 
        New-SMEXCOEvent -Source "CustomEvents" -EventId 25 -LogMessage $logMessage -Severity "Error" 
        }
    }

    '*[USER2]*'{
       try { 
        $User = Get-SCSMObject -Class $UserClass -Filter "Username -eq 'USER2'"
        New-SCSMRelationshipObject -RelationShip $AssignedToUserRelClass -Source $Incident -Target $User -Bulk 
            }
            catch { $logMessage = $_.Exception.Message 
                New-SMEXCOEvent -Source "CustomEvents" -EventId 25 -LogMessage $logMessage -Severity "Error" 
            }
        }
    }
}

Thank you!

EDIT: Updated example code to show my new wisdom about relationships and assigning the analyst. I got this to work in a small example script where I explicitly defined the SR# and User, just trying to translate it to custom events automation now.

Comments

  • Options
    Simon_ZeinhoferSimon_Zeinhofer Customer Ninja IT Monkey ✭✭✭✭

    So when poeple are writing an email they send it to the corresponding Analyst in bcc? Why not in cc, as cc gets saved into the $email object inside the exchange connector and then you could easily assign it to the analyst who is mentioned.

  • Options
    _ABIM_Support_ABIM_Support Customer IT Monkey ✭
    edited April 4

    People use to, cc, and bcc (for varying use cases). I want to support all of them (I currently have it working with TO/CC via transport rules). I honestly don't think it is possible without using tons of extra mailboxes + redirect which is why I wanted to look into subject based processing (something we always wanted to mess with). I would try my code but I don't really know how to debug it with SMLets running as a mgmt pack and custom events dot sourced in so just looking for some feedback.

  • Options
    Simon_ZeinhoferSimon_Zeinhofer Customer Ninja IT Monkey ✭✭✭✭

    Bcc is a way to hide recipients on purpose and after some searching, there is no way finding it in the header. Imo it is like decrypting an encrypted password with no key - if it was possible, the encryption wouldn't make any sense - and it's the same with BCC (maybe not exactly the same but I guess you get what I mean 😉 )

    I guess the easiest way around would bring people to use cc if they want SRs to be automatically assigned.

    To the customevents, the variables are correct. Still I wouldn't recommend searching a user via some information in square brackets. We use square brackets for direct group assignment, be it via Support Group names or certain key words, and what can I say: It seems there are so many stumbling blocks (Some are not able to differentiate between [ and {, others forget the square brackets as a whole, misspelling, etc. etc.) with that.

    And you really want end users to be able to assign an SR or Incident directly based on the user they mention in to, cc or bcc? May I ask why you wanna do that? I guess if I implemented such thing in our company, the whole IT would chase me away with torches 😁

  • Options
    _ABIM_Support_ABIM_Support Customer IT Monkey ✭

    I think we agree on inability to use BCC here. Like I said, I want to support it. It is just easier to throw in a BCC when you are replying to a thread you know has to end up with a certain analyst and not risk all the replies making new tickets or exposing the 'secret' email to random people. All of this is for internal use within my IT group only. We constantly use this to assign certain things to certain analysts as quickly as possible and to do scheduled tickets to certain people. I may also want to expand subject based routing in the future now that I have started messing with it.

    You think my code looks ok? Is your main issue with using brackets in the subject just because you think users would mess it up? I am not worried about that since we are only using it internally. Worst case they typo it, it makes an unassigned ticket as normal. Based on another thread I read from Adam looks like I would be able to debug this by doing the following? I guess I am not sure how to include the custom events in the debugging if I do it this way

    Thanks for replying Simon

  • Options
    Adam_DzyackyAdam_Dzyacky Product Owner Contributor Monkey ✭✭✭✭✭
    edited April 4

    I saw this the other day on the main/larger thread but saw a couple of responses that kinda covered things. But I'll cover them here as well:

    • Custom Events are really only documented in so far as name and the descriptions contained therein for those functions. The repo has a handful of very direct examples. Some functions contained in the custom events script also feature verbose explanations of variables such as when using Custom Rules
    • Per my cited comment above, while powerful. Custom Events create the opportunity to bring the connector to a grinding halt if written incorrectly. All in all, its a fine line of - yes these exist and you can use them, but its undertaken entirely at your own risk as everyone's custom events could be different and I/others would have no way of quick and easily troubleshooting.
    • When it comes to debugging Custom Events. You'll need to open the SCSM Console, head over to Adminstration → Settings → SMlets Exchange Connector settings. In there, you'll go the workflow tab and disable the workflow then save. The connector is now no longer running. On the SCSM server, or using a run as account - you'll need to open PowerShell ISE or VSCode. Then open up the smletsExchangeConnector.ps1 script. Run it. This now gives you a first hand experience of the connector running and you can watch what errors (if any) arise. More importantly, you can breakpoint the Invoke-AfterCreateIR function and step line by line through it to verify your logic. You don't have to do this and should be a last resort if your custom log events aren't telling you what you're expecting

    Now with all of that said. Your function at a high level makes sense for what you want to do. What's worth calling out here is when you're in a Custom Event. Log where at all possible for your own troubleshooting. Second, make sure to include a default case in your switch statement so when things don't go to plan you have a path AND event as to why. Take the following example:

    $email = "problem on four, attn: user1"
    switch -wildcard ($email) { "*user1" { write-output "The assignee is user1. Log info event." } "*user2" { write-output "The assignee is user2. Log info event." } default { write-output "Not sure who the assignee should be. Log warning event." }}

    But a couple of things worth pointing out in the context of the function you are in:

    $ID = $NewWorkItem.ID ### I am guessing here based off custom events examples
        $SRClass = Get-SCSMClass -name System.WorkItem.ServiceRequest$
        $UserClass = Get-SCSMClass -name System.Domain.User$
        $AssignedToUserRelClass  = Get-SCSMRelationshipClass -Name System.WorkItemAssignedToUser$
        $ServiceRequest = Get-SCSMObject -Class $SRClass -Filter "ID -eq $ID"
        #Maybe I could use $newWorkItem instead of doing the $serviceRequest lookup on the ID?
    

    Your guesses are correct but $ID, $SRClass, $UserClass $AssignedToUserRelClass, and even $ServiceRequest are all already known when you are in the function

    • Your function can simply make use of the $newWorkItem variable as you commented
    • The classes $SRClass, $UserClass ($domainUserClass in the case of the connector), and $AssignedToUserRelClass are set by the connector. Check out things in the primary script starting around line 800. You'll see a host of common variables that you can use if necessary to avoid redeclaring them
    • The function is Invoke-AfterCreateIR, but you're using a Service Request based class. Either you're in the wrong function, or this was a copy paste mistake. In any case, it's all the more reason to use the $newWorkItem variable as its Id, Class, etc. are all known, and exist contextually. Which means the nature of your function can not only be trimmed down significantly, but the core logic of what you're trying to do is really just what's in your switch statement

  • Options
    _ABIM_Support_ABIM_Support Customer IT Monkey ✭

    Thank you so much Adam! Exactly what I needed and very much appreciated.

  • Options
    _ABIM_Support_ABIM_Support Customer IT Monkey ✭
    edited April 5

    I ended up with this which seems to work. However, it only works when the logging level is set to Verbose (4) lol. Anything lower and it does not seem to run or even write my debug event logs like it isn't parsing the customEvents. Might just need to upgrade SMLets which is like 3.4? Anyone have upgrade tips? I assume for the ps1 i just replace it but how do I handle the upgraded management pack without losing the config?

    Anyway in case someone stumbles across this thread:

    function Invoke-AfterCreateSR {
        $matchFound = $false
        $userMappings = @{
            'user1' = 'user1username'
            'user2' = 'user2username'
            # Add more mappings here as needed
        }
        # Iterate through each user identifier and process accordingly
        # Iterate through each user identifier and process accordingly
        foreach ($userIdentifier in $userMappings.Keys) {
            # Check if the user identifier matches any key in the hashtable
            if ($email.Subject -match "\[$userIdentifier\]" -or $email.Body -match "\[$userIdentifier\]") {
                $username = $userMappings[$userIdentifier]
                $matchFound = $true
                # Attempt to retrieve the user from SCSM and create relationship
                try {
                    $User = Get-SCSMObject -Class $domainUserClass -Filter "Username -eq '$username'"
                    New-SCSMRelationshipObject -RelationShip $AssignedToUserRelClass -Source $newWorkItem -Target $User -Bulk
                }
                catch {
                    $logMessage = $_.Exception.Message
                    New-SMEXCOEvent -Source "CustomEvents" -EventId 25 -LogMessage $logMessage -Severity "Error"
                }
                # Exit the loop once a match is found
                break
            }
        }
        # If no match is found, throw an error
        if (-not $matchFound) {
            $logMessage = "No matching user found in the email subject."
            New-SMEXCOEvent -Source "CustomEvents" -EventId 3 -LogMessage $logMessage -Severity "Information"
        }
        else {
            $logMessage = "Found match, assigning to analyst $user"
            New-SMEXCOEvent -Source "CustomEvents" -EventId 3 -LogMessage $logMessage -Severity "Information"
        }
    }
    

  • Options
    Adam_DzyackyAdam_Dzyacky Product Owner Contributor Monkey ✭✭✭✭✭
    edited April 23

    Yes, you'll need to upgrade. That was an issue that was fixed in v5.0.3. All you need to do is:

    • Upgrade the management pack. You wont lose the settings.
    • Replace the smletsExchangeConnector.ps1 script
    • New Custom Events have been introduced since then. You'll need to add them yourself/merge into your Custom Events. Perhaps the easiest thing here since you only have one function your using is copy your code off to the side, replace the Custom Events file to get yourself to parity, and then paste it back in.

  • Options
    _ABIM_Support_ABIM_Support Customer IT Monkey ✭

    Thanks again!

Sign In or Register to comment.