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