CHAPTER 3

image

Working with PowerShell

Anyone familiar with SharePoint 2010 or Windows Server Administration is likely familiar with PowerShell—it is hard to escape it. Microsoft introduced PowerShell as a more advanced script language to replace legacy DOS batch files, which are clunky and difficult to work with. PowerShell includes a number of programming concepts that we are used to seeing in modern-day programming languages, like C# and VB.NET. Furthermore, Microsoft built PowerShell atop of the .NET platform, so scriptwriters can take advantage of the .NET Framework to manipulate objects, instead of strings.

SharePoint 2010 embraced PowerShell with Cmdlets (units of functionality accessible in PowerShell scripts) and allowed users to script SharePoint via the API. With the release of SharePoint 2013, PowerShell is now the accepted standard for configuring SharePoint, via script, as opposed to via the graphical user interface (GUI).

Windows 7 and Server 2008 R2 include PowerShell out of the box, which is good, because SharePoint 2013 requires, at a minimum, Windows Server 2008 R2. All the same, installing SharePoint 2013 gets you a PowerShell instance, called the SharePoint 2013 Management Shell. In this chapter, I shall introduce you to the basics of PowerShell. You will also learn how to write scripts that interface with your SharePoint 2013 farm.

Like many topics in SharePoint, PowerShell is a vast one, and many good books exist on the topic. I included this chapter on PowerShell so you may appreciate the script functionality available to you as a SharePoint administrator. This chapter focuses on the basics of PowerShell and specifics relating to SharePoint Administration. If you are familiar with PowerShell, feel free to skip some of the sections in this chapter, or the complete chapter.

What About STSADM?

The web user interface to SharePoint is powerful, but as good as Central Administration is you cannot escape the need to script commands in batch via a command line. SharePoint 2007 included a nifty command-line application, called STSADM. STSADM is a versatile and very powerful tool for administering SharePoint and operates, like many command-line tools, with string parameters and switches.

As SharePoint evolved, from the early beta version of MOSS 2007/WSS 3.0, through SharePoint 2010, and now SharePoint 2013, STSADM also evolved. The problem was that STSADM became bloated with many operations, and yet the tool remains limited by command-line string parameters. Microsoft released PowerShell so we could administer Windows, so it made sense to add support for PowerShell in SharePoint. STSADM still exists as a tool, and some SharePoint administrators will continue to use it until the tool is snatched from their tight clutches. However, Microsoft has deemed PowerShell the new standard for command-line interaction with SharePoint, and we can expect STSADM to depreciate over time.

Many of the operations you can perform in STSADM, you can also perform in PowerShell, but with better control, since PowerShell works with objects instead of string parameters. SharePoint 2013 includes the same operations via STSADM as it always has, but any new functionality is now part of PowerShell. Thus, STSADM commands are a subset of those available in PowerShell.

PowerShell Basics

If you have read the introduction in this chapter, I hope I have convinced you that PowerShell is the way forward for scripting command-line operations in SharePoint 2013. Without further delay, I will now dive into the basics of PowerShell. You begin by opening a PowerShell window.

  1. Log in to your SharePoint Application server (the same server hosting SharePoint Central Administration).
  2. Search for the application named SharePoint 2013 Management Shell and execute it.
  3. You should see a new shell window, like that in Figure 3-1.

    9781430249412_Fig03-01.jpg

    Figure 3-1. SharePoint 2013 Management Shell

That was easy! Opening a PowerShell window is as easy as opening a command prompt window. If you are familiar with the PowerShell window available via Windows, you might be tempted to use this entry into PowerShell, rather than the SharePoint Management Shell. If you take this route, I shall make you aware of the required plug-in to enable SharePoint Cmdlets.

Loading the SharePoint Cmdlets

Microsoft has provided a number of SharePoint-specific Cmdlets, so you can easily manipulate SharePoint objects (applications, site collections, sites, lists, etc.) via PowerShell. These Cmdlets are available to you via a DLL plug-in, which you must enable in a regular Windows PowerShell window. If you launch the SharePoint Management Shell, the shell preloads the SharePoint Cmdlets for you. Type the following commands into your PowerShell window to see if you have the SharePoint Cmdlets loaded:

Get-PSSnapin -Registered | Where-Object { $_.Name -eq "Microsoft.SharePoint.PowerShell" }

The preceding command executes a PowerShell Cmdlet to get all registered snap-in objects, which you then pipe to another built-in Cmdlet, called Where-Object, to filter the list to a specific snap-in for SharePoint. If the SharePoint snap-in is loaded, you should see details about the registered snap-in object. If the preceding command produces no output, you can register the snap-in with the following:

Add-PSSnapin "Microsoft.SharePoint.PowerShell"

After adding the snap-in, re-run the script to check for the registered snap-in, and you should see details of the snap-in.

image Note  It is a good idea to use the SharePoint Management Shell for all SharePoint scripts, since all Cmdlets and functions run within the same thread. Scripts that run in the standard Windows PowerShell use separate threads for Cmdlets and functions, which can cause memory leaks when using SharePoint objects.

PowerShell Syntax

Once you start using PowerShell frequently, you will understand the terminology and syntax for PowerShell Cmdlets and script notation. PowerShell Cmdlets assume the syntax verb-prefix noun. The verb always indicates the action on the Cmdlet, and PowerShell supports the verb standards, listed in Table 3-1.

Table 3-1. PowerShell Verbs

Verb Action
Add Adds an object to a container or attaches an item to another item
Clear Removes all objects from a container
Close Changes the state of an object to closed
Copy Copies an object from one container to another
Enter Specifies an action that allows the user to enter a resource
Exit Specifies an action that allows the user to exit out of a resource
Find Looks for an object in a container
Format Formats an object to a specific form or layout
Get Retrieves a specific object; paired with the Set verb
Hide Makes an object undetectable; paired with the Show verb
Join Combines objects to one single object
Lock Secures an object; paired with the Unlock verb
Move Moves an object from one container to another
New Creates a new object instance; the Set verb may often be used
Open Opens an existing object
Pop Removes an object from the top of a stack container
Push Pushes an object to the top of a stack container
Redo Resets an object to a state that was undone; pairs with the Undo verb
Remove Removes an object from a container
Rename Renames the name of an object
Reset Sets an object to its default state
Search Creates a reference to an object in a container; do not use Find or Locate verbs
Select Locates an object in a container
Set Creates an object that contains data, or replaces data on an object; paired with the Get verb
Show Makes an object detectable; paired with the Hide verb
Skip Bypasses an object in a sequence
Split Separates parts of an object, such as a string
Step Moves to the next object in a sequence
Switch Specifies an action that alternates between two objects, such as to change between two locations, responsibilities, or states
Undo Set an object to its previous state; paired with the Redo verb
Unlock Releases a locked object; paired with the Lock verb
Watch Continually monitors an object for changes

The prefix in a Cmdlet is usually a two-letter qualifier that identifies the technology; for example, PS identifies PowerShell, AD identifies Active Directory, and SP identifies SharePoint. Finally, the noun is the affected object or resource; for example, Get-SPSite calls the SharePoint Cmdlet to “get” a new SharePoint “site” object.

Exploring SharePoint Cmdlets

As I mentioned in the earlier sections, SharePoint provides a number of Cmdlets, enabling you to interface with SharePoint and configure your farm. What do you do if you want to see a list of these Cmdlets? In using STSADM, you could provide the –o parameter to see a list of operations. Fortunately, PowerShell has a nice built-in Cmdlet called Get-Command.

Executing the Get-Command Cmdlet with no parameters will list every single available Cmdlet in PowerShell—yes, all of them! Passing the –Noun parameter to the Get-Command Cmdlet allows you to filter the list by a given noun name. If you cast your memory back to the previous section, you may remember that I mentioned standard syntax includes a noun prefix to identify the technology. SharePoint prefixes all nouns with “SP,” so you can easily get a list of all SharePoint Cmdlets as follows:

Get-Command –Noun SP*

The previous command uses a wildcard character, which tells the Get-Command Cmdlet to return any Cmdlets that start with “SP” and end with any other string of characters. There is still a large number of Cmdlets listed just for SharePoint operations; the following command tells us exactly how many (my install lists over 770):

(Get-Command –Noun SP*).Count

I think you need to narrow down the list; the Get-Command Cmdlet allows you to search for specific words in the noun. For example, if you wanted to list all the Cmdlets that deal with subsites (SPWeb) objects, you would use the following syntax:

Get-Command –Noun SPWeb

Figure 3-2 shows a much smaller (and manageable) list of Cmdlets. You can use the same trick to find all Cmdlets for site collection control—using the SPSite noun, rather than SPWeb.

9781430249412_Fig03-02.jpg

Figure 3-2. SPWeb Cmdlets

Getting Help

Getting a list of PowerShell Cmdlets is good, but knowing more about a specific Cmdlet is better. PowerShell includes another built-in Cmdlet to get help for a specific Cmdlet: Get-Help. The Get-Help Cmdlet provides details about Cmdlets, providers, aliases, functions, and scripts. The following line demonstrates how to execute the Get-Help Cmdlet to get help about the Get-SPWeb Cmdlet:

Get-Help Get-SPWeb

Figure 3-3 shows a screenshot of the Get-Help Cmdlet used with the Get-SPWeb Cmdlet as a parameter. As you can see, the Get-Help Cmdlet displays the name, a synopsis, syntax, and description of the Cmdlet passed as argument. The syntax information is probably most important because it details the various arguments for the Cmdlet.

9781430249412_Fig03-03.jpg

Figure 3-3. Using Get-Help Cmdlet

image Note  PowerShell incorporates auto-complete with the Tab key. Typing a ‘-‘, followed by Tab will cycle through the various arguments of a Cmdlet.

The Get-Help Cmdlet includes parameters to get information that is more detailed on a Cmdlet. Passing the –Examples parameter will return various examples to demonstrate the use of the Cmdlet. Passing the –Detailed parameter will give more detail beyond the basic information, and passing the –Full parameter will provide the complete help file for a Cmdlet. Try out the Get-Help Cmdlet on a number of well-known Cmdlets as well as some you have not encountered to get a good understanding of available help information.

The –Parameter argument is helpful in conjunction with the Get-Help Cmdlet because it provides details about a given parameter. Typically, when introduced to a new Cmdlet, you would use the Get-Help Cmdlet to get the syntax of available parameters and then provide the –Parameter argument to get details on a specific parameter for a Cmdlet. You can pass a * as the name to the –Parameter argument to get detailed information on all parameters supported by a Cmdlet.

Aliases

An alias is a shortcut for lengthy Cmdlets. For example, typing the lengthy Cmdlet named Get-SPBrowserCustomerExperienceImprovementProgram might get annoying quickly. By creating an alias for the Cmdlet, you can then use the alias in place of the full-length Cmdlet. Of course, I deliberately chose a Cmdlet name that stood out as long, but the likelihood of needing to get the browser customer experience program too often is small. However, this example does demonstrate that some PowerShell Cmdlets can get quite long.

The following example demonstrates how to create an alias, called web, for the Get-SPWeb Cmdlet:

Set-Alias –Name web –Value Get-SPWeb

You can then get the alias value with the following line:

Get-Alias web

To use the alias, simply replace the full name of the Cmdlet with the alias, complete with required parameters, as follows:

web http://sp2013

image Note  Aliases exist only in the current PowerShell session. If you close and reopen the PowerShell window, any previous aliases are gone.

Pipelines

Pipelines, in my opinion, really set PowerShell apart from standard command-line operations in Windows. Pipelines allow passing of output information from one PowerShell script or Cmdlet to another. Earlier in the chapter, I mentioned that PowerShell deals with objects rather than strings, and this becomes apparent when using pipelines.

The following Cmdlet lists all SPList objects within the root web of a site collection:

(Get-SPSite http://sp2013).RootWeb.Lists

Looking at the preceding command, you see that I use parentheses around the Get-SPSite Cmdlet and then access the RootWeb property and Lists collection. This further illustrates the fact that PowerShell uses objects—the Get-SPSite Cmdlet returns a SPSite object, which has a property called RootWeb. Now, back to our discussion about pipelines.

If you execute the preceding command, you will get back pages of unhelpful information as PowerShell displays every SPList object returned from the Lists collection. By default, PowerShell displays all information about an object if you do not specify the property or method associated with the object.

The following modified example shows the same command piping the output to the ForEach Cmdlet. The ForEach Cmdlet iterates a collection and allows you to control fine-grained operation on each object in the collection.

(Get-SPSite http://sp2013).RootWeb.Lists | ForEach-Object { $_.Title }

The preceding command pipes the results to the ForEach Cmdlet, which iterates the collection and executes the commands in the curly braces. When working with Cmdlets that iterate over collections or filter collections, the special syntax $_ denotes the current object in the iteration. The preceding command outputs the title of each list in the collection.

PowerShell and SharePoint

In the previous section and subsections of this chapter, I introduced you to the beginning concepts in PowerShell. As mentioned in the introduction, whole books exist on the subject, and my goal was to get you started on PowerShell, such that you can administer SharePoint 2013. With the basics out of the way, I shall now dive into specifics about managing SharePoint via PowerShell.

If you followed the examples in the previous section about the Get-Command and used this Cmdlet to get a list of SharePoint Cmdlets, you will know that SharePoint 2013 has many, many, many Cmdlets. My goal in this chapter is not to bore you by reviewing every Cmdlet laboriously, but to cover the mainstream of Cmdlets required to perform typical administration of your SharePoint 2013 farm.

Administration Permissions

If you have used STSADM in any capacity, you might understand the frustration that comes from failure to execute operations because the current user does not have enough permissions in SharePoint content and configuration databases. The typical response from IT is to provide you the credentials of the SharePoint farm account and have you run the SharePoint Management Shell as the farm user—not ideal.

SharePoint requires the current user (running the PowerShell session) to be a member of the SharePoint Shell Access role, and be a member of the local Windows security group WSS_ADMIN_WPG. Assuming you have administrator rights on the SQL Server hosting SharePoint, and the local SharePoint server, you could assign users to the SQL role for a SharePoint database and assign the same users to the local security group via server management. However, this is a chapter on PowerShell, so you should learn how to accomplish the same result using the SharePoint Management Shell.

To grant administration rights for a user, you first have to possess administration rights—a chicken and egg situation. In all likelihood, because you are reading this book, you have already established farm administration rights and have SQL administration rights on the SQL Server. All the same, it is good to try out the following commands and assign an otherwise-non-admin user permissions to execute shell commands against SharePoint.

In this example, I am going to grant my user permissions on my default WSS content database, by providing the database parameter. If you do not include the database parameter in the following command, then SharePoint will assign the permission in the main SharePoint configuration database—this is fine if you plan to perform PowerShell commands that configure the farm. If you plan to use PowerShell to administer site collections, subsites, lists, etc. belonging to a specific content database, then I recommend using the database parameter with a specific content database.

$db = Get-SPContentDatabase -Identity WSS_Content
Add-SPShellAdmin -database $db -UserName ROBDEVsp_admin

Follow up the preceding command with the following one to get a list of shell administrators for the default content database:

$db = Get-SPContentDatabase -Identity WSS_Content
Get-SPShellAdmin –database $db

It probably goes without saying (but I will say it regardless) that you can revoke shell administration rights with the following commands:

$db = Get-SPContentDatabase -Identity WSS_Content
Remove-SPShellAdmin -database $db -UserName ROBDEVsp_admin

Content Databases

In the previous section, ”Administration Permissions,” I included the Cmdlet Get-SPContentDatabase. This Cmdlet is one of a small list that deals with content databases. A content database, as you may already know, stores all content for one or many site collections. The following command lists the content database Cmdlets, explained in Table 3-2. Of course, you can leverage the Get-Help Cmdlet to get more information on any of the listed Cmdlets.

Get-Command *SPContentDatabase*

Table 3-2. Content Database Cmdlets

Cmdlet Description
Dismount-SPContentDatabase Detaches a currently mounted content database from its associated web application—use this command if you are planning to take a content database out of service. The database remains attached to SQL Server.
Get-SPContentDatabase Gets an instance of a content database; an example of this Cmdlet is in the previous section on administration permissions when you assigned shell permissions to a content database.
Mount-SPContentDatabase Attaches an existing content database to an existing web application. If the content database requires upgrade to a newer version, SharePoint will perform the upgrade before mounting. I demonstrate use of this Cmdlet as part of SharePoint 2010 to 2013 upgrade in Chapter 4. SharePoint requires you to have attached the content database to SQL Server already.
New-SPContentDatabase Creates a new content database and attaches it to a specified web application. This Cmdlet assumes you do not already have a content database by the designated name in SQL Server.
Remove-SPContentDatabase Similar to the Dismount-SPContentDatabase Cmdlet, but this Cmdlet will detach the content database from SQL Server and delete it. Do not use this Cmdlet if you wish to retain the database (and data within) for later attach to another SharePoint farm.
Set-SPContentDatabase Sets global properties of an existing content database, such as the maximum number of site collections, status, etc.
Test-SPContentDatabase Tests a content database against an existing web application to verify that all customizations referenced within the content database also reside in the web application. You can issue this Cmdlet against a content database currently attached to the farm, or a content database not connected to the farm, and it is useful for testing SharePoint 2010 content database pre-upgrade.
Upgrade-SPContentDatabase Initiates upgrade of an existing content database that otherwise failed to upgrade in a previous operation. This Cmdlet assumes the content database attached to SQL Server.

Of the Cmdlets listed in Table 3-2, the Cmdlet Mount-SPContentDatabase plays an important part in database-attach upgrades from SharePoint 2010 to SharePoint 2013. We use the Get-SPContentDatabase Cmdlet most often because it returns an object instance representing the content database, which we may then pass to other Cmdlets. This Cmdlet returns a SPContentDatabase object, which has many properties. To see a list of them, execute the following command:

Get-SPContentDatabase | Format-List *

The Format-List Cmdlet displays the properties of a piped object in list format (Figure 3-4).

9781430249412_Fig03-04.jpg

Figure 3-4. List properties for the Get-SPContentDatabase Cmdlet

The Get-SPContentDatabase Cmdlet lists all content database–associated web applications; using the –WebApplication parameter, provide the name of the web application.

Get-SPContentDatabase –WebApplication "SharePoint -80"

Every site collection resides in at least and no more than one content database, which you can establish using the –Site parameter, as follows:

Get-SPContentDatabase –Site " http://hostname/sitecollection "

Web Applications

PowerShell includes a selection of Cmdlets to manipulate web applications. A web application is the hosting application that resides in Internet Information Server and hosts one or many site collections. Execute the following PowerShell command to obtain a list of web application Cmdlets:

Get-Command –Noun SPWebApplication

Table 3-3 provides a description of each of the web application–related Cmdlets.

Table 3-3. List of Web Application Cmdlets

Cmdlet Description
Convert-SPWebApplication Converts the authentication mode of an existing web application from Classic to Claims-Based Authentication (CBA). SharePoint 2010 used to allow you to create Classic Mode web applications via Central Administration, and this Cmdlet provided conversion to CBA after creation. Since the default authentication mode in SharePoint 2013 is CBA, this Cmdlet comes into play only if you create a Classic Mode web application via PowerShell and then decide to convert to CBA later.
Get-SPWebApplication Gets an instance of a SPWebApplication object. Pipe the result of this command to the Format-List Cmdlet to see the properties belonging to the object. Use this Cmdlet with other Cmdlets to make changes to or operate on an existing web application in your farm.
New-SPWebApplication Creates a new web application in the farm. This Cmdlet takes a number of parameters, including the content database, application pool managed account, URL, port, etc. Cast back to Chapter 2 when I demonstrated creating a new web application via Central Administration—the dialog for creating a new web application contained many options, all of which are also available to this PowerShell Cmdlet.
Remove-SPWebApplication Deletes an existing web application for all zones or a particular zone. Using this command preserves content databases and, depending on the –DeleteIISSite parameter, will delete the IIS site entry.
Set-SPWebApplication Takes in a SPWebApplication object and allows you to set properties on the web application. This Cmdlet provides behavior in PowerShell similar to how you can edit an existing web application’s settings via Central Administration.

Now that I have covered web applications in PowerShell, I shall examine site collections next, followed by sites and subsites.

Site Collections (SPSite)

A site collection represents the taxonomy of a web site, and hosts a hierarchy of sites. In Central Administration, you create, edit, and delete site collections under the Application Management section. Table 3-4 lists the available Cmdlets; you can see a list of these Cmdlets by executing the following command:

Get-Command –Noun SPSite

Table 3-4. List of Site Collection Cmdlets

Cmdlet Description
Backup-SPSite Performs a backup of a site collection to a file on disk. This Cmdlet locks the site collection while the backup process completes. The –UseSqlSnapshot parameter ensures integrity when backing up the site collection while allowing users to read and write to the active site collection.
Copy-SPSite Copies a site collection to a new URL and content database. This Cmdlet assumes the ability to create SQL snapshots and effectively provides the same operation as using the Backup and Restore Cmdlets with SQL snapshot and content database parameters. When copying the site collection, the new site collection has a new unique identifier.
Get-SPSite Gets a new instance of a SPSite object from a provided URL.
Move-SPSite Moves a site collection to a new URL and content database. During the move, SharePoint applies a no-access lock on the site collection so users cannot read or write to the site collection. Similar to the Copy Cmdlet, the new site collection has a new unique ID and resides in a new content database.
New-SPSite Creates a new site collection. This Cmdlet accepts parameters for site owners, target URL, and template for the new site collection.
Remove-SPSite Removes an existing site collection, including all contained sites and subsites.
Repair-SPSite Performs a health check on the site collection and automatically repairs any encountered issues (when possible). Run the Test-SPSite Cmdlet to get a report on repairs required.
Restore-SPSite Restores a site collection from a backup file on disk. This Cmdlet will not allow you to overwrite an existing site collection at the destination URL, unless you provide the –Force parameter. A content database may not host multiple site collections with the same unique identifier, which the backup operation preserves. Therefore, to restore a site collection to a different URL in the same farm as the backup, create a new content database and pass an object instance of this database to the Restore Cmdlet.
Set-SPSite Provides ability to set property values on a provided SPSite object and the site collection. To obtain a list of available properties, use the Format-List * Cmdlet with the SPSite object.
Test-SPSite Runs the same set of rules as the Repair-SPSite Cmdlet without repairs, and produces a report of issues.
Upgrade-SPSite Performs an upgrade on site collection as either build-to-build (default) or version-to-version. Execute this Cmdlet after patching for build-to-build. When executing in version-to-version mode the Cmdlet performs a health check before performing an upgrade.

The more common of the SPSite Cmdlets are the Backup and Restore Cmdlets. As administrators, we are familiar with the STSADM backup and restore commands, which provide granular backup of complete site collections (often used when deploying a version of a web solution from development to staging and production). The new PowerShell Backup and Restore Cmdlets support the use of SQL snapshots, which ensures integrity of the backup, while allowing users to continue reading and writing to the active site collection. STSADM backup places a read-only lock on the site collection, prohibiting backup of a busy SharePoint site collection during business hours.

Sites (SPWeb)

Consider a modern intranet or public web site, which consists of multiple levels, accessible via navigation elements. A site represents a single level in a site hierarchy. In SharePoint, a single site contains document libraries, lists, and subsites. It does not matter if the site is a publishing site, team site, meeting site, etc. The site represents one node in the overall site taxonomy.

The SharePoint object model, and hence PowerShell, represents a site as a SPWeb object. Similar to other objects in PowerShell, you can get an idea of the number of properties associated with the SPWeb object by using the following command:

Get-SPWeb http://web-url | Format-List *

Table 3-5 lists the available Cmdlets, using the following command:

Get-Command –Noun SPWeb

Table 3-5. List of Site Cmdlets

Cmdlet Description
Export-SPWeb Exports a subsite hierarchy, starting at a particular site node in the site collection, to a file on disk (if using compression, or files in a directory otherwise). Unlike backing up a site collection, exporting a subsite hierarchy allows you to attach the sub-tree to another site collection or another subsite in a different location. Export assigns new IDs to objects. This Cmdlet provides export of the entire site (and subsites), or a single document library, or single list in the site.
Get-SPWeb Returns a series of SPWeb objects representing sites that match the scope in the identity parameter –URL or site collection SPSite object.
Import-SPWeb Imports a previously exported site hierarchy, list, or library to an existing site, whether the root site in the site collection or another subsite.
New-SPWeb Creates a new subsite under an existing site, whether the parent is the root site in the collection or an existing subsite in the hierarchy. This Cmdlet expects the URL of the new site, which resides under an existing site in the site collection. You may provide a template for the new site or assume the default template associated with the site collection.
Remove-SPWeb Removes a site from the site collection and any subsites belonging to the site specified. Deleting the root (top-level) site in a site collection causes deletion of the site collection, since every site collection must include at least one site.
Set-SPWeb Provides ability to set the value of a property on an existing SPWeb object. Use the Format-List * Cmdlet to get a list of available properties.

Typically, the most common of the preceding SPWeb Cmdlets is the Get-SPWeb Cmdlet, with which you might perform multiple operations via different SP Cmdlets. The SPSite site collection maintains a list of all SPWeb objects available in the site collection, which you can iterate as follows:

(Get-SPSite http://sp2013).AllWebs | Foreach-Object { $_.Title }

The preceding command gets SPWeb objects via the AllWebs collection on the SPSite object returned by the Get-SPSite Cmdlet. In my example, I am simply displaying the title of each site in the site collection, but I could just as easily pass the SPWeb object to a Cmdlet that performs an operation on the SPWeb object.

Memory and Disposal

Developers of SharePoint applications understand the need for memory disposal practice. SharePoint objects, such as SPSite, SPWeb, etc., consume resources, and it is the developer’s responsibility to release these resources by calling the Dispose method on these types of objects when done using them. Do you have to concern yourself with memory disposal when using these objects in PowerShell? Fortunately, PowerShell, in conjunction with the SharePoint object model, assists in the disposal of expensive SharePoint objects.

Earlier in this chapter, I mentioned using the SharePoint Management Shell, rather than the standard Windows PowerShell, because each command or single-line pipeline runs in a single thread. This is important when using objects like SPSite and SPWeb, because we often like to pipe these objects and Cmdlets that return these objects together, which would ordinarily leak memory in a multi-threaded Windows PowerShell window.

So, how does PowerShell manage memory disposal? I shall provide an example.

Get-SPWebApplication | Get-SPSite –limit all | Foreach-Object { $._Url }

The preceding command iterates over every site collection for every web application in the farm. For each site collection, the command displays the URL. The issue with this command is that the call to Get-SPSite for each web application uses space in memory for the new SPSite object. In a standard Windows PowerShell, not disposing of the SPSite object after each iteration would cause a memory leak. The SharePoint Management Shell caters to these scenarios and ensures disposal of all objects allocated in the preceding pipeline sequence.

Now, consider the following scenario, where SPSite and SPWeb objects are used over several lines of a PowerShell script:

$site = Get-SPSite " http://sp2013 "
Foreach ($web in $site.AllWebs) {
      Write-Host $web.Title
}

The preceding script gets a new instance of a SPSite object for a site collection URL, then iterates every site in the site collection (represented by SPWeb objects) displaying the title. In this example, PowerShell cannot help you because it has no way of knowing whether to dispose of the SPSite object nor each SPWeb object in the iteration, since the operations span several lines in the script. In this case, disposal is the responsibility of the script developer.

As a rule, I like to dispose of all SharePoint objects that implement the IDisposable interface. The following modified script ensures disposal:

$site = Get-SPSite " http://sp2013 "
try {
  Foreach ($web in $site.AllWebs) {
    try {
      Write-Host $web.Title
    } finally {
      $web.Dispose();
    }
  }
} finally {
  $site.Dispose();
}

Although the second version of the script ensures disposal of memory, the script is messy. Developers writing code in C# have a shortcut to clean up disposable objects with the using keyword. In PowerShell, we also have a shortcut, shown as follows:

Start-SPAssignment –Global
$site = Get-SPSite " http://sp2013 "
Foreach ($web in $site.AllWebs) {
      Write-Host $web.Title
}
Stop-SPAssignment –Global

Wrapping our script between the Start-SPAssignment –Global and Stop-SPAssignment –Global statements ensures that PowerShell disposes of any object allocated and assigned to the global space. Objects in the global space are those that the script has not scoped to a particular named space. The following example shows the script using two scoped name spaces:

$siteScope = Start-SPAssignment
$site = Get-SPSite " http://sp2013 "
for ($i=0;$i -lt $site.AllWebs.Count; $i++) {
  $webScope = Start-SPAssignment
  Write-Host $site.AllWebs[$i].Title
  Stop-SPAssignment $webScope
}
Stop-SPAssignment $siteScope

As you have discovered, memory management of SharePoint objects in PowerShell is important. If you are writing small scripts that have a short execution time—as in they complete within a few seconds—then memory-management is probably not one of your major concerns. However, if you have a script that iterates a large site collection and performs significant processing, then you can easily find yourself eating memory until your PowerShell instance crashes.

Before I conclude this section on memory and disposal, there is one more important point to be aware of—PowerShell does not clean up leaked objects at the end of scripts. In other words, if you have a leaky script, which you execute several times (perhaps because you are debugging), PowerShell is unable to claim the leaked memory until you terminate the PowerShell process. Again, this is not a big consideration if you are executing your scripts in a short window of time, but if you have a PowerShell script running for a lengthy duration, pay close attention to the amount of memory the PowerShell process consumes.

Summary

In this chapter, I introduced you to the basic concepts of PowerShell, including how to establish available Cmdlets, get help on Cmdlet syntax, and learn about pipelines. You then jumped into administration of your SharePoint 2013 farm with the common SharePoint objects: SPWebApplication, SPSite, and SPWeb.

Throughout this chapter, I provided examples on how to use some of the Cmdlets for manipulating site collections, sites, and web applications. You read about permissions required to execute PowerShell scripts against SharePoint. Finally, I provided you some best practices for memory disposal of expensive objects.

In Chapter 4, I will show you how to use some of your knowledge of PowerShell to perform an upgrade of content in a working SharePoint 2010 farm to a new empty instance of a SharePoint 2013 farm.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.27.74