In the last couple of weeks I’ve been evaluating a number of different approaches/concepts for some upcoming MIM development projects. Some of these I’ve blogged about already.

Having an Identity Manager Metaverse with identity data is a key dependency to being able to validate ideas and concepts. So what’s a good source of some interesting and varied identity data with string, integer, reference, and boolean attributes? Twitter? Yeah why not. There’s an API. Should be pretty quick to get some sample data right?

In this blog post I’m going to give an overview of creating a PowerShell Management Agent to consume Twitter identities and their data into Microsoft Identity Manager. I’ll cover;

  • Obtaining Twitter user data from Twitter using Powershell and the Twitter RestAPI
  • Using Søren’s Powershell Management Agent to import Twitter user data obtained via the RestAPI
  • Manipulating the Twitter data into the MIM Synchronisation Engine

Twitter Data

Here’s an overview of my approach/rationale of what data I was looking for and how I got it from Twitter;

  • I don’t need real-time data. Just identity data
  • I need data of all different data-types
  • I need data with all the randomness that identity data often contains
  • I created a standalone script that took a seed Twitter identity (one of my accounts) and;
    • obtained the Twitter account info including the list of the Twitter accounts it followed
    • the Twitter accounts that follows it
  • The standalone script uses the Twitter RestAPI to obtain the data and respected the service and rate-limits
  • To make the Twitter API calls easy I leveraged the awesome InvokeTwitterAPI Powershell Module from Shannon Conley & Mehmet Kaya available here https://github.com/MeshkDevs/InvokeTwitterAPIs . I notice that there is an updated version from Marc R Kellerman available here https://www.powershellgallery.com/packages/InvokeTwitterAPIs/2.1/Content/InvokeTwitterAPIs.psm1 that was released after I had done most of my work. Notably it supports having multiple OAuth keys and the ratelimit restrictions. The details below leverage this updated version.

Here is what a sample of some of the data looks like in the Metaverse.

https://dl.dropboxusercontent.com/u/76015/BlogImages/TwitterMA/DataSample1.PNG

Pre-requisites

You need to enable your Twitter Account for API access. Follow the details here 

Getting the Seed Twitter account info

By now you should have downloaded the Twitter PowerShell API Modules and installed them. If you haven’t get WMF5 installed and run the install-module command as shown below in Line 1.

Modify the script below to give the;

  • Seed Twitter Account you want to bring in the Friends and Followers for as users into the MIM Metaverse
  • The API keys asscoiated with your Twitter account(s) you’re going to use to query the Twitter API
  • The directory you want to dump the account info out to

….. and let it loose.

Install-Module -Name InvokeTwitterAPIs
Import-Module InvokeTwitterAPIs
#Seed Account
$twitterScreenName = 'mytwitteraccount'
# output directory for XML MA Import Files
$downloadDirectory = 'C:\Users\darren\Dropbox\Kloud\Powershell\Twitter\data'
$OAuths = @()
# My Twitter Account Key
# Not valid values obviously
$OAuthBA = @{'ApiKey' = 'IysRMMT6asdfasdVVNefP2DIwLiv'; 'ApiSecret' = 'CbgtzwIQf0JIIsdfkjsdf97ZFuM7C97BYbTgRPoqsBFafDIKXYq'; 'AccessToken' = '22887449-ZCp4ysUkw2lLB2iXrNVljsafdljsdfljdstxZIETb45B'; 'AccessTokenSecret' = 'ssrJtykkW2C43AK3esafdklkjfdsljlfds;jdnLKSLk9GR'}
$OAuths += $OAuthBA
# My Other Twitter Account app keys
# Not valid values obviously
$OAuthDC = @{'ApiKey' = '02HdTLtasdfsdfdsfkC3f7Y5t'; 'ApiSecret' = 'UziOItem1UlxnQNiesdfdsafsfdszwwr0hvbe62dWCmixs'; 'AccessToken' = '18929736-co7kF76TAsdfsdfdsdfdsf0IgU1NJKYFsM6sbxz0'; 'AccessTokenSecret' = 'HgwQNsCTyrD43IfhZoP79Osdfsadfsafdsfds7gRxzv'}
$OAuths += $OAuthDC
# Get Seed Account
$twitterSeed = Get-TwitterUser_Lookup -screen_name $twitterScreenName
$outfile = $downloadDirectory +'\' + $twitterScreenName +'Details.xml'
$twitterSeed | Export-Clixml -Path $outfile
# Get Seed Account and all Followers with details and export.
$twitterfollowerusers = Get-TwitterFollowers_IDs -screen_name $twitterScreenName -all | Get-TwitterUser_Lookup
$outfile = $downloadDirectory +'\' + $twitterScreenName +'FollowersDetails.xml'
$twitterfollowerusers | Export-Clixml -Path $outfile
# Get Seed Account and all Friends with details and export.
$twitterfriendsusers = Get-TwitterFriends_IDs -screen_name $twitterScreenName -all | Get-TwitterUser_Lookup
$outfile = $downloadDirectory +'\' + $twitterScreenName +'FriendsDetails.xml'
$twitterfriendsusers | Export-Clixml -Path $outfile

Now we have two XML files with a whole bunch of Twitter accounts and their metadata. There is an almost certainty that the seed account you’ve used is both followed by twitter accounts that you also follow. We’re going to need to remove the duplicates so that when we import the Twitter accounts into MIM we don’t have duplicates.

Basic, basic script to read in both files and spit out the unique Twitter Accounts is shown below.

#Seed Account
$twitterScreenName = 'mytwitteraccount'
# Output directory for the MA Import File
$downloadDirectory = 'C:\Program Files\Microsoft Forefront Identity Manager\2010\Synchronization Service\MaData\Twitter'
# Import XML Files Path
$importFileDirectory = 'C:\Users\darren\Dropbox\Kloud\Powershell\Twitter\data'
$tweetersinput = import-Clixml -Path $importFileDirectory+'\' + $twitterScreenName +'FollowersDetails.xml'
$tweetersinput.Count
# Get the ID's to compare against from followers input file
$baseIDs = @()
foreach ($id in $tweetersinput) {
$baseIDs += $id.id_str
}
# Get the Friends File
$tweetersinput2 = Import-Clixml -Path $importFileDirectory+'\' + $twitterScreenName +'FriendsDetails.xml'
$tweetersinput2.Count
# Ignote the duplicates and store the uniques
foreach ($twit in $tweetersinput2){
if($baseIDs | select-object | Where-Object {$_ -eq $twit.id_str} ){
#duplicate so ignore
}
else
{
$tweetersinput += $twit
write-host "Added" $twit.id_str
}
}
$tweetersinput.count
$tweetersinput | Export-Clixml -Path $downloadDirectory"\TwitterMAUsersInput.xml"

Using the Granfeldt PowerShell Management Agent to import Twitter Identities

Consuming data into the MIM Sync Engine obtained via PowerShell is quick and simple utilising Søren Granfeldt’s extremely versatile PowerShell Management Agent. I’m just going to cover importing the data from the XML file we generated above.

Getting Started with the Granfeldt PowerShell Management Agent

First up, you can get it from here. Søren’s documentation is pretty good but does assume you have a working knowledge of FIM/MIM and this blog post is no different.

A few items of note are;

  • You must have a Password.ps1 file. Even though we’re not doing password management on this MA, the PS MA configuration requires a file for this field. The .ps1 doesn’t need to have any logic/script inside it. It just needs to be present
  • Same for an Export.ps1 file. I’m not doing any exports on the MA, but an export script must be present.
  • The credentials you give the MA to run this MA are irrelevant as they aren’t used as part of the import as I’m bringing in data from files generated via separate PowerShell scripts
  • The path to the scripts in the PS MA Config must not contain spaces and be in old-skool 8.3 format. I’ve chosen to store my scripts in an appropriately named subdirectory under the MIM Extensions directory. Tip: from a command shell use dir /x to get the 8.3 directory format name. Mine looks like C:\PROGRA~1\MICROS~2\2010\SYNCHR~1\EXTENS~2\Twitter

Import Twitter Users into Microsoft Identity Manager

Using the guidance above on the Granfeldt PSMA here are the two key scripts for the Twitter MA.

The Schema Script to expose the core Twitter identity attributes.

Schema Script

$obj = New-Object -Type PSCustomObject
$obj | Add-Member -Type NoteProperty -Name "Anchor-ID|String" -Value "402931642"
$obj | Add-Member -Type NoteProperty -Name "objectClass|String" -Value "user"
$obj | Add-Member -Type NoteProperty -Name "DisplayName|String" -Value "Another Twitter User"
$obj | Add-Member -Type NoteProperty -Name "ScreenName|String" -Value "twitteruser1"
$obj | Add-Member -Type NoteProperty -Name "Location|String" -Value "Sydney"
$obj | Add-Member -Type NoteProperty -Name "Description|String" -Value "account description"
$obj | Add-Member -Type NoteProperty -Name "URL|String" -Value "http://my.homepage.com"
$obj | Add-Member -Type NoteProperty -Name "entities|String" -Value "URL|Description"
$obj | Add-Member -Type NoteProperty -Name "Protected|Boolean" -Value $False
$obj | Add-Member -Type NoteProperty -Name "FollowersCount|Integer" -Value 101
$obj | Add-Member -Type NoteProperty -Name "FriendsCount|Integer" -Value 201
$obj | Add-Member -Type NoteProperty -Name "ListedCount|Integer" -Value 2
$obj | Add-Member -Type NoteProperty -Name "CreatedDate|String" -Value "Mon Oct 26 23:11:33 +0000 2011"
$obj | Add-Member -Type NoteProperty -Name "FavouritesCount|Integer" -Value 2
$obj | Add-Member -Type NoteProperty -Name "UTCOffset|Integer" -Value 2
$obj | Add-Member -Type NoteProperty -Name "TimeZone|String" -Value "Sydney"
$obj | Add-Member -Type NoteProperty -Name "GeoEnabled|Boolean" -Value $False
$obj | Add-Member -Type NoteProperty -Name "Verified|Boolean" -Value $False
$obj | Add-Member -Type NoteProperty -Name "StatusCount|Integer" -Value 299
$obj | Add-Member -Type NoteProperty -Name "Language|String" -Value "en"
$obj | Add-Member -Type NoteProperty -Name "Status|String" -Value "look at my awesome breakfast"
$obj | Add-Member -Type NoteProperty -Name "ContributorsEnabled|Boolean" -Value $False
$obj | Add-Member -Type NoteProperty -Name "IsTranslator|Boolean" -Value $False
$obj | Add-Member -Type NoteProperty -Name "IsTranslatorEnabled|Boolean" -Value $False
$obj | Add-Member -Type NoteProperty -Name "ProfileBackgroundColor|String" -Value "C0DEED"
$obj | Add-Member -Type NoteProperty -Name "ProfileBackgroundImageURL|String" -Value "http://abs.twimg.com/images/themes/theme1/bg.png"
$obj | Add-Member -Type NoteProperty -Name "ProfileBackgroundImageURLHTTPS|String" -Value "https://abs.twimg.com/images/themes/theme1/bg.png"
$obj | Add-Member -Type NoteProperty -Name "ProfileBackgroundTitle|Boolean" -Value $False
$obj | Add-Member -Type NoteProperty -Name "ProfileImageURL|String" -Value "http://pbs.twimg.com/profile_images/themes/9329872387843276/sljsfddf_normal.jpg"
$obj | Add-Member -Type NoteProperty -Name "ProfileImageURLHTTPS|String" -Value "https://pbs.twimg.com/profile_images/themes/9329872387843276/sljsfddf_normal.jpg"
$obj | Add-Member -Type NoteProperty -Name "ProfileLinkColor|String" -Value "C0DEED"
$obj | Add-Member -Type NoteProperty -Name "ProfileSidebarBorderColor|String" -Value "C0DEED"
$obj | Add-Member -Type NoteProperty -Name "ProfileSidebarFillColor|String" -Value "C0DEED"
$obj | Add-Member -Type NoteProperty -Name "ProfileTextColor|String" -Value "C0DEED"
$obj | Add-Member -Type NoteProperty -Name "ProfileUseBackgroundImage|Boolean" -Value $True
$obj | Add-Member -Type NoteProperty -Name "HasExtendedProfile|Boolean" -Value $False
$obj | Add-Member -Type NoteProperty -Name "DefaultProfile|Boolean" -Value $True
$obj | Add-Member -Type NoteProperty -Name "DefaultProfileImage|Boolean" -Value $True
$obj | Add-Member -Type NoteProperty -Name "Following|Boolean" -Value $True
$obj | Add-Member -Type NoteProperty -Name "FollowRequestSent|Boolean" -Value $True
$obj | Add-Member -Type NoteProperty -Name "Notifications|Boolean" -Value $True
$obj | Add-Member -Type NoteProperty -Name "Muting|Boolean" -Value $True
$obj | Add-Member -Type NoteProperty -Name "Blocking|Boolean" -Value $True
$obj | Add-Member -Type NoteProperty -Name "BlockedBy|Boolean" -Value $True
$obj

Import Script

The Import Script that takes the rationalised XML file created earlier from the friends and followers queries and populates the connector space.

param (
$Username,
$Password,
$Credentials,
$OperationType,
$downloadDirectory = 'C:\Program Files\Microsoft Forefront Identity Manager\2010\Synchronization Service\MaData\Twitter',
[bool] $usepagedimport,
$pagesize
)
[string]$CSVFile = $null
$DebugFilePath = "C:\PROGRA~1\MICROS~2\2010\SYNCHR~1\EXTENS~2\Twitter\Debug\DebugTWeetMA.txt"
if(!(Test-Path $DebugFilePath))
{
$DebugFile = New-Item -Path $DebugFilePath -ItemType File
}
else
{
$DebugFile = Get-Item -Path $DebugFilePath
}
"Starting Import : " + (Get-Date) | Out-File $DebugFile -Append
## Load Previously Retreived Twitter Feed that we've exported to an XML file
# Seed Friends & Followers
$tweetersinput = Import-Clixml -Path $downloadDirectory"\TwitterMAUsersInput.xml"
ForEach($tweeter in $tweetersinput)
{
#Only bring in tweeters we have an anchor for (which should be every identity anyway)
if ($tweeter.id_str)
{
$obj = @{}
$obj.Add("ID",$tweeter.id_str)
$obj.Add("objectClass", "user")
$obj.Add("DisplayName",$tweeter.name)
$obj.Add("ScreenName",'@'+$tweeter.screen_name)
$obj.Add("Location",$tweeter.Location)
$obj.Add("Description",$tweeter.Description)
$obj.Add("entities",$tweeter.entities)
$obj.Add("Protected",$tweeter.Protected)
$obj.Add("FollowersCount",$tweeter.Followers_Count)
$obj.Add("FriendsCount",$tweeter.Friends_Count)
$obj.Add("ListedCount",$tweeter.Listed_Count)
$obj.Add("CreatedDate",$tweeter.created_at)
$obj.Add("FavouritesCount",$tweeter.favourites_count)
$obj.Add("UTCOffset",$tweeter.UTC_Offset)
$obj.Add("Timezone",$tweeter.time_zone)
$obj.Add("GeoEnabled",$tweeter.Geo_Enabled)
$obj.Add("Verified",$tweeter.Verified)
$obj.Add("StatusCount",$tweeter.Statuses_Count)
$obj.Add("Language|",$tweeter.lang)
$obj.Add("Status",$tweeter.Status.text)
$obj.Add("following",$tweeter.following)
# Pass the object to the MA
$tweeter.screen_name | Out-File $DebugFile -Append
$obj
}
}
#endregion

Password Script

Required by the PSMA but not used as detailed earlier

# Not Implemented

Export Script

Required by the PSMA but not used as detailed earlier

# Not Implemented

Creating the Management Agent

Path to the Schema Script in 8.3 format as detailed earlier.

https://dl.dropboxusercontent.com/u/76015/BlogImages/TwitterMA/MA1.png

Path to the Import, Export and Password scripts also in 8.3 format.

https://dl.dropboxusercontent.com/u/76015/BlogImages/TwitterMA/MA2.png

Select the attributes you want to bring in to the connector space.

https://dl.dropboxusercontent.com/u/76015/BlogImages/TwitterMA/MA3.png

Any Join logic, and a Projection Rule.

https://dl.dropboxusercontent.com/u/76015/BlogImages/TwitterMA/MA4.png

Import Flow Rules to bring in the Tweeters.

https://dl.dropboxusercontent.com/u/76015/BlogImages/TwitterMA/MA5.png

Create your Run Profiles, perform a Stage and Full Sync and BAM; Tweeters in the Metaverse. Real Word Identity Data Ahoy. Exception testing commences now.

Follow Darren on Twitter @darrenjrobinson

Category:
FIM, Identity and Access Management, PowerShell
Tags:
,

Join the conversation! 1 Comment

  1. Thanks for the shoutout!

Comments are closed.