FIM Windows PowerShell Cmdlet Examples

Applies To: Forefront Identity Manager 2010

The Windows PowerShell functions in this appendix demonstrate how to use Microsoft® Forefront® Identity Manager (FIM) 2010 cmdlets in the Windows PowerShell command-line interface to create, delete, or modify FIM resources. Some of these example functions are reused by more complex Windows PowerShell examples. These functions are provided as examples only. Many organizations have custom requirements that make it necessary to modify these scripts.

Tip

You can find additional Windows PowerShell script examples in the FIM ScriptBox (https://go.microsoft.com/fwlink/?LinkID=163230). The FIM ScriptBox contains community-generated scripts to accomplish many common tasks.

Create FIM Service Resources Using Windows PowerShell

To create a FIM Service resource, you must create an ImportObject object, add attribute values to that object, and commit that object to the FIM Service database by using the Import-FIMConfig cmdlet. The CreatePerson function and the CreateGroup function are examples of functions that create resources. You can use these functions as helper functions to a Windows PowerShell script that creates Person or Group resources using a bulk import.

Delete FIM Service Resources Using Windows PowerShell

To delete a FIM Service resource, you must create an ImportObject object that represents the resource that you want to delete as shown in the DeleteObject example function. Then you must commit that object to the FIM Service database using the Import-FIMConfig cmdlet.

You can delete values from a multi-valued attribute by creating an ImportObject object that represents the changes that you want to make to resources in the FIM Service as shown in the RemoveMultiValue example function. Then, you use the Import-FIMConfig cmdlet to commit those changes to the FIM Service.

Querying FIM Service Resources Using Windows PowerShell

To query the FIM Service for information, use the Export-FIMConfig cmdlet with an XPath filter that defines the resources that you want to retrieve. For example, the QueryResource example function returns a collection of resources based on an XPath filter. For more information, see XPath Filter Dialect Examples.

Modifying FIM Service Resources Using Windows PowerShell

To modify a FIM Service resource, you must create an ImportObject object that represents the changes that you want to make to resources in the FIM Service. Then, you use the Import-FIMConfig cmdlet to commit those changes to the FIM Service. The EnableAllMPRs example function shows how to query for resources and make changes to those resources.

Performing Bulk Operations Using Windows PowerShell

You can use Windows PowerShell scripts to perform create, read, modify, and delete operations on FIM resources instead of using the FIM Portal, which can be tedious if you are performing bulk operations. You can perform bulk create, modify, and delete operations by using the Import-FIMConfig cmdlet, as described in the previous sections. You can create an XPath filter and use the Export-FIMConfig cmdlet to export any data set. Remember that there are practical limits on the number of resources that you can retrieve from the FIM Service database with a single call using one of the cmdlets. Consider the following guidelines when you are using Windows PowerShell to perform bulk operations:

  • Make sure that you define the XPath filter so that it returns only the resources that you need. For example, you can write a Windows PowerShell script that retrieves all ManagementPolicyRule resources and enables them. However, this means that you might retrieve many more ManagementPolicyRule resources than you need to update because some of them might already be enabled. A better practice is to retrieve only ManagementPolicyRule resources that were disabled and then enable them, as the EnableAllMPRs example function demonstrates.

  • If you have to retrieve information about many resources, you might have to retrieve that information by using the Export-FIMConfig cmdlet multiple times using different XPath filters that partition the resources. For example, if you have to update all Person resources in a very large organization, you might want to create a Windows PowerShell script that retrieves all Person resources in a particular cost center, updates those resources, and then continues to do this for each cost center.

FIMPowerShell.ps1

The following code example includes the Windows PowerShell functions that are included in this section.

# Copyright 2010 Microsoft Corporation

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

# States
# 0 = Create
# 1 = Put
# 2 = Delete
# 3 = Resolve
# 4 = None

# Operations
# 0 = Add
# 1 = Replace
# 2 = Delete

# Low-level operations

$DefaultUri = "https://localhost:5725"

function CreateImportObject
{
    PARAM([string]$ObjectType)
    END
    {
        $importObject = New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ImportObject
        $importObject.SourceObjectIdentifier = [System.Guid]::NewGuid().ToString()
        $importObject.ObjectType = $ObjectType
        $importObject
    }
}

function ModifyImportObject
{
    PARAM([string]$TargetIdentifier, $ObjectType = "Resource")
    END
    {
        $importObject = New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ImportObject
        $importObject.ObjectType = $ObjectType
        $importObject.TargetObjectIdentifier = $TargetIdentifier
        $importObject.SourceObjectIdentifier = $TargetIdentifier
        $importObject.State = 1 # Put
        $importObject
    }
}

function DeleteObject
{
    PARAM([string]$TargetIdentifier, $ObjectType = "Resource")
    END
    {
        $importObject = New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ImportObject
        $importObject.ObjectType = $ObjectType
        $importObject.TargetObjectIdentifier = $TargetIdentifier
        $importObject.SourceObjectIdentifier = $TargetIdentifier
        $importObject.State = 2 # Delete
        $importObject
    }
}

function ResolveObject
{
    PARAM([string] $ObjectType, [string]$AttributeName, [string]$AttributeValue)
    END
    {
        $importObject = New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ImportObject
        $importObject.TargetObjectIdentifier = $TargetIdentifier
        $importObject.ObjectType = $ObjectType
        $importObject.State = 3 # Resolve
        $importObject.SourceObjectIdentifier = [System.String]::Format("urn:uuid:{0}", [System.Guid]::NewGuid().ToString())
        $importObject.AnchorPairs = New-Object Microsoft.ResourceManagement.Automation.ObjectModel.JoinPair
        $importObject.AnchorPairs[0].AttributeName = $AttributeName
        $importObject.AnchorPairs[0].AttributeValue = $AttributeValue
        $importObject
    }
}

function SetSingleValue
{
    PARAM($ImportObject, $AttributeName, $NewAttributeValue, $FullyResolved=1)
    END
    {
        $ImportChange = CreateImportChange -AttributeName $AttributeName -AttributeValue $NewAttributeValue -Operation 1
        $ImportChange.FullyResolved = $FullyResolved
        AddImportChangeToImportObject $ImportChange $ImportObject
    }
}

function AddMultiValue
{
    PARAM($ImportObject, $AttributeName, $NewAttributeValue, $FullyResolved=1)
    END
    {
        $ImportChange = CreateImportChange -AttributeName $AttributeName -AttributeValue $NewAttributeValue -Operation 0
        $ImportChange.FullyResolved = $FullyResolved
        AddImportChangeToImportObject $ImportChange $ImportObject
    }
}

function RemoveMultiValue
{
    PARAM($ImportObject, $AttributeName, $NewAttributeValue, $FullyResolved=1)
    END
    {
        $ImportChange = CreateImportChange -AttributeName $AttributeName -AttributeValue $NewAttributeValue -Operation 2
        $ImportChange.FullyResolved = $FullyResolved
        AddImportChangeToImportObject $ImportChange $ImportObject
    }
}

function AddImportChangeToImportObject
{
    PARAM($ImportChange, $ImportObject)
    END
    {
        if ($ImportObject.Changes -eq $null)
        {
            $ImportObject.Changes = (,$ImportChange)
        }
        else
        {
            $ImportObject.Changes += $ImportChange
        }
    }
}

function CreateImportChange
{
    PARAM($AttributeName, $AttributeValue, $Operation)
    END
    {
        $importChange = New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ImportChange
        $importChange.Operation = $Operation
        $importChange.AttributeName = $AttributeName
        $importChange.AttributeValue = $AttributeValue
        $importChange.FullyResolved = 1
        $importChange.Locale = "Invariant"
        $importChange
    }
}

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 -TypeName System.Security.Principal.NTAccount -ArgumentList $args
        $desiredSid = $ntaccount.Translate([System.Security.Principal.SecurityIdentifier])
        $desiredSid.GetBinaryForm($sidArray,0)
        $desiredSidString = [System.Convert]::ToBase64String($sidArray)
        $desiredSidString
    }
}

# Diagnostic operations

function ConvertResourceToHashtable
{
    PARAM([Microsoft.ResourceManagement.Automation.ObjectModel.ExportObject]$ExportObject)
    END
    {
        $hashtable = @{"ObjectID" = "Not found"}
        foreach($attribute in $exportObject.ResourceManagementObject.ResourceManagementAttributes)
        {
            if ($attribute.IsMultiValue -eq 1)
            {
                $hashtable[$attribute.AttributeName] = $attribute.Values
            }
            else
            {
                $hashtable[$attribute.AttributeName] = $attribute.Value
            }
        }
        $hashtable
    }
}

function ConvertHashtableToResource
{
    PARAM($Hashtable)
    END
    {
        $ExportObject = New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ExportObject
        $ExportObject.Source = $DefaultUri
        $ExportObject.ResourceManagementObject = New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ResourceManagementObject
        foreach($key in $Hashtable.Keys)
        {
            $value = $Hashtable[$key]
            $newAttribute = New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ResourceManagementAttribute
            $newAttribute.AttributeName = $key
            $newAttribute.Value = $value
            $newAttribute.HasReference = 0
            $newAttribute.IsMultiValue = 0
            
            if($newAttribute.AttributeName -eq "ObjectID")
            {
                $ExportObject.ResourceManagementObject.ObjectIdentifier = $newAttribute.Value
            }
            
            if($newAttribute.AttributeName -eq "ObjectType")
            {
                $ExportObject.ResourceManagementObject.ObjectType = $newAttribute.Value
            }
            
            $ExportObject.ResourceManagementObject.IsPlaceholder = 0
            
            if($ExportObject.ResourceManagementObject.ResourceManagementAttributes -eq $null)
            {
                $ExportObject.ResourceManagementObject.ResourceManagementAttributes = (,$newAttribute)
            }
            else
            {
                $ExportObject.ResourceManagementObject.ResourceManagementAttributes += $newAttribute
            }
        }
        $ExportObject
    }
}

