Monday, March 9, 2015

Reading from Workday using .NET

Workday is a huge HR service and many companies are moving. Trying to figure out how to interact with Workday has been difficult. Mostly because there are so few samples available.  Workday has lots of documentation on their API, but because the objects are nested/nested/nested, it make it convoluted to figure out exactly where you need to go.

So here I'm putting out how to read a user from the Human Resources WSDL.

Before you can actually get this code to work you have to create reference file using svcutil then modify it because it creates 2 and 3 dimensional arrays.  This is a problem with Visual Studio.
See here for the pre-reqs and how to fix the Human_Resources.cs file

/////////////////////////
   empId = "12345";

                    var request = new Get_Workers_RequestType { version = "v22.0" };
                   
                    var workerId = new WorkerObjectIDType()
                    {
                        type = "Employee_ID",
                        Value = empId
                    };

                    var idTypes = new List { workerId };
                    request.Request_References = new Worker_Request_ReferencesType { Worker_Reference = new WorkerObjectType[1] { new WorkerObjectType() } };                  
                    request.Request_References.Worker_Reference[0].ID = idTypes.ToArray();
                    request.Request_Criteria = new Worker_Request_CriteriaType
                    {
                        Exclude_Inactive_Workers = true,
                        Exclude_Inactive_WorkersSpecified = true
                    };

                    var proxy =  CreateHumanResourcesProxy();

                    Get_Workers_ResponseType response = null;
                    try
                    {
                        response = proxy.Get_Workers(request);
                        Console.WriteLine(response.Response_Data.FirstOrDefault());
                        string first = response.Response_Data.FirstOrDefault().Worker_Data.Personal_Data.Name_Data.Preferred_Name_Data.Name_Detail_Data.First_Name;
                        string last = response.Response_Data.FirstOrDefault().Worker_Data.Personal_Data.Name_Data.Preferred_Name_Data.Name_Detail_Data.Last_Name;
                        Console.WriteLine(first + " " + last);
                    }
                    catch (FaultException fe)
                    {
                        // _logger.LogError("Error occurred invoking GetWorker", fe);
                        //return null;
                        Console.WriteLine("error " + fe.Message);
                    }


 public static Human_ResourcesPortClient CreateHumanResourcesProxy()
        {
            SecurityBindingElement sb = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
            sb.IncludeTimestamp = false;
            const int lim = Int32.MaxValue;
            var timeout = TimeSpan.FromMinutes(2);

            var cb = new CustomBinding(
                sb,
                new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8)
                {
                   
                    ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas
                    {
                        MaxDepth = lim,
                        MaxStringContentLength = lim,
                        MaxArrayLength = lim,
                        MaxBytesPerRead = lim,
                        MaxNameTableCharCount = lim
                    }
                },
                new HttpsTransportBindingElement
                {
                    MaxBufferPoolSize = lim,
                    MaxReceivedMessageSize = lim,
                    MaxBufferSize = lim,
                    Realm = string.Empty
                })
            {
                SendTimeout = timeout,
                ReceiveTimeout = timeout
            };

            var proxy = new Human_ResourcesPortClient(cb, new EndpointAddress("https://wd5-impl-services1.workday.com/ccx/service//Human_Resources/v23.2"));

            proxy.ClientCredentials.UserName.UserName = "userName@tenant";
            proxy.ClientCredentials.UserName.Password = "pass";
            return proxy;
        }

/////////////////////////

Keep in mind this will work with a worktype of Employee.  You have to change a few things for a Contingent Worker.



Saturday, January 10, 2015

The Project Journey

As a consultant we try very hard to help set the right expectations of how a project may go.  The client and typically us (the consultant) have an undue optimism of trajectory of a project.  Together we typically fool ourselves into thinking the project will go as expected, so as we estimate the project we try to hard to paint a rosy picture.  That nothing could ever go wrong.  Wrong.... 

The longer I do projects the more I try to estimate the way projects typically go.  There is always going to be something that you didn't expect.  Maybe a requirement was tougher than you expected, maybe the client forgot to mention something, maybe the requirements change.  The piece you are depending on to complete a milestone in the project is late.  There are a million things are might happen.  Things never go as expected. 

As consultants we try to 'be nice' to the client, don't want to scare them, try to be their friend.  You want to be their friend, then be honest and help guide them to the end of their journey.  Most of the time its not easy, but that's our job.  So accept it and try to enjoy the journey!  I borrowed this from a friend's Facebook post. A picture says a million words.

Friday, June 6, 2014

ECMA2 schema and multi-valued attributes

Hello all,

I've been working with ECMA2s recently and I've just started to need a multi-valued attribute as part of the object schema.

Working with this, I had a problem trying to populate this attribute during an Import run.

Typically dealing with multi-valued attributes strategies in the past involves iterating through each value using a For Each... loop or something similar.  The issue I was running into was how to designate the index on the multi-valued attribute.  I couldn't find much on the web either.

For ECMA2 schemas I figured out an easy to populate the attribute. Place the value(s) in a List (of Object) type then you can populate the multi-valued attribute with the List.

Here's a little code showing what I mean:

Dim groups As List(Of Object) = New List(Of Object)

'populate groups with values as needed

newCsentry.AttributeChanges.Add(AttributeChange.CreateAttributeAdd("groupName", groups))

Hope this helps.
-Peter

Monday, March 10, 2014

SharePoint 2013 and BHold

I've upgraded my FIM installation to 2010 R2 SP1 on a demo machine that I've had for a while and re-installed SharePoint to 2013.  There are some extra things that need to be done for SP2013 and finally got FIM Portal working as expected.

After installing BHold I would get this Error that the Service was unavailable with Error 503.



After doing some research I discovered that SharePoint 2013 doesn't allow 32 bit apps by default.  So the trick is to change a configuration to allow 32 bit apps.

This can be found here: http://www.stefanjohansson.org/2013/07/how-to-run-a-32-bit-web-application-on-a-sharepoint-2013-server/

All you really need to do is run a command line at c:\windows\system32\inetsrv.  Then execute the following command:  appcmd.exe set config -section:system.webServer/globalModules /[name='SPNativeRequestModule'].preCondition:integratedMode,bitness64

Now BHold should work.

Sunday, January 12, 2014

Redmond IDM Summit

Thanks to Oxford Computer Group and Microsoft for another great IDM Summit held in Redmond last week. 
Lots of great presentations, classes and a final panel discussion including IDM world's very own Jackson Shaw.  Great speakers were there like: Stuart Kwan & Mark Wahl.  Jeremy Palenchar discussed his SSO project with the state of Kentucky.  OCG's North American President, Marvin Tansley, discussed pieces of IDM and how they fit together. Other OCG'er discussed ADFS and Cloud technology to name a few. 
I was lucky enough to join Microsoft's Rob de Jong to present/demo BHold's attestation feature, we showed how easy it could be to run attestation campaigns.  Further we showed how you can use the reporting feature to review attestation progress.  Imagine you had an application you wanted to attest to that was not connected to any identity management solution - you could use BHold's reporting feature to hand off a report to the application owner showing those owners that should have permissions revoked. It was great to see the amount of questions and powerful engagement from the audience.  This leads me to believe the US public is coming to the conclusion that audit and compliance are becoming more important.

There were some great after hours events too. We did a tour of three micro-distilleries which was really fantastic!

Here's more information of the summit in case you missed it.  http://www.oxfordcomputergroup.com/redmond-summit-agenda/  . If you're interested they mentioned they are doing it again next year around the same time.

Wednesday, August 7, 2013

Stagger your FIM SSPR end user roll out

Lots of people are now using FIM for their end user self-service password reset requirements.  One of the challenges to rolling this out to the user population is how can you roll this out in phases.  Because what you don't want is come Monday morning have all your users be guided to the registration page and have the FIM server fall over.

So here's some options:
1. Stagger out the roll out of the client extensions.  Depending on how well you can roll this out by department or section, this might be a challenge for you.  Typically once the end user has the client extensions installed then during next logon the client will talk to the FIM Service to see if they need to register.  If you roll out the extensions to your entire user population then you could have a headache that morning.

2. If you opt not to roll the client out then it should be easy enough to send emails to user segments with the Registration link in there.

3. Though not documented after testing it a bit I found another option to stagger out your roll out.  You can deploy the client extensions to all your users at an earlier time.  Then when you're ready, you can just add users to the Password Reset Users set in the FIM Portal.  If the user is not part of the set they won't be directed to the registration page.  Another thing to keep in mind, if users that aren't in the set try to register they'll get a 'Not Authorized' error.

You may decide just to create an AD group to keep it simple then synchronize that group to the above set.  That way your admins continue to deal with what's typically familiar with them.

Tuesday, July 23, 2013

FIM Client Service not starting?

I installed FIM client extensions on a Win 7 box.  All seemed to go well, until the very end when the service was starting.  It never did, ugh.

Not much on this, except make sure the Network Service account had the correct perms on the machine.config file.  But which one?  There's four, so I gave it full perms on all four; a security violation? ahhh this was a dev environment anyways.  That didn't fix the problem, so what's next. 

I did realize the client box was a VM and pretty slow, so I changed the service time-out from 30 seconds (default) to 60 seconds. here's the blog on that one, if you want to try it yourself. This just caused the slow failure to go even slower... Strike 2.

After thinking about it, I remembered in the past having issues with services not starting if there was no internet connection.  This was true - my dev environment had no internet connection, so I went back and found some notes on this topic.  But then I also remembered there was an IE trick I learned from a buddy (thanks Frank Drewes!)  the idea is to just turn off CRL checking directly in IE.  This was straight-forward and easy to do. Caveat:  not really the best for a permanent solution as this is a per user setting.  So if this client reboots it'll probably time out again.  But if this works then you solved the mystery!



After doing this the service started right up.  Time for a beer.





Hopefully this'll help out others in the same boat.