Create PAM (Privileged Access Management) Mobile Apps with PowerApps

Maybe you already read my last blog post about using PowerApps for Microsoft Identity Manager where you find a definitions file for the Lithnet RestAPI for MIM to create a custom API for PowerApps. If not, please do so for some basic information’s.

I also will present the MIM and PAM PowerApps solution with some detailed information on the next MIM Team User Group meeting on June 15.

This time I give to all of you the swagger JSON definition file for the Privileged Access Management (PAM) RestAPI around with a demo PowerApp.

The swagger JSON and YAML files contains all the API calls that PAM provides, so you can do the following:

  • Get a list of all PAM roles you are a candidate for
  • Get the PAM role request history
  • Request a PAM role and also Cancel your request before TTL exceeds
  • Get a list of all PAM role requests you should approve
  • Approve of Reject a PAM role request

Since PowerApps is still a preview feature you might have some issues like I have, but I was able to test all scenarios mentioned above.
Read more of this post

Advertisements

Authorize MIM Portal user image upload with Microsoft Cognitive Services

I saw these great videos from //build keynote some weeks ago about the Microsoft Cognitive Services and I was really impressed. I know these APIs like face, emotion, speech are designed for other purposes but I was thinking to myself on who to benefit from them for identity management.

So I remembered some time ago when talking about MIM Portal as a user self-service portal for personal data some customers find it is sometimes not a good idea if users can upload their own photos. The arguments where that photos cannot be validated in that way that it really belongs to that person. So people could upload for example funny pictures and avatars or even more bad images.

Sure, you can handle this by organizational policies, but I was thinking of a technical solution. At this point when thinking about Microsoft Cognitive Services the Face API came to my mind.

If you check the Face API it has methods for face detection in images and also face identification or verifying. You can also create person groups and persons with multiple faces saved in Azure if you want.

But for my little demo I only need the face detect and verify methods.

So here is how this demo works:

If people upload new images to MIM Portal, I trigger an authorization workflow and get the current and new photo with an MIMWAL update resource activity and pass that data to a PowerShell script which then calls the Face API.

The PowerShell Script uploads both images to Azure to do a face detection within the image and then returns a faceId for each of the pictures. Images are saved 24 hours Azure.
Read more of this post

AADConnect: User Writeback: Filtering user objects from the cloud

I recently installed the Preview #2 of Azure Active Directory Connect (AADConnect) in on my testlab with user write-back feature enabled.

Sadly there is currently no possibility to filtering objects that are created in the cloud, so they get not provisioned to the on-premise directory.

I already provided that as a feedback to connect and I assume there will be some filtering OOB in future/final release.

As a workaround you can do the following to modify the sync rules on your own:

Read more of this post

PowerShell Activity: Issues with GUIDs in Workflow Activities and Sync Rules

I recently faced a problem with GUIDs generated in a PowerShell Workflow Activity. As you can see in my previous blog posts I use the FIM PowerShell Workflow Activity a lot of times (nearly most the time).

Currently I’m working on provisioning of user accounts with exchange mailboxes, in addition I have to activate/create the Online Archive for users.

I’m following this blog article from Eihab Isaac for the correct attributes to set, except that I want to do all this with portal sync rules and declarative provisioning.
If you take a look at the article you can see that you have to provide a new GUID to the msExchArchiveGUID attribute in order to get the archive feature to work. Read more of this post

A minimalistic FIM AAD sync connector solution for Windows Intune

After some DirSync implementations one of my FIM customers has the need for mobile device management with Windows Intune. So it seems a perfect time to me for my first implementation of the AAD Connector for FIM 2010 R2.

The customer had the following special requirements:

  • No Password Sync, instead using SSO with ADFS
  • Minimalistic set of attributes on users in the cloud (Corporate and legal issues)
  • Manual management of which user goes into the cloud or not (by helpdesk)
  • Usage of proxy connection for all servers incl. FIM (no direct internet connect)

I searched the internet a bit for configuration of the WAAD connector, but the technical reference ends at the step of adding attribute flows and other posts are mostly for complex scenarios (hybrid, multi-forest and so on).

So once again I had to figure it out by myself and I decided to put my solution on here for this minimalistic implementation. I will skip the installation and configuration of ADFS and WAP, the Azure AD configuration and also the firewall/proxy configuration. There is a lot of documentation out there for this. Bit I will give the one or the other hint on some facts.
To setup your Azure/Intune for SSO with ADFS follow the guide in your Azure/Intune portal.

Read more of this post

Error using the Null() function with IIF in FIM workflows

After some time I ran into the same error a second time, so I think it is worth a blog post to avoid this happening again in the future and in addition as information to you all.

So here is my situation:

From the HR system I’m importing Team Information which should only be used on initial creation of the users. So I have an attribute called PrimaryTeamInitial that on user create we copy over to the PrimaryTeam attribute in portal.

So what I have done is a workflow that triggers on update of the PrimaryTeamInitial attribute, which in normal cases only occurs once in the lifetime of an object.
(Why I don’t use the Create event I will tell you in possibly my next post).

The workflow uses a custom expression like in the screenshot below:

WrongUsage

Because I only need to check if the attribute PrimaryTeam is not present, but there is no function for that in FIM I used the IsPresent and try to do nothing when the IIF statement is true using the Null() function.

I tested the workflow by creating a new user with a PrimaryTeamInital set by HR and all seems to work fine.

However a day later I saw “System Events” with “Postprocessing Errors” in FIM portal and in addition there where the following eventlog errors.

System.InvalidOperationException: There was an error generating the XML document.
System.InvalidOperationException: The type Microsoft.MetadirectoryServices.FunctionLibrary.NoFlowSingleton was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.
   at System.Xml.Serialization.XmlSerializationWriter.WriteTypedPrimitive(String name, String ns, Object o, Boolean xsiType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterRequestParameter.Write1_Object(String n, String ns, Object o, Boolean isNullable, Boolean needType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterRequestParameter.Write9_UpdateRequestParameter(String n, String ns, UpdateRequestParameter o, Boolean isNullable, Boolean needType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterRequestParameter.Write11_RequestParameter(Object o)
   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
   at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o)
   at Microsoft.ResourceManagement.WebServices.WSResourceManagement.RequestType.AddParameter(RequestParameter parameter)
   at Microsoft.ResourceManagement.WebServices.WSResourceManagement.RequestType.SetRequestParameters(OperationType operation, UniqueIdentifier targetObject, List`1 requestParameters)
   at Microsoft.ResourceManagement.WebServices.WSResourceManagement.RequestType..ctor(UniqueIdentifier creator, UniqueIdentifier targetIdentifier, OperationType operation, List`1 requestParameters, CultureInfo locale, Boolean isChildRequest, Guid cause, Boolean maintenanceMode, UniqueId messageIdentifier, UniqueIdentifier requestContextIdentifier)
   at Microsoft.ResourceManagement.WebServices.RequestDispatcher.CreateRequest(UniqueIdentifier requestor, UniqueIdentifier targetIdentifier, OperationType operation, String businessJustification, List`1 requestParameters, CultureInfo locale, Boolean isChildRequest, Guid cause, Boolean doEvaluation, Nullable`1 serviceId, Nullable`1 servicePartitionId, UniqueId messageIdentifier, UniqueIdentifier requestContextIdentifier, Boolean maintenanceMode)
   at Microsoft.ResourceManagement.WebServices.RequestDispatcher.CreateRequest(UniqueIdentifier requestor, UniqueIdentifier targetIdentifier, OperationType operation, String businessJustification, List`1 requestParameters, CultureInfo locale, Boolean isChildRequest, Guid cause)
   at Microsoft.ResourceManagement.Workflow.Hosting.RequestWorkItemProcessor.CreateRequest(UniqueIdentifier requestor, UniqueIdentifier objectId, OperationType operation, List`1 requestParameters, Guid parentRequest)
   at Microsoft.ResourceManagement.Workflow.Hosting.RequestWorkItemProcessor.ProcessPutWorkItem(UpdateRequestWorkItem updateWorkItem)
   at Microsoft.ResourceManagement.Workflow.Hosting.RequestWorkItemProcessor.ProcessWorkItem(WorkItem workItem)

After some investigation on the net I remember that I have similar errors is the past using the Null() function and so I changed the workflow like you can see in the screenshot below:

CorrectUsage

Now setting the attribute to the current attribute value in case IIF is true, the error is gone and all is working like expected without errors.

I am currently not quite sure if this error only occurs on reference attribute like my team attribute, but be careful using the Null() function if you want to do nothing it does not always work like you expect.

I wish all readers a merry Christmas and a happy new year.

Peter

FIM 2010 R2: Searching for Request Details in msidmCompositeType

With Forefront Identity Manager 2010 R2 Microsoft add some performance modifications to Service and Portal. By default exports from the FIM Management Agent are batched (aggregated) up to 1000 changes. So in request details you may see only an Update to msidmCompositeType ‘’ Request which includes all the changes of maybe multiple objects in the RequestParameter attribute.

Craig has also post a short description on how to deal with this objecttype.

Since this is very good for performance on exports, it is very bad for searching changes in the request log in portal. In my environment I even see changes that seems to be only relevant to one object, holding changes to multiple objects. In this particular case the requests display name is Update to msidmCompisiteType ‘myuser’ Request, but in the RequestParameter attribute I also found changes to other objects.

While you cannot actually searching the request log for changes to a specific object, especially with the new batch object type, I’ve decided to create a little script for this in PowerShell of course.

The script is based on the FIMAutomation snap-in and also the FIM PowerShell Module from Craig. Because I missed some attribute in output of the Get-FIMRequestParameter cmdlet I have modified this a little bit.

Giving an objectType, attribute and value to search, the script will retrieve all changes to this object searching all direct/single requests and also all batched updates.

To use this script you must in addition to install the FIMPowerShellModule modify the FIMPowerShellModule.psm1 file like below. I’ve only added the Mode and Target properties to the output of the Get-FIMRequestParameter function.

$RequestParameter | foreach-Object{
    New-Object PSObject -Property @{
        Mode = ([xml]$_).RequestParameter.Mode
	Target = ([xml]$_).RequestParameter.Target
        PropertyName = ([xml]$_).RequestParameter.PropertyName
        Value = ([xml]$_).RequestParameter.Value.'#text'
        Operation = ([xml]$_).RequestParameter.Operation
     } |
     Write-Output

Here is my PowerShell Script, see also comments inside the code:

param($objectType, $attribute, $searchValue)
#objectType = The objectType of the target object you are trying to get requests for.
#attribute = The attribute of the target object you want to use for searching
#searchValue = The value of the attribute of the target object you are searching requests for
#
#ex. Get-FIMRequestDetails.ps1 -objectType "Person" -attribute "AccountName" -searchValue "pstapf"
#
#This gets all requests matching the given target object.

# Load FIMAutomation SnapIn and FIMPowershellModule (http://fimpowershellmodule.codeplex.com)
if(@(get-pssnapin | where-object {$_.Name -eq "FIMAutomation"} ).count -eq 0) {add-pssnapin FIMAutomation}
Import-Module C:\Windows\System32\WindowsPowerShell\V1.0\Modules\FIM\FIMPowerShellModule.psm1

# Check if the object you are searching requests for exists in portal and get its GUID
$filter = "/" + $objectType + "[" + $attribute + "=" + $searchValue + "]"
$searchObject = Export-FIMConfig -OnlyBaseResources -CustomConfig $filter

If ($searchObject -ne $null)
{
    $searchObjectGuid = $searchObject.ResourceManagementObject.ObjectIdentifier.Replace("urn:uuid:","")
    Write-Host "Object found:" $searchValue " with GUID:" $searchObjectGuid
}
else
{
    Write-Host "The object you are searching for does not exists in FIM Portal"
    Exit
}

# Get the aggregated requests of the object you search for
$export=@()
$filter = "/Request[Target=/msidmCompositeType[/msidmElement=/" + $objectType + "[" + $attribute + "=" + $searchValue + "]]]"
$export = Export-FIMConfig -OnlyBaseResources -CustomConfig $filter

# Get the single requests of the object you search for
$filter = "/Request[Target=/" + $objectType + "[" + $attribute + "=" + $searchValue + "]]"
$export += Export-FIMConfig -OnlyBaseResources -CustomConfig $filter
$requestlist = $export | Convert-FimExportToPSObject | Sort-Object msidmCompletedTime

# Get the RequestParameter of the object you search fo from all requests and add some requestDetails
If ($requestlist.count -gt 0)
{
    $resultItems = @()
    foreach ($requestItem in $requestList)
    {
        $resultItems += $requestItem | Get-FimRequestParameter | where { $_.Target -eq $searchObjectGuid } | ForEach-Object {
        New-Object PSObject -Property @{
            Target = $_.Target
            Operation = $_.Operation
            Mode = $_.Mode
            Attribute = $_.PropertyName
            Value = $_.Value
            RequestName = $requestItem.DisplayName
            RequestGuid = $requestItem.ObjectID.Replace("urn:uuid:","")
            CompleteTime = $requestItem.msidmCompletedTime
            Status = $requestItem.RequestStatus
            }
        }
    }
    $resultItems

}
else
{
    Write-Host "No request found for the object you searched for."
}

Using Notes:

Script output is PSObject, so you can pipe the output to many other cmdlets, like Out-GridView or Convertto-Html for example. In addition you can filter the output by date also on your own.

Out-GridView is a very neat cmdlet for this, as you can show/hide columns and also do some basic filtering, try a Status:Completed filter for example.

OutGridView

Here is also some output with ConverTo-Html with some basic CSS:

OutHtml

%d bloggers like this: