dinsdag 30 november 2010

FIM 2010: Delete a user when the end date is reached (Expiration Workflow)

If you are using the FIM portal, you problaby have noticed the Expiration Workflow. This workflow can became very handy to delete users from the FIM portal if the end date is reaced.

But how do you use it? I will provide you with a little manual that will guide you through the steps.

1. First create a set that will contain all users with the end datum that is equal to today:




















 2. Then create a set that contains the Expiration Workflow, because you need to give the Expiration Workflow rights to delete a user object.


















3. Then you need to configure rights for the Expiration Workflow to delete a user object




































4. And then youb need to create a MPR to launch the Expiration Workflow when a user joins the set.






































After creating this MPR users will be deleted from the FIM portal if there end date is reached. If you want to delete them from other connected systems you need to configure the Object Deletion rules in the FIM Synchronisation Engine and configure deprovisining.

dinsdag 9 november 2010

PowerShell: Create a FIM user and add the SID from AD

Today I created a PowerShellscript that displays a inputbox where you can enter a username, after that the script will create a new user in the FIM portal and it will find the SID in the AD and add it to the user.

This scripts is a combination of two scripts found on the technet forum with a little bit custom code.

The code is a little bit "dirty", it needs some optimalisation.

The code is below:


[void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')

#----------------------------------------------------------------------------------------------------------
 set-variable -name URI -value "http://localhost:5725/resourcemanagementservice' " -option constant
#----------------------------------------------------------------------------------------------------------
 function SetAttribute
 {
    PARAM($object, $attributeName, $attributeValue)
    END
    {
        $importChange = New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ImportChange
        $importChange.Operation = 1
        $importChange.AttributeName = $attributeName
        $importChange.AttributeValue = $attributeValue
        $importChange.FullyResolved = 1
        $importChange.Locale = "Invariant"
        if ($object.Changes -eq $null) {$object.Changes = (,$importChange)}
        else {$object.Changes += $importChange}
    }
}
#----------------------------------------------------------------------------------------------------------
 function CreateObject
 {
    PARAM($objectType)
    END
    {
       $newObject = New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ImportObject
       $newObject.ObjectType = $objectType
       $newObject.SourceObjectIdentifier = [System.Guid]::NewGuid().ToString()
       $newObject
     }
 }
#----------------------------------------------------------------------------------------------------------
 function CreateUser
{

 if(@(get-pssnapin | where-object {$_.Name -eq "FIMAutomation"} ).count -eq 0) {add-pssnapin FIMAutomation}
 clear-host

 if($args.count -ne 1) {throw "You need to specify your attribute values as parameter"}
 $attributes = ($args[0]).split("|")

 if(0 -ne [String]::Compare(($attributes[0]).split(":")[0],"displayname", $true))
 {throw "You need to specify a display name"}

 $objectName = ($attributes[0]).split(":")[1]
 $exportObject = export-fimconfig -uri $URI `
                                  –onlyBaseResources `
                                  -customconfig "/Person[DisplayName='$objectName']"
 if($exportObject) {throw "L:User $objectName already exists"}

 $newUser = CreateObject -objectType "Person"
 foreach($attribute in $attributes)
 {
    $attrData = $attribute.split(":")
    SetAttribute -object $newUser `
                 -attributeName  $($attrData[0]) `
                 -attributeValue $($attrData[1])
 }            

 $newUser | Import-FIMConfig -uri $URI
 write-host "`nUser created successfully`n"
}
#----------------------------------------------------------------------------------------------------------
 trap
 {
    $exMessage = $_.Exception.Message
    if($exMessage.StartsWith("L:"))
    {write-host "`n" $exMessage.substring(2) "`n" -foregroundcolor white -backgroundcolor darkblue}
    else {write-host "`nError: " $exMessage "`n" -foregroundcolor white -backgroundcolor darkred}
    Exit
 }
#----------------------------------------------------------------------------------------------------------
 function GetSidAsBase64
{
    PARAM($AccountName, $Domain)
    END
    {
        $sidArray = [System.Convert]::FromBase64String("AQUAAAAAAAUVAAAA71I1JzEyxT2s9UYraQQAAA==") # This sid is a random value to allocate the byte array
        $args = (,$Domain)
        $args += $AccountName
        $ntaccount = New-Object System.Security.Principal.NTAccount $args
        $desiredSid = $ntaccount.Translate([System.Security.Principal.SecurityIdentifier])
write-host " -Account SID : ($Domain\$AccountName) $desiredSid"
        $desiredSid.GetBinaryForm($sidArray,0)
        $desiredSidString = [System.Convert]::ToBase64String($sidArray)
        $desiredSidString
    }
}

function fixSid
{
PARAM([string]$AccountName,[string]$Domain)
cls
#------------------------------------------------------------------------------------------------------
 set-variable -name URI    -value "http://localhost:5725/resourcemanagementservice"    -option constant

#------------------------------------------------------------------------------------------------------
 write-host "`nFix Account ObjectSID"
 write-host "=========================="
#------------------------------------------------------------------------------------------------------
#Retrieve the Base64 encoded SID for the referenced user
 $accountSid = GetSidAsBase64 $AccountName $Domain
#------------------------------------------------------------------------------------------------------
#Export the account configuration from the service:
 write-host " -Reading Account information"
 if(@(get-pssnapin | where-object {$_.Name -eq "FIMAutomation"} ).count -eq 0)
 {add-pssnapin FIMAutomation}

 $exportObject = export-fimconfig -uri $URI `
                                -onlyBaseResources `
                                -customconfig ("/Person[AccountName='$AccountName']")
 if($exportObject -eq $null) {throw "Cannot find an account by that name"}
 $objectSID = $exportObject.ResourceManagementObject.ResourceManagementAttributes | `
                 Where-Object {$_.AttributeName -eq "ObjectSID"}

 Write-Host " -New Value = $accountSid"
 Write-Host " -Old Value =" $objectSID.Value

 if($accountSid -eq $objectSID.Value)
  {
Write-Host "Existing value is correct!"
}
 else
  {
$importChange = New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ImportChange
$importChange.Operation = 1
$importChange.AttributeName = "ObjectSID"
$importChange.AttributeValue = $accountSid
$importChange.FullyResolved = 1
$importChange.Locale = "Invariant"
$importObject = New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ImportObject
$importObject.ObjectType = $exportObject.ResourceManagementObject.ObjectType
$importObject.TargetObjectIdentifier = $exportObject.ResourceManagementObject.ObjectIdentifier
$importObject.SourceObjectIdentifier = $exportObject.ResourceManagementObject.ObjectIdentifier
$importObject.State = 1
$importObject.Changes = (,$importChange)
write-host " -Writing Account information ObjectSID = $accountSid"
$importObject | Import-FIMConfig -uri $URI -ErrorVariable Err -ErrorAction SilentlyContinue
if($Err){throw $Err}
Write-Host "Success!"
}
#------------------------------------------------------------------------------------------------------
 trap
 {
    Write-Host "`nError: $($_.Exception.Message)`n" -foregroundcolor white -backgroundcolor darkred
    Exit
 }
#------------------------------------------------------------------------------------------------------
}
$c=[Microsoft.VisualBasic.Interaction]::InputBox("Enter the admin account that need access to FIM","Create FIM admin account")

if ($c.Trim()) {
createUser "DisplayName:$c|AccountName:$c"
fixSid $c
}

donderdag 4 november 2010

FIM 2010 Self-Service Password Reset Now Supports All Domain Password Policies


FIM 2010 Self-Service Password Reset now supports all domain password policies.  It was a joint effort between the Windows Active Directory and FIM development teams to provide this new functionality. 
Details of this change can be found in http://support.microsoft.com/KB/2443871.