8. May 2012 14:11 

One of our customers has a stretched farm topology where some of the SharePoint servers exist in the main datacenter, and some others exist in a separate datacenter 30 miles down the road. Rather than use SQL mirroring in this environment, we’re using a virtualization level failover for SQL, but otherwise it’s a traditional stretched farm.

As per TechNet, all of the SharePoint web servers in the farm must maintain 1ms ping times to the SQL servers.  We started noticing some intermittent service application endpoint failures (specifically on PerformancePoint), so my initial hunch was to see if we were possibly experiencing network latency issues.  The client was able to find a PowerShell cmdlet that could ping an array of servers, but each server ping occurred sequentially.  What I wanted to do was to have a relatively long running ping request to all the servers in the farm so we could see the average ping time and maximum ping times between all servers during a specific time period. 

In the script below you can plug in your server names in the initial variable, then set the –Count parameter to the number of pings you’d like to aggregate.  You'll want to run this script on a server in your farm, and point it to all the other servers in your farm.

 1: $CompNames = "webserver1", "webserver2", "sqlServer";
 2:  
 3: foreach($computer in $CompNames){
 4:  
 5:   # Execute the jobs in parallel
 6:   Start-Job { param($compName)
 7:         #Note - update the -Count parameter below for how many ping requests you want to aggregate
 8:         $results = Test-Connection -ComputerName $compName -Count 100;
 9:         $avg = ($results | Measure-Object ResponseTime -Average).Average;
 10:         $max = ($results | Measure-Object ResponseTime -Maximum).Maximum;
 11:         $avgInt = ($avg -as [int] );
 12:         $maxInt = ($max -as [int] );
 13:         Write-Host "The Average response time for $compName is $avgInt ms";
 14:         Write-Host "The Maximum response time for $compName is $maxInt ms";
 15:         Start-Sleep 10; 
 16:         } -ArgumentList $computer;
 17: }
 18:  
 19: # Wait for it all to complete
 20: While (Get-Job -State "Running")
 21: {
 22:   $a = Get-Date
 23:   Write-Host "$a Still waiting for the job to complete..."
 24:   Start-Sleep 10
 25: }
 26:  
 27: # Getting the information back from the jobs
 28: Get-Job | Receive-Job

Tags:

Infrastructure | PowerShell

30. April 2012 14:59 

I’ve run into this error 3 times now, and each time it takes me way longer to resolve than it should.

