Workflows with if-then, PowerShell scripts, and $work.SavedObjectProperies

Hi,

I am working on a workflow to do some automation on our computer objects, and I am running into a weird issue that I am struggling to wrap my head around.

The error I am receive:

Executing the 'Run script: DEV New Computer Object Tag Location on Search Results' activity  
 
7/11/2023 12:33:21 PM (UTC) 

•Activity 'Run script: DEV New Computer Object Tag Location on Search Results' encountered an error.  Details <<< 
An item with the same key has already been added. 

ARS Version: 7.4.3

The workflow is setup in the following way

  • The workflow will run on a schedule
  • There is a managed unit that the workflow uses to search for objects
  • The properties of the found objects are saved.
    • Currently I am saving the DistinguishedName
  • There is then an If-then statement that evaluates the DistinguishedName and will update a virtual attribute based on what is found. There are 5+ conditions being evaluated.

NOTE - Up until this point, everything works as expected

  • I then have a PowerShell script that will connect to a 3rd party service
    • Important - This is WITHIN the If-then statement and takes place immediately after the virtual attribute is updated 
    • This has not yet been tested because I am struggling with another piece. I am just included this for reference.
  • I then have a PowerShell script that will essentially check if the previous steps were successful, and if not, the script will update some virtual attributes to allow us to be alerted and cause the machine to be re-evaluated the next time the workflow runs.
    • Important - This is NOT WITHIN the if-then statement. It is set to run AFTER. 
    • This is where I receive the error above.

In the PowerShell script that triggers the error above I have managed to narrow down the exact line that is causing it.

$computers = $workflow.SavedObjectProperties("Save object properties").get("distinguishedName")

My intent with this line of code is to loop through all the objects that were originally found, and then check their attributes to see if the previous steps were successful.

What seems to be happening though is that the "$workflow.SavedObjectProperties("Save object properies")" is being changed by the If-then statement.

After the if-then statement is run, it seems only 1 computer object is returned by the above command. Even though there are two objects.

If I re-order things, and I run the PowerShell script that triggers the error BEFORE the workflow if-then statement, the PowerShell script will work and process each object found.

But this is out of order and not what I want.

Is there some way of having the PowerShell script use the object that is running through the If-then statement?

Or am I doing something else wrong? I can't figure out why the if-then statement appears to be impacting the "$computers = $workflow.SavedOjectProperies.." in the PowerShell script.

I have a few other examples where this is actually working.

It is important to note that if only 1 computer object is returned by the search operation of the workflow, then everything things to run as expected.

Not sure if any of what I just described made any sense, I hope so.

I am sure I am doing something stupid, any suggestions would be greatly appreciated.

Regards,