function GetResource
{
    PARAM($ObjectIdentifier, $Uri = $DefaultUri)
    END
    {
        $object = Export-FIMConfig -CustomConfig [System.String]::Format("*[ObjectID='{0}']", $ObjectIdentifier) -Uri $Uri
        if($object -eq $null)
        {
            Write-Host "Object was not found."
        }
        else
        {
            $object
        }
    }
}

function QueryResource
{
    PARAM($Filter, $Uri = $DefaultUri)
    END
    {
        $resources = Export-FIMConfig -CustomConfig $Filter -Uri $Uri
        $resources
    }
}

# High-level operations

function AddMembersToGroup
{
    PARAM($GroupIdentifier, $PersonIdentifiers, $IdentifierName="Email", $Uri = $DefaultUri)
    END
    {
        $ResolveGroup = ResolveObject -ObjectType "Group" -AttributeName $IdentifierName -AttributeValue $GroupIdentifier
        $ResolveGroup | Import-FIMConfig -Uri $Uri
        $ImportObjects = $NULL
        $AddedMembers = $NULL
        foreach($PersonIdentifier in $PersonIdentifiers)
        {
            $ImportObject = ResolveObject -ObjectType "Person" -AttributeName $IdentifierName -AttributeValue $PersonIdentifier
            if($AddedMembers -eq $NULL)
            {
                $AddedMembers = @($ImportObject.SourceObjectIdentifier)
            }
            else
            {
                $AddedMembers += $ImportObject.SourceObjectIdentifier
            }
            if($ImportObjects -eq $NULL)
            {
                $ImportObjects = @($ImportObject)
            }
            else
            {
                $ImportObjects += $ImportObject
            }
        }
        
        $ModifyImportObject = ModifyImportObject -TargetIdentifier $ResolveGroup.TargetObjectIdentifier -ObjectType "Group"
        $ModifyImportObject.SourceObjectIdentifier = $ResolveGroup.SourceObjectIdentifier
        
        foreach($AddedMember in $AddedMembers)
        {
            $newValue = $AddedMember
            AddMultiValue -ImportObject $ModifyImportObject -AttributeName "ExplicitMember" -NewAttributeValue $newValue -FullyResolved 0
            #RemoveMultiValue -ImportObject $ModifyImportObject -AttributeName "ExplicitMember" -NewAttributeValue $newValue -FullyResolved 0
        }
        $ImportObjects += $ModifyImportObject
        #$ImportObjects | Import-FIMConfig -Uri $Uri
        $ImportObjects
    }
}

