wondering if anyone has any advice idea of how to go about this.
Situation, I have a datasource that sync's several thousand user accounts against an Active Directory. Because of a network issue (the closest domain controller is actually in another location and was being testy) we lost the syncing when the schedule went off. Long story short every domain account got disabled by UserSync service and I had to manually flip them all back on but also changed the user accounts from type "Windows - synchronized" to "simply "Windows".
Now fast forward a number of weeks. The DC issues have been fixed and now I want to flip them all back to "windows - synchronized". Unfortunately in that time apparently some account (no idea who's) have been purged/removed from the domain and it's causing the mass changing because I get an error when it fails to find a SID. Unfortunately the admin console doesn't tell me what account it failed on, nor does it continue with the remaining accounts. It simply fails.
Has anyone any suggestions on how to get around this issue and get the rest of my good accounts re-syncing? Is there a way to test accounts against the domain and if they can't get a SID then they get disabled (kinda like UserSync does but only when the accounts are set that way)?
Thanks in advance.
Can think of a couple of options but my preference would be to get a dump of the names currently in the AD group and then extract the user names from the ProjectWise user table and do a compare. Microsoft Access has a wizard for comparing the contents of two tables that could be used to identify names that no longer appear in AD if SQL is not your thing.
I wish it were that easy. Data extraction and comparison isn't really the hard part. Even after automating that part, what do you do with the results? What's the method of separating into something you can use and operate on in PW Admin? Or are you just stuck fixing every account listed in the results, one at a time? With the automation capabilities of ProjectWise, does it really make any sense to be left having to do this task using a manual, hunt and peck approach? Especially when you are talking about thousands upon thousands of user accounts, I don't think that's a realistic approach.
The SQL query it takes to figure out whether a PW user account is "windows - synchronized" involves 3 tables, not just the user table. The user table has an o_flags column, but all that is currently used for is indicating whether the account is enabled or disabled. Which is too bad, because I think if they did use the field as a bit mask to also indicate that it is a synchronized account, it would make it easier to query.
If we were to start doing some custom SQL to update information about the SID and its mapping in the appropriate PW tables, we'd have to obtain the SID for the account from the domain. That is a whole other process that you can't do *easily* with SQL when you are running Oracle, but I digress. For the sake of the discussion, let's just assume we've gotten past that hurdle.
The problem now is that we run afoul of the "thou shalt not write directly to PW tables" rule for being able to get support from Bentley (not to mention the risk posed to the system and data integrity if something goes wrong or we didn't quite get the relationships exactly right). The only alternative is to build something custom using the SDK. Really shouldn't have to do that since this is functionality Bentley (IMHO) should provide out of the box. What's provided now is fine when no errors are encountered in the process, but it all falls apart quickly when there is one.
As it is now, the way this is currently handled in PW Admin is that when you grab a bunch of user accounts and change them from "windows" to "windows - synchronized", the process does not have robust error handling or reporting. It will throw an error when it tries to process an account that doesn't have a match in the domain, but it doesn't tell you which account threw the error, and then aborts the process. So for example, if you had selected 1000 accounts to change to "windows synchronized", and it ran into a problem on the the 100th account, the first 99 will have been changed, but 100 - 1000 will not have been, because the entire process aborts upon encountering any error, such as did in this scenario at the 100th account. It should at least have an option to not abort the entire process when an account match isn't found, and instead, output at least a log file or something showing where errors were. That would be a huge improvement.
But since that's not the way it works currently, the fun doesn't stop there. You have NO idea which accounts accounts got changed because the only way to see whether the account is "windows" or "windows - synchronized" is to look at the properties of each account individually, because there is no column in PW Admin when looking at users that would show you the difference and at least allow you to sort the list based on that difference.
Long story longer, yes, this issue bugs me. A lot.
the problem you have is not easy to solve. I cannot come up with a solution that would be absolutely safe to try on a production system without any side effects. But I am going to propose one less than perfect, as I do not think there is any better way to fix your system.
Please do due consideration before you try what I propose. I'd advise to backup your dms_user table before proceeding as a safeguard.
PW Admin executes user type update one by one, without a global transaction, thus when it stops due to a missing AD account, it already has some accounts successfully updated. You could repeat the operation on a part of the remaining set, and with some (hopefully not too many) attempts you could update all users that can be updated. I know, there is a catch: PW Admin does not indicate what users are Windows and what Windows-Synchronized in a list, and one cannot tell where the operation has stopped.
There is a workaround for this visibility problem: you have to update another user property that is visible.
Say you select all domain "Acme" users, open properties and change domain name to "x-Acme", type to "Windows" and hit apply - this should proceed without errors, as no AD operation is done. Then you change domain name back to "Acme", type to "Windows - Synchronized" and hit apply. It will stop when a missing AD account is encountered, but all changed accounts will be clearly visible by having a proper domain name. It is likely that the top item with domain "x-Acme" is the failing one, so you may select all "x-Acme" excluding the top one, and continue the process until you are done.
Please note that changing the domain name affects users ability to login to PW, so you should never do this within the working hours.
You could also use Description and Email properties instead of domain name for the procedure, but since these fields have distinct values, you will not be able to easily manually restore them until USS sync will do the update.
hope this helps you; at least some more food for thoughts.
Audrius ZimnickasSay you select all domain "Acme" users, open properties and change domain name to "x-Acme", type to "Windows" and hit apply - this should proceed without errors, as no AD operation is done. Then you change domain name back to "Acme", type to "Windows - Synchronized" and hit apply. It will stop when a missing AD account is encountered, but all changed accounts will be clearly visible by having a proper domain name. It is likely that the top item with domain "x-Acme" is the failing one, so you may select all "x-Acme" excluding the top one, and continue the process until you are done.
Thanks for that tip. Very useful!
Ditto of what Jeff said... thanks!
I would reccomend writing a C# program to look up the accountname with LDAP and modify the user if it is good. It would be less tedius and less error prone than the manual update.
I've got a chunk of code in C++ that can query the domain for user name and give me back the SID if it finds it. So it's not much work to sling it into a custom module for PW. The problem is, once you have that information, how do you update the account in PW using the SDK? I'm not seeing anything in the SDK that gives me that option. Lacking SDK methods, if we are going to automate this programmatically, we are only left with using SQL to update accounts by writing to PW tables directly - technically a violation of our support contract with Bentley.
Yes, I could just do it and not tell anyone and no one might ever know. And that's the crux of the problem. I shouldn't have to do this. While I still think it should be out of the box functionality in PW admin to handle (at least in a better way than it does now), I can accept that maybe it isn't worth their time to develop the feature any further since it's likely not a common issue. But then Bentley should at least provide some way of handling this via the SDK so I'm not faced with having to write something that boils down to a choice between knowingly violating the terms of their support contract just to get the job done in a timely manner, or following the rules and be relegated to dealing with this in a slow, manual process due to present limitations.
aaApi_ModifyUserExt allows you to modify the Type and the Security Provider (read Domain). That function should allow you to change the Type of the accounts that you need to chnage.
aaApi_EnableUserAccount will allow you to enable their account again, or make sure it is marked disabled if they are not in the LDAP.
Hope that helps.
Thanks Dean. Unfortunately the modify command is still limited to setting up the account as a windows account; there is no option on the user type to make it a synchronized account. This is where I'm stuck (trying to go from plain domain accounts to synchronized accounts).