Giter Club home page Giter Club logo

miis-powershell's People

Contributors

ryannewington avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

miis-powershell's Issues

Start-ManagementAgent : The given key was not present in the dictionary.

When executing Start-Management "MIM Portal" ExFIFS I get an error "Start-ManagementAgent : The given key was not present the dictionary." It works on other run profiles on that MA and others. Also it does actually start the management agent with that run profile so it functions correctly but throws the error.

Get-MVObject fails when running the script in a schedule task

Hi,

I have the following script:

Import-Module LithnetMIISAutomation
sleep -Seconds 2

Get the metaverse object

$queryfilter = @();
$queryfilter += New-MVQuery -Attribute legalHold -Operator IsPresent
$results = Get-MVObject -Queries $queryfilter

When i run it using Powershell ISE, it runs successfully. However, when i run it in a scheduled task under the same user that ran it in Powershell ISE, i get the following error "The Synchronization Service Manager service has stopped." While the Sync service is actually running and never was stopped.

worth to mention that i'm using windows task scheduler to schedule the task running the script.

any ideas?

When try to Get-CSObject using -ID, get error of value does not fall within the expected range

Hi Ryan,
I am getting errors when I try to get csobject by using id. I am not sure if I did something wrong. Below is a sample of a csobject (without DN information for client privacy reason).

ConnectedCSObjects : {5111c970-121b-e611-80ca-00155d948d09, 4e1da4de-0618-e611-80ca-00155d948d09}
ID : 4e1da4de-0618-e611-80ca-00155d948d09
MAID : 91bd6acd-c6a9-4340-86b1-0ce6d7805f46
MaName : ECD
MvGuid : cb861f5d-f655-e511-80c0-00155d948d09
MetaverseLink : cb861f5d-f655-e511-80c0-00155d948d09

I have tried using every single guid but they all returned error.
PS C:\Users\adm_kcheng> Get-CSObject -id 4e1da4de-0618-e611-80ca-00155d948d09 -ma ecd
Get-CSObject : Value does not fall within the expected range.
At line:1 char:1

  • Get-CSObject -id 4e1da4de-0618-e611-80ca-00155d948d09 -ma ecd
  •   + CategoryInfo          : NotSpecified: (:) [Get-CSObject], MiiserverException
      + FullyQualifiedErrorId : Lithnet.Miiserver.Client.MiiserverException,Lithnet.Miiserver.Automation.GetCSObject
    
    

PS C:\Users\adm_kcheng> Get-CSObject -id cb861f5d-f655-e511-80c0-00155d948d09 -ma ecd
Get-CSObject : Value does not fall within the expected range.
At line:1 char:1

  • Get-CSObject -id cb861f5d-f655-e511-80c0-00155d948d09 -ma ecd
  •   + CategoryInfo          : NotSpecified: (:) [Get-CSObject], MiiserverException
      + FullyQualifiedErrorId : Lithnet.Miiserver.Client.MiiserverException,Lithnet.Miiserver.Automation.GetCSObject
    
    

Get-MVObject with multiple queries seem to fail with large result set

Hi Ryan.

Loving this library mate! Using v1.0.6053

I have the following query set:

Attribute Value Operator


employeeStatus active Equals
sourceForest NA Equals
accountName E StartsWith
employeeID IsPresent
assignedLicenses IsPresent

When I run Get-MVObject -Queries $queries I end up with 675 objects and no error. However when I remove the accountName filter the result should be 2849 objects but instead I get the following exception:

`Get-MVObject : There are multiple root elements. Line 172030, position 2.
At line:9 char:17

  • $mvPeople = Get-MVObject -Queries $queries
    
  •             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : NotSpecified: (:) [Get-MVObject], XmlException
    • FullyQualifiedErrorId : System.Xml.XmlException,Lithnet.Miiserver.Automation.GetMVObject`

Is there an undocumented limit for this function?
Thanks.

get-disconnectors or get-pendingexportdeletes running incredibly slow on some MIM management agent while fast on another

I'm having the issue that on some of my MIM (v4.6.263.0) Management Agents the command get-disconnectors or get-pendingexportdeletes takes ages to return the results while on another one it runs quite fast.

Examples:
This one goes fast....
image

while this one runs slow:
image

I chancelled it after 7 minutes and had zero results returned. Same with the get-pendingexportdeletes and also get-csobject is running way slow on that Management Agent. On the other it is again fast and I don't have any clue why though? Both Agents are for ADservices and it's connector space is pointing to the same sql instance.

Did you ever face such an issue?

