none
Mail notification with blank [//Target/AccountName] RRS feed

  • Question

  • I have a mail notification process that sends an email when a person moves out of set.

    However, the move out also applies when the user is deleted, thus emails are sent that contain no data e.g. [//Target/AccountName] is blank.

    Is there a built in way of validating that [//Target/AccountName] contains something, before getting to the Mail Notification Workflow activity? I considered that I could use an Authorization activity, but can't see how that would work.

    I see the other alternatives being - to create a custom workflow activity (with an If Else condition) or to use something like the PowerShell workflow Activity.

    Any advice gratefully received.

    TIA,

    Jon.

    Tuesday, October 20, 2015 10:27 AM

Answers

  • Got it. Is there a way you can redesign this process so it's not triggered on a Transition Out? That's probably going to be your cleanest option here.

    Thanks,
    Brian

    Consulting | Blog

    • Marked as answer by Jon Bryan Tuesday, October 20, 2015 11:13 PM
    Tuesday, October 20, 2015 9:35 PM
    Moderator

All replies

  • Jon-

    You could put a Function Evaluator activity ahead of the Notification Activity and inspect the AccountName field and either store it in WorkflowData (to be rendered in the email) or store some alternate text in there instead as one option.


    Thanks,
    Brian

    Consulting | Blog

    Tuesday, October 20, 2015 9:17 PM
    Moderator
  • Thanks Brian.

    What I'd like to achieve is, if the AccountName is NULL/ not present, then don't send the mail.

    I believe that what is happening is that as a user is deleted from the portal, they transition out of the set (as they no longer exist), thus the workflow is kicked off, but the workflow and mail template are trying to refer to the attributes of the now deleted account, so return no values.

    I could have an IIF statement looking for AccountName, and returning a fixed value for the workflow (maybe to use in the mail), but that will not prevent the mail from being sent.

    I have been playing with custom workflows today to see if they would provide a solution, but getting my head around the method is troublesome, especially as most examples are in C# rather than VB.net.

    Regards,

    Jon

    Tuesday, October 20, 2015 9:32 PM
  • Got it. Is there a way you can redesign this process so it's not triggered on a Transition Out? That's probably going to be your cleanest option here.

    Thanks,
    Brian

    Consulting | Blog

    • Marked as answer by Jon Bryan Tuesday, October 20, 2015 11:13 PM
    Tuesday, October 20, 2015 9:35 PM
    Moderator
  • Brian,

    Yes, I was also thinking along those lines today. However, I can't think of a way of defining the process so that it would be a transition in instead. The process notifies when a person moves within the organisation - the sets are essentially based on the OU that the account resides in. When the person moves out of an OU and into another - an internal move - the notification is sent to the helpdesk that used to manage that account.

    I was also considering using the PowerShell workflow, doing the evaluation there and then sending the mail directly from PowerShell. Need to do a little more digging to see how I can do this.

    Regards,

    Jon

    Tuesday, October 20, 2015 9:45 PM
  • Perhaps you could look at Transition In sets based on the various OUs or are there too many?

    You could send the message from the PowerShell workflow. You'd need to duplicate some of the email configuration stuff that's in FIM already plus you'd lose the retry capabilities but it could be easier.


    Thanks,
    Brian

    Consulting | Blog

    Tuesday, October 20, 2015 10:26 PM
    Moderator
  • Thanks Brian,

    There are many OU's and many sets of recipients, so I think that it would be unmanageable.

    I'll mark your suggestion for using a transition in as the answer, as I think that it is the out of the box answer.

    Out of interest - If I made a custom workflow that checked for the presence of the attribute, and set a mail notification based on an IfElse workflow function, would I retain the retry capability that I would lose by using the PowerShell activity?

    Regards,

    Jon

    Tuesday, October 20, 2015 11:13 PM
  • Thanks Brian,

    There are many OU's and many sets of recipients, so I think that it would be unmanageable.

    I'll mark your suggestion for using a transition in as the answer, as I think that it is the out of the box answer.

    Out of interest - If I made a custom workflow that checked for the presence of the attribute, and set a mail notification based on an IfElse workflow function, would I retain the retry capability that I would lose by using the PowerShell activity?

    Regards,

    Jon

    Hi Jon-

    A custom workflow that you describe would do what you want. You'd lose the built-in UI but you could recreate some or all of it if you wanted.

    Another option as I was thinking about this is to look at a Request driven MPR. If you can scope this to a change in a certain attribute (department or something like that?), you can setup an MPR that fires only when the relevant attributes are present and changed.


    Thanks,
    Brian

    Consulting | Blog

    Wednesday, October 21, 2015 12:20 AM
    Moderator
  • Brian,

    The problem is that the organisations structure is not hierarchical. All users have a Directorate, but that is the only assured value - some have Department, but no Division and vice versa - plus that scenario flows right down to the lowest structure "label"/ type.

    Thus, placement of users in AD (dn) is calculated on the Import from HR, in a coded flow. The idea of using the AD DN in the sets was to simplify the criteria needed to build the set memberships. I could use the same logic (from the code) to build the set membership, but that would not change the behaviour that I'm seeing - deletion would still result in leaving the set.

    I can't visualise how a request MPR could be constructed with this constraint.

    I'm going to further investigate creating a custom workflow to resolve this issue. It will be a good learning experience if nothing else!

    Thank you for your help.

    Regards,

    Jon

    Wednesday, October 21, 2015 3:01 PM
  • Hi, Brian,

    I'll add here my solution, it may help others.

    I spent quite some time trying to get a Custom Workflow solution together, but even trying those (VB.net) examples on Carols blog, I could not get anything to work. I'll probably come back to these workflows another time, for now I just need a workaround.

    I have ended up using the PowerShell Workflow. After a little frustration trying to get the attributes out of the PSObject, I have this:

    $VerbosePreference = 'Continue'
    $Global:ErrorActionPreference="Stop"
    $error.clear()
    if (-not $fimwf)
    {
        Throw "Failed to get workflow details from the FIM Target"
    }
    Write-Verbose "Processing FIM WF with TargetId: $fimwf"
    
    ###
    ### Load the FIM PowerShell Module and snapin
    ###
    add-pssnapin FIMAutomation
    Import-Module C:\CodePlex\FimPowerShellModule\FimPowerShellModule.psm1 -Verbose:$false
    
    ### 
    ### Get the Target
    ### 
    Write-Verbose ("Getting the Target by ObjectID: {0}" -F $fimwf.TargetId.Guid)
    $Target= Export-FimConfig -Custom ("/*[ObjectID='{0}']" -F $fimwf.TargetId.Guid) -OnlyBaseResources | Convert-FimExportToPSObject 
    
    ###
    ###	Get attributes (where available) for the mail
    ###
    Try
    {
    	$AccountName=$Target.AccountName
    	If ($AccountName -ne $NULL) # If there is no AccountName, the user has been deleted, so don't continue trying to send a mail - it will have N/A for all attributes - not very useful!
    	{
    	Try
    		{
    		$DisplayName=$Target.DisplayName
    		If ($DisplayName -eq $NULL)
    			{
    			$DisplayName="N/A"
    			}
    		}
    	Catch 
    	{
    	}
    	Try
    		{
    		$EmployeeType=$Target.EmployeeType
    		If ($EmployeeType -eq $NULL)
    			{
    			$EmployeeType="N/A"
    			}
    		}
    	Catch 
    	{
    	}
    	Try
    		{
    		$Company=$Target.Company
    		If ($Company -eq $NULL)
    			{
    			$Company="N/A"
    			}	
    		}
    	Catch 
    	{
    	}
    	Try
    		{
    		$Directorate=$Target.Directorate
    		If ($Directorate -eq $NULL)
    			{
    			$Directorate="N/A"
    			}
    		}
    	Catch 
    	{
    	}
    	Try
    		{
    		$Department=$Target.Department
    		If ($Department -eq $NULL)
    			{
    			$Department="N/A"
    			}
    		}
    	Catch 
    	{
    	}
    	Try
    		{
    		$Division=$Target.Division
    		If ($Division -eq $NULL)
    			{
    			$Division="N/A"
    			}
    		}
    	Catch 
    	{
    	}
    	Try
    		{
    		$Group=$Target.Group
    		If ($Group -eq $NULL)
    			{
    			$Group="N/A"
    			}
    		}
    	Catch 
    	{
    	}	
    	Try
    		{
    		$Section=$Target.Section
    		If ($Section -eq $NULL)
    			{
    			$Section="N/A"
    			}
    		}
    	Catch 
    	{
    	}
    	Try
    		{
    		$Site=$Target.Site
    		If ($Site -eq $NULL)
    			{
    			$Site="N/A"
    			}
    		}
    	Catch 
    	{
    	}
    ###	Get the HTML body
    $html=(Get-Content "C:\FIMScripts\PowerShellWorkflow\ROEUSERMOVEDOUT.HTML" | out-string )
    ### Send the mail
    Send-MailMessage -From fimservice@blah.ac.uk -To jon.bryan@blah.ac.uk -Subject "ROE User Move Notification" -BodyAsHtml ($html -f $AccountName, $DisplayName, $EmployeeType, $Company, $Directorate, $Department, $Division, $Group, $Section, $Site)  -SmtpServer exchsmtp.blah.ac.uk
    }
    }
    Catch 
    {
    Write-Verbose -Message "Error: $_.Exception.Message"
    Write-Verbose -Message "Deleted User falling out of a set - no further action to take"
    }

     

    With this as the email template:

    <!DOCTYPE html>
    
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="utf-8" />
        <title>Existing Account Moved out of the ROE OU</title>
    </head>
        <body>
                <h1 style="padding-left: 30px; font-family: verdana; font-size: 150%">Existing Account Moved out of the ROE OU</h1>
                <h2 style="padding-left: 30px; font-family: verdana; font-size: 150%">Attributes:</h2>
                <h3 style="padding-left: 30px; font-family: verdana; font-size: 100%">Account Name = {0}</h3>
                <h3 style="padding-left: 30px; font-family: verdana; font-size: 100%">DisplayName = {1}</h3>
                <h3 style="padding-left: 30px; font-family: verdana; font-size: 100%">EmployeeType = {2}</h3>
            <p>
                <h2 style="padding-left: 30px; font-family: verdana; font-size: 150%">New Organisation attributes :</h2>
            </p>
            <p>
                <h3 style="padding-left: 120px; font-family: verdana; font-size: 100%">Company = {3}</h3>
                <h3 style="padding-left: 120px; font-family: verdana; font-size: 100%">Directorate = {4}</h3>
                <h3 style="padding-left: 120px; font-family: verdana; font-size: 100%">Department = {5}</h3>
                <h3 style="padding-left: 120px; font-family: verdana; font-size: 100%">Division = {6}</h3>
                <h3 style="padding-left: 120px; font-family: verdana; font-size: 100%">Group = {7}</h3>
                <h3 style="padding-left: 120px; font-family: verdana; font-size: 100%">Section = {8}</h3>
                <h3 style="padding-left: 120px; font-family: verdana; font-size: 100%">Site = {9}</h3>
            </p>
        </body>
    </html>

    Regards,

    Jon



    • Edited by Jon Bryan Tuesday, November 3, 2015 8:01 PM
    Tuesday, November 3, 2015 4:24 PM
  • Hi Jon-

    Thanks for sharing! As an FYI, you should be able to replace this:

    $Target.Get($_).AccountName

    with this:

    $Target.AccountName


    Thanks,
    Brian

    Consulting | Blog | AD Book

    Tuesday, November 3, 2015 5:01 PM
    Moderator
  • Brian,

    That was exactly what I was expecting to work, when setting up the script, but found that it returned $NULL.

    Thus, I ended up using this convoluted method to get the data out - just because it works!

    In fact, if I run the query directly in PS, e.g.:

    $Target= Export-FimConfig -Custom ("/*[ObjectID='{0}']" -F "af3c9f70-983b-492c-bac9-ddd9fa0bc677") | Convert-FimExportToPSObject

    $Target.accountname returns both the user AccountName and the users managers AccountName.

    By amending the script as described, I no longer get the mail notification (so it is now "broken"), but don't see the error that I was seeing previously (I added back the error reporting logic), before wrapping everything up in Try-Catch'es. This was:

    ERROR: You cannot call a method on a null-valued expression.

    If I run:

    $DisplayName=$Target.DisplayName

                                    If ($DisplayName -eq $NULL)

                                                    {

                                                    $DisplayName="N/A"

                                                    }

    Then DisplayName returns "N/A" - indicating that it sees it as $NULL.

    I also noted that when using the PowerShell workflow - even though the "add-pssnapin FIMAutomation" is called from the FimPowerShellModule, Export-FimConfig was not available unless the pssnapin was loaded as part of the script. I already have the fix applied that is described here: https://social.technet.microsoft.com/Forums/en-US/295fc491-ffc8-4e02-b923-43af1c3aef1d/custom-activity-to-make-changes-as-different-user?forum=ilm2

    Happy to try further suggestions to clean up "data getting" bit of the script. It certainly was not what I was expecting to have to do!

    Regards,

    Jon


    • Edited by Jon Bryan Tuesday, November 3, 2015 5:39 PM
    Tuesday, November 3, 2015 5:38 PM
  • Jon-

    What happens if you add -OnlyBaseResources to your Export-FIMConfig call? The cmdlet will give you objects that are referentially linked to the base object you request if you don't specify this.


    Thanks,
    Brian

    Consulting | Blog | AD Book

    Tuesday, November 3, 2015 5:45 PM
    Moderator
  • Perfect! Thanks Brian,

    That fixes it. I can now reference the data by $Target.Attribute and the mailing process works as expected.

    I'll update the script above to reflect those changes.

    Many thanks,

    Jon

    Tuesday, November 3, 2015 7:59 PM