Get SID by Powershell for SharePoint

You can use following powershell to check SID from AD.

$NTAccount = new-object System.Security.Principal.NTAccount(‘SamAccountName’)
$TranslatedToSidObject = $NTAccount.Translate( [System.Security.Principal.SecurityIdentifier])
$SID = New-Object System.Security.Principal.SecurityIdentifier($TranslatedToSidObject.Value)
$TranslatedToNTAccount = $SID.Translate([System.Security.Principal.NTAccount])
Write-host $TranslatedToSidObject.Value `t`t $TranslatedToNTAccount.Value

You can use following powershell to check SID in SharePoint

$site = get-spsite http://blog.bugrapostaci.com
$web = $site.OpenWeb()
$user = $web.EnsureUser(“BLOG\bugra”)
$user.Sid

 

Advertisements

Why we are using warm-up scripts

SharePoint is built upon the Microsoft .NET Framework and ASP.NET, specially the 2.0 releases of those technologies. ASP.NET is architected so that its pages are not compiled until the first time a server request .As you know when an IIS worker process has coming up for the first time , It makes lots of jobs in the background. The big portion of this time used by compiling assemblies, and reading configurations  . For a standard ASP.Net application it takes very small time but for a SharePoint Application we have tons of assemblies and configurations and more than one WCF services which is need to be activated . So it will usually takes more time over 1 minutes. The warm up duration also depends on your configuration , hardware and assembly counts and changes for every system.

The issue happens when application pool recycle, iisreset or a worker process crashes.  And for SharePoint sites every application pool has a configuration that force the recycle itself . You can check from IIS -> Application Pools -> (For example Select “SharePoint Central Administration v4”) and right click   Select Recycling option And you can see the recycle time.

We have also an Idle Time Out property defined in Application Pool settings that make free worker processes resources which are in idle state for defined time period . Configure Idle Time-out Settings for an Application Pool (IIS 7) http://technet.microsoft.com/en-us/library/cc771956(v=WS.10).aspx

However even it is disabled by setting “Idle Time Out” value to 0 still IIS requires and also suggested way that recycle application pools daily manner. The default IIS behavior of naturally cycling an app pool somewhere between 1am and 3am or off hours if there is such a thing is healthy to clean out the memory space in IIS. Also same consideration is valid for SharePoint Timer service , there is a Timer job in SharePoint for responsible to restart timer service in daily manner. It is a good and suggested thing http://blogs.msdn.com/b/besidethepoint/archive/2012/01/10/the-timer-recycle-job-job-timer-recycle.aspx

But sometime in the midnight a recycle occurs and assume that no one send a request a server until morning and when a user open his browser and try to connect SharePoint site He/She should wait more, because the worker process is only getting up until the first time a server get the request. Warm up scripts send a requests to your server for a scheduled time  that forces IIS to worker process up and running .when a user’s request a page through a browser, preventing your users from seeing a delay when making that first request. That’s pretty much all they do, and the only purpose most of them serve is to “warm up” your server by having precompile your site’s ASP.NET pages ahead of an actual user request. You can use warm up scripts .

For the warm up scripts which is described in fallowing article http://blogs.technet.com/b/rgullick/archive/2011/12/02/minimalist-sharepoint-warmup-script.aspx have very common usage on this kind of issues.

 

How to send Real Meeting Request From Sharepoint 2010 – Part 2

Hello Everyone ,

How to send Real Meeting Request From Sharepoint 2010 article continues with part2

Here is the links for How to send Real Meeting Request From Sharepoint 2010 Series:
http://blog.bugrapostaci.com/2012/02/17/how-to-send-real-meeting-request-from-sharepoint-2010-part-1/
http://blog.bugrapostaci.com/2012/02/17/how-to-send-real-meeting-request-from-sharepoint-2010-part-2/
http://blog.bugrapostaci.com/2012/02/17/how-to-send-real-meeting-request-from-sharepoint-2010-part-3-deployment/
http://blog.bugrapostaci.com/2012/02/17/how-to-send-real-meeting-requests-from-sharepoint-2010-part4-usage/
Lets have a look for internally whats happening in a Meeting Workspace.