I have some unwanted export deletes outstanding which need to be removed and it took now more than 4 hours to delete 158 objects for only one agent.

PendingExports data cleared after Export Audit Drop file

Hi @ryannewington ... this may not be a bug with the module, but I've noticed this weekend that after an export audit drop file is created on an export run profile ("and stop run" option), the Pending Exports attributes/dnattributes collection are cleared. Can you verify this, and if so indicate if you think this is an MS bug (which rings a bell) or something you believe you can fix? I updated your library today after I noticed the operations were showing as "None" for multivalue attribute changes, and appreciate the work you've done to fix that issue.
Cheers ... hope you're doing well.
Bob

New-MVQuery to support search of object class

Hi Ryan,

New-MVQuery can query MV objects based on a search criteria, but can't seem to query and return all objects of a particular object class without applying a search criteria which would be a nice addition, similar to what you can do in the console under Metaverse Search.

Also your link to https://github.com/lithnet/miis-powershell/wiki/New-MVQuery doesn't find the page, although full help in PowerShell does work - 'get-help New-MVQuery'.

Dave

Import MA from File

Hi.

I saw the Export MA cmdlet, but I could not find an Import cmdlet.

Do you have plans to implement a Import MA cmdlet to import MA from File?

Thanks

Get-CSObject failed to return result if CN contanins "&"

Hi Ryan,
I recently experienced an issue when I was searching for a CSObject which has a symbol "&" in the CN. The result returned nothing. But if I use the console, it finds the object.
Can you please check this?
Thanks,
Kevin

Get-PendingExportUpdates and multivalued attribute

Hi,

I am running the Get-PendingExportUpdates cmdlet to get all CS objects that are about to be exported. For each CS, I check the attributes that are about to be modified (need to log before/after modification). One attribute I monitor happens to be a "multivalued" attribute.
In the exemple shown below, I see that there are changes for that attribute but my problem is that I cannot tell which entry is a "New" versus a "Delete".

Example:
There is one CS object pending export in MIIS. It shows that the AD GroupPriority attribute has one (1) new entry and one (1) delete:

image

In Powershell, when I run:

[DBG]: PS C:\apps\psscripts>>$a = Get-PendingExportUpdates -ma AD -Delta
[DBG]: PS C:\apps\psscripts>> $a[0]

image

I see that the changes is with the [GroupPriority] attribute and that two entries are referred but how would I be able to tell if it is a delete or a add. Any way it can be done ?

Thanks!

Can the Get-CSOjbect command return all attributes of the object?

Hi Ryan,

I had scenario where I needed to get a copy of all the CS objects and their attributes. I tried Get-CSObject with the -RDN switch, but doesn't look like the Get-CSObject commandlet returns the attributes of the objects. Can this be added? I could cut-and-paste the records in the GUI but it seems to hang when trying to copy many thousands of rows.

Cheers

David

Export-ManagementAgent fails to export MA without error

Export-ManagementAgent cmdlet fails to create the requested .xml file.
If the incorrect MA name is provided the expected error is received.
Have tried full path to intended output file, file only path for the current directory for the output file.
Verbose provides no additional information.
Have tried with core MIM MA's (eg. the Out of the Box AD MA), as well as the MIM Service MA and Granfeldt PowerShell MA.

Can reproduce on MIM 2016 w/ SP1 4.4.1302.0 and MIM 2016 4.3.2195.0

PS C:\temp\backup> Export-ManagementAgent -File c:\temp\backup\adusers.xml -MA "AzureADUsers" -Verbose -Debug

PS C:\temp\backup> dir

PS C:\temp\backup> Export-ManagementAgent -File c:\temp\backup\adusers.xml -MA "AzureADUsers2" -Verbose -Debug
Export-ManagementAgent : Management agent AzureADUsers2 was not found
At line:1 char:1
+ Export-ManagementAgent -File c:\temp\backup\adusers.xml -MA "AzureADU ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Export-ManagementAgent], InvalidOperationException
    + FullyQualifiedErrorId : System.InvalidOperationException,Lithnet.Miiserver.Automation.ExportManagementAgent
 

PS C:\temp\backup> Export-ManagementAgent -File adusers.xml -MA "AzureADUsers" -Verbose -Debug

PS C:\temp\backup> dir

PS C:\temp\backup> 

Get-SavedRunHistory returns no objects

Today, I ran:
Save-RunHistory -File I:\Scripts\_Investigations\_data\RunHistory_2020.08.17.xml
which generated a file of around 15 KB.

