I am trying to update the profiles of users in my SSP Application and I have 10000 records. Most of them are being updated for the first time and there are 21 records which are getting updated everytime I run the code.
I don't know why this is happening..
Could any body help me what's happening with my code.
SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPSite sc = new SPSite("http://xxxxx:81");
ServerContext context = ServerContext.GetContext(sc);
HttpContext currentContext = HttpContext.Current;
HttpContext.Current = null;
UserProfileManager profileManager = new UserProfileManager(context);
foreach (UserProfile profile in profileManager)
{
if (profile[PropertyConstants.PreferredName].ToString().Contains("Domain\\"))
{
profile[PropertyConstants.PreferredName].ToString().Replace("Domain\\", "").ToString();
profile.Commit();
NoOfUser++;
}
}
Thank You
Hari Gillala
NHS Direct
You are aware that there is a user profile import option in the SSP already are you? If you import AD properties only, use that. Only create a timerjob when the profile data is coming from another source. If there are any non-standard properties in AD, you can map those too by creating new profile properties and defining which AD property they map to.
Related
In the OneDrive user interface, it is possible to update a drive item so that the permissions no longer inherit from the parent (Stop Inheriting Permissions). Is it possible to do the same through the Graph API? I can seem to find any call that seems to allow for that. In the documentation for Delete Permissions, it says:
"Only sharing permissions that are not inherited can be deleted. The inheritedFrom property must be null."
We need to be able to programatically set the permissions on drive folders and items and one of the things we have to do is to stop inheritance from parent.
Regards,
LT
i know it's a long time question but here what you can do :
Get the directory item Id
Get the permissions id list
=> https://graph.microsoft.com/v1.0/me/drive/items/{itemId}/permissions
Loop over all permissionIds and delete them
Post a new Invite with all the users/groups you want
The "inherited" is only a list of allow users/groups ... if you delete all of them, your folder become a "only you" folder permission (no inheritance)
I use that in my application, it's not the most simple but it works
I am also struggling with the Graph Api invite-endpoint https://learn.microsoft.com/en-us/graph/api/driveitem-invite?view=graph-rest-1.0&tabs=http
I have not found an better solution than #Dadv.
My job is to copy an Sharepoint folder to another folder, including any subfolders.
And then make sure that subfolders get the exactly same permissions as the source subfolders.
Unfortunaly this has to be 2 seperate tasks, when using the Graph Api, using /copy endpoint to copy the subfolders, and for the permissions I use a combination of Delete / Update / Add to syncronize the permissions.
Rather complicated with lots of roundtrips to the API, for such a simple job.
Now I hope to hear from someone who knows of an simpler way of doing the permission part.
Here is some pseudo code to show visualize the syncronization of the permissions.
// Now the targetFolders exists --> syncronize permissions
var targetFolderGraphUr = "https://graph.microsoft.com/v1.0/drives/<id>/items/<item-id>";
// First remove all permissions not existing in the sourcefolder
foreach (var targetPermission in targetFolderPermissions)
{
if (!sourceFolderPermissions.FirstOrDefault(p => p.GrantedTo?.User?.DisplayName == targetPermission.GrantedTo?.User?.DisplayName))
{
var deleteUrl = $"{targetFolderGraphUr}/permissions/{targetPermission.Id}";
var deleteResult = await myHttpClient.DeleteAsync(deleteUrl);
}
}
// Then apply permissions from template: Update (Patch) or Add (using /invite)
foreach (var sourcePermission in sourceFolderPermissions)
{
var pcPerm = targetFolderPermissions.FirstOrDefault(p => p.GrantedTo?.User?.DisplayName == sourcePermission.GrantedTo?.User?.DisplayName);
// Update
if (pcPerm != null)
{
bool isUpdateNeeded = CheckIfUpdateNeeded(...);
if (isUpdateNeeded)
{
var updateUrl = $"{targetFolderGraphUr}/permissions/{sourcePermission.Id}";
var updateResult = await myHttpClient.PatchAsync(updateUrl, sourcePermission);
}
}
else
{
// Add
var userId = sourcePermission.GrantedTo?.User?.Id;
var invitePermission = new InvitePermission()
{
Recepients = GetRecepientArray( userId ), // returns a list of recipients, setting objectId = userId
ObjectId = userId,
Roles = sourcePermission.Roles,
RequireSignIn = true,
SendInvitation = false,
};
var inviteUrl = $"{targetFolderGraphUr}/invite";
var inviteResult = await myHttpClient.PostAsync(inviteUrl, invitePermission);
// response is 200 OK, but no permissions are added.
// Using Dadv's workarround, deleting all permissions on targetfolder first, then it works.
// (not shown in this example)
}
}
I have removed the "AspNetUserClaims" table from my DB because I am not saving any claims information.
After creating a user I am trying to fetch user info by its user name and it returns an error:
"Invalid object name 'dbo.AspNetUserClaims'.".
IdentityResult result = await manager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
var userInfo = manager.FindByName(user.UserName);
foreach (var myRole in myRoles)
{
manager.AddToRole(userInfo.Id, myRole.Name);
}
await AddToPreviousPasswordsAsync(user, user.PasswordHash);
}
In the UserManager class of Identity 2, the Entity Framework-backed UserStore will ensure the claims are loaded for the requested user.
This accesses the AspNetUserClaims table, which will throw an exception when your database doesn't contain that table.
Simply don't remove tables that are required by a library, or rebuild the library without the claims part. And you don't want to do the latter, because then you won't receive any updates from the official channel anymore, and have to manually patch it. This is no way to handle a security-related library, or generally any library for that matter.
I would like to display a list of active users on my application's dashboard.
All of my users are employees and access the application through their Active Directory credentials.
I have used UserPrincipal to get the details of the current user, but can this be done for all of the current users?
You can use a PrincipalSearcher and a "query-by-example" principal to do your searching:
// create your domain context
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
// define a "query-by-example" principal - here, we search for all "enabled" UserPrincipal
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.IsEnabled = true;
// create your principal searcher passing in the QBE principal
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);
// find all matches
foreach(var found in srch.FindAll())
{
// do whatever here - "found" is of type "Principal" - it could be user, group, computer.....
}
}
If you haven't already - absolutely read the MSDN article Managing Directory Security Principals in the .NET Framework 3.5 which shows nicely how to make the best use of the new features in System.DirectoryServices.AccountManagement. Or see the MSDN documentation on the System.DirectoryServices.AccountManagement namespace.
I have written the following code to edit the User Profiles for MOSS 2007. User Profiles are being populated through the Active directory.
SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPSite sc = new SPSite("http://xxxxx:81");
ServerContext context = ServerContext.GetContext(sc);
HttpContext currentContext = HttpContext.Current;
HttpContext.Current = null;
UserProfileManager profileManager = new UserProfileManager(context);
foreach (UserProfile profile in profileManager)
{
if (profile[PropertyConstants.PreferredName].ToString().Contains("Domain\\"))
{
profile[PropertyConstants.PreferredName].ToString().Replace("Domain\\", "").ToString();
profile.Commit();
NoOfUser++;
}
}
The Details are being updated properly.
My question is Which site do I need to use, to update the details.
For Example I have SSP service WebApplication, Central Administration Web Application and Other Web Applications.
Which Site I need to use to update the profiles, So that the profile name gets updated in all the Sites.
Could Anybody point me in the right direction.
Thank You.
Hari Gillala
NHS Direct.
With sharepoint 2007, SPSite's belong to SPWebApplications, which are associated with an SSP, which store the user profile properties.
SPSite sc = new SPSite("http://xxxxx:81");
ServerContext context = ServerContext.GetContext(sc);
Those lines effectivity lookup the SSP associated with the SPSite url you pass in.
It looks like you only have one SSP, so any SPSite url you use in the constructor will give you a reference to the correct SSP.
Once the information is stored in the SSP database, a timer job copies the info from the SSP store to the individual SPSite databases, into a hidden list "User Information List"s.
This link explains it for 2010, let me see if i can find it for 2007:
http://www.harbar.net/articles/sp2010ups.aspx
EDIT
I found the 2007 explanation link for you:
http://blah.winsmarts.com/2007-7-MOSS_User_Profile_Info_-_How_the_information_flows.aspx
Is there a way to search profiles in MOSS from the object model? I need to search for profiles that have a certain value set on their profile and then perform some action for them.
I need to write some c# code that can search the profiles database and return the matching profiles. Basically,
List of Profiles = Select Profiles From Profile Store Where Profile Property Value = SomeValue
I'm trying to avoid the following:
private IEnumerable<UserProfile> SearchProfiles(string value) {
ServerContext serverContext = ServerContext.GetContext(SPContext.Current.Site);
UserProfileManager profileManager = new UserProfileManager(serverContext);
foreach (UserProfile profile in profileManager) {
if ((string)profile["MyProp"].Value == value) {
yield return profile;
}
}
}
This is possible using the FullTextSqlQuery class:
FullTextSqlQuery q = new FullTextSqlQuery(ServerContext.Current);
q.ResultTypes = ResultType.RelevantResults;
q.QueryText = "SELECT UserName, Email, PreferredName FROM SCOPE() WHERE \"scope\" = 'People' AND Department = 'IT'";
ResultTableCollection tables = q.Execute();
ResultTable results = tables[ResultType.RelevantResults];
This class allows you to query a specific scope (i.e. people) and filter them based on properties using the WHERE clause, which looks basically the same as a regular Sql Query.
To be able to search and filter on (custom) user profile properties, the profile property needs to have a mapping in the Shared Service Provider's metadata settings. Most out of the box user profile properties already have these, custom properties you have to add yourself.
More info on managed properties here.
Two things:
when running with elevated privileges we need to create a new SPSite object within the call and load the security context from there. DO NOT use the context obtained using SPContext.Current.Site.
Hence:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite("<your site url>"))
{
ServerContext context = ServerContext.GetContext(site);
UserProfileManager profileManager = new
UserProfileManager(context);
foreach (UserProfile profile in profileManager)
{
// your code
}
}
}
make sure that the app pool account has appropriate user permissions in SSP. i.e. (use personal features, manage user profiles)