Adding a permission level to a SharePoint site collection

This is a nice, simple trick! My customer wanted to add a permission level to all site collections. It’s called Site Owner and is basically full control without the ability to create sub-sites (webs). So I added this to my site creation script.

#Create the Site Owner permission level
write-host “Creating custom permission level: Site Owner”

$plAdmin=New-Object Microsoft.SharePoint.SPRoleDefinition
$plAdmin.Name=”Site Owner”
$plAdmin.Description=”Custom Permission Level for site owners”
$plAdmin.BasePermissions=”EmptyMask,
ViewListItems,
AddListItems,
EditListItems,
DeleteListItems,
ApproveItems,
OpenItems,
ViewVersions,
DeleteVersions,
CancelCheckout,
ViewFormPages,
Open,
ViewPages,
ViewUsageData,
BrowseDirectories,
BrowseUserInfo,
AddDelPrivateWebParts,
UpdatePersonalWebParts,
UseClientIntegration,
UseRemoteAPIs,
ManageAlerts,
CreateAlerts,
EditMyUserInfo,
ManageWeb,
ManageLists,
AddAndCustomizePages,
ManagePersonalViews,
ApplyThemeAndBorder,
ApplyStyleSheets,
EnumeratePermissions”

$web.RoleDefinitions.Add($plAdmin);

I have yet to find a list of all the role definitions so you pretty much have to figure it out from the Site Permissions page.

Go to Site Settings, Site Permissions, and click Permission Levels on the toolbar. Once you are there, click on Full Control and that will give you a list of all the permissions. You can use the above code to figure out what you want to include.

That’s it! Until next time,

Leave a comment

Posting PDF files to a SharePoint 2013 blog

This problem has been around forever. I remember dealing with this back in the 2003 days. You try to copy and paste from a PDF file into a SharePoint blog and all the graphics and formatting go away. Below is a somewhat painful solution but it’s a pretty good solution none the less. Enjoy!

Step 1 – Convert your PDF to Microsoft Word format

Office cannot publish a PDF file directly to a SharePoint blog. If you try to copy and paste the information from the PDF file, it will not retain the formatting or the images. The easiest way to accomplish this is to convert the PDF file into a Word document using an online conversion service.

There are a large number of sites that will take care of the conversion and, if security is a concern, you can download a free application to do the conversion. The easiest thing to do is just Google “pdf to word online”. Most likely it will name the document with the .rtf extension. That’s OK. It will open in Word just fine.

Step 2 – Open the converted document in Word

Open the converted document in Word. Note that it will open Read Only. Click the Enable Editing button to change the mode to read/write.

Step 3 – Create a blog post

Click the File tab in Word and select New. From the template selection screen pick Blog Post. The first time you create a blog post, you will be required to register a blog. Simply enter the URL to the SharePoint blog and click next. You can actually have multiple accounts for blogging. Simply click the Manage Accounts button in the tool ribbon in Word.

At this point you will have 2 Word documents open: the converted PDF file and the blank blog post.

Step 4 – Copy the PDF data to the blog post

Go to the window that has the open, converted PDF document. Press Ctrl-A on the keyboard to select the entire document. Then press Ctrl-C on the keyboard to copy the data to the clipboard.

Select the window with the open, blank blog post, add a title and paste the information as desired.

Step 5 – Publish the blog post

Click the Publish button on the Word tool ribbon to publish the blog post to SharePoint. You can publish the blog post as a draft as well.

There you have it! All the steps required to post a PDF doc into a SharePoint blog post. Is it perfect? Nope. Sometimes the formatting gets hosed but it’s better than nothing.

Peace!

Leave a comment

Unable to stop crawl and/or Index Reset SharePoint 2013 Search

I swear if you breath on SharePoint wrong, you will be in a world of hurt. Guess you guys figured by that statement, that I’m from Texas, huh? God Bless Texas!