Then I ran:
Get-SavedRunHistory -File I:\Scripts\_Investigations\_data\RunHistory_2020.08.17.xml
and got no results.

I had a nose around in the source for RunDetails.cs in miis-client and then ran this:
Get-Content -path I:\Scripts\_Investigations\_data\RunHistory_2020.08.17.xml -First 3
and got these lines:

	<?xml version="1.0" encoding="utf-8"?>
	<execution-histories>
	  <run-details>

I think the issue is in line 108 of RunDetails.cs where it says:

foreach (XmlNode node in d.SelectNodes("/execution-histories/run-history/run-details"))

I'm running the current version of LithnetMiisAutomation:

PS C:\Windows\system32> Get-Module LithnetMiisAutomation | Select-Object -Property Name,Version

Name                  Version
----                  -------
LithnetMiisAutomation 1.0.6960.34402	

and MIM 4.6.34:

PS C:\Windows\system32> (Get-Item "C:\Program Files\Microsoft Forefront Identity Manager\2010\Synchronization Service\Bin\miiserver.exe").VersionInfo | Select-O
bject -Property FileVersion,ProductVersion

FileVersion ProductVersion
----------- --------------
4.6.34.0    4.6.34.0

Disconnect-CSObject : Exception from HRESULT: 0x80230703

Hi,

i'm using the example in the disconnect-csobject page to disconnect an object. when i run the get-csobject it works:

PS E:\FIM> $cs = Get-CSObject -RDN "CN=Andoni, Majd2" -MA "ADMA"
PS E:\FIM> $cs

ConnectedCSObjectLinks : {PeopleSoftMA, FIMMA, ADMA}
ConnectedCSObjects : {bb8da061-5514-eb11-816e-000d3a12abca, b25e089d-5514-eb11-816e-000d3a12abca,
b35e089d-5514-eb11-816e-000d3a12abca}
AccountName :
DN : CN=Andoni, Majd2\0ADEL:d0f34618-215d-4650-a9c1-9411503916e4,CN=Deleted
Objects,DC=xxx,DC=xxx,DC=fim
DomainName :
FullyQualifiedDomainName :
ID : b35e089d-5514-eb11-816e-000d3a12abca
MAID : 289377d4-734f-4621-af2f-090423ba2bb1
MaName : ADMA
MvGuid : b15e089d-5514-eb11-816e-000d3a12abca
ObjectType : user
PartitionGuid : c16d9aab-cdea-4d04-b50d-ed8206d26a0e
PartitionName : DC=xxx,DC=xxx,DC=fim
PendingRefDelete : False
SeenByImport : True
IsConnector : True
ConnectorState : Normal
RebuildInProgress : False
Obsoletion : True
NeedFullSync : False
IsPlaceholderParent : False
IsPlaceholderLink : False
IsPlaceholderDelete : False
IsPending : True
PendingReferenceRetry : False
PendingRenameRetry : False
ImportDeltaOperation : delete
ExportDeltaOperation : none
LastImportDeltaTime : 10/22/2020 11:23:53 AM
LastExportDeltaTime : 10/22/2020 11:11:47 AM
DisconnectionType :
DisconnectionID :
DisconnectionTime :
MetaverseLink : b15e089d-5514-eb11-816e-000d3a12abca
UnappliedExportDelta : CN=Andoni, Majd2\0ADEL:d0f34618-215d-4650-a9c1-9411503916e4,CN=Deleted
Objects,DC=xxx,DC=xxx,DC=fim
EscrowedExportDelta : CN=Andoni, Majd2\0ADEL:d0f34618-215d-4650-a9c1-9411503916e4,CN=Deleted
Objects,DC=xx,DC=xxx,DC=fim
UnconfirmedExportDelta : CN=Andoni, Majd2\0ADEL:d0f34618-215d-4650-a9c1-9411503916e4,CN=Deleted
Objects,DC=xxxDC=xxxDC=fim
PendingImportDelta : CN=Andoni, Majd2,OU=Employees,OU=User Accounts,DC=xxx,DC=xxx,DC=fim
SynchronizedHologram : CN=Andoni, Majd2,OU=Employees,OU=User Accounts,DC=xxxDC=xxxg,DC=fim
UnappliedExportHologram : CN=Andoni, Majd2\0ADEL:d0f34618-215d-4650-a9c1-9411503916e4,CN=Deleted
Objects,DC=xxxDC=xxx,DC=fim
EscrowedExportHologram : CN=Andoni, Majd2\0ADEL:d0f34618-215d-4650-a9c1-9411503916e4,CN=Deleted
Objects,DC=ixxxDC=xxx,DC=fim
UnconfirmedExportHologram : CN=Andoni, Majd2\0ADEL:d0f34618-215d-4650-a9c1-9411503916e4,CN=Deleted
Objects,DC=xxxDC=xxx,DC=fim
PendingImportHologram : CN=Andoni, Majd2\0ADEL:d0f34618-215d-4650-a9c1-9411503916e4,CN=Deleted
Objects,DC=xxxDCxxx,DC=fim