When registering a Trusted Identity Token Issuer/Security Token Service within SharePoint 2010, you get the following error once you’re redirected back to the _trust/default.aspx site on your SharePoint Server:
Operation is not valid due to the current state of the object.
Operation is not valid due to the current state of the object.
[InvalidOperationException: Operation is not valid due to the current state of the object.]
   Microsoft.SharePoint.WebControls.SPControl.SPWebEnsureSPControl(HttpContext context

When you dig into the ULS logs, you can see a bit more information:

  • Claims Authentication             Monitorable    SPSecurityTokenService.Issue() failed: System.ServiceModel.FaultException: The trusted login provider did not supply a token accepted by this farm.     at Microsoft.SharePoint.IdentityModel.SPSecurityTokenService.SPRequestInfo.ValidateTrustedLoginRequest()     at Microsoft.SharePoint.IdentityModel.SPSecurityTokenService.SPRequestInfo..ctor(IClaimsIdentity identity, RequestSecurityToken request, Boolean initializeForActor)     at Microsoft.SharePoint.IdentityModel.SPSecurityTokenService.SPRequestInfo..ctor(IClaimsPrincipal principal, RequestSecurityToken request)     at Microsoft.SharePoint.IdentityModel.SPSecurityTokenService.GetTokenLifetime(Lifetime requestLifetime)     at Microsoft.IdentityModel.SecurityTokenService.SecurityTokenService.Issue(IClaimsPrincipal principal, RequestSecurityToken request)     at Microsoft.SharePoint.IdentityModel.SPSecurityTokenService.Issue(IClaimsPrincipal principal, RequestSecurityToken request)    
  • Claims Authentication             fsq7    High        Request for security token failed with exception: System.ServiceModel.FaultException: The trusted login provider did not supply a token accepted by this farm.     at Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannel.ReadResponse(Message response)     at Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannel.Issue(RequestSecurityToken rst, RequestSecurityTokenResponse& rstr)     at Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannel.Issue(RequestSecurityToken rst)     at Microsoft.SharePoint.SPSecurityContext.SecurityTokenForContext(Uri context, Boolean bearerToken, SecurityToken onBehalfOf, SecurityToken actAs, SecurityToken delegateTo)   
  • Claims Authentication             8306    Critical    An exception occurred when trying to issue security token: The trusted login provider did not supply a token accepted by this farm..   
  • SharePoint Foundation             Runtime                           tkau    Unexpected    System.InvalidOperationException: Operation is not valid due to the current state of the object.    at Microsoft.SharePoint.WebControls.SPControl.SPWebEnsureSPControl(HttpContext context)     at Microsoft.SharePoint.Utilities.SPUtility.DetermineLayoutsUrl(SPWeb overrideWeb, HttpContext context, Boolean includeLCID, Boolean doNotInitWeb)     at Microsoft.SharePoint.Utilities.SPUtility.DetermineRedirectUrl(String urlProposed, SPRedirectFlags flags, HttpContext context, SPWeb overrideWeb, String queryString, String& urlRedirect)     at Microsoft.SharePoint.Utilities.SPUtility.Redirect(String url, SPRedirectFlags flags, HttpContext context, String queryString)     at Microsoft.SharePoint.Utilities.SPUtility.HandleAccessDenied(HttpContext context)     at Microsoft.SharePoint.IdentityModel.SPFed

When you dig deeper into the InvalidOperationException, the error is actually being thrown in the Access Denied page of SharePoint where it attempts to render out the current user’s login name. This allows us to identify that the error is in the claim type mapping that is bound to the IdentifierClaim when registering the Trusted Identity Token Issuer.  When I looked at the STS Provider’s configuration, indeed the initial claim being provided to us didn’t match the claim that I had registered within my PowerShell cmdlet.

$map1 = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/email" -IncomingClaimTypeDisplayName "Email" –SameAsIncoming
should have been in this case
$map1 = New-SPClaimTypeMapping -IncomingClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" -IncomingClaimTypeDisplayName "LoginName" -LocalClaimType http://schemas.justink.org/ws/2005/05/identity/claims/name

Or whatever my incoming claim should have been.  If you don’t know the claim that’s being passed to you, I highly recommend checking out Tyler Durham’s blog on how to properly enable WIF tracing so you can determine the claims that are being passed to you. 

Tags:

Claims Authentication | SharePoint 2010

7. March 2012 16:50 

First of all – the “right” way to do this would be to use a monitoring tool such as SCOM or MOM and the SharePoint 2010 management pack , then using the provided reports and monitoring components to monitor how your Search Instances are doing. That being said, sometimes you can’t justify the purchase and deployment of an enterprise monitoring solution to just get around a single occasionally stuck search crawl.

So, one of our customers has a search content source that once every 6 weeks or so gets “stuck”.  Based off a quick investigation this appeared to be tied to the Adobe PDF iFilter we had installed; but it was so intermittent we couldn’t pin point why exactly it was getting stuck. Unfortunately, unless somebody was logging onto the server daily to check on the content source, the crawl could be stuck for hundreds of hours before being noticed. 

What we created below was a simple PowerShell cmdlet we could setup to run on an hourly basis as a scheduled job on the server, to enumerate all of our content sources, check how long they’ve been crawling, and if the crawl was over our threshold (in this case 12 hours), stop them and email the administrator. Obviously to use this in your environment, you’d need to swap in your “mail to” and “mail from” variables, as well as tweak the hours threshold value to your desired threshold.

   1: $snapIn = Get-PSSnapin | where-object {$_.Name -eq "Microsoft.SharePoint.PowerShell"}
   2: if($snapIn -eq $null) {
   3:     Add-PsSnapin Microsoft.SharePoint.PowerShell
   4: }
   5:  
   6: function SendEmail($contentSource, $timeRunning)
   7: {
   8:     $webApp = Get-SPWebApplication | select -first 1
   9:     $smtpServer = $webApp.OutboundMailServiceInstance.Parent.Name
  10:  
  11:     $emailFrom = "admin@contoso.com"  
  12:     $emailTo = "admin@contoso.com"  
  13:     $subject = "A long running crawl was just automatically stopped"  
  14:     $body = "A long running crawl on $contentSource was just automatically stopped after " + $timeRunning
  15:  
  16:     $smtp = new-object Net.Mail.SmtpClient($smtpServer)  
  17:     $smtp.Send($emailFrom, $emailTo, $subject, $body)  
  18: }
  19:  
  20:  
  21: $hoursThreshold = 12
  22:  
  23: $searchService = Get-SPEnterpriseSearchServiceApplication 
  24: $contentSources = Get-SPEnterpriseSearchCrawlContentSource -SearchApplication $searchService
  25:  
  26: foreach($contentSource in $contentSources)
  27: {
  28:     Write-Host $contentSource.CrawlStatus
  29:     if($contentSource.CrawlStatus -ne "Idle")
  30:     {
  31:         $now = Get-Date
  32:         $timeRunning = $now.Subtract($contentSource.CrawlStarted)
  33:         Write-Host "Hours running: " $timeRunning.Hours
  34:         if($timeRunning.Hours -ge $hoursThreshold)
  35:         {
  36:             $name = $contentSource.Name
  37:             $contentSource.StopCrawl()
  38:             SendEmail $name $timeRunning
  39:         }       
  40:     }
  41: }

Tags:

SharePoint 2010 | PowerShell | Search

8. February 2012 15:58 

 

So this is a really easy one, but I couldn’t find anywhere online that had the right answer.  

I was reviewing a farm that I inherited from a previous setup, and all of the web applications were created in Classic mode.  Since we had no plans to use PowerPivot 2008 R2, which requires classic authentication; I went ahead and flipped over all of our web applications to use claims.  (Small note, as of SQL 2012 RC0, PowerPivot 2012 still appears to have this requirement). 

After doing so, I started seeing the following error in ULS and the Event Viewer on the servers:

An exception occurred when trying to issue security token: Could not connect to http://localhost:32843/SecurityTokenServiceApplication/securitytoken.svc/actas. TCP error code 10061: No connection could be made because the target machine actively refused it 127.0.0.1:32843. .

After checking that the application pool, IIS virtual directory, etc. were all behaving properly, I noticed that the Claims to Windows Token Service had not been started on the farm.  Starting that up wound up clearing up the error without any IISResets. 

Tags:

2. January 2012 16:09 

 

I’ve configured Project Server several times in the past, but always from the GUI (since that’s all that TechNet has detailed).  I was getting ready to do another installation, and figured that it was past due to figure out how much is do-able via PowerShell.

To date, our PowerShell automation of Project Server 2010 is fairly limited.  We only get about 10 cmdlets special to project server, and our use of Project Server automation via traditional .Net object model is pretty limited as well, since most of their classes appear to be marked as private or internal. 

The below script assumes we’ve already setup a SharePoint 2010 Enterprise farm (if you haven’t done this already, hop on over to AutoSPInstaller on codeplex).

The script has been divided into two main sections, one of which will need to be run on every server on the farm you want to run the Project Server Service on, and another that configures the service application, creates the managed paths and content databases, and provisions the Project Web Access site collection. 

Unfortunately, after running this script, you’ll still have to perform several manual tasks, such as configuring the workflow automation service and setting up your reporting configuration.

 1: Add-PsSnapin Microsoft.SharePoint.PowerShell
 2:  
 3: #this script was designed to deploy the project web access environment to a explicit managed path off the root of the web application, and will create the managed path for you.
 4: #Part 1 of this script will need to be run on each application server, Part 2 will need to be run only once
 5: $webAppUrl = "http://spdemo/"
 6: $managedPath = "pwa"
 7: $contentDatabaseName = "SP_Content_PWA"   #as per technet, we should aim to use a dedicated content database for our project web access instance
 8:  
 9: #---Begin Part 1 that must be run on every application server---#
 10: #Copy the files from the doc lib template to the Project Server doc lib feature as per: http://technet.microsoft.com/en-us/library/ee662109.aspx
 11: Copy-Item  -LiteralPath "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\Template\Features\DocumentLibrary\DocLib\FileDlg.htm" -Destination "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\Template\Features\pwsdoclibs\pwsdoclib\FileDlg.htm"
 12: Copy-Item  -LiteralPath "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\Template\Features\DocumentLibrary\DocLib\EditDlg.htm" -Destination "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\Template\Features\pwsdoclibs\pwsdoclib\EditDlg.htm"
 13:  
 14: #Make sure our service instance is up and running
 15: $PSServiceInstance = Get-SPServiceInstance | Where {$_.TypeName -eq "Project Application Service"}
 16: Write-Host "Found PS Service Instance GUID " $PSServiceInstance.ID
 17: if($PSServiceInstance.Status -ne "Online")
 18: {
 19:     ServerManagertart-SPServiceInstance $PSServiceInstance.ID
 20: }
 21: else
 22: {
 23:     Write-Host "Not starting the Project Server instance since it's already started"
 24: }
 25: #--- End Part 1 ---#
 26:  
 27:  
 28: #--- Begin Part 2 that must be run only once on the farm ---#
 29: #build our service applicaiton and proxy
 30: $DefaultServiceAppPool = Get-SPServiceApplicationPool -Identity "SharePoint Web Services Default"
 31: $PSServiceApplicaiton = New-SPProjectServiceApplication -Name "Project Server Service Application" -ApplicationPool $DefaultServiceAppPool
 32: $PSServiceApplicationProxy = New-SPProjectServiceApplicationProxy -Name "Project Server Service Application Proxy" -ServiceApplication $PSServiceApplicaiton
 33:  
 34: #Create the Project Web Application content database
 35: $PWAContentDB = New-SPContentDatabase -Name "SP_Content_PWA" -WebApplication $webAppUrl -MaxSiteCount 1 -WarningSiteCount 0
 36:  
 37: #Prep the web application for our PWA instance
 38: New-SPManagedPath -RelativeURL $managedPath -WebApplication $webAppUrl  -Explicit
 39:  
 40: #Create the PWA instance
 41: New-SPProjectWebInstance -AdminAccount "contoso\yourlogon" -ArchiveDbname "Project_ArchiveDB" -DraftDbname "Project_DraftDB" -PrimaryDbserver "lousql2k8r2" -PublishedDbname "Project_Published" -ReportingDbname "Project_Reporting"  -ReportingDbserver "lousql2k8r2" -Url "$webAppUrl$managedPath"
 42:     
 43: $webInstance = Get-SPProjectWebInstance -Url "$webAppUrl$managedPath"
 44: while($webInstance.ProvisioningStatus -ne "Provisioned")
 45: {
 46:     Write-Host "Still waiting" $webInstance.Status
 47:     $webInstance = Get-SPProjectWebInstance -Url "$webAppUrl$managedPath"
 48: }
 49:  
 50: #Provision any additional administrators here
 51: New-SPProjectSiteAdministrator -AdminAccount "contoso\johndoe1" -Url "$webAppUrl$managedPath"
 52: New-SPProjectSiteAdministrator -AdminAccount "contoso\johndoe2" -Url "$webAppUrl$managedPath"
 53:  
 54: #You will still need to set the workflow account detailed at http://technet.microsoft.com/en-us/library/ee662105.aspx
 55:  
 56: #After configuring the workflow, you will then need to configure the reporting configuration as well
 57: #http://technet.microsoft.com/en-us/library/ee662106.aspx
 58:  
 59: #--- End Part 2 --- #

Tags:

PowerShell | Project Server | SharePoint 2010

20. November 2011 15:48 

I was configuring a farm for a customer the other day, and noticed that I was getting an “Access Denied” message whenever I was viewing the Usage Health and Data Collection” service application settings.  I looked through UAC and didn’t see anything too telling, so decided to take a brain break and peruse my RSS feed lists.  I noticed the last post from Vincent Rothwell mentioned a similar issue, and sure enough; it turns out I forgot to open an UAC-elevated instance of IE on the server.  Note – some of these may also be symptoms of being a Farm Administrator in SharePoint, but not being a local administrator on the SharePoint server hosting Central Administration

Below is a list of things that I’ve been able to identify that don’t work quite properly when UAC is enabled, and IE isn’t UAC’ed.  I’ll attempt to keep this updated as I discover more quirks.

  1. “Create or Extend Web Application” is disabled
    UAC’ed Not UAC’ed
    image "New Web Application" disabled
  2. “Authentication Providers” is disabled
    UAC’ed Non-UAC’ed
    image "Authentication Providers" disabled
  3. “Configure usage and health data collection” is not visible
    UAC’ed Non-UAC’ed
    image Missing "Configure usage and health data collection"
  4. “Perform a backup”, “Restore from a backup” and “Configure backup settings” are not visible
    UAC’ed Non-UAC’ed
    image Missing Perform, Restore and Configure backup options
  5. “Usage Health and Data Collection” service application gives “Error: Access Denied”
    UAC’ed Non-UAC’ed
    Working Usage Health and Data Collection Error: Access Denied
  6. “Configure Incoming E-mail” is not visible
    UAC’ed Non-UAC’ed
    image "Configure incoming email settings" disabled
  7. “Manage services on server” is not visible (Both on the Application Management and System Management panes)
    UAC’ed Not UAC’ed
    image "Manage services on server" missing
    image "Manage services on server" missing

Tags:

SharePoint 2010 | User Account Control

12. November 2011 11:29 

On one of our customer’s farms, we have a fairly large farm consisting of 7 SharePoint servers; three web servers, two search servers, two app servers. Normally we don’t have any major issues with the environment (other than the occasional VMWare related network connection dropping); but over the past week, we’ve had numerous users report the dreaded “An unexpected error has occurred” when utilizing portions of our application that use the Secure Store Service and Managed Metadata Services heavily .

 

Looking into the ULS logs, there tend to be a couple of errors related to this request:

Exception returned from back end service. System.ServiceModel.Security.MessageSecurityException: An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail. ---> System.ServiceModel.FaultException: An error occurred when verifying security for the message. --- End of inner exception stack trace
Server stack trace: at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout) at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout) at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at Microsoft.SharePoint.Taxonomy.Internal.IDataAccessReadOnly.GetChanges(Nullable`1 rawPartitionId, DateTime sinceTime, Nullable`1 groupId, Nullable`1 termSetId, Nullable`1 changedItemType, Nullable`1 changedOperationType) at Microsoft.SharePoint.Taxonomy.Internal.TaxonomyProxyAccess.<>c__DisplayClass22.<GetChanges>b__21(IMetadataWebServiceApplication serviceApplication) at Microsoft.SharePoint.Taxonomy.MetadataWebServiceApplicationProxy.<>c__DisplayClass2c.<RunOnChannel>b__2b()

Obviously the above exception was from the Managed Metadata Web Service call. We get a similar one with the Secure Store Service:

Unexpected exception from endpoint address : https://servername:32844/7d044e20fa4b4ea6a2771f211022eabe/SecureStoreService.svc/https
Logging unknown/unexpected client side exception: FaultException`1. This will cause this application server to be removed from the load balancer queue. Exception: System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: Access is denied. (Fault Detail is equal to An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is: Microsoft.Office.SecureStoreService.Server.SecureStoreServiceException: Access is denied. at Microsoft.Office.SecureStoreService.Server.ClaimsManager.GetClaimsWithValidation(IList`1& currentUserClaims, SecureStoreServiceClaim& identityClaim) at Microsoft.Office.SecureStoreService.Server.CredentialsManager.GetCredentials(Guid partitionId, String applicationId) at Microsoft.Office.SecureStoreService.Server.SecureStoreServiceApplication.GetCredentials(Guid rawPartitionId, String applicationId) at SyncInvokeGetCredentials(Object , Object[] , Object[] ) at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchR...)

For a while, the only solution we could find was to reset our application servers, and the services would start working correctly. Obviously something else was going on though, and the servers looked fairly healthy. A couple of days later, while getting ready to reset our application servers again, somebody noticed that the time on the app servers was 27 minutes off from the proper time. Sure enough, running
w32tm /resync
And running an IIS reset cleared up all of our errors. The servers’ time keep on shifting, and currently we’re trying to figure out why our GPO is failing on these servers and they’re syncing with the VMWare CMOS clock rather than the designated time servers; but at least we figured out what was going on in our SharePoint farm.

When you think about it, the above exceptions make perfect sense that they’re being thrown. Whenever we issued a request from our web servers to the application servers’ WCF services, the timestamp of the request was off from the timestamp on the server.

 

Tags:

Infrastructure | SharePoint 2010

9. November 2011 21:43 

Many times in SharePoint, we have a simple parent child relationship between two lists.  When we’re on the “parent” list, we want to click a button to create a new child item, that is automatically set to lookup to the parent list.   I’ve had to deal with this issue a couple of times in the past, and finally broke down this past time and tried to build a modular approach to handle this for SharePoint 2010.  SharePoint 2007 would utilize a similar approach, but a different script that I haven’t had time to write up yet. 

Let’s say we have the following scenario (although obviously this could apply to any SharePoint lookup or parent/child relationship):

  1. We have a SharePoint list that tracks Change Requests.  For simplicity’s sake, it will just track the Title and Description, but obviously other fields can be captured.
  2. We have a child list that tracks work items associated with each change request.  We track here another Title and Description, as well as a single-valued lookup field to the Change Request list, called “Related Change Request”

The way we can solve this problem can basically be broken down into two parts: a menu item on the Change Request list called “New Work Item” that brings us to the New Item page of the Work Item list, and some JavaScript on the New Item page that automatically sets the selected value of our lookup field. 

The one kink in this plan is that SharePoint 2010 gives us an “enhanced” lookup field functionality if the parent list contains over 20 items and the client is using a Tier 1 browser (Internet Explorer).  This enhanced view doesn’t render your traditional SELECT menu, but instead an INPUT field that allows a user to begin typing a value, and then presents a SELECT that is loaded post-page-load of the options. 

Over 20 Items in IE Behavior:
image

Under 20 Items (and Over 20 items non-IE behavior):
image

So, what we wound up having to do was to write some JavaScript that could handle both scenarios.  Note the below code snippets could be refactored in jQuery, but below they don’t it.

Part 1 – Ribbon Button on Parent List

  1. Open SharePoint Designer 2010 and navigate to your parent list (in this example, our Change Requests list)
  2. Click Custom Action… Display Form Ribbon (note, this could also just as easily be done as a List Item menu or View Ribbon with a slightly different syntax in Step 3
    image
  3. Input a name for this command, as well as an image do display in the ribbon.  On the Action pane, select “Navigate to URL:”, then input your child list’s NewForm.aspx URL (or whatever your customized New page may be called), appending a query string parameter to sent in you’re the current item’s ID.  Note – if you’re on a Display or Menu Item Action, this will be {ItemId}, otherwise it maybe an alternative syntax.
    image
  4. Verify your action brings you to your child item’s New item page. 

Step 2 – Set Script to Handle Query String Parameter and Automatically Select

  1. Navigate to your New Item page for your child list in a Brower, and insert a new Content Editor Web Part.  (Note, if you prefer, you may insert the script via SharePoint Designer).  Also note, that when you’re in a Modal Dialog mode (IsDlg=1 in your query string), you won’t be able to access the ribbon to add or edit the web part.  Removing the IsDlg query string or setting will allow you to interact with the form as a traditional web part page.
  2. Insert the following script.  Note you will need to swap out your lookup column’s title, as well as the Query String’s key (should you not utilize CRID in your environment)
     1: <script type="text/javascript">
     2:  
     3:  
     4: //looks for the control of the requested type with a title that matches our current field
     5: function getField(typeOfField,fieldDisplayTitle) {   
     6:       var matchingDocs = document.getElementsByTagName(typeOfField);   
     7:       for (var i=0; i < matchingDocs.length; i++) {   
     8:           if (matchingDocs[i].title == fieldDisplayTitle) {   
     9:               return matchingDocs[i];   
     10:           }   
     11:       }   
     12:       return false;   
     13: }    
     14:   
     15: //function copied from http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript
     16: function getParameterByName(name) {   
     17:     name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");   
     18:     var regexS = "[\\?&]" + name + "=([^&#]*)";   
     19:     var regex = new RegExp(regexS);   
     20:     var results = regex.exec(window.location.href);   
     21:     if(results == null)     
     22:         return "";   
     23:     else     
     24:         return decodeURIComponent(results[1].replace(/\+/g, " ")); 
     25: } 
     26:  
     27: //enumerates the choice options of the select control and sets the one with the matching id
     28: function setSelectValue(lookupControl, valueToSet){
     29:  for(var i = 0; i < lookupControl.length; i++) {
     30:    if(lookupControl[i].value == valueToSet) {
     31:       lookupControl[i].selected = true;
     32:    }
     33:  }
     34: }
     35:  
     36: //function to be registered on SP Body On Load to attempt to select the corresponding lookup field information
     37: function attemptToSetField(){
     38:  var fieldNameToBeAutoSet = "Related Change Request";  //This is the display name of the field you want to auto-set
     39:  var queryStringParameterName = "CRID";  //This is the query string key name you will be retrieving the ID from
     40:  var idToBeSet = getParameterByName(queryStringParameterName);
     41:  if(idToBeSet)//only run the auto-set if it's been passed to us via query string
     42:  {
     43:   var lookupControl = getField('select',fieldNameToBeAutoSet);
     44:   if(lookupControl) {
     45:     setSelectValue(lookupControl, idToBeSet);
     46:   } 
     47:   else
     48:   {
     49:      lookupControl = getField('input', fieldNameToBeAutoSet);
     50:      CoreInvoke('ShowDropdown',lookupControl.id);
     51:      var dropDownControl = document.getElementById(lookupControl.opt);
     52:      setSelectValue(dropDownControl, idToBeSet);
     53:   }
     54:  }
     55: }
     56: _spBodyOnLoadFunctionNames.push('attemptToSetField');</script>

And that should be it!  Whenever a user clicks the button from the parent list, they should be redirected to your child list, and the dropdown control should automatically have selected the parent item by it’s ID and display title for the lookup.

If the script isn’t working for you, check to ensure that you have the proper “Title” variable set of the lookup control.  Also note that I have only tested this script on SharePoint 2010 RTM and SP1 + June 2011 CU.  Since we’re calling some non-documented SharePoint internal JavaScript functions, this script may need to be tweaked for your environment. 

Tags:

JavaScript | SharePoint 2010

28. September 2011 22:01 

On Microsoft's security bulletin, a recent SharePoint security vulnerability and patch was announced: http://technet.microsoft.com/en-us/security/bulletin/ms11-074.  The specific issue at hand is XSS related, allowing for malicious URL's to execute SharePoint commands unintentionally, and overall is bad news.  Of course, most modern browsers have XSS protection built in, but most also disable it when in "Local Intranet" mode (which is how most SharePoint deployments tend to be deployed)

This security issue affects Office 2007 and 2010 clients, as well as SharePoint 2007 and 2010 servers.  Installing this update for Office clients is pretty straight forward, but like all SharePoint related updates, this one has some gotchya's.

First of all: if you are running SharePoint 2010 or 2007, you ABSOLUTELY SHOULD install these updates as soon as you can.  If you don't install them, WSUS may install them for you and wind up breaking your farm (since you need to run the SharePoint 2010 configuration wizard post-installation).  BUT, make sure you thoroughly test them before you do anything on production.

If you're running SharePoint 2010 I recommend doing the following:

  1. If you aren't already on SharePoint 2010 Service Pack 1 + the June Cumulative Updates (which Microsoft and Spencer Harbar now recommend installing in addition to SP1), go ahead and do so now.  Many of the SP1 issues that were reported regarding Claims authentication are resolved in the June 2011 update.
  2. Ensure your environment is still functioning post-Service Pack and CU.  Resolve any issues that may arise (such as restarting the User Profile Service, and ignoring the false farm health check error Microsoft discovered)
  3. Install all of the SharePoint 2010 security updates:
    SharePoint Foundation 2010 "base" update – KB 2494001
    KB 2494022
    KB 2560885
    KB 2560890
    KB 2566456
    KB 2566954
    KB 2566958
    KB 2566960
    If you're running Office Web Apps – KB 2566449
  4. Make sure that you've run the configuration wizard on all servers in your farm.

Like all SharePoint updates, TEST IT BEFORE YOU INSTALL IT IN PRODUCTION.  If you only deploy partial versions of this update, there are chances your publishing pages or User Profile service may throw errors until you get everything back in sync. 

Tags:

Security | SharePoint 2010 | Updates

24. September 2011 16:48 

 

You'll notice, that on the "standard" InfoPath Print interface in Office Web Apps, the client-side print dialog doesn't automatically show, requiring the user to click their browser's "Print" button.  On one of my applications that heavily leverages InfoPath browser based forms, we had the requirement that users shouldn't have to perform this extra click. 

To start off, I simply added a "window.print()" event to the “_spBodyOnLoadFunctionNames array.  On some of my simplest forms we used for testing, this didn't cause any issues.  However, as we introduced more complex forms into the application, some that accessed mainframe data, web services, and performed complex operations, some of our testers reported getting blank pages printed, rather than the form as they expected.  It turns out that InfoPath forms don't load the standard SharePoint document's lifecycle, and can be rendered separate from their containing page's life cycle. 

Upon inspecting the HTML rendered by InfoPath Form Services, there is a hidden input within the Form Server's control, called  ControlName_InfoPathContinueLoading.  The value of this field starts off as "1", then changes to "0" once the form has completed loading within the web page. 

image

Leveraging this input, I could build a JavaScript function (utilizing everybody's favorite Javascript library, jQuery) that poll's this control's state, and invokes the client-side print dialog only once the form has completed loading.

 1: <script type="text/javascript">
 2:     $(document).ready(function () { SetUpPrintFormPage(); });
 3:     function SetUpPrintFormPage() {                 
 4:         registerFormChangeWatch();
 5:     }
 6:  
 7:     //begins watching the form on an interval
 8:     function registerFormChangeWatch() {
 9:         formPrintIntervalId = setInterval("checkIfEditableFormIsReady(50)", 300);
 10:     }             
 11:  
 12:     //verify if the form has completed loading
 13:     function checkIfEditableFormIsReady(threshold) {
 14:         if (document.getElementById("FormControl_InfoPathContinueLoading").value == 0) {
 15:             //make sure we stop watching the form
 16:             clearInterval(formPrintIntervalId);
 17:             window.print();                 
 18:         }             
 19:     }
 20: </script>

Since this input is not documented (as with most of the IPFS's web rendering); any time you service pack or upgrade your SharePoint farm, you'll want to ensure that the behavior of this input has not changed.  Also note, that in my solution, I've hardcoded the parent form control's name into the soltution ("FormControl").  The name of this control will vary depending on your environment.

Also, if you're using this solution, paired with my Multiple Form Printing solution, you'll have to tweak the code to check all of the forms' statuses, rather than just the first form on the page. 

Tags:

InfoPath 2010 | InfoPath Form Services | SharePoint 2010

About Justin

I am the Prinicipal Consultant at KiZAN Technologies for our SharePoint division.  As a Principal Consultant, I act in architect, developer, infrastructure, and management roles.  I've been using SharePoint since SharePoint Portal Server 2003 in 2005. 

Currently I work on projects primarily using SharePoint 2010, but still support SharePoint 2007 and 2003 customers, as well as dabble in traditional ASP.Net web development, SSRS, SSIS, and most other products in the Microsoft web development stack.

Other Pages

Month List