My coworker did something very reasonable a couple of days ago by setting up a content source to crawl a WSS 3.0 farm from our SharePoint 2013 farm. Seemed like a fine idea until we tried to run a full crawl on our farm content source and it ran past the 27 hour mark when it usually takes less than 8. So something was stuck. Then the search was failing on all the sites. We were getting the infamous “Sorry but something is hosed, loser” error. Great.

Since the farm isn’t really in production yet, an intelligent course of action was to stop the crawl, do an Index Reset, and try to run another full crawl. I volunteered to do that deed late one night. Bad idea. Of course, nothing worked as planned.

IMPORTANT: Don’t forget to make sure you set all your crawl schedules to None before you start.

Issue number 1: Crawl stuck in Stopping. Tried to stop the crawl. It stayed in the Stopping state for about 15 minutes and then went to the “Sorry loser” error. So let’s kill the search service and see what happens. Now this should be a simple process but it isn’t. You need to stop the “SharePoint Server Search 15” on all the SharePoint servers in the farm. Do the following on all the SharePoint servers:

  1. Start -> Run -> Services.msc
  2. Find the “SharePoint Server Search 15” service. Right click and go to Properties.
  3. Select the Recovery tab.
  4. Set First Failure and Second Failure to “Take no action”. This is going to keep the service from restarting when you turn it off. This is very important.
  5. Click OK and then stop the service.
  6. Do this on all the servers.
  7. Check in CA and make sure the crawl is in the Idle state (it will be).
  8. Go back and turn the services back on for each server. While you are there, go ahead and set First Failure and Second Failure back to “Restart the Service”.

Now that the crawl is in Idle, it’s time to do an Index Reset. You can give it a try in CA but, in my case, it threw a “Sorry loser” error. This one is a little more painful to fix. Clear the SharePoint cache. Crap.

Issue number 2: Index Reset throws an error.

  1. Start -> Run -> Services.msc
  2. Find the “SharePoint Timer Service”, right click and select properties.
  3. Go to the Recovery tab and set all the Failures to “Take No Action”. This is very important.
  4. While you are there, stop the service.
  5. Do this for all SharePoint servers in the farm.
  6. Find the cache folder. It’s usually somewhere like C:\ProgramData\Microsoft\SharePoint\Config. Just do a search for the file cache.ini and that will be the right folder.
  7. Delete all the files in that folder EXCEPT Cache.ini.
  8. Open Cache.ini with Notepad and change the number to 1. You can make note of that number for later if you wish.
  9. Do this for all the SharePoint servers in the farm.
  10. No go back and turn on the “SharePoint Timer Service” on all the servers. You can put back the Failures their previous state at this time, too.
  11. Take a look in the cache folders and make sure they are filling up with new files. If you are ultra paranoid, you can compare the cache.ini number to the one you saved and make sure they are the same. I have no idea what you would do if they didn’t match.

Try doing the Reset Index again and it should work. It only takes a short amount of time, so if it hangs, clear the cache again and give it another try.

So there you have the painful process of clearing up your search crawls on SharePoint 2013. Next, we are going to discuss continuous crawls and why they are a good thing.

Until then, keep it real.

The Grumpy Guru

6 Comments

Error changing a site title in SharePoint 2013

Here’s a good one: You have a new 2013 site and attempt to change the Tile, Description, and Logo. You click on the link and get a nice black and white page that says:

A list, survey, discussion board, or document library with the specified title already exists in this Web site.  Please choose another title.

Cool, huh? I found this trying to apply a custom Composed Look to a site. Seems like just about anything causes this error.

Come to find out, the Site Assets library is hosed up. The solution? Here it is step by step:

  1. Browse to Site Content and see if the Site Assets library exists. If it does, delete it.
  2. If you don’t see it there, open the site in SharePoint Designer and select All Files.
  3. See if the Site Assets library is there. If it is, delete it. (I did find it there in my case).
  4. Now go back to your site and go to Site Settings then Title, Description, and Logo.

Low and behold! Everything works! If you still have the site open in SPD, hit F5 and you will see that it re-provisioned the Site Assets library.

If this keeps happening, I’m going to write some PowerShell to fix it on site creation. Stay tuned!

 