However, when i run the disconect-csobject, i get the following error:
PS E:\FIM> Disconnect-CSObject -CSObject $cs -Explicit

Confirm disconnection
This action will result in the metaverse object being deleted. Continue
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): Y
Disconnect-CSObject : Exception from HRESULT: 0x80230703
At line:1 char:1

  • Disconnect-CSObject -CSObject $cs -Explicit
  •   + CategoryInfo          : NotSpecified: (:) [Disconnect-CSObject], MiiserverException
      + FullyQualifiedErrorId : Lithnet.Miiserver.Client.MiiserverException,Lithnet.Miiserver.Automation.DisconnectCSObj
     ect
    

Get-MAStatistic return wrong numbers from Full Import

I've an issue regarding a numbers of Adds I've in a full import.

MIM Reports no adds
fullimport

Get-MaStatistic returns 1 Add (It remember the last value)
PS C:\Windows\system32> $maSNOW = Get-ManagementAgent "SNOW CONSULENTI" -Reload
PS C:\Windows\system32> Start-ManagementAgent -RunProfileName "Full Import" -ma $maSNOW -ErrorAction Stop
PS C:\Windows\system32> $LastImport = Get-MAStatistics -ma $maSNOW
PS C:\Windows\system32> $LastImport
Total : 9
TotalConnectors : 8
TotalDisconnectors : 1
Placeholders : 0
NormalConnectors : 8
ExplicitConnectors : 0
NormalDisconnectors : 1
ExplicitDisconnectors : 0
FilteredDisconnectors : 0
ImportAdds : 1
ImportUpdates : 1
ImportDeletes : 0
ImportUnchanged : 7
PendingImportTotal : 2
ExportAdds : 0
ExportUpdates : 0
ExportDeletes : 0
PendingExportTotal : 0

I restart MIMService and Entire Server but Issue Remains..

Get-PendingExports result doesn't clarify what old and new values are