Todd

  • An important thing to understand about the Search Activity is that any workflow activities (be it a script or a built-in activity) that you place in the "workspace" of the search are executed for each item returned by the search.

    So, the "$computers =" line you cite above is only going to receive ONE computer at a time for processing.

    Hence why I typically don't use Searches if I have established a Managed Unit to pull together my object "queue".

    Rather, I just do this within my script:

    $ObjectList = Get-QAD<something> ...to enumerate the contents of the Managed Unit

    $ObjectList | foreach {

    <Do stuff on each object returned from the MU>

    }

  • Hey  ,

    I do something similar to this, I think. Although your way is more elegant.

    # Pull devices missing location
    $computers = $workflow.SavedObjectProperties("Save object properties").get("distinguishedName")
    
    # Process found devices
    foreach ( $computer in $computers )
    {
        <do stuff>
    }

    But before I can even get to this point, my script is failing at the "$computers =  $workflow.SavedObjectProperties..." part.

    On a side note, I decided to completely rebuild the workflow from scratch. Not copying anything from the original one, to the new one. I just re-created it step for step. Now it seems to be working. I haven't enabled every single step yet, but so far so good.

    I feel like that doesn't make any sense.

  • Can you please post a screen cap of your workflow so we can see how things are arranged?

    Why are you using "Saved Object Properties"?  Are you not trying to search the contents of your MU to get the list of computers to process?

    If yes, then you should be using $Workflow.FoundObject("Enumerate MU").get("distinguishedName")

    ...where "Enumerate MU" is a name I just made up for a Search Activity that is listing the contents of your Managed Unit.

    Again, you could just skip the Search Activity by incorporating the enumeration of the MU right in your script which would be fired directly by your workflow.

  • If I had the following workflow, where I'm searching for any computer in my environment, then for each computer found I execute the "Do-Something" function in the "Found object script"

    I can use the $Workflow.FoundObject method, to get the current record in the found object, and ask for the (for example) distinguishedName

     function Do-Something()
     {
         $ComputerDN =  $workflow.FoundObject("Inscope Computers").get("distinguishedName")
         $EventLog.ReportEvent($Constants.EDS_EVENTLOG_WARNING_TYPE,"Result: $($ComputerDN)")
    
     }

    In my case, I then write the DN out to the event log

    If you have a look in the SDK under "Retrieving data from workflow context", you'll also be able to find other methods to get data into your scripts.

  • I definitely can post a screenshot, but I am struggling a little bit to figure out how to correctly do that.

    Is there a way to upload the screenshot directly to the forum post? Or does it have to be hosted externally?

    The reason I am using "Saved Object Properties" is because that is what I have been shown in another project I worked on. It just happened to be what I am familiar with.

    Yes, I am trying to utilize the results from the search operation and perform some action on those objects.

    I am using the native "Change object property" feature of the workflow to make some changes to the object so I couldn't eliminate the search entirely. But I understand what you are saying.

    After some additional testing, it looks like my workflow has stopped working again with the same error. I will try adjusting the logic to use the "FoundObject" call instead.

  • This is very similar to what I am already doing.

    I am familiar with the steps you laid out here. I don't understand where the error I am getting is coming from.

  • Do you even have a Save Object Properties activity in your workflow?  If not, then there's no data to be obtained.

    FWIW, as its name implies, that is a specific type of workflow activity designed to allow you to save the state (i.e. contents of properties) of an object before changes get made to it.

    What Stu showed above is what I have been talking about with respect to the Search Activity.  The snippet of code both he and I provided is the correct way to get the DN of an object returned from the Search if that's the way you want to approach this.

    Have you updated your $computers = line to reflect this correct method?

  • Yes, I have a "Save Object Properties" in my workflow. I am familiar with working with the "Save Object Properties" feature of Active Roles.

    I haven't been able to figure out when in this specific context it wasn't working.

    Having said that, after reading through your suggestions and trying a bunch of different stuff, I have a working workflow now.

    I have eliminated the "Save Object Properties" entirely and I have modified my script slightly to remove the additional loop that was in there. I think I may have not learned correctly how the workflows return their information.

    Another thing that appeared to be wrong was within the if-then workflow statement. Within that, I was setting an attribute, I had copied the set attribute function from one condition to the next and that appeared to have caused some issues. Once I fixed that up, now everything is working correctly.

    The revelation that that the workflow runs any defined steps against returned search objects is huge. I have to completely re-write a bunch of other stuff now Disappointed

    I will try and post some screenshots when I get home.

  • Hello  

    I wanted to revisit some items you mentioned above in your initial post:

    "I then have a PowerShell script that will connect to a 3rd party service

    Important - This is WITHIN the If-then statement and takes place immediately after the virtual attribute is updated

    Is there some way of having the PowerShell script use the object that is running through the If-then statement?"

    I was recently reminded of some currently known limitations of Active Roles Workflows and accessing certain things from within If-Else activities, such as FoundObject, but I've also seen this issue affecting SavedObjectProperties and Global Variables defined in the Workflow's Initialization Script.

    A script module in a workflow which uses the '$Workflow.FoundObject ("name")' method works fine elsewhere but fails to work in a If-Else branch conditional (4336836) (oneidentity.com)

    Maybe this is related to something you were originally posting about, maybe not. Just thought I mention it if so.

  • Hi  ,

    Thank you for your message.

    I read through the KB and it is definitely something to be aware of.

    Luckily, since the restructuring of the workflow, the PowerShell script that connects to the 3rd party is no longer within the workflow If-Then statement so I should be able to avoid this issue. Having said that, I do have other scripts that may have this problem in the future.

    Thank you for letting me know about this!