If you open a meeting workspace web with Sharepoint Manager 2010 you can brows all components in a basic meeting workspace template.
Some important list are Attendees , Meeting Serries , Workspace Pages ,

The Meeting Serries list contains Event information when you related a calender item with a meeting workspace instance. In this demo we have already attached two calender event this this meeting workpaced named “Scrum Meetings” . Every item has in Meeting Series an InstanceID so when you open a Event item and click linked workspace url
you can see this instanceID has been added end of this url . For example:
http://blog.bugrapostaci.com/scrummeetings?InstanceID=2

That means sharepoint sperates data according this Instance Parameter. As you noticed if you look carefully above image we have 6 attendees . This number is sum of all attendees count .But when you connect a workspace with an InstanceID  and if you compare fallowing properties for an Attendees list.
SPList attendeesList = web.Lists[“Attendees”];
attendeesList.ItemCount  is 6 : means all attendees count contains other meeting instances counts
attendeesList.Items.Count is 2 : meens this instance attendees count.

Sharepoint is differantiate the attendees data automatically and internally for which meeting workspace instance in use.

So be careful when you are working with in Meeting Workspaces on InstaceID property and differantiation of data according to this property.

Sharepoint Manager 2010 is a very useful tool when you programming with Sharepoint. You can use it with define Column Names and properties for serval objects in hiearchically.

But what if you dont want to use it , the powershell can also makes some help in this issue. For example if you want to learn which internal columns of an Meeting Series List item . you can get this information via powershell and write in a file in your drive like:

$Site = Get-SPList http://blog.bugrapostaci.com
$web = $site.OpenWeb(“ScrumMeetings”)
$mList = $web.Lists[“Meeting Series”]
$mList.Fields |ft title , internalname > c:\MeetingSeriesFields.txt

One advantage of powershell that you can also check values of created properties which SPM2010 does not. For example you may wonder how sharepoint keeps EventURL of an Related Event item:
$Site = Get-SPList http://blog.bugrapostaci.com
$web = $site.OpenWeb(“ScrumMeetings”)
$mList = $web.Lists[“Meeting Series”]
$item = $mList.Items[1];
$item[“EventURL”] and press enter
Results is: [URL], [List Title] -> There is a space char after “,” so you should use trim() function when you parsing this data.
http://blog.bugrapostaci.com/lists/TestCalender, Meeting Calendar

After we complete understanding on Meeting Workspace  now contine with our project

MeetingRequestWebPart -> Page Load
  1. protected void Page_Load(object sender, EventArgs e)
  2. {
  3.     #region GUI operations
  4.     //Some GUI operations
  5.     #endregion
  6.     //This webpart is only usable for Meeting Workspace Sites.
  7.     if (!SPMeeting.IsMeetingWorkspaceWeb(SPContext.Current.Web))
  8.     {
  9.         InformationText.Text = “This webpart is only addable for a Meeting Workspace Web Site”;
  10.         AdminPanel.Visible = false;
  11.         return;
  12.     }
  13.     //Get Current Meeting information
  14.     SPMeeting currentMeeting = SPMeeting.GetMeetingInformation(SPContext.Current.Web);
  15.     MeetingInfo info = MeetingInfo.GetMeetingInfo(currentMeeting);
  16.     //Only the meeting organizer manage meetigs.
  17.     if (!info.OrgnaizerAccount.Equals(SPContext.Current.Web.CurrentUser.LoginName, StringComparison.InvariantCultureIgnoreCase))
  18.     {
  19.         InformationText.Text = “Only Organizer of this meeting \”” + info.OrganizerName + “\” can manage the requests”;
  20.         AdminPanel.Visible = false;
  21.     }
  22.     else
  23.     {
  24.         if (IsAppointmentExists(info.MeetingIdentifier)) //if Meeting request is already sent.
  25.         {
  26.             SavedMeetingInfo = LoadAppointment(info.MeetingIdentifier);
  27.             btnSendMeetingRequest.Visible = false;
  28.             btnReSendMeetingRequest.Visible = true;
  29.             btnCancelMeeting.Visible = true;
  30.             btnRefreshAttendeesStatus.Visible = true;
  31.             if(!_ByPassClearInfo)
  32.                 InformationText.Text = “Meeting requests have been send at” + SavedMeetingInfo.RequestSentDate.ToLongDateString() + ” “ + SavedMeetingInfo.RequestSentDate.ToLongTimeString();
  33.         }
  34.         else // if not sent before
  35.         {
  36.             btnSendMeetingRequest.Visible = true;
  37.             btnReSendMeetingRequest.Visible = false;
  38.             btnCancelMeeting.Visible = false;
  39.             btnRefreshAttendeesStatus.Visible = false;
  40.         }
  41.         //assign button events.
  42.         btnSendMeetingRequest.Click += new EventHandler(btnSendMeetingRequest_Click);
  43.         btnReSendMeetingRequest.Click += new EventHandler(btnReSendMeetingRequest_Click);
  44.         btnCancelMeeting.Click += new EventHandler(btnCancelMeeting_Click);
  45.         btnRefreshAttendeesStatus.Click += new EventHandler(btnRefreshAttendeesStatus_Click);
  46.     }
  47. }


In Page Load,

We are doing some gui operations.
Checking webpart added correct web site template , should be a meeting workspace template
Getting Current and latest meeting information
Checking the owner mean organizer beacuse only orginazer manages meetings.
Prepare GUI according to if meeting is already send or not.
Also we set here the SavedMeetinfo property of control via fallowing line
-> SavedMeetingInfo = LoadAppointment(info.MeetingIdentifier);
MeetingInfo LoadAppointment(string identifer)  helper function brings us the Saved MeetingInfo in previous state from web.Properies bag.
That information is imported because we are storing Exchange Appointment object’s ID in this object.

MeetingRequestWebPart -> Refresh Attendees Status
  1. public void RefreshAttendeesStatus()
  2. {
  3.     if (SavedMeetingInfo == null) return;
  4.     ExchangeServiceConnection conn = new ExchangeServiceConnection(SPContext.Current.Web.CurrentUser);
  5.     SPMeeting currentMeeting = SPMeeting.GetMeetingInformation(SPContext.Current.Web);
  6.     Appointment app = Appointment.Bind(conn.Service, SavedMeetingInfo.AppointmentID);
  7.     Dictionary<string, MeetingResponseType> aStatus = new Dictionary<string, MeetingResponseType>();
  8.     foreach (Attendee att in app.RequiredAttendees)
  9.     {
  10.         if (att.ResponseType != null)
  11.         {
  12.             aStatus.Add(att.Address, (MeetingResponseType)att.ResponseType);
  13.         }
  14.     }
  15.     foreach (Attendee att in app.OptionalAttendees)
  16.     {
  17.         if (att.ResponseType != null)
  18.         {
  19.             aStatus.Add(att.Address, (MeetingResponseType)att.ResponseType);
  20.         }
  21.     }
  22.     RunAsAdmin.Run((site, web) =>
  23.     {
  24.         SPList Attendees = web.Lists[“Attendees”];
  25.         foreach (SPListItem item in Attendees.Items)
  26.         {
  27.             SPUser user = web.EnsureUser(item.Title);
  28.             if (aStatus.ContainsKey(user.Email))
  29.             {
  30.                 MeetingResponseType rtype = aStatus[user.Email];
  31.                 item[“Response”] = ExchangeHelper.ConvertSPMeetingResponse(rtype);
  32.                 item.Update();
  33.             }
  34.         }
  35.     });
  36. }

In refresh attendees function,

We are getting current Meeting information and already created Appointment object. For updating attendees status a meeting request must already be created.
Collecting all Attedees and thier responses in a dictionary (considering performance )
Updating Attendees status in web.Lists[“Attendees”] list . We are converting Response type beacuse Exchange.MeetingResponseType has 6 option but Response (Choice)
Column in attendees list only 4 option that none,Accepted,Declined,Tentative

MeetingRequestWebPart -> Update Meeting Request
  1. public void UpdateMeetingRequest()
  2. {
  3.     if (SavedMeetingInfo == null) return;
  4.     ExchangeServiceConnection conn = new ExchangeServiceConnection(SPContext.Current.Web.CurrentUser);
  5.     SPMeeting currentMeeting = SPMeeting.GetMeetingInformation(SPContext.Current.Web);
  6.     Appointment app = Appointment.Bind(conn.Service, SavedMeetingInfo.AppointmentID);
  7.     MeetingInfo info = MeetingInfo.GetMeetingInfo(currentMeeting);
  8.     ExchangeHelper.UpdateAppointment(app, info);
  9.     //Clear All Attendees
  10.     app.RequiredAttendees.Clear();
  11.     app.OptionalAttendees.Clear();
  12.     //Add Atteendees from Workspace Attendees List.
  13.     AddAttendees(app);
  14.     try
  15.     {
  16.         app.Update(ConflictResolutionMode.AutoResolve);
  17.         info.AppointmentID = SavedMeetingInfo.AppointmentID;
  18.         InfoMessage = “Meeting Request sent successfully”;
  19.     }
  20.     catch (Exception ex)
  21.     {
  22.         ULSLoggingService.LogError(ULSLoggingService.SMR_ERROR, ex.Message + Environment.NewLine + ex.StackTrace);
  23.         InfoMessage = “An Error occured.Please contact your administrator”;
  24.     }
  25.     UpdateAppointment(info);
  26. }

In UpdateMeetingRequest Function ;
First we checking SavedMeetingInfo object is exists.
Creating an exchange connection.
Getting current meeting.
Appointment app = Appointment.Bind(conn.Service, SavedMeetingInfo.AppointmentID); // with this line we are binding already created Appointment object in Exchange. SavedMeetingInfo object contains AppointmentID which i mentioned above.
We are setting old Appointment object with new values by calling ExchangeHelper.UpdateAppointment(app, info);

(Basically we are doing in ExchangeHelper.UpdateAppointment something like below:
app.Subject = info.Title;
app.Start = info.EventDate;
app.End = info.EndDate;
app.Location = info.Location;
…. return app; )
Clearing All Attendeess
Add all attendees again

Update Appointment object that will resend all meeting request again via app.Update() command.
Set AppointmentID to new MeetingInfo class instance.
Update new MeetingInfo class via overriding old MeetingInfoClass (SavedMeetingInfo)

MeetingRequestWebPart -> Cancel Meeting Request
  1. public void CancelMeetingRequest()
  2. {
  3.     if (SavedMeetingInfo == null) return;
  4.     ExchangeServiceConnection conn = new ExchangeServiceConnection(SPContext.Current.Web.CurrentUser);
  5.     SPMeeting currentMeeting = SPMeeting.GetMeetingInformation(SPContext.Current.Web);
  6.     try
  7.     {
  8.         //Get existed appointment.
  9.         Appointment app = Appointment.Bind(conn.Service, SavedMeetingInfo.AppointmentID);
  10.         app.CancelMeeting();
  11.         ClearAppointment(SavedMeetingInfo);
  12.         InfoMessage = “Meeting has been canceled successfully.”;
  13.     }
  14.     catch (Exception ex)
  15.     {
  16.         ULSLoggingService.LogError(ULSLoggingService.SMR_ERROR, ex.Message + Environment.NewLine + ex.StackTrace);
  17.         InfoMessage = “An error occured.Please contact your administrator”;
  18.     }
  19. }

In CancelMeetingRequest function:
Like before we are checking SavedMeetInfo is exists , creating an exchange connection object and getting currentmeeting object.
Appointment app = Appointment.Bind(conn.Service, SavedMeetingInfo.AppointmentID); // with this line we are binding already created Appointment object in Exchange.
And Canceling Meeting via app.CancelMeeting() function.
Clearing previously saved MeetingInfo instance from web.properties.
PS: There is a trick when you try removing a property correctly from SPWeb object .Check the fallowing link:
http://blog.bugrapostaci.com/2012/02/17/clearing-or-removing-a-keyvalue-from-spweb-properties-tipstricks/

Next Article: Part 3 Deployment.

getting serivce url of exchange server by Exchange Web Service (EWS) Api using AutoDiscoverURL

if you don’t know your exhcange service url you can use powershell for getting url information easyly.

[System.Reflection.Assembly]::LoadFile(“C:\Program Files\Microsoft\Exchange\Web Services\1.1\Microsoft.Exchange.WebServices.dll”);
$Service = new-object Microsoft.Exchange.WebServices.Data.ExchangeService $Service.AutoDiscoverUrl(“<EMAIL ADDRESS>”)
$Service.Url

Powershell find files with versions.

If you are searching all same files and versions in your drive you can user fallowing powershell command:

get-childitem -Recurse | where-object { $_.Name -eq “Microsoft.Sharepoint.ApplicationPages.dll” } |%{ $_.VersionInfo }| select * > c:\FileVersions.txt

Create all users’ personal site via Powershell script – Sharepoint 2010

#PowerShell Script - Create All Users Personel Sites - SharePoint 2010 #The scripts is distributet "as-is." Use it on your own risk. 
#Add SharePoint PowerShell SnapIn if not already added if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) {
    Add-PSSnapin "Microsoft.SharePoint.PowerShell"
}

[Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server")

$mysiteHostUrl = "http://my"
$personalSiteGlobalAdmin = "DOMAIN\padm"
$personalSiteGlobalAdminNot ="padm@bugrapostaci.com"
$personalSiteGlobalAdminDisplayName = "Personel Site admin"
$mysite = Get-SPSite $mysiteHostUrl

$context = [Microsoft.Office.Server.ServerContext]::GetContext($mysite)
$upm =  New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)

$AllProfiles = $upm.GetEnumerator()

foreach($profile in $AllProfiles)
{

    $DisplayName = $profile.DisplayName
    $AccountName = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::AccountName].Value
       #Add your restrictions for users.        if($Accountname -like "YourDomain*")
       {
          if($profile.PersonalSite -eq $Null)
          {
               write-host "Creating personel site for ", $AccountName
               $profile.CreatePersonalSite()
               #Adding an extra admin for personel sites                $pweb = $profile.PersonalSite.OpenWeb()
               $pweb.AllUsers.Add($personalSiteGlobalAdmin,$personalSiteGlobalAdminNot,$personalSiteGlobalAdminDisplayName,$null);
               $padm= $pweb.AllUsers[$personalSiteGlobalAdmin];
               $padm.IsSiteAdmin = $true;
               $padm.Update();
               $pweb.Dispose();
               write-host "Personal Site Admin has assigned"
          }
          else
          {
               write-host $AccountName ," has already personel site"
          }
   }
}
$mysite.Dispose();

Sharepoint 2010 – Delete all users’ personel sites via powershell

#PowerShell Script - Delete All Users Personel Sites - SharePoint 2010
#The scripts is distributet "as-is." Use it on your own risk. The author give no warranties, guarantees or conditions.

#Add SharePoint PowerShell SnapIn if not already added
 if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) {
    Add-PSSnapin "Microsoft.SharePoint.PowerShell"
}
[Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server")

$mysiteHostUrl = "http://my"
$mysite = Get-SPSite $mysiteHostUrl
$context = [Microsoft.Office.Server.ServerContext]::GetContext($mysite)

$upm =  New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)

$AllProfiles = $upm.GetEnumerator()

foreach($profile in $AllProfiles)
{
   $DisplayName = $profile.DisplayName
   $AccountName = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::AccountName].Value  

   if($profile.PersonalSite -ne $Null)
   {

	   $profile.PersonalSite.Delete()
	   write-host $AccountName , " personel site deleted successfully"
   }
}
$mysite.Dispose();