Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Bulk update objects in FIM/MIM based on CSV file
<#
.SYNOPSIS
Example script to bulk update users from CSV file.
The CSV file needs to have columnnames in row 1.
Columnnames need to correspond to the attribute name in FIM/MIM.
The column specified as "anchor" will not be updated all other columns will be updated based on content in csv file.
Multivalue and Reference data types are not supported in this version.
The script requires that the Lithnet Power Shell module is installed on the computer running the script.
The account running the script requires write permission to all attributes in the csv file except for the anchor attribute.
#>
PARAM(
[string]$CSVFile = 'C:\Temp\CSVUsers.txt',
[string]$Delimiter = ',',
[string]$Anchor = 'AccountName',
[string]$ResourceType = 'Person',
[string]$FIMServiceURI = 'http://localhost:5725'
)
#region Lithnet
if(!(Get-Module -Name LithnetRMA))
{
Import-Module LithnetRMA;
}
Set-ResourceManagementClient -BaseAddress $FIMServiceURI;
#endregion Lithnet
$Objects = Import-Csv -Delimiter $Delimiter -Path $CSVFile
$Attributes = (Get-Content $CSVFile)[0] -split $Delimiter | ?{$_ -ne $Anchor}
ForEach($Object in $Objects)
{
$resource = Get-Resource -ObjectType $ResourceType -AttributeName $Anchor -AttributeValue ($Object.psobject.Properties | ?{$_.Name -eq $Anchor}).Value -AttributesToGet $Attributes
ForEach ($Attribute in $Attributes)
{
($resource.psobject.Properties | ?{$_.Name -eq $Attribute}).Value = ($Object.psobject.Properties | ?{$_.Name -eq $Attribute}).Value
}
$resource | Save-Resource
}
AccountName,DisplayName,OfficePhone
jdoe,John Doe,1-234-567
@KentNordstrom
Copy link
Author

KentNordstrom commented Mar 15, 2017

As you can see it does not have any errorhandling in it. I wanted the published version to be as clean as possible to show functionality. Feel free to add comments about what kind of basic errorhandling I should add.

@KentNordstrom
Copy link
Author

KentNordstrom commented Mar 15, 2017

What would be a good way to handle MultiValue and Reference attributes? Reading the datatype of the attribute I can ask FIMService about it, but what format should we have in the data?

If it is Reference should we then assume it's the same ResourceType and containing the "same" Anchor column/value or should the column name be like #Ref#ResourceType#AnchorAttribute#?

@msidmvp
Copy link

msidmvp commented Mar 17, 2017

Hi Kent. Flexibility and control of #Anchor#Action#...#RefResourceType#RefAnchorAttribute#RefValue seems right.

SalesGroup,add,person,accountname,jdoe
SalesGroup,add,person,accountname,kdoe
SalesGroup,delete,person,accountname,ldoe

For multivalued, I would suspect most would have multivalues in a column therefore something like:
#Anchor#Action#AttribName#AttribuValue

jdoe,add,proxyaddresses,jdoe@company.com
jdoe,add,proxyaddresses,alias@company.com
jdoe,delete,proxyaddress,bademail@company.com

What do you think?

@KentNordstrom
Copy link
Author

KentNordstrom commented Mar 17, 2017

I agree that for MV values we really need some #Action Add/Remove for Multivalue. Action is not needed for Single Value since "empty" column will be delete of value. So for MV attributes we would get two columns in the CSV something like [#Add#EmailAlias] and [#Remove#EmailAlias]

But if we then combine all and need MV Reference like Group ExplicitMembers we will need some special tagging for #Ref#Type#Anchor.

I will try to come up with some examples and post them here to get feedback. Have made similar script for customers before but they were not as "generic" as I would like this one to be, but at the same time very simple to use.

@shubhigaur
Copy link

shubhigaur commented Jun 3, 2022

Hi @KentNordstrom
I have a multi-valued attribute that needs to be updated through CSV. The single valued are getting updated as you mentioned, but not the MV, can you suggest the change I need to make in the script to accomplish this. Thanks.

@KentNordstrom
Copy link
Author

KentNordstrom commented Jun 4, 2022

Hi @shubhigaur as you can see in the other comments it's not as easy at it looks to make it a "generic" solution. If you have a column with data that needs to go into a MV attribute it will likely be easier to make a version covering your specific scenario.

I have several variants for this depending on the scenario... For example Group.ExplicitMember can be handled from Group perspective adding Persons as members or from Person perspective adding them as members in the listed Group(s).

@shubhigaur
Copy link

shubhigaur commented Jun 6, 2022

Thanks Kent, I made the necessary changes in the script, I will post the script here for reference.

@shubhigaur
Copy link

shubhigaur commented Jun 6, 2022

PARAM(
[string]$CSVFile = 'C:\Temp\CSVUsers.txt',
[string]$Delimiter = ',',
[string]$Anchor = 'AccountName',
[string]$ResourceType = 'Person',
[string]$FIMServiceURI = 'http://localhost:5725'
)

#region Lithnet
if(!(Get-Module -Name LithnetRMA))
{
Import-Module LithnetRMA;
}

Set-ResourceManagementClient -BaseAddress $FIMServiceURI;
#endregion Lithnet

$Objects = Import-Csv -Delimiter $Delimiter -Path $CSVFile
$Attributes = (Get-Content $CSVFile)[0] -split $Delimiter | ?{$_ -ne $Anchor}

ForEach($Object in $Objects)
{
$resource = Get-Resource -ObjectType $ResourceType -AttributeName $Anchor -AttributeValue ($Object.psobject.Properties | ?{$.Name -eq $Anchor}).Value -AttributesToGet $Attributes
ForEach ($Attribute in $Attributes)
{
if ($resource.MVattribute -eq $null)
{
($resource.psobject.Properties | ?{$
.Name -eq $Attribute}).Value = ($Object.psobject.Properties | ?{$.Name -eq $Attribute}).Value
}
else
{
$resource.MVattribute.Add(($Object.psobject.Properties | ?{$
.Name -eq $Attribute}).Value)
}
}
$resource | Save-Resource
}

@KentNordstrom
Copy link
Author

KentNordstrom commented Jun 6, 2022

@shubhigaur Do you have a small sample csv file that works with your version of the script? Just for reference if people find this Gist.

@shubhigaur
Copy link

shubhigaur commented Jun 6, 2022

ADDN:OUMapping
OU=00001,OU=Branches,DC=LO,DC=AD,DC=UAT:Oxford Branch
OU=00002,OU=Branches,DC=LO,DC=AD,DC=UAT:ABCD Branch
OU=00003,OU=Branches,DC=LO,DC=AD,DC=UAT:MI Branch
OU=00003,OU=Branches,DC=LO,DC=AD,DC=UAT:COD Branch
OU=00004,OU=Branches,DC=LO,DC=AD,DC=UAT:NO Branch
OU=00004,OU=Branches,DC=LO,DC=AD,DC=UAT:CSO Branch

I am mapping ADDN with a branch name here. 00003 and 0004 has multiple values and OUMapping is a MV attribute here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment