Using PowerShell to bulk create criteria-based security groups from a CSV file
Summary Create one or more criteria-based security groups in the FIM Portal using a CSV file. # Create criteria-base security groups from a CSV file. # The CSV file must include a header row, such as in the following example (without the leading hashes): #DisplayName,AccountName,Description,Filter #SG-Geneva,sgGeneva,Staff based in Geneva,/Person[(EmployeeType = 'Employee') and (OfficeLocation = 'Geneva')] #SG-Engineers,sgEngineers,All Engineers,/Person[(EmployeeType = 'Employee') and ((starts-with(JobTitle, 'Consultant')) or (starts-with(JobTitle, 'Technical')))] #---------------------------------------------------------------------------------------------------------- set-variable -name CSV -value "groups.csv" set-variable -name URI -value "http://fim:5725/resourcemanagementservice" set-variable -name DOMAIN -value "MYDOMAIN" set-variable -name SCOPE -value "Global" set-variable -name TYPE -value "Security" set-variable -name OWNER -value "Administrator" set-variable -name PREFILTER -value "<Filter xmlns:xsi=`"http://www.w3.org/2001/XMLSchema-instance`" xmlns:xsd=`"http://www.w3.org/2001/XMLSchema`" Dialect=`"http://schemas.microsoft.com/2006/11/XPathFilterDialect`" xmlns=`"http://schemas.xmlsoap.org/ws/2004/09/enumeration`">" set-variable -name POSTFILTER -value "</Filter>" #---------------------------------------------------------------------------------------------------------- function SetAttribute { PARAM($object, $attributeName, $attributeValue) END { write-host $attributeName $attributeValue $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 } } #---------------------------------------------------------------------------------------------------------- if(@(get-pssnapin | where-object {$_.Name -eq "FIMAutomation"} ).count -eq 0) {add-pssnapin FIMAutomation} # Get Owner $ownerObject = export-fimconfig -uri $URI ` onlyBaseResources ` -customconfig "/Person[AccountName='$OWNER']" if($ownerObject -eq $null) {throw "Owner not found!"} $ownerID = $ownerObject.ResourceManagementObject.ObjectIdentifier -replace "urn:uuid:","" # Import CSV and process each line import-csv($CSV) | foreach { # Check if a group with the same name already exists $objectName = $_.DisplayName $exportObject = export-fimconfig -uri $URI ` onlyBaseResources ` -customconfig "/Group[DisplayName='$objectName']" if($exportObject) {write-host "`nGroup $objectName already exists"} else { $filter = $PREFILTER + $_.Filter + $POSTFILTER # Create group and add attributes $newGroup = CreateObject -objectType "Group" SetAttribute -object $newGroup -attributeName "DisplayName" -attributeValue $objectName SetAttribute -object $newGroup -attributeName "AccountName" -attributeValue $_.AccountName SetAttribute -object $newGroup -attributeName "Domain" -attributeValue $DOMAIN SetAttribute -object $newGroup -attributeName "Scope" -attributeValue $SCOPE SetAttribute -object $newGroup -attributeName "Type" -attributeValue $TYPE SetAttribute -object $newGroup -attributeName "Filter" -attributeValue $filter SetAttribute -object $newGroup -attributeName "Description" -attributeValue $_.Description SetAttribute -object $newGroup -attributeName "Owner" -attributeValue $ownerID SetAttribute -object $newGroup -attributeName "DisplayedOwner" -attributeValue $ownerID SetAttribute -object $newGroup -attributeName "MembershipLocked" -attributeValue $true SetAttribute -object $newGroup -attributeName "MembershipAddWorkflow" -attributeValue "None" # Import group into the FIM Portal $newGroup | Import-FIMConfig -uri $URI write-host "`nGroup creation request complete`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 } #---------------------------------------------------------------------------------------------------------- Go to the FIM ScriptBox http://www.wapshere.com/missmiis
February 28th, 2010 4:03pm

Carol, thanks so much for posting this - I've taken your approach and used it to create AttributeTypeDescriptions, Bindings, Policies and Search Scopes!Brad Turner, ILM MVP - Ensynch, Inc - www.identitychaos.com
Free Windows Admin Tool Kit Click here and download it now
April 7th, 2010 10:46am

Updated to fix a bug with the CSV file name.http://www.wapshere.com/missmiis
April 8th, 2010 2:54pm

Carol, I'm no PowerShell wiz, but personally I like to use the PARAM switch at the top of the program to paramertize the script and it will accept defaults: PARAM($CSV = "groups.csv", $URI = "http://fim:5725/resourcemanagementservice", $DOMAIN = "MYDOMAIN", $SCOPE = "Global", $TYPE = "Security", $OWNER = "Administrator") set-variable -name PREFILTER -value "<Filter xmlns:xsi=`"http://www.w3.org/2001/XMLSchema-instance`" xmlns:xsd=`"http://www.w3.org/2001/XMLSchema`" Dialect=`"http://schemas.microsoft.com/2006/11/XPathFilterDialect`" xmlns=`"http://schemas.xmlsoap.org/ws/2004/09/enumeration`">" set-variable -name POSTFILTER -value "</Filter>" This allows you to override any of the values either positionally, or as I learned just the other day, using a named switch, although that might be a PowerShell 2.0 feature: .\Script.ps1 -CSV mygroups.csv -DOMAIN yourdomain.comBrad Turner, ILM MVP - Ensynch, Inc - www.identitychaos.com
Free Windows Admin Tool Kit Click here and download it now
April 12th, 2010 6:16am

Yes that would be much nicer. Thanks! :-)http://www.wapshere.com/missmiis
April 12th, 2010 7:59am

Carol, Im just wondering, i would like to run yiour script above but also make it produce "mail enabled secuirty groups" with email alias... im not fluent in powersehll scripting so can you let me know how i would add these additional variables to the script? stu
Free Windows Admin Tool Kit Click here and download it now
September 20th, 2010 5:05am

Hi, I am having the following error when running the script to create teh security groups, using the same example group on top: table.MsoNormalTable { font-size: 11pt; font-family: "Calibri","sans-serif"; } Import-FIMConfig : Failure when making web service call. SourceObjectID = c207e75b-e1a1-488b-8b82-79ef9d496159 Error = Microsoft.ResourceManagement.WebServices.Client.PermissionDeniedException: Policy prohibits the request from co mpleting. ---> Microsoft.ResourceManagement.WebServices.Faults.ServiceFaultException: Policy prohibits the request from completing. at Microsoft.ResourceManagement.WebServices.ResourceFactoryClient.Create(Message request) at Microsoft.ResourceManagement.WebServices.ResourceFactoryClient.Create(Create createBody) at Microsoft.ResourceManagement.WebServices.Client.ResourceTemplate.CreateResource() --- End of inner exception stack trace --- at Microsoft.ResourceManagement.WebServices.Client.ResourceTemplate.CreateResource() at Microsoft.ResourceManagement.WebServices.ResourceManager.CreateResource() at Microsoft.ResourceManagement.Automation.ImportConfig.Create(String objectType, List`1 changeList) at Microsoft.ResourceManagement.Automation.ImportConfig.EndProcessing() At C:\Users\talmeida\desktop\create_groups.ps1:78 char:31 + $newGroup | Import-FIMConfig <<<< -uri $URI + CategoryInfo : InvalidOperation: (:) [Import-FIMConfig], InvalidOperationException + FullyQualifiedErrorId : ImportConfig,Microsoft.ResourceManagement.Automation.ImportConfig Can you help me? Thanks. Regards, Edgar Oliveira
October 15th, 2010 5:20pm

It says "PermissionDeniedException". Check the MPRs related to the account you are using from powershell.http://www.wapshere.com/missmiis
Free Windows Admin Tool Kit Click here and download it now
October 18th, 2010 11:50am

This is an older thread but I wanted to see if you had some ideas on this.. I'm doing the same thing you were, but I wanted to add the owner as a member of the group, so I added SetAttribute -object $newGroup -attributeName "Type" -attributeValue $_.Type SetAttribute -object $newGroup -attributeName "Description" -attributeValue $_.Description SetAttribute -object $newGroup -attributeName "Owner" -attributeValue $ownerID SetAttributeMV -object $newGroup -attributeName "Member" -attributeValue $ownerID SetAttribute -object $newGroup -attributeName "DisplayedOwner" -attributeValue $ownerID and created a new function Called SetAttributeMV, and tried various combination of .operation and .fully resolved based on some other posts, but anytime I try to set member, I get the error below.. I tried with the regualr SetAtrtibute function also with the same error.. I'm able to set 'owner', which is also a MV attribute, so i'm not sure what's different about 'member' If i leave off the member setting, it creates properly. I also tried to change the "MembershipAddWorkflow" to 'None' to make sure that wasn't the issue. function SetAttributeMV { PARAM($object, $attributeName, $attributeValue) END { write-host $attributeName : $attributeValue $importChange = New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ImportChange $importChange.Operation = 0 $importChange.AttributeName = $attributeName $importChange.AttributeValue = $attributeValue $importChange.FullyResolved = 0 $importChange.Locale = "Invariant" if ($object.Changes -eq $null) {$object.Changes = (,$importChange)} else {$object.Changes += $importChange} } } DisplayName : dist grp 3 AccountName : dist grp 3 Domain : corp Scope : Universal Type : Distribution Description : My distribution group 3 Owner : 63ce3bcc-aaa4-477e-bffe-bf9ad8ee8834 Member : 63ce3bcc-aaa4-477e-bffe-bf9ad8ee8834 DisplayedOwner : 63ce3bcc-aaa4-477e-bffe-bf9ad8ee8834 MembershipLocked : False MembershipAddWorkflow : Owner Approval SourceObjectIdentifier : aba63ea4-bee0-44b5-8bf1-fc4e9c5c6901 TargetObjectIdentifier : ObjectType : Group State : Create Changes : {DisplayName, AccountName, Domain, Scope...} AnchorPairs : Import-FIMConfig : Failure when making web service call. SourceObjectID = aba63ea4-bee0-44b5-8bf1-fc4e9c5c6901 Error = System.InvalidOperationException: Operation is not valid due to the current state of the object. at Microsoft.ResourceManagement.WebServices.ResourceManager.get_Item(String attributeName) at Microsoft.ResourceManagement.Automation.ImportConfig.Create(String objectType, List`1 changeList) at Microsoft.ResourceManagement.Automation.ImportConfig.EndProcessing() At C:\scripts\createGroup3x.ps1:126 char:31 + $newGroup | Import-FIMConfig <<<< -uri $URI + CategoryInfo : InvalidOperation: (:) [Import-FIMConfig], InvalidOperationException + FullyQualifiedErrorId : ImportConfig,Microsoft.ResourceManagement.Automation.ImportConfig
February 8th, 2011 11:13am