When running Get-PendingExports -MA xxx -Delta and inspecting the .Attributes["xxx].Values collection, it's not clear what the old and new values are in an update scenario. I thought there was a convention in use, i.e. first value was old and second value was new, but this isn't the case, sometimes they get reversed and show different to how you view the object in the GUI.

Am I doing anything wrong? Is there a way to determine old and new value?

The term 'export-fimconfig' is not recognized as the name of a cmdlet, function, script file, or operable program

Hi All,

after applying a patch on the MIM Service, Executing powershell scripts are not working anymore with the following error:

The term 'export-fimconfig' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. | The term 'export-fimconfig' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. | The term 'export-fimconfig' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. | The term 'export-fimconfig' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. | The term 'export-fimconfig' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

Running the scripts form PowerShell ISE works fine, but when it is being kicked in from a MIM portal workflow, the issue above is happening. i can work with you if needed to help troubleshoot and debug.

Install MSI / Powershell module to use it with Azure AD Connect

Hello,

I would like to use your powershell module to request metaverse of Azure AD Connect (which is build on FIM for the directory sync part).
I have checked your MSI and it seems you have some hardcoded check to detect the installation of FIM during the MSI Wizard (RegLocator\FimInstallDirFromRegistry).
Is it possible to skip this check officially to install it on an Azure AD Connect server ?
Do you already have tested it in that particular context ?

Thanks for your help,

Kind Regards,

Lucas.

Operation type of changes to DN attributes incorrectly shows 'none'

@ryannewington, I have a very similar question. When inspecting pending exports on a REF MVA, we use the DNAttributes property, though drilling down into each MVA value the Operation is always 'none', regardless of whether it's a Delete or Add. Is this a limitation of the MIM API or perhaps a bug in the module?

In the sync engine manager, you can see whether it's a add/delete, but not via the module.

Originally posted by @Amethi in #31 (comment)

Set-MVProvisioningRulesExtension does not manage declarative provisioning

This Command should support all values corresponding to the mv-data SyncConfig-provisioning-type.

  1. "none" = Off
  2. "sync-rule" = Synchronization Rule Provisioning is ON
  3. "scripted" = Enable Provisioning Rules Provisioning is ON
  4. "both" = 2+3 is ON

I usually manage this using the FIMService mv-data object, but this has been declared as a deprecated feature and I need to start using alternative (WMI?) method to turn declarative provisioning on/off.

Disconnect-CSObject -confirm parameter

The Disconnect-CSObject cmdlet requires confirmation for the deletion of the object.
Could we please have a parameter to accept the confirmation so the command can be used programmaticly.

Management Agent not found Scheduled Task

I have a Script which runs "Get-ManagementAgent -Name $Maname.
The script runs fine when I start it from the shell, when I start the script in a scheduled task the following error is logged:

PSMessageDetails :
Exception : System.InvalidOperationException: Management agent Equitrac Import was
not found
at Lithnet.Miiserver.Client.ManagementAgent.MANameToID(String name)
at Lithnet.Miiserver.Client.ManagementAgent.GetManagementAgent(String
name)
at
Lithnet.Miiserver.Automation.MiisController.GetManagementAgent(String
name, Boolean reload)
at Lithnet.Miiserver.Automation.GetManagementAgent.ProcessRecord()
at System.Management.Automation.CommandProcessor.ProcessRecord()
TargetObject :
CategoryInfo : NotSpecified: (:) [Get-ManagementAgent], InvalidOperationException
FullyQualifiedErrorId : System.InvalidOperationException,Lithnet.Miiserver.Automation.GetManagemen
tAgent
ErrorDetails :
InvocationInfo : System.Management.Automation.InvocationInfo
ScriptStackTrace : at , D:\MIMConfig\Scripts\Invoke-HourlyMARuns.ps1: line 82
at , : line 1
PipelineIterationInfo : {}

The MA "Equitrac Import" does exist.

Can this work on Adconnect?

i know theoretically it should work since it based on fim
but the install msi doesn't install because it doesn't find fim
is there away to get the module as standalone?

Start-ManagementAgent waits if already running

I'm wondering if there's a way when a PS script runs a Start-ManagementAgent command to not stop and wait if that MA is already running. I would like to have the script just continue on with the next line instead of waiting if the MA on the current Start-ManagementAgent line is already running. Is that possible or would I have to use a PS If statement to check if it's running before using that command? If I must use an If statement, do you have an example of how to do that? Thanks so much.

Ability to show all Agents current sync status and time

The way Wait-ManagementAgent -MA<MA_NAME> shows you what profile is running and how much approx time / speed etc..

Would like a new cmdlet or a -ALL flag which can show all the MA's found and output the same in a tabular format or something in shell..

Good for monitoring..

New-MVQuery only supports 'text' Operators (Equals, Contains, NotContains, IsPresent, IsNotPresent, StartsWith, EndsWith)

Awesome tools. Very powerful.

Please add support for Integer Operators to New-MVQuery.
GreaterThan | GreaterThanOrEquals | LessThan | LessThanOrEquals

Also please add the following Operator
NotEquals

New-MVQuery : Cannot bind parameter 'Operator'. Cannot convert value "notequals" to type
"Lithnet.Miiserver.Client.MVSearchFilterOperator". Error: "Unable to match the identifier name notequals to a valid
enumerator name. Specify one of the following enumerator names and try again:
Equals, Contains, NotContains, IsPresent, IsNotPresent, StartsWith, EndsWith"
At line:1 char:52

DR

Join-CSObject may cause an MV object to become orphaned

Hello,

I have used Join-csobject to join metaverse object and csobject in adma:

Join-CSObject -MVObjectType person -CSObject $cs -MVObjectID $mv.ID

The error is generated on the powershel console:
Join-CSObject : Exception from HRESULT: 0x80230232
At line:1 char:1

  • Join-CSObject -MVObjectType person -CSObject $cs -MVObjectID $mv.ID
  •   + CategoryInfo          : NotSpecified: (:) [Join-CSObject], MiiserverException
      + FullyQualifiedErrorId : Lithnet.Miiserver.Client.MiiserverException,Lithnet.Miiserver.Automation.JoinCSObject
    
    

Now the MV object used is not exist on metaverse and each time i do a sync, no matter it is a Full or Delta, an unexpected-error occuring on the Sync Service manager...

How can this be resolved?

WTF (where to find) Lithnet.Miiserver.Client

Nice work Ryan! Looks like a really nice job abstracting mmswebservice into nice commands. Looking at the source I see a reference to Lithnet.Miiserver.Client but don't see that package or source anywhere. Is it available too?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.