Posts Tagged ‘Powershell’

How do I – Validate user input is numeric from Powershell?

Written by Cornelius J. van Dyk on . Posted in Blog

As the level of complexity and power of our Powershell scripts increase, it is inevitable that we reach a point where we need to interact with the user and prompt them for some information.  In this case we were building a script to automate the creation and scaling of Search so we needed to know how many servers would be configured as Crawl servers.  We all know the Read-Host cmdlet can provide us with the input, but how do we know that the user actually entered numeric only data?  The easiest way is to simply use a try/catch block and attempt to convert the input to an int value.  Here’s how we do that:

$numberOfCrawl = 0
$inputOK = $false
do
{
  try
  {
    [int]$numberOfCrawl = Read-Host -ForegroundColor red "Please enter the number of servers you wish to configure as Crawl servers."
    $inputOK = $true
  }
  catch
  {
    Write-Host -ForegroundColor red "INVALID INPUT!  Please enter a numeric value."
  } 
}
until ($inputOK)
Write-Host –ForegroundColor green "You chose to configure [$numberOfCrawl] Crawl servers."

We start by defining the $inputOK variable as false and then wrap the entire piece of code in a do/until loop that repeats until the user enters a valid numeric only value.  Inside of this loop, we have a try/catch block.  Inside the try, we attempt to assign the entered value from Read-Host to the $numberofCrawl variable which we cast as an int.  If the user enters a non-numeric value, the cast will fail and will be caught by the catch.  In the catch we output an error message in red text and simply allow the loop to restart from the top.  If however, the user entered a valid numeric value, the cast will succeed afterwich we set the $inputOK variable to true thus allowing the loop to end gracefully.  As a final step, we display the entered value to the user.



Cheers
C




image

How do I – Identify the SharePoint site template type and ID of a given sub web?

Written by Cornelius J. van Dyk on . Posted in How Do I...

This one always comes up at some point in time, especially after migrations. I’ve seen issues with migrated sites many times when custom site templates were used for sites, since SharePoint doesn’t know how to upgrade these sites 100%. A good example is the Fab40 templates that people loved to install in SharePoint 2007. When migrating to 2010, the templates are not supported and if the templates were not installed on the target server, issues will arise with the sites. The most common of these are that the home pages will simply throw a 404 error. You can navigate through the site settings pages just fine, but the home pages just doesn’t work. For this reason, I always start my trouble shooting by asking what type of site I’m dealing with. Since it’s most unlikely that your site admin would know in most cases, it becomes necessary to be able to identify that. Here’s a quick Powershell script for doing so.

$web = Get-SPWeb "http://sharepoint.crayveon.com/Research/Encryption Algorithms"
write-host "Template Name: " $web.WebTemplate
write-host "Template ID: " $web.WebTemplateId
$web.Dispose()
NOTE:  The URL supplied to Get-SPWeb should be in quotes and should NOT contain unescaped characters i.e. http://sharepoint.crayveon.com/Research/Encryption%20Algorithms will NOT yield a valid SPWeb object, but “http://sharepoint.crayveon.com/Research/Encryption Algorithms” will.

Cheers
C




image

How do I – Resolve the issue where the Term Store Management option does not show up in Site Settings for a SharePoint site

Written by Cornelius J. van Dyk on . Posted in How Do I...

A friend of mine pinged me the other day asking about the Term Store. The problem he was seeing was that the “Term store management” link wasn’t showing up under the Site Administration section of the site. He had another site in the same web application that did show the link so the question was why this site did not show the link. When looking at the Site Settings page for the site in question, we saw this: image3_thumb_399679A7 Wondering if this was another of SharePoint’s hide-and-seek games (like hiding the Delete Site link), I entered the direct URL to the Term Store into my browser. The direct URL is located as /_Layouts/termstoremanager.aspx Of course, I did not get the Term Store, but instead was confronted with the wonderful CorrelationID page. Nonetheless, now that I had a CorrelationID, I had a log I could look to for more information. Upon inspection of the ULS log file, this is what I found:

05/30/2012 09:40:26.47 w3wp.exe (0x3AE4) 0x35E0     SharePoint Foundation  Logging Correlation Data  xmnv  Medium      Name=Request (GET:http://workspaces.crayveon.com:80/ZBI/_Layouts/termstoremanager.aspx)  a7de1d35-c1ba-467b-9099-492693dcd124
05/30/2012 09:40:26.83 w3wp.exe (0x3AE4) 0x35E0     SharePoint Foundation  Logging Correlation Data  xmnv  Medium      Site=/ws/ZBI  a7de1d35-c1ba-467b-9099-492693dcd124
05/30/2012 09:40:26.95 w3wp.exe (0x3AE4) 0x35E0     SharePoint Foundation  Runtime                   tkau  Unexpected  System.InvalidOperationException: The Taxonomy feature (Feature ID "73EF14B1-13A9-416b-A9B5-ECECA2B0604C") has not been activated.
    at Microsoft.SharePoint.Taxonomy.OM.CodeBehind.TermStoreManager.OnLoad(EventArgs e)     at System.Web.UI.Control.LoadRecursive()     at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)    a7de1d35-c1ba-467b-9099-492693dcd124
05/30/2012 09:40:26.97 w3wp.exe (0x3AE4) 0x35E0     SharePoint Foundation  Monitoring                b4ly  Medium      Leaving Monitored Scope (Request (GET:http://workspaces.crayveon.com:80/ZBI/_Layouts/termstoremanager.aspx)). Execution Time=501.213422376308    a7de1d35-c1ba-467b-9099-492693dcd124
As always, the most important line is the first one of type “Unexpected” following the first reference of your CorrelationID. In this case, the issue is easily identified as: The Taxonomy feature (Feature ID “73EF14B1-13A9-416b-A9B5-ECECA2B0604C”) has not been activated. Now the solution was easy, right? Simply activate the Taxonomy Feature on the site or site collection and you’re all set. Not so fast… The Taxonomy Feature is a hidden Feature. As such, this Feature is activated via the Taxonomy Feature Stapler which is attached with most site templates. The keyword is MOST. This stapler is NOT attached to the BLANK SITE TEMPLATE. The reason for this is because there’s a site attribute called “AllowGlobalFeatureAssociations” which is set to false on blank site templates. Because of this, the Feature Stapler will not fire upon the creation of the blank site and as a result, Taxonomy will not work on the site. So how do we solve that? Unfortunately, you’re going to need console access which is a problem for hosted environments such as SharePoint Online in Office 365. If however you have rights and access to your server, it can easily be done through the following Powershell cmdlet:
Enable-SPFeature -identity "73EF14B1-13A9-416b-A9B5-ECECA2B0604C" -url 

Of course if you're still old school and want to use STSADM, you can still do that by using this command:

STSADM -o activatefeature -id "73EF14B1-13A9-416b-A9B5-ECECA2B0604C" -url  –force
Once you’ve activated the Feature, a refresh of the Site Administration page shows: image_thumb_399679A7

Cheers
C




image

How do I – Resolve the Powershell New-SPConfigurationDatabase command error – The pipeline has been stopped, This SharePoint farm currently has pending upgrades

Written by Cornelius J. van Dyk on . Posted in How Do I...

I was building a fresh SharePoint farm and issued the “New-SPConfigurationDatabase” Powershell commandlet when I was presented with the following error:

 

PS C:\Users\blog-spadm> New-SPConfigurationDatabase

cmdlet New-SPConfigurationDatabase at command pipeline position 1 
Supply values for the following parameters: 
DatabaseName: SharePoint_Config 
DatabaseServer: SPSQL.Crayveon.com 
FarmCredentials 
Passphrase: ********* 
New-SPConfigurationDatabase : The pipeline has been stopped. 
At line:1 char:28 
+ New-SPConfigurationDatabase <<<< 
    + CategoryInfo          : InvalidData: (Microsoft.Share…urationDatabase: 
   SPCmdletNewSPConfigurationDatabase) [New-SPConfigurationDatabase], Pipelin 
  eStoppedException 
    + FullyQualifiedErrorId : Microsoft.SharePoint.PowerShell.SPCmdletNewSPCon 
   figurationDatabase

New-SPConfigurationDatabase : This SharePoint farm currently has pending upgrad 
es.  The cmdlet New-SPConfigurationDatabase cannot be executed until the upgrad 
e is completed. 
At line:1 char:28 
+ New-SPConfigurationDatabase <<<< 
    + CategoryInfo          : InvalidOperation: (:) [New-SPConfigurationDataba 
   se], SPException 
    + FullyQualifiedErrorId : Microsoft.SharePoint.PowerShell.SPCmdletNewSPCon 
   figurationDatabase

PS C:\Users\blog-spadm> New-SPConfigurationDatabase

cmdlet New-SPConfigurationDatabase at command pipeline position 1 
Supply values for the following parameters: 
DatabaseName: SharePoint_Config 
DatabaseServer: SPSQL.Crayveon.com 
FarmCredentials 
Passphrase: ***************** 
PS C:\Users\blog-spadm> 

The really silly outcome of this was not related to any upgrade or stopped pipelines or anything of that sort.  Yet another case of the error message NOT having anything to do with the actual problem.  As it turns out, the solution was in the farm Passphrase I was specifying.  The GUI version of PSCONFIG gives you notification when the specified farm passphrase does not conform to domain password policies, but the Powershell version does not.

I reran the exact same command but this time specifying a more complex passphrase that conforms to domain security policies, and the problem was solved!



Cheers
C




image

SharePoint 2010 People Picker de-mystified!

Written by Cornelius J. van Dyk on . Posted in Blog

The problem with most demos and classes is that the presenters use straight Active Directory for the configurations and though this most certainly has the desired effect of making the demo run smoothly because everything “just works”, it doesn’t help you and me in the REAL WORLD where more often that not, we encounter a blended environment.  If you are fortunate enough to work in a straight AD shop, count your blessings every night!

For the rest of us, we have to make that “blend” work for the customer because at the end of the day, they don’t care, nor should they, about the technical difficulty behind the scenes to make it work… they just want it to work… first time… every time. 🙂

Such is the case when you’re dealing with a Forms Auth/LDAP environment.  My client has a huge deployment in SP2007 under LDAP.  We deployed SP2010 under Claims Auth which meant a shift away from our old SiteMinder LDAP authentication scheme.  Of course, under Forms Auth, we controlled the database against which the authentication and searching was done ala the source against which the PeoplePicker control was searching.  Under claims, AD is the source and that adds new technical challenges to the mix in order to ensure that your customer search experience remains the same.  Thus my search for information about the PeoplePicker in 2010 began…

There are lots of links out there related to PeoplePicker and custom AD searches.  The first and most obvious is this MSDN link that gives us the basic overview.  It even provides some basic examples, but it doesn’t actually EXPLAIN how to use it.  Joel posted on his old blog on the topic, but it was basically a collection of what’s on MSDN so I was still looking for more detail.  There were lots of other posts on the “peoplepicker-searchadcustomquery” switch in STSADM, but they were all either references to the MSDN article or copy and paste jobs. 🙁

In the end, I was left to decipher the problem the old fashion way… through trial and error.  After many attempts, I finally managed to get a good read on how it actually works and was able to explain it to my colleagues as well.  Now I’m hoping this blog post saves someone some time in the future when they have to work through this.  I’ll begin with my Powershell script:

 1:  clear-host
   2:  write-host -f green "========================="
   3:  write-host -f green "========= BEGIN ========="
   4:  write-host -f green "========================="
   5:  write-host ""
   6:  $snapin = "Microsoft.SharePoint.PowerShell"
   7:  if (get-pssnapin $snapin -ea "silentlycontinue")
   8:  {
   9:    write-host -f green "PSsnapin $snapin is loaded"
  10:    write-host ""
  11:  }
  12:  else
  13:  {
  14:    if (get-pssnapin $snapin -registered -ea "silentlycontinue")
  15:    {
  16:      write-host -f green "PSsnapin $snapin is registered"
  17:      Add-PSSnapin $snapin
  18:      write-host -f green "PSsnapin $snapin is loaded"
  19:      write-host ""
  20:    }
  21:    else
  22:    {
  23:      write-host -f Red "PSSnapin $snapin not found"
  24:      write-host ""
  25:    }
  26:  }
  27:  [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
  28:  $webapps = get-spwebapplication
  29:  foreach ($webapp in $webapps)
  30:  {
  31:    write-host -f yellow $webapp.displayname;
  32:    write-host -f yellow $webapp.url;
  33:    stsadm -o setproperty -url $webapp.url -pn peoplepicker-searchadcustomquery -pv "(userPrincipalName={0}*)(givenName=*{0}*)(sn=*{0}*)(displayName=*{0}*))";
  34:    stsadm -o setproperty -url $webapp.url -pn peoplepicker-searchadforests -pv "domain:<<>>.com";
  35:  }
  36:  write-host ""
  37:  write-host -f green "========================="
  38:  write-host -f green "========== END =========="
  39:  write-host -f green "========================="
  Lines 1-5 simply clears the screen and writes a starting header. Line 6 sets a local variable ($snapin) to “Microsoft.SharePoint.PowerShell”. Lines 7-11 checks if the snapin is loaded already.  If it is, it writes a message on screen noting that.

Lines 12-26 kicks in if the snapin is not already loaded.  In this case, it gets the registration info for the snapin and then tries to load the snapin.

Line 27 loads the Microsoft.SharePoint.dll in order to access the SharePoint object model. Line 28 sets a local variable ($webapps) to the return value of the “get-spwebapplication” PowerShell cmdlet.

Lines 29-30 sets up an iteration loop for each object in the $webapps variable.  It temporarily sets the current object to another local variable ($webapp) for processing in subsequent lines.

Lines 31-32 writes the Display Name and the URL values of the web application being processed.

Lines 33-34 is where the magic happens.  These lines call STSADM and passes the needed values to it in order to set SharePoint’s metadata properties for the people picker.

Line 35 closes the loop.

Lines 36-39 simply writes to closing a closing footer.

Now let’s look at the two STSADM commands in more detail.

stsadm -o setproperty -url $webapp.url -pn peoplepicker-searchadcustomquery -pv "(userPrincipalName={0}*)(givenName=*{0}*)(sn=*{0}*)(displayName=*{0}*))";

The key is the “setproperty” operation in STSADM.  Since these properties are stored by SharePoint on a web application basis which is why this command is issued for each web application in SharePoint.

The first switch we provide to the operation is the URL of the web application.

The second switch is the property name and in this case, we’re targeting the “peoplepicker-searchadcustomquery” property.

The third switch is the property value.  The value we pass here is the search values that is appended and passed into Active Directory for the search query.  This is where the available documentation is lacking.  The format to use is as follows:

(<AD Name>=<wildcard>{0}<wildcard>)

where <AD Name> is replace by the Active Directory property name you’re targeting and <wildcard> is replaced by either a star (*) if you want to wildcard on that side of the query or nothing if you don’t want the wildcard on that side.

In our example, we are targeting 4 Active Directory properties.  The first is “userPrincipalName” which is the user ID e.g. “cjvandyk@crayveon.com”.  In this example, we are using a wildcard at the back of the query so a search such as just using “cjvandyk” or “cjvan” should yield a match.

The second property is “givenName” which is a user’s fist name.  We are using front and back wildcards here so any part of the user’s name would yield a match.

The third property is “sn” which is the user’s last name.  Again, we’re using front and back wildcards in order to yield a match on any part of the user’s last name.

The last property is “displayName”.  This field is populated with the commonly used name of the user.  In most cases, a user’s name is registered for a match on the default query passed to Active Directory as “First MI Last” for example, a user would be matched as “Robert E. Doe” within the system.  For a user to locate him in a people picker they’d have to use “Robert E. Doe”.  In person he may be known as “Bob Doe” instead.  A user trying to find Bob in the people picker with “Bob Doe” won’t get a match, but if the Active Directory property for “displayName” is populated with this value i.e. “Bob Doe”, our fourth property would yield a match for the user.

The second STSADM property we are setting for the web application is that of the “peoplepicker-searchadforests”.  This is used when you have a very large Active Directory and wish to limit the AD query down to just a specific sub set instead of searching the entire directory.  Doing this, can result in some major performance gains in your people picker.  The syntax is:

stsadm -o setproperty -url $webapp.url -pn peoplepicker-searchadforests -pv "domain:<<<CHANGEME>>>.com";

As before, our first switch passed is the URL of the target web application.

The second switch is again the property name which as we’ve already mentioned is “peoplepicker-searchadforests”.

The third switch is the property value.  In this switch, simply replace the “<<<CHANGEME>>>” with your target domain you wish to limit the search to.

The last thing you need to do, is ensure that your Active Directory team configure indexes on all the properties that you have specified in your search query.  Having indexes on these properties within AD will also give you a good boost in the performance of the people picker control.

Provided that your AD is populated correctly, using this script, you can configure the people picker for optimal results for the end user.  For your convenience, you can download the PowerShell script from my downloads library located here:



Cheers
C




image