Showing posts with label SharePoint 2013. Show all posts
Showing posts with label SharePoint 2013. Show all posts

Sunday, September 28, 2014

Upgrading the web.config file to SharePoint 2013

In SharePoint 2010 if we have any of the custom CAS policy defined and which is also referred in web.config file, then on upgrading the site from 2010 to SharePoint 2013, that entry will be missing in the web.config file.

<TrustLevel node is not available in web.config by default in SP2013, we need to update the code to insert the additional node before adding the custom CAS policy.

Configure Best Bets in SharePoint


SharePoint 2013 Preview transforms all your old Search Keywords or Best Bets  into Query Rules .

So let’s create a Query Rule that fires on the exact query ‘image library’ or ‘picture library’, then promotes a result for the Image Library to the top of the page.

First, we’ll go to the Query Rules management page. On your search center’s upper-right-hand corner, click the gear icon, then select Site Settings.


Next, on the Site Settings page, under the Search heading, click Query Rules. Note that you may see a Search Query Rules link under Site Collection Administration. This happens if you’re the Site Collection administrator and the search center is the site collection’s root site. Don’t click that one; those Query Rules affect every site in the site collection, and for now we want to focus only on the search center site.


Now that you’re on the Query Rules page, the first question to ask is “Where will the user be?” For example, do you want to manage Query Rules for your main Enterprise Search? Or for People Search? Or Video Search? Each search experience, out-of-the-box or custom, can have its own Query Rules.

This is what we call the query’s context. You configure Query Rules for a particular context by using that first row of dropdowns in the Query Rules management page.


To manage Query Rules for a specific search experience, use the first dropdown to pick the Result Source for that experience. We’ll go into Result Sources in another post — for now, think of them as a SharePoint 2010 Federated Location plus a Search Scope. Each search experience sends queries to a Result Source, and that source guarantees results meeting certain conditions. For instance, People Search sends queries to the Local People Results source, which only returns People results.

We want our new Query Rule to fire on the main Enterprise Search. That search experience sends queries to the Local SharePoint Results source (which includes everything SharePoint crawls except People). So choose Local SharePoint Results from the first dropdown.

Next, click Add Rule to start creating your new rule.


Having picked a context, we just need to give the rule a name, then specify its conditions and actions. In other words, say when this rule will fire, and what it will do when it does. This is very similar to creating a Search Keyword in SharePoint 2010:

    1.  Give the rule a name: Image Library.
     2.  In the Query Conditions section, leave the condition type on “Query Matches Keyword Exactly”. In the textbox, type the queries we want to match, separated by semicolons: image library; picture library.
     3. In the Actions section, since we want to promote a result to the top of the page, click Add Promoted Result. These are just like Best Bets in SharePoint 2010.


4. In the Add Promoted Result dialog, fill out the title, URL, and description.


5. Click Save in the dialog, then Save in the Add Query Rule page.
And that’s it…you’ve created a Query Rule! To try it out, go to your search center and search for ‘image library’ or ‘picture library’ (note that it can take a few seconds for the Query Rule to start working).



This Query Rule, while simple, demonstrates the high-level steps for creating all Query Rules.
  1.      Pick the context (e.g., queries sent to the Local SharePoint Results source).
  2.      Specify the conditions (e.g., fire if the query exactly matches ‘image library’ or ‘picture library’).
  3.      Specify the actions (e.g., promote a result for the Image Library).



Clean up SharePoint User Profile Store using PowerShell

Today i had a problem in my development environment for my SharePoint Projects regarding User Profile Store. My user profile was a messed up and was not available for editing in central administration. When i searched for my profile it still there but not shown for administration.  This was a really strange behavior because a couple of days it worked well. I added various new profile properties to my user profile service application. So the recreation of User Profile Service 
Application was not an option. Deletion of orphan or corrupted user profiles is not possible using Central Administration or even using avaliable PowerShell commands.

But there is a solution using PowerShell without compiled code. Using PowerShell everything what is avaliable in the server object model is avaliable. First of all two assemblies must be referenced.
These assemblies are:

These assemblies are:

Script:

/* Load required Assemblies for SharePoint Server and User Profile */
[System.Reflection.Assembly]::LoadWithPartialName(“Microsoft.Office.Server”)
[System.Reflection.Assembly]::LoadWithPartialName(“Microsoft.Office.Server.UserProfiles”)
/* Central Adminstration URL or any Web Application*/
$url = "http://myserver:Port"
/* Create a new Context Object */
$contextWeb = New-Object Microsoft.SharePoint.SPSite("http://servername");
/* Get the right Service Context */
$ServerContext = [Microsoft.Office.Server.ServerContext]::GetContext($contextWeb);
/* create a new connection to the UserProfileManager */
$UserProfileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($ServerContext);
/* Ger all User Profiles */
$Profiles = $UserProfileManager.GetEnumerator();
/* Loop through user profile */
foreach ($oUser in $Profiles ) {
/* Remove Profile */
$UserProfileManager.RemoveUserProfile($oUser.item("AccountName"));
}

This script can be extended to delete only specific users from user profile information. At the end I was able to solve my problem. My User Profile was deleted and recreated on first access and due profile import. Everything worked fine.

In the old days you had to write some custom command line tool to address those batch update and deletion task. With the introduction of PowerShell to SharePoint any possible administrative task could be accomplished by just use scripting.

Those assemblies could be referenced using System.Reflection and the rest of the script is quite simple SharePoint Development. So get a context object, open profile service application get all use and delete them.

Update Mysites/UserProfile user image url

I have recently had reason to update the PictureURL property value via PowerShell in SharePoint 2013 for all users in the system.
As a result, I wrote the following PowerShell script to update the property value using string replace.

You will ideally need to run this on the server with an account with the appropriate permissions to update all user profiles.

Script:

#Set up default variables
  
  #My Site URL
  $mySiteUrl = "http://mysite/"
  
  #The part of the picture URL you are trying to find
  $currentURLValue = "http://mypersonalsite"
  
  #The value that will replace the above
 $newURLValue = "http://mysite:80"
 #The internal name for PictureURL
 $upPictureURLAttribute = "PictureURL"
 #Get site objects and connect to User Profile Manager service
 $site = Get-SPSite $mySiteUrl
 $context = Get-SPServiceContext $site
 $profileManager = New-Object   Microsoft.Office.Server.UserProfiles.UserProfileManager($context) 
 $profiles = $profileManager.GetEnumerator()
 foreach ($userProfile in $profiles) {
  if ($userProfile[$upPictureURLAttribute] -ne '') {
    
    $newPictureURL = $userProfile[$upPictureURLAttribute].toString()
    $newPictureURL  = $newPictureURL.Replace($currentURLValue, $newURLValue)
    
    write-host "Before: " $userProfile[$upPictureURLAttribute].toString() " | After: " $newPictureURL 
    
    #Get user profile and change the value - uncomment the lines below to commit the changes
    #$userProfile[$upPictureURLAttribute].Value = $newPictureURL
    #$userProfile.Commit()
  }
 }

Get the Site Collection url's for a specific Data base using Powershell script

Get-SPSite -Limit All -ContentDatabase "DBTestSiteCol" | Select URL, Owner, SecondaryOwner | Export-CSV C:\SiteInfoDB.csv -NoTypeInformation

Deploying solutions in SharePoint 2013


Disable-SPFeature -Identity "Feature1" -Url "http://sharepointsite" -force

Uninstall-SPFeature -Identity "<Feature Name>" -force

OR

Uninstall-SPFeature -Identity "<Feature ID>" -force

Uninstall-SPSolution -Identity testsolution.wsp

Remove-SPSolution -Identity testsolution.wsp

Add-SPSolution -LiteralPath "C:\Packages\testsolution.wsp"

Install-SPSolution -Identity testsolution.wsp -GACDeployment -CompatibilityLevel {14,15}

Saturday, September 27, 2014

How to display Search Results filtered on a specific Content Source

One of the things you may wish to do if you have multiple content sources is to limit a search result to a specific Content Source. For example I have created a BCS connection to a database table containing a list of products from the sample database Adventureworks product table. When I search, I only want to see results from the products table, like below.



 The first thing we would need to do is setup a content Source. For this example, I had previously created a BCS connection to the Adventureworks product table. Now I will create a search content source to point to this BCS connection. When I create a new content source on the search administration page and select BCS Service, a list of external data sources display. In this example I selected my Adventureworks data source.


When I am done it displays here in my content source list. I will need to do a full crawl to populate the index with items.



 Next, I will want to create a Result Source.  A Result Source will allow me to create a scope, or a subset of the crawled content to only return my BCS content source data. in the snapshots below I created a result source called AWResultSource. Note that I have created this result source at the search application level. this allows me to leverage the result source from any site collection. I could also create this same kind of filter at the result page or site collection level which we will see later in this blog.

  

 On the new Result Source page I have chosen "Local SharePoint" and "SharePoint Search Results" and then I will select "launch Query Builder". This will bring up the page to build the actual filter. When I first go to select my property from the property filter, the content source property does not show up. I needed to select "Show all managed properties".

  

 Now I select the ContentSource property, choose Manual value, and enter the name of the content source I created earlier. On the right, you will get a sample of the results to make sure you are on track. If you get a nasty message about not being able to show a preview, you will need to turn on the "Search Server Webpart and properties" feature in site settings for the admin site.

 

The feature name:



 At this point, I have a content source to index the content, and I have a result source to filter search results for the content.

Now I will add it to a search center site. The rest of this blog is focused on modifying the search center site collection.
For your reference, go to the Site Settings page for your search center and select "Manage Result Sources". You will note that the Result Source I created above is in the list. If I had wanted to, I could have just added it here and it would be available for this site collection.



 At this point I need a page to show the filtered results with. This is the interesting part, the settings for the filter to only show the results for the content source is part of the results page. Now lets create the page. Go to the Pages library under Site Contents for the search center site. Select Files, New Document, and then Page. Note that the page layout is a Search Results page layout. choose a name and save. In the screenshot below I created a page called awresultpage.



Now we will edit the page to set our filter. Edit the page and choose edit the webpart for the Search results webpart. in the "Properties for Search Results" section, select change query.




 For "Select a query" choose the result source. In this case it would be the AWresultSource we created earlier. This will set the filter on the results we want. Again I should see a search result preview. Note that I could have set the result source filter right here instead of at the service application level. You have lots of options for the visibility level for returning a subset of the crawled index.



The last thing I need to do is to modify the Search Settings page under site settings to show the menu item on the search page. Here I will add a link under Configure Search Navigation.



 The link points to the results page I created.



Now when I go to the search page, I see products as a menu option. and when I click it, I see the results for the content source.

 

Update Redirect Page url programatically

Below is the code to update the Redirect url of a page in sharepoint.

Code snippet:

SPSite site = new SPSite("http://sharepointsite");
SPWeb web = site.OpenWeb();
SPList library = web.Lists["Pages"];
SPQuery query = new SPQuery();
query.Query = "<<Where><Eq><FieldRef Name='ContentType' /><Value Type='Computed'>Redirect Page</Value></Eq></Where><OrderBy><FieldRef Name='Created' Ascending='true' /></OrderBy>";
query.RowLimit = 4;
SPListItemCollection items = library.GetItems(query);
foreach (SPListItem item in items)
  {
     if (item.ContentType.Name == "Redirect Page")
         {
              item.File.CheckOut();
              SPFieldUrlValue urlValue = new SPFieldUrlValue();
              urlValue.Description = "https://www.google.com"; // ValidURL is a correct URL that I've tested
              urlValue.Url = "https://www.google.com";
              item["Redirect URL"] = urlValue;
              item.SystemUpdate(false);
              item.File.CheckIn("", SPCheckinType.MajorCheckIn);                  
         }              

  }

Powershell scripts for the Infopath Form.