1 Comment

WSS 3.0 ULS logs empty

You ever do 2 things and then wonder which one actually fixed the issue? Yeah, me too. So here’s what happened: We have a number of site collections on an old WSS 3.0 farm that are not returning search results (more on that later). Microsoft wanted us to turn on verbose logging during a crawl to see what was happening.

To make a long story even longer, the ULS logs were getting generated but were empty. 0 KB. Damn.

Everything revolves around the Windows SharePoint Services Tracing service. That’s the timer job that runs all the logging. This should be running under Local Service. Check. So maybe the farm account can’t write to the log files? Worth a try so I added the farm account to the local group Performance Log Users. Just for drill, I restarted the Windows SharePoint Services Tracing service.

Bingo! Everything worked! Logs are filling up again. So which one fixed it? Who knows? But it works so do both. 

Leave a comment

List files and folders (DIR) with PowerShell

Here’s a quickie. You want to get a list of all the files and folders to use in a script? Here’s how:

$fileEntries = [IO.Directory]::GetFiles(“c:\somefolder”/);
foreach($fileName in $fileEntries)
{
    Write-Host $fileName;

Want to do the equivalent of *.txt? Add this:

$fileEntries = [IO.Directory]::GetFiles(“c:\somefolder”,”*.txt”);

Fun stuff!

Leave a comment

Reading and Writing CSV files with PowerShell

I don’t always use CSV files but when I do, I do them manually. Like a man.

I use to fancy myself a lazy coder. The simpler, the better. With that in mind, here’s an easy one for you.

There are many goofy ways to create and read CSV files in PowerShell. But here is a quick and easy way that won’t make you crazy.

Writing the CSV file

Add-Content d:\backup\backup.txt “Url,Path”;

foreach($site in $spWebApp.Sites)
{
$line = $site.Url + “,” + $fullpath;
Add-Content d:\backup\backup.txt $line;
}

This is as simple as using Add-Content to write to a text file. The first Add-Content command writes the headers which is the only thing you need to really make this a CSV file. The loop just writes two value separated by a comma.

Now comes the fun part: reading the CSV file into a couple of variables.

$csvlines = import-csv d:\backup\backup.txt
foreach($line in $csvlines)
{
$url=$line.Url;
$path=$line.Path;
Write-Host “url=” $url;
Write-Host “path=” $path;
}

Basically, the import-csv command “opens” the file. The loop just enumerates through the file and gets the “records”. Finally, the lines object will contain whatever you put in for the headers. In this case, Url and Path.

Simple and to the point. And always remember …

Stay thirsty my friends

1 Comment

Listing the properties and methods of an object in PowerShell

Here’s a quick one. Have you ever wondered how to list all the properties and methods of an object in PowerShell? It’s pretty simple. Just use the Get-Member cmdlet. Here’s an example to get the properties and methods of an object returned from Get-SPSite:

Get-SPSite | Get-Member

As you can see, you are just piping the output to the Get-Member cmdlet. You get a nice list of everything all organized and alphabetized for you. It looks something like this:

Capture

Try it! You’ll like it!

Leave a comment

Validate Input of PowerShell Commands

In a previous post I presented some code to create site collections in a new content database. My new client requested a similar process but this time I wanted to add some validation to the front. There is a lot of prompts to type and I’ve fat fingered some data on more than one occasion. Of course, once the code starts to execute, it’s too late. Then it’s go to SQL and delete content database, a trip to CA, etc. Not fun.

Now you would think there would be a ton of info on how to manage a simple Y/N prompt but it was a bit harder to find than expected. So I’m putting it here for all to see!

There are several ways to handle this. Some cmdlets have the -confirm parameter. Just use the -? parameter to find out what’s available. However, what I wanted to do was dump out the user input and have them verify everything before running the script.

The basics are pretty simple. We are going to use the
System.Management.Automation.Host.ChoiceDescription function. We just setup a few variables to use and $host.ui.PromptForChoice to make it happen. Below is the sample code:

$title = “Create Site Collection”
$message = “Do you want to create this site collection?”
$yes = New-Object System.Management.Automation.Host.ChoiceDescription “&Yes”, `
    “Creates site collection.”
$no = New-Object System.Management.Automation.Host.ChoiceDescription “&No”, `
    “Do not create site collection.”
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$result = $host.ui.PromptForChoice($title, $message, $options, 0)

As you can see, everything gets returned in the variable results. What you get back is 0 for the first choice (the default), 1 for the second choice, 2 for the third choice, etc. You can add about as many choices are you want here. In our case we have only 2: yes and no. We do have the built in third choice which is help (you get that for free). The help responses are the second parameter in the System.Management.Automation.Host.ChoiceDescription call. For the Yes prompt, for example, it reads “Creates site collection.”. Uber simple stuff.

Now let’s add the code to either execute the script or leave it:

switch ($result)
    {
        0 {break;}
        1 {exit;}
    }

The 0 value returned means we have a Yes so we just leave the switch statement. If we get 1, that’s a no so we just exit out of the PowerShell script. Pretty cool, huh?

Now let’s put it all together. This code gets all the parameters needed to create a site collection in a new content DB, dumps them to the screen, and asks the user if they want to execute the commands or not.

$ErrorActionPreference = “Continue”;

#Get input from user
$server = Read-Host “Enter Content Database Alias”; #This is the alias you setup to your database server.
$webapp = Read-Host “Enter the WebApp Root URL (https://url.webapp.com)”; #This is the root URL to your web app
$name = Read-Host “Enter New Site Collection Name”; #Prompts for Site Title (you can change this later)
$site = Read-Host “Enter New Site Collection URL”; #Prompts for your new site collection URL (https://url.webapp.com/sites/newsitecoll for example)
$dbname = Read-Host “Enter Content Database Name”;
$owner1 = Read-Host “Enter Site Owner 1 (domain\owner1)”;
$owner2 = Read-Host “Enter Site Owner 2 (domain\owner2)”;

#Confirm everything (just dumps out what they entered)
Write-Host “”
Write-Host “Site Collection Parameters”
Write-Host “__________________________”
Write-Host “DB Server: $server”;
Write-Host “Root URL of Web App: $webapp”;
Write-Host “Site Collection Title: $name”;
Write-Host “Site Collection URL: $site”;
Write-Host “Content Database Name: $dbname”;
Write-Host “Site Owner 1: $owner1”;
Write-Host “Site Owner 2: $owner2”;
$title = “Create Site Collection”;
$message = “Do you want to create this site collection?”;
$yes = New-Object System.Management.Automation.Host.ChoiceDescription “&Yes”, `     “Creates site collection.”
 $no = New-Object System.Management.Automation.Host.ChoiceDescription “&No”, `     “Do not create site collection.”
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$result = $host.ui.PromptForChoice($title, $message, $options, 0)
switch ($result)
 {
   0 {break;}
   1 {exit;}
    }
Write-Host “”; Write-Host “Creating site collection: $name”;
Write-Host “______________________________”;

 

 

Leave a comment

Popularity Trends missing in SharePoint 2013

For those of you who have taken the time to wrap your head around the new web analytics for SharePoint 2013, my sympathies are with you. It’s more FAST than SharePoint and the learning curve is steep.

One of the “features” Microsoft left for us was the Site Web Analytics reports link in Site Actions. Click on it. I dare you. Yep, an error. Because it doesn’t exist anymore! So why is it there? Whoever figures that out, please let me know.

The new thing is called Popularity Trends. Sounds more like the it would relate to Paris Hilton and Lady Gaga, doesn’t it? Anyway, it’s no where to be found until you do a little trick. Go to Manage Site Features and turn on the Reporting feature. Then navigate back to Site Settings. You magically have Popularity Trends under Site Administration and Popularity and Search Reports under Site Collection Administration. And, last but not least, the Site Web Analytics link is gone. Two for the price of one!

Now if I can just figure out why my reports are empty …

2 Comments