function EnableAllMPRs
{
    PARAM($Uri = $DefaultUri)
    END
    {
        $AllMPRs = QueryResource -Filter "/ManagementPolicyRule[Disabled='true']" -Uri $Uri
        $ImportObjects = $null
        foreach($mpr in $AllMPRs)
        {
            $ModifyImportObject = ModifyImportObject -TargetIdentifier $mpr.ResourceManagementObject.ObjectIdentifier -ObjectType "ManagementPolicyRule"
            SetSingleValue $ModifyImportObject "Disabled" "false"
            if($ImportObjects -eq $null)
            {
                $ImportObjects = (,$ModifyImportObject)
            }
            else
            {
                $ImportObjects += $ModifyImportObject
            }
            
        }
        if($ImportObjects -ne $null)
        {
            $ImportObjects | Import-FIMConfig -Uri $Uri
        }
    }
}

function CreatePerson
{
    PARAM($FirstName, $LastName, $AccountName, $Domain, $Email, $Uri = $DefaultUri)
    END
    {
        $DisplayName = [System.String]::Format("{0} {1}", $FirstName, $LastName)
        
        $NewPerson = CreateImportObject -ObjectType "Person"
        SetSingleValue $NewPerson "FirstName" $FirstName
        SetSingleValue $NewPerson "LastName" $LastName
        SetSingleValue $NewPerson "DisplayName" $DisplayName
        SetSingleValue $NewPerson "AccountName" $AccountName
        SetSingleValue $NewPerson "Domain" $Domain
        SetSingleValue $NewPerson "Email" $Email
        
        $UserSid = GetSidAsBase64 -AccountName $AccountName -Domain $Domain
        SetSingleValue $NewPerson "ObjectSID" $UserSid
        
        $NewPerson | Import-FIMConfig -Uri $Uri
    }
}

function CreateGroup
{
    PARAM($DisplayName, $Owner, $AccountName, $Domain, $Email, $GroupType, $GroupScope, $Uri = $DefaultUri)
    END
    {
        $NewGroup = CreateImportObject -ObjectType "Group"
        SetSingleValue $NewGroup "DisplayName" $DisplayName
        SetSingleValue $NewGroup "AccountName" $AccountName
        SetSingleValue $NewGroup "Domain" $Domain
        if($Email -ne $null)
        {
            SetSingleValue $NewGroup "Email" $Email
        }
        if($GroupScope -ne $null)
        {
            SetSingleValue $NewGroup "Scope" $GroupScope
        }
        SetSingleValue $NewGroup "Type" $GroupType
        
        $ResolveOwner = ResolveObject -ObjectType "Person" -AttributeName "Email" -AttributeValue $Owner
        SetSingleValue -ImportObject $NewGroup -AttributeName "Owner" -AttributeValue $ResolveOwner.SourceObjectIdentifier -FullyResolved 0
        
        $ImportObjects = (,$ResolveOwner)
        $ImportObjects += $NewGroup
        $ImportObjects
        $ImportObjects | Import-FIMConfig -Uri $Uri
    }
}

# Value values for scope:
# Universal
# Global
# Domain
function CreateSecurityGroup
{
    PARAM($DisplayName, $Owner, $AccountName, $Domain, $Email, $GroupScope, $Uri = $DefaultUri)
    END
    {
        CreateGroup -DisplayName $DisplayName -Owner $Owner -AccountName $AccountName -Domain $Domain -Email $Email -GroupScope $GroupScope -GroupType "SecurityGroup" -Uri $Uri
    }
}

function CreateDistributionGroup
{
    PARAM($DisplayName, $Owner, $AccountName, $Domain, $Email, $Uri = $DefaultUri)
    END
    {
        CreateGroup -DisplayName $DisplayName -Owner $Owner -AccountName $AccountName -Domain $Domain -Email $Email -GroupType "Distribution" -Uri $Uri    
    }
}

function AllRequestsToElevatedSecurityGroup
{
    END
    {
        $resources = QueryResource -Filter "/Request[Creator=/Group[DisplayName='Elevated Access Security Group']/ComputedMember and Operation='Put' ' and Status='Completed']"
        $resources
    }
}

See Also

Reference

Export-FIMConfig
Compare-FIMConfig
Import-FIMConfig
Join-FIMConfig

Concepts

Windows PowerShell Example Functions that Communicate with the FIM Service
Windows PowerShell Example Helper Functions
Annotated Script Examples
Windows PowerShell Tools for FIM 2010

Other Resources

FIM ScriptBox