Please find the list of powershell scripts for the Infopath Form.

  1. Installs an InfoPath 2013 form template on a farm: [http://technet.microsoft.com/en-us/library/ff608053(v=office.15).aspx]


Install-SPInfoPathFormTemplate [-Path] <String> [-AssignmentCollection <SPAssignmentCollection>] [-Confirm [<SwitchParameter>]] [-EnableGradualUpgrade <SwitchParameter>] [-NoWait <SwitchParameter>] [-WhatIf [<SwitchParameter>]]

---------------EXAMPLE--------------
è Install-SPInfoPathFormTemplate -Path c:\Form.xsn

     
è "FormTemplateFirst.xsn", "FormTemplateSecond.xsn", "FormTemplateThird.xsn" | Install-SPInfoPathFormTemplate
This example installs multiple form templates on a farm

     2.   Saves InfoPath 2013 form templates on the SharePoint Central Administration Web site and .udcx files to a .cab file. [http://technet.microsoft.com/en-us/library/ff608075(v=office.15).aspx]

Export-SPInfoPathAdministrationFiles [-Path] <String> [-AssignmentCollection <SPAssignmentCollection>] [-Confirm [<SwitchParameter>]] [-Identity <SPFormsServicePipeBind>] [-WhatIf [<SwitchParameter>]]

---------------EXAMPLE--------------
è Export-SPInfoPathAdministrationFiles -path d:\file.cab

This example saves all InfoPath 2013 form templates (.xsn files) and universal data connections (.udcx files) located on the SharePoint Central Administration Web site in a compressed cabinet file named file.cab



For more information on InfoPath Services cmdlets in SharePoint Server 2013.

Yammer’s Integration with Microsoft SharePoint


Yammer’s enterprise social networking solution now integrates with Microsoft® SharePoint®. With the Yammer SharePoint Web Parts, you can see your Yammer feed directly inside SharePoint, eliminating the need to toggle between SharePoint and Yammer.

Although SharePoint Server 2013 provides basic enterprise social features, Yammer provides a richer enterprise social experience.

Yammer is a best-in-class enterprise social network that brings together employees, content, conversations, and business data in a single location.

Yammer empowers employees to be more productive by enabling them to collaborate in real time across departments, geographies, and business applications. You can add Yammer functionality to your SharePoint sites by adding Yammer to the navigation bar or by using the Yammer app to embed a Yammer feed in a site.

About Yammer

Yammer comes in two varieties: Yammer Basic and Yammer Enterprise.

Yammer Basic is free and available to all users. It provides a way for employees to collaborate with other members of their organization.

Yammer Enterprise is a premium version that extends an organization’s basic Yammer network. It’s offered both as a stand-alone product and with various SharePoint Online and Office 365 plans . 

Yammer Enterprise provides additional tools and resources to help organizations set up the best possible enterprise social network.


You can choose whether to use SharePoint’s social features or Yammer. If you want to take advantage of the power of Yammer with SharePoint, you can use any of the following methods:


You can use a toggle switch to replace the Newsfeed link with a Yammer link on the top navigation bar for SharePoint. This functionality is included in Service Pack 1 (SP1) for SharePoint Server.




To take advantage of the features provided by Yammer, it's a good idea to replace the default SharePoint Server 2013 enterprise social features with equivalent Yammer features. You can remove the SharePoint Server social web parts from My Sites and team sites, and you can hide the user interface controls that provide social functionality.





The new Yammer app for SharePoint lets you embed Yammer feeds (such as the home feed, a group feed, or comment feeds) into on-premises sites to make them more social and engaging.





For Integrating Yammer Apps to SharePoint Page:

Note: Trouble in adding Yammer App in CentralAdmin :



Check this blog:

Important Link:
Yammer integration with SharePoint 2010:
Go to SharePoint Link, Click for more information.

Configure the Secure Store Service in SharePoint 2013


Microsoft SharePoint Server 2013 provides a default feature of Secure Store Service (SSS) which has replaced the Single Sign-On (SSO) service, a feature of Microsoft office SharePoint Server 2007 for the storage and mapping of credentials for use in connecting with third-party or back-end systems. Many companies have already developed an in-house credential storage system or use a solution other than Microsoft Secure Store Service (SSS).

Sequence of events occurs as follows:
  •          A SharePoint Server 2013 user accesses a data-connected object such as an Excel Services worksheet, Visio Services diagram, or PerformancePoint Services dashboard.
  •          The Business Intelligence Service Application accesses the target application specified by the object.
  •          If the user is a Member of that target application, the credentials stored in the target application are returned and the Business Intelligence Service Application impersonates the credentials while accessing the data.
  •         The data is displayed to the user within the context of the worksheet, Visio diagram, or dashboard

A Secure Store Service (SSS) is a storage area to keep all the user ids and passwords that are used mainly in SharePoint 2013/2010 service applications. To create a SSS, we need to use the following procedure:
  1. Register a managed account to SharePoint Server 2013
  2. Start Secure Store Service
  3. Create Secure Store Application
  4. Encryption of Keys
  5. Create a target application and set the credentials for the target application
  6. Enable Audit logging for Secure Store
A. Register a managed account
  1. Navigate to "CA"-> "Security"
  2. Navigate to "General Security" -> "Configure managed accounts".
  3. Navigate to "Managed Accounts" -> "Register Managed Account".
  4. In the User name box, type the name of the account.
  5. In the Password box, type the password for the account.
  6. If you want SharePoint Server 2013 to handle changing the password for the account, select the "Enable automatic password change" box and specify the password change parameters that you want to use.
  7. Click "OK".

Power shell commands

$account = "domain\username"
$credential = Get-Credential -Credential $account
New-SPManagedAccount -Credential $credential


B. Start Secure Store Service
  1. Navigate to "CA" -> "System Settings" -> "Manage services on server".
  2. Choose the server on which the service should run by clicking the Server drop-down list, and then click "Change Server".
  3. Click "Start next to Secure Store Service".

$ServiceName = "Secure Store Service"
Get-SPServiceInstance -server $env:COMPUTERNAME | where-object {$_.TypeName -eq $ServiceName} | Start-SPServiceInstance -confirm:$false > $null

  1. Navigate to "CA" -> "Application Management" -> "Manage service applications".
  2. In the Manage Service Applications page on the ribbon click "New", then click "Secure Store Service".
  3. In the Service Application Name box, type a name for the service application.
  4. In the Database Server box, type the instance of SQL Server where you want to create the Secure Store database.
  5. Select "Create new application pool" and type a name for the application pool in the text box.
  6. Select the Configurable option, and, from the drop-down list, select the account for which you created the managed account earlier.
  7. Click "OK".

Power Shell commands

$appPool = New-SPServiceApplicationPool -Name $secureStoreServiceAppPool -Account $account
$sssApp = New-SPSecureStoreServiceApplication -Name "Secure Store Service Application" -DatabaseServer "DatabaseServer" -DatabaseName "DatabaseName" -ApplicationPool $appPool -AuditingEnabled:$false
Start-Sleep -s 15
$sssAppProxy = New-SPSecureStoreServiceApplicationProxy -Name "Secure Store Service Application Proxy" -ServiceApplication $sssApp –DefaultProxyGroup
Start-Sleep -s 15


Note: Back up the database of the Secure Store Service application before generating a new key.


  1. Navigate to "CA" -> "Application Management" -> "Manage service applications".
  2. Click on the "Secure Store Service application".
  3. In the Key Management group, click "Generate New Key".
  4. On the Generate New Key page, type a pass phrase string in the Pass Phrase box, and type the same string in the Confirm Pass Phrase box. This pass phrase is used to encrypt the Secure Store database.
  5. Click "OK".
Note: The pass phrase that is entered is not stored anywhere in SharePoint. Make sure you write this down and store it in a safe place. You must have it to refresh the key, such as when you add a new application server to the server farm.
Power Shell

Update-SPSecureStoreMasterKey -ServiceApplicationProxy $sssAppProxy -Passphrase

E. Create target application and Set credential for target application

  1. Navigate to "CA" -> "Application Management" -> "Manage service applications".
  2. Click the "Secure Store Service application".
  3. In the Manage Target Applications group, click "New".
  4. In the Target Application ID box, type a unique text string.
  5. In the Display Name box, type a text string that will be used to display the identifier of the target application in the user interface.
  6. In the Contact Email box, type the e-mail address of the primary contact for this target application.
  7. Target Application Page URL:


    • Use the default page: Any web sites that use the target application to access external data will have an individual sign-up page that was added automatically. The URL of this page will be: http:/<samplesite>/_layouts/SecureStoreSetCredentials.aspx?TargetAppId=<TargetApplicationID>
  • where "<TargetApplicationID>" is the string provided in the Target Application ID box.
  • Use custom page: You provide a custom web page that lets users provide individual credentials. Provide the URL of the custom page in this field.
  • None: There is no sign-up page. Individual credentials are added only by a Secure Store Service administrator who is using the Secure Store Service application.
  1. Target Application Type: choose the target application type: Group, for group credentials, or Individual, if each user is to be mapped to a unique set of credentials on the external data source.
  2. Click "Next".
  3. Use the Specify the credential fields for your Secure Store Target Application page to configure the various fields that may be required to provide credentials to the external data source. By default, two fields are listed: Windows User Name and Windows Password.
To add an additional field for supplying credentials to the external data source, on the Specify the credential fields for your Secure Store Target Application page, click "Add Field".
  1. By default, the type of the new field is "Generic". The following field types are available:
Field
Description
Generic
Generic Values that do not fit in any of the other categories.
User Name
A user account that identifies the user.
Password
A secret word or phrase.
PIN
A personal identification number.
Key
A parameter that determines the functional output of a cryptographic algorithm or cipher.
Windows User Name
A Windows user account that identifies the user.
Windows Password
A secret word or phrase for a Windows account.
Certificate
A certificate.
Certificate Password
The password for the certificate.
  1. Specify the membership settings: Target Application Administrators Field, list all users who have access to manage the target application settings.
  2. If the target application type is group, in the Members field, list the user groups to map to a set of credentials for this target application.
  3. Click "OK".

Power Shell
$UserNameField = new-spsecurestoreapplicationfield -name "UserName" -type WindowsUserName -masked:$false
$PasswordField = new-spsecurestoreapplicationfield -name "Password" -type WindowsPassword -masked:$true
$fields = $UserNameField, $PasswordField
$targetApp = new-spsecurestoretargetapplication -Name "IntranetFarmTargetApplication" -FriendlyName "Intranet Farm Target Application" -ContactEmail "admin@domain.com" -ApplicationType Individual
$targetAppAdminAccount = New-SPClaimsPrincipal -Identity "Domain\Account" –IdentityType WindowsSamAccountName
$defaultServiceContext = Get-SPServiceContext "http://demo.com"
$ssApp = new-spsecurestoreapplication -ServiceContext $defaultServiceContext -TargetApplication $targetApp -Administrator $targetAppAdminAccount -Fields $fields
F. Enable Audit logging for Secure Store

  1. Navigate to "CA" -> "Application Management" -> "Manage service applications".
  2. Select the "Secure Store Service application".
  3. On the ribbon, click "Properties".
  4. From the Enable Audit section, click to select the "Audit log enabled" box.
  5. To change the number of days that entries will be purged from the audit log file, specify a number in days in the "Days Until Purge" field. The default value is 30 days.
  6. Click "OK".

For more Information:
How to configure SSS in SP2013: http://technet.microsoft.com/en-us/library/ee806866(v=office.15).aspx

Login as a different user in sharepoint 2013

In SharePoint 2013, we don't have an option to login as a different user as in Sharepoint 2010. So we have to use the following link to sign in as a different user.

http://<SITE URL>/_layouts/closeConnection.aspx?loginasanotheruser=true

Upgrade Site collection using powershell script

Upgrade-SPSite -identity http://test2013 -VersionUpgrade

Update the web part property using powershell script

Sometimes you need to change the properties of a Web Part without browsing to the page itself and set it. There could be numerous reasons as to why you would want or need to do this. A while back I created a really simple redirect web part for one of my clients. It had two custom properties, EnableRedirect and Url. If EnableRedirect was true, it would redirect the user to the specified Url. Obviously, if you want to change either of these properties while the EnableRedirect is true, that's going to be a problem.
Fast forward and the redirect web parts need to be changed and/or disabled. Obviously we can't navigate to the page and just change it, because the page will redirect you. But it can be done relatively easy using PowerShell.
Start out with opening the site and getting the file we want to work on. Also note that the site I'm working on is a publishing site, which is why we need to check out, check in and publish the page we want to change the web part on.

$site = new-object Microsoft.SharePoint.SPSite("http://sharepointsite")$web = $site.OpenWeb("RandomSite/AnotherSite/")$page = $web.GetFile("Pages/default.aspx")$page.CheckOut()$wpm = $web.GetLimitedWebPartManager("Pages/default.aspx", [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)

From here we can look up and see which web parts are currently active on the page.
$wpm.WebParts | ft

There are two web parts on this page currently, and we want to change the second one. Let's finish of the script by doing this:
$wp = $wpm.WebParts[1]$wp.EnableRedirect = $false$wp.Url = "http://www.google.com"$wpm.SaveChanges($wp)$page.CheckIn("Test")$page.Publish("Test")$web.Close()$site.Close()

And that's it. The redirect is turned off, and it's been changed to point to Google. It's not a work of art, and a little cruddier than what I usually like to make my scripts, but I needed something quick and dirty to do the job. And that's what this does.