For all of you out there that have not yet been allowed the opportunity to dig into the vastness that is SharePoint 2010 and have become bored with SharePoint 2007, I just might have something new for you to play with. That’s right…PowerShell! My new addiction…
Note that before getting started, you should have a good working knowledge of the SharePoint Object Model.
Step 1: Get started
PowerShell by default comes with Windows Server 2008, however it doesn’t come with Windows Server 2003 and my guess is that if you’re still running SharePoint 2007 you’re probably still running Server 2003. If you are among this group, all you need to do is install the hotfix (KB926139) on one of your web servers. If you’re running Server 2008, you’re ready to go.
Step 2: Get excited!
So without getting too deeply into the nuts and bolts of PowerShell, what you need to know is that it gives you a command line interface, which provides the added ability of leveraging compiled code without actually compiling any of your own code. How could anyone not be excited about that?
And given the richness of the SharePoint object model, you are basically given unlimited potential for managing your SharePoint applications.
Step 3: Get to Work
Go ahead and fire up PowerShell. Also start up your favorite text editor program because we will write a few simple scripts. In these scripts we will do a few things: specify command line arguments, load any required libraries, and write some code to run the program.
Within your text editor paste the following:
param([string] $url)
[System.Reflection.Assembly]::Load('Microsoft.SharePoint, Version=12.0.0.0,
Culture=neutral, PublicKeyToken=71e9bce111e9429c') | Out-Null
$site = new-object Microsoft.SharePoint.SPSite($url)
$site
$site.Dispose()
Save this file as Get-SPSiteInfo.ps1 in the current PowerShell directory (or anywhere else if you have no problem navigating through directories in the command line).
If you look at the above code you will notice the 3 things I mentioned earlier. The param section which specifies that we will accept a parameter named “url” which is of type string. The next section specifies which assemblies should be loaded. We are loading in the “Microsoft.SharePoint” assembly, which is generally all you will need for these kinds of scripts. Also note in this section the “| Out-Null” command. This just basically suppresses PowerShell from outputting whether or not the assembly was successfully loaded. Finally, the last section is where we are running our code. We are just creating an SPSite object from the passed in URL, displaying the contents of the SPSite object, and finally disposing of it (never forget to dispose of objects when needed).
Now go back to your PowerShell window and type the following (replace <SITE URL> with the URL of your SharePoint site) and hit enter:
If the command runs correctly your output should look like the following screenshot (Click image to enlarge; if you receive an error stating something about an execution policy see this link http://technet.microsoft.com/en-us/library/ee176961.aspx):
What you are seeing are all of the properties, methods, objects, etc of the $site (SPSite) object. You can actually do this with any objects that you create in PowerShell. By just entering $site on its own line, you are telling PowerShell to output the contents of that object. This is usually where I start when I write scripts so that I can find all of the elements that I need.
So to recap, what we did was wrote a script that: 1) accepts a URL parameter; 2) loads the SharePoint library; 3) creates an SPSite object based on the passed in URL; 4) displays its contents; and finally 5) disposes of it. Very simple right?
Step 4: Get Something Useful
I don’t know about you, but on numerous occasions I’ve been asked to provide a list of all inactive sites in my environment. Now you can do things like set policies to delete sites that are inactive automatically, but sometimes that isn’t the best way to go about it. So if you’re in that boat, how do you get this information? You could always write a SQL script to query the databases, but why do that if you don’t need to? How about we make use of the SharePoint Usage data?
So for this example, our script will provide us with a list of all top-level sites in a specified web application that have not been accessed within the past month. Additionally this script will provide us with the ability to specify users to not count, as well as provide the ability to export to CSV. Open up a new text editor window and paste the following:
param($url, [string[]] $users, [switch]$exportToCSV)
[System.Reflection.Assembly]::Load('Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c') | Out-Null
# Lookup Web Application as specified in the command line parameter
$wa = [Microsoft.SharePoint.Administration.SPWebApplication]::Lookup($url)
# Create an array to store a list of all inactive sites
$sites =@()
Write-Output("`nProcessing sites...`n")
# Loop through all site collections in the web application
foreach($site in $wa.Sites)
{
$siteCount = $wa.sites.Count
# Counter used to track number of active users
$counter = 0
# Create a DataTable, which contains the user usage data for the past month
$usage = $site.RootWeb.GetUsageData([Microsoft.SharePoint.Administration.SPUsageReportType]::user, [Microsoft.SharePoint.Administration.SPUsagePeriodType]::lastMonth)
# Loop through all rows in the DataTable
foreach ($row in $usage.Rows)
{
# If the array of users to not count does not contain the current user, the user is unique, which means that the site is active, so increase the counter
if ($users -notcontains $row.User)
{
$counter++
}
}
# If the counter is equal to zero, then no unique users were found, and the site is considered inactive
if ($counter -eq 0)
{
# Create a generic object containing the site information and add it to the array
$o = new-object psobject
$o | Add-Member -MemberType noteproperty -Name Name -value $site.RootWeb.Title
$o | Add-Member -MemberType noteproperty -Name Url -value $site.RootWeb.Url
$sites += $o
# Outputs any inactive sites that are found
Write-Output("Site Processed: {0} (Inactive)" -f $site.RootWeb.Title)
}
else
{
# Outputs any active sites that are found
Write-Output("Site Processed: {0} (Active)" -f $site.RootWeb.Title)
}
# Dispose of the SPSite object
$site.Dispose()
}
# If the exportToCSV switch is entered, output the array of sites to CSV (without file type information)
if ($exportToCSV)
{
$sites | export-csv "Inactive_Sites.csv" -noTypeInformation
}
# else output the array of sites to the screen in a formatted list
else
{
$sites | format-list
}
#Output stats
Write-Output("`nTotal Sites Processed: {0}" -f $siteCount)
Write-Output("Total Inactive Sites: {0}" -f $sites.Count)
Write-Output("Processing complete`n")
Save this file as Get-InactiveSites.ps1
Now go back to your PowerShell window and type the following (replace <SITE URL> with the URL of your SharePoint site) and hit enter:
./Get-InactiveSites -url <SITE URL> -exportToCSV
If the command runs correctly your output should look like the following screenshot (Click image to enlarge):
Image may be NSFW.
Clik here to view.
Hopefully the comments explain everything that is going on here. And just be aware that this does cycle all site collections in your web application, so if you have a huge number of site collections, it may take a while to run. The only real thing to note is the –exportToCSV switch, which instead of outputting the results to the screen, they are outputted to a CSV. Awesome!
Let me know if you have any questions or comments below in the comments section.
The post Leveraging SharePoint 2007 through Windows PowerShell appeared first on MetroStar Systems Blog.