Updating a SharePoint page’s Page Layout using PowerShell
Earlier today I tried to update the page layout on a SharePoint 2010 site via the browser, which produced an error. I looked up the error’s correlation ID in the ULS logs and found this:
GetFileFromUrl: ArgumentException when attempting get file Url https://oldsitename/webname/_catalogs/masterpage/Block.aspx Value does not fall within the expected range.
I couldn’t change the page layout via the browser. I couldn’t change the page layout via SharePoint Designer.
Fortunately, I found Patrick Lamber’s helpful post, How to programmatically change the page template in Moss 2007, which basically described the same error and described applying a new page layout via the object model.
For whatever reason, I thought I could do it just as easily via PowerShell. I started following Jason Grimme’s post, Update SharePoint List Item(s) with Powershell, but I was unable to check-out/check-in the page or access the PublishingPageLayout property.
Liam Cleary’s reply on a TechNet post (Using PowerShell to Checkout and Checkin a file) tipped me off that I needed to use SPFile (rather than SPListItem) in order to perform the necessary operations. Here are the commands I ended up using:
$spWeb = Get-SPWeb("http://currentsitename/webname")
$spFile = $spWeb.GetFile("http://currentsitename/webname/Pages/Test-Page.aspx")
$spFile.CheckOut("Online",$null)
$spFile.Properties["PublishingPagelayout"] = "/_catalogs/masterpage/Block.aspx, Block"
$spFile.Update()
$spFile.CheckIn("Update page layout via PowerShell",[Microsoft.SharePoint.SPCheckinType]::MajorCheckIn)
$spWeb.Dispose()
I visited the page and…another error! This one telling me there wasn’t a valid page layout. Funny, it worked in development.
It turns out, when I compared it to the PublishingPageLayout property of a working page, I had missed the space character after the comma.
Doesn’t work:
"/_catalogs/masterpage/Block.aspx,Block"
Works:
"/_catalogs/masterpage/Block.aspx, Block"
Once I applied the proper path, I was also able to change the page layout via the browser again.
Monitoring web server status with a shell script
Recently, my VPS (Virtual Private Server) ran into some issues where it exceeded the maximum amount of RAM allotted under my subscription. When this happens, the web server software shuts down and does not restart until I manually restart it.
This is bad. I’m not always visiting my own web site, so it could be down for days without me knowing. Although I really need to identify what is using all the RAM, in the meantime I’ll settle for a monitoring system that will notify me when the server is down.
#!/bin/bash
if curl -s --head http://osric.com/ | grep "200 OK" > /dev/null
then
echo "The HTTP server on osric.com is up!" > /dev/null
else
echo "The HTTP server on osric.com is down!"
fi
cURL will let you retrieve a URL via the command line, and provides more options than Wget for a single URL. In this case, I used the silent switch to eliminate the status/progress output, and the head switch to retrieve only the document headers. The document header is then piped to Grep, which searches for the string “200 OK” (the HTTP status message for a successful request).
I send the result of that to /dev/null so that the output doesn’t appear on the screen.
If grep does find 200 OK, then I send a success message to /dev/null. This is largely unnecessary, but it is nice to leave in to test the script in a successful case–just remove the > /dev/null. If it doesn’t find 200 OK, then there is a problem. It might not mean, necessarily, that the web server is down, but it definitely indicates there is a problem that needs to be identified.
I added a call to this script to a crontab to run every 5 minutes. If there is no output, nothing happens. If there is output, the output is sent to me via e-mail, which, assuming I am checking my e-mail religiously, should reduce server downtime.
CFFTP Transfers a Zero-Byte File and Throws a Timeout Error
Although I’ve used ColdFusion for 7+ years now, I’ve never used the cfftp tag before. Yesterday, I found a reason to try it out. I figured it would be as simple as cfhttp–and it was, with one exception (no pun intended).
Here is my sample code:
<cfftp action="open"
connection="test"
server="ftp.osric.com"
username="chris"
password="********************"
timeout="60"
stoponerror="yes">
<cfftp
connection = "test"
action = "getFile"
name = "downloadFile"
transferMode = "binary"
localFile = "S:\chris\handlebar-moustache.jpg"
remoteFile = "handlebar-moustache.jpg"
timeout="60">
Here’s the error message it produced:
An error occurred during the FTP getFile operation.
Error: getFile operation exceeded timeout.
However, the local file was still created (as a zero-byte file).
The solution, in my case, was to turn on passive mode (add attribute passive="yes" to the cfftp tag).
Active FTP vs. Passive FTP, a Definitive Explanation has a brief explanation of the differences between active and passive FTP.
Importing Data into a SharePoint List
SharePoint Joel’s recent post, Managing Large Lists in SharePoint for Users and Site Admins got me interested in testing the 5000 list view item limit.
It also gave me a good opportunity to put fakenamegenerator.com to the test. The site quickly provided me with a list of 6000 random names.
Now, how to get them into a SharePoint list? › Continue reading
CSS Sprites and Accessibility
Yahoo’s Best Practices for Speeding Up Your Web Site lists minimizing HTTP requests as the very first recommendation. One of the ways they suggest doing that is by using CSS sprites (which I mentioned previously in Clever Ways to Save Bandwidth).
I recently applied this technique to a series of social media icons. Here’s an example:
http://osric.com/chris/css-sprites-social-media-icons-example.html
The example page uses a single image to display 8 separate icons from the following single image:
![]()
Be careful when using background images as links. › Continue reading
SharePoint user control to display a random image
The master page of a SharePoint site I work on loaded 7 photographic images, all over 50 kB each, to display at random as a banner adjacent to the site logo. The way it loaded the images was very inefficient: a default image was loaded in the HTML, and Javascript on the page created 7 image objects and returned one at random to overwrite the default. I decided to find a C# way to solve the problem.
› Continue reading
WordPress Manual Update Instructions
One of the great things about WordPress is the one-click upgrade procedure. It’s particularly convenient, because WordPress has frequent upgrades and security updates. Without an easy way of upgrading, many users would complain of upgrade fatigue, or would continue running older versions with security flaws.
Of course, not everyone can use the one click upgrade: My host is not configured properly, so I need to upgrade manually. Fortunately, a manual upgrade is relatively painless. Although it is described in some detail at Upgrading WordPress: Manual Update, I’m listing my specific procedures (using the Bash shell) here.
- Download the latest version to your home directory:
wget http://wordpress.org/latest.tar.gz - Remove any old WordPress directory before unpacking the latest:
rm -r ./wordpress - Unpack the latest version:
tar -xf wordpress-3.2.tar.gz - Backup the database:
mysqldump --add-drop-table -h localhost -u [username] -p [database name] | bzip2 -c > [site name].[dd-MMM-yyyy].bak.sql.bz2 - Disable plugins. You can do this via the admin interface, or the database:
UPDATE wp_options SET option_value = 'a:0:{}' WHERE option_name = 'active_plugins'; - Remove the wp-admin and wp-includes directories:
rm -r ./path/to/your/wordpress/wp-admin ./path/to/your/wordpress/wp-includes - Copy only the updated files over to the WordPress install:
cp -ru ./wordpress/* ./path/to/your/wordpress/ - Visit the admin page (which may prompt a database upgrade).
- Re-enable any plugins.
Step 6 may seem unnecessary in light of step 7, but in my experience merely updating the wp-admin and wp-includes directories is not enough: there may be old files that are not present in the latest version, but that will cause problems if they still exist.
I’ve found that my reCAPTCHA plugin doesn’t retain its API keys, but you can look them up again on the reCAPTCHA site. Other plugins may have similar issues.
Thanks to Perishable Press for the tip on disabling WordPress plugins via MySQL.
SQL Injection Goes Mainstream
Note to the web development world: even a mainstream media source like Time Magazine knows about SQL injection. Don’t you think it’s time you protected your web applications against it?
Last week’s issue of Time featured an article that focused on LulzSec‘s activities. In Hack Attack, author Bill Saporito went a step beyond most journalists covering web security by mentioning an actual technique: SQL injection. 
SQL injection is a subclass of injection attacks, wherein a malicious user manipulates input so as to insert (or inject) a tag-along command into the application code. It’s #1 on OWASP’s Top Ten Vulnerabilities for 2010, in part because such vulnerabilities are:
- Common
- Easy to exploit
- Have a huge payoff (i.e. devastating impact)
Because it is so common and easy-to-exploit, there are a lot of automated tools that malicious users (often by way of compromised machines) use to scan sites and test them for vulnerabilities. If a vulnerability is found, the application may be targeted for further attacks. Basically, attackers are on the lookout for low-hanging fruit in the same way that thieves look for valuables sitting in plain sight in a parked car. Don’t take the car analogy too far, though: if someone breaks into your car, there will be broken glass and your iPod will be gone. If someone exploits a SQL injection vulnerability on your site, they may have all your user data (and more), with hardly a trace: entries in your access logs and error logs, which are too-often completely ignored.
As the joke goes, you don’t have to outrun the bear to avoid being mauled and eaten–you just have to outrun the other guy. One of the best ways to make sure your web application is not targeted for further attacks is to make sure the relatively simple SQL injection scanners don’t find any vulnerabilities.
SQL injection is fairly simple to defend against using parameterized input, and your development language of choice should have documentation on how to do this. OWASP also offers a SQL Injection Prevention Cheat Sheet. There are also automated tools to you can use to check your code for SQL injection flaws (such as QueryParam Scanner for ColdFusion), or test your site for vulnerabilities–also known as penetration testing or pen testing–such as the (currently out-of-date) SQL Inject Me add-on for Firefox.
Checking your web applications for SQL injection vulnerabilities is the first thing you should do, but it is hardly the last. Although fending off automated SQL injection attempts is definitely a good thing, there are many other categories of vulnerabilities, and a determined attacker will find them. Stay informed, and make sure you know what attackers are up to before you read about it in Time.
Online Advertising Click-Thru Rates, Revisited
A couple years ago, I wrote Online Advertisements and Statistical Analysis, in which I did my best to show that a past study of online advertising click-thru rates (CTRs) wasn’t worth the pixels it was printed on.
About a week ago, my wife and I were visiting friends, and I found myself in a room with 3 neuroscientists. The topic of statistics came up, and I managed to insert into conversation my small triumph in analyzing the click-thru study and determining both a confidence interval and the number of tests that would need to be run in order to have a meaningful confidence interval. “Sure,” one of the scientists says, “but what you should really do instead is a chi-square test for goodness-of-fit.”
› Continue reading
3 Ways to Make Your Pages Facebook-Friendly
You’ve made a Facebook page and a Twitter account. You’ve even added “chicklets” to your site to let people easily share your content. But are your pages optimized for sharing?
When a user shares a link on Facebook, they can change the title and the description–but most people don’t know that, and won’t take the time even if they do. It is important to make sure that the default information that appears is what you want other users to see.
- Use a good title.
This has always been important for SEO, but it’s also what shows up when a user shares your link. You can supply text specifically for sharing with an Open Graph meta tag:
<meta property="og:title" content="3 Ways to Make Your Pages Facebook Friendly" />This can help you keep it short by eliminating your lengthy blog name or company name.
- Make sure the first paragraph is important.
The first paragraph shows up as the descriptive text. If your page contains rich media or other non-text content, you can add an Open Graph meta tag
Like the title meta tag, it looks very similar:
<meta property="og:description" content="What do your pages look like when you share them on Facebook? Do they have a good title? Relevant intro text that interests the reader? An interesting image? Tips on how to make your page work for all 3." /> - Include a relevant image.
Wall posts with images stand out more. Facebook will select the first non-linked image as the default, and will let users select from a menu of other non-linked images on the page
You can find out about other Open Graph meta tags at http://developers.facebook.com/docs/opengraph/. Facebook recommends including the XML namespace attribute for the Open Graph in your html element:
xmlns:og="http://ogp.me/ns#"
Digital Inspiration’s Set Thumbnail Images for Your Web Pages describes a way to specify a thumbnail images using a link element:
<link rel="image_src" href="http://osric.com/chris/images/sharing-on-facebook.gif" />
Pages
Archives
- April 2012
- March 2012
- January 2012
- December 2011
- November 2011
- September 2011
- August 2011
- July 2011
- June 2011
- May 2011
- March 2011
- February 2011
- January 2011
- November 2010
- May 2010
- March 2010
- January 2010
- December 2009
- October 2009
- September 2009
- August 2009
- July 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008