It has something to do with the " $importChange.Operation = 0" Possibly because you need to explicitly state ADD operation. I ran into those errors when trying to use the wrong operation on a multi-value attribute.
Free Windows Admin Tool Kit Click here and download it now
February 8th, 2011 11:24am

The problem may be that the attribute is not actually called "Member" but "ExplicitMember"http://www.wapshere.com/missmiis
February 8th, 2011 11:36am

Carol - That was it.. You know I would never have thought to actually look at the object to get its attribute's names.. :) Thanks. I'm working on an add-on to your script to read a text file with a list of members of the group. For each group, there will be a text file with the same name as the group. I'll post the script when i'm done with it. I'll have another script that takes group data from AD and generates the input files.
Free Windows Admin Tool Kit Click here and download it now
February 8th, 2011 1:29pm

Frank, I have one that reads from a text file the names of the groups to bulk update...i.e. owner, displayed owner and the like, but I would really appreciate the next script that takes the group data from AD to generate that list. :)
February 8th, 2011 2:12pm

Don't forget to post your finished product in the scriptbox http://social.technet.microsoft.com/wiki/contents/articles/how-to-post-a-fim-scriptbox-script.aspx :-) BTW there is an updated version of this script in the scrptbox now: http://social.technet.microsoft.com/wiki/contents/articles/how-to-use-powershell-to-create-criteria-based-security-groups-from-a-csv-file.aspx http://www.wapshere.com/missmiis
Free Windows Admin Tool Kit Click here and download it now
February 8th, 2011 2:34pm

Carol, This addition is something you may or may not want to do, depending on if you want members added to your groups. Insert this in the section where you are setting attributes. For each group, it takes the accountName of the group and reads a file called %accountname%.members which is a csv file with only one column, 'member' and a list of the sAMAccountNames of the members. Of course you need a script to dump this data from AD into the corresponding text files, but that's a fairly simple exercise. You do have to transate the GroupType into FIM Types and scopes, but most other attributes come over as-is. $MemberFile = $_.AccountName Write-Host ".. Reading $MemberFile" import-csv($MemberFile.members) | foreach { # convert format from accountName to FIM ObjectIdentifier $groupMember = $_.Member $memberObject = export-fimconfig -uri $URI -onlyBaseResources -customconfig "/Person[AccountName='$groupMember']" if($memberObject -eq $null) {throw "Member not found!"} $memberID = $memberObject.ResourceManagementObject.ObjectIdentifier -replace "urn:uuid:","" #Add user to group SetAttributeMV -object $newGroup -attributeName "ExplicitMember" -attributeValue $memberID }
February 12th, 2011 12:19am

Good one!http://www.wapshere.com/missmiis
Free Windows Admin Tool Kit Click here and download it now
February 12th, 2011 3:37am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics