Provisioning Search on SharePoint 2013 Foundation Using PowerShell
There was recently a twitter conversation between @cacallahan, @toddklindt, and @brianlala discussing provisioning Search on SharePoint Foundation and whether it was possible or not and somewhere during the conversation it was suggested that I might know how to do this (sorry guys for not responding immediately) – unfortunately I hadn’t actually done any work with SharePoint 2013 Foundation yet and so had not yet tried and thus didn’t know the answer (I knew there were issues and suspected a workaround was possible but I didn’t have a server built to test anything). Well, last night and today I managed to have some free time so I figured I’d take a look at the problem to see if my guess about a workaround was correct.
Before I get to the results of my discovery let’s first look at what the blocking issue is. It’s actually quite simple – the product team, for various reasons, have decided that for SharePoint 2013 Foundation you can only have one Search Service Application and you shouldn’t be able to modify the topology of the Service Application; this means that when you provision Search using the Farm Configuration Wizard it will create a default topology for you in which all roles are on a single server. So, to enforce these rules they chose to make it so that the PowerShell cmdlets would not allow you to provision the service application or run any method or cmdlet that would otherwise allow you to modify an existing topology (so you can’t change the topology created by the wizard). I totally get the reasoning for the restriction – if you need enterprise topology type structures then pony up the money and get off the free stuff. That said, I think they took the lazy way out by simply blocking the cmdlets when they could have easily put in other restrictions that would have achieved their goals while still allowing users to use PowerShell to provision the environment.
If you’re curious as to what happens when you try to provision the service using PowerShell on SharePoint Foundation 2013 here’s a screenshot which shows the error that is thrown:

This error is thrown by a simple piece of code in the InternalValidate() method of the cmdlet which checks to make sure you are on Standard or Enterprise before allowing the cmdlet to execute (and any other cmdlets or methods that would otherwise affect the topology likewise perform this check).
To solve the problem I decided to start from the perspective of code run via the browser and drill down to see what I could find. So using Reflector I located the class and associated methods that are called by the Farm Configuration Wizard; this quickly led me to the public Microsoft.Office.Server.Search.Administration.SearchService.CreateApplication() static methods. So I did a quick test calling one of these methods and I was happy to find that the Search Service Application created perfectly – though there was one minor problem: the topology was empty. At first glance I figured this wouldn’t be an issue – I could simply clone the topology and add my components – unfortunately this is where I learned that they applied the SKU check to methods and cmdlets that would allow you to manipulate the topology. (On a side note, using these methods for Standard or Enterprise is potentially a great alternative to the New-SPEnterpriseSearchServiceApplication cmdlet as it lets you specify the names of databases that you can’t specify when using the cmdlet and because it creates an initially empty topology there’s less cleanup and manipulation of the cloned topology (assuming you don’t want to use what’s created) and it provisions slightly faster because it does less). So at this point I figured I’d hit the real road block – I could create the service application but it was useless as I couldn’t manipulate it.
This left me with only one option – to use reflection to call the internal method that the Farm Configuration Wizard calls to provision the service application. Now, before I get to the code that demonstrates how to do this I need to share a word of caution – using reflection to call internal methods is totally not supported. So what does this mean? Will Microsoft no longer support your Farm? Well, my understanding (and folks in the know please correct me if I’m in the wrong) is that Microsoft will continue to support you and that you will simply have to remove unsupported code before they will help you troubleshoot issues. Well, in this case it’s a one-time operation so there’s nothing really to remove; I figure the worst case scenario is that they’ll tell you that you need to recreate the service application using the Farm Configuration Wizard and then they’ll help you with your issue. But let’s take the question of supportability out of the equation for a second and look at it from a completely practical standpoint – if you were to look at the code that the Farm Configuration Wizard calls you’d see that, outside of some error checking and data validation and variable initialization, there’s effectively just two lines of code that do the provisioning of the service so I believe that the probability of getting it wrong is pretty low and the fact is search will either work or it won’t so if it doesn’t work then try again or just use the dang wizard. So, with all that said, if you decide to use any of this code you need to weigh the risks yourself and make an informed decision with those risks in mind. Alright, enough of that crap – you want to see the code so let’s get to the code.
To keep the PowerShell itself nice and simple I decide to derive this example from a script that Todd Klindt provides on his blog (the script I use is considerably more complex as it handles the changing of service options like the index folder and the service and crawl accounts, to name a few, and I don’t want the point of this post to be lost in all those details). Just to make sure the full chain of credit is provided I should note that Todd’s script is actually a derivative of what Spence Harbar provides on his blog but I wanted to reference Todd’s post specifically as it’s a bit shorter and more focused on the topic. Okay, background info – check; disclaimer – check; attribution – check – looks like it’s time for some code so here you go:
Start-SPEnterpriseSearchServiceInstance $env:computername
Start-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance $env:computername
#Provide a unique name for the service application
$serviceAppName = "Search Service Application"
#Get the application pools to use (make sure you change the value for your environment)
$svcPool = Get-SPServiceApplicationPool "SharePoint Services App Pool"
$adminPool = Get-SPServiceApplicationPool "SharePoint Services App Pool"
#Get the service from the service instance so we can call a method on it
#Use reflection to provision the default topology just as the wizard would
$bindings = @("InvokeMethod", "NonPublic", "Instance")
$types = @([string], [Type], [Microsoft.SharePoint.Administration.SPIisWebServiceApplicationPool], [Microsoft.SharePoint.Administration.SPIisWebServiceApplicationPool])
$values = @($serviceAppName, [Microsoft.Office.Server.Search.Administration.SearchServiceApplication], [Microsoft.SharePoint.Administration.SPIisWebServiceApplicationPool]$svcPool, [Microsoft.SharePoint.Administration.SPIisWebServiceApplicationPool]$adminPool)
$methodInfo = $searchService.GetType().GetMethod("CreateApplicationWithDefaultTopology", $bindings, $null, $types, $null)
$searchServiceApp = $methodInfo.Invoke($searchService, $values)
#Create the search service application proxy (we get to use the cmdlet for this!)
$searchProxy = New-SPEnterpriseSearchServiceApplicationProxy -Name "$serviceAppName Proxy" -SearchApplication $searchServiceApp
#Provision the search service application
$searchServiceApp.Provision()
Basically there’s two things that need to be done: first we need to use reflection to get the MethodInfo object for the CreateApplicationWithDefaultTopology() method of the Microsoft.Office.Server.Search.Administration.SearchService class and we’ll use this object to invoke the actual method, passing in the parameter types and values (and yes, the cast of the SPIisWebServiceApplicationPool objects is necessary otherwise you’ll get an error about trying to convert PSObjects to SPIisWebServiceApplicationPool types); the next thing we need to do, after the service application is created, is to create the service application proxy and then call the Provision() method on the search service application that we previously created (if you miss this step you’ll get errors about things like the admin component not be started and whatnot).
Once completed you’ll get a fully functional, PowerShell provisioned search service application. If you navigate to the search administration page you should see something that looks just like this (just like if you used the wizard):
So there you have it – it is indeed possible to provision the service using PowerShell – I’ll let you determine whether you should or not
Happy PowerShelling!
-Gary
Fix: The trust relationship between this workstation and the primary domain failed
This short post is really just for my own memory as I keep bumping into this with my virtual machines but I figured others might also find it useful. Typically when I do SharePoint development I do everything on an all-up server but with SharePoint 2013 I’ve moved my Domain Controller to a separate server (where I also will install the Office Web Apps); however, if I leave any of my machines off for a while then the computer password will expire which means that things start to break and you’ll see errors like "The trust relationship between this workstation and the primary domain failed." The common fix is to remove the server from the domain and then join it back in but that takes some time so what I prefer to do is to simply run the following command which will reset the password:
netdom.exe resetpwd /s:domain_controller_name /ud:domain\administrator /pd:*
Be sure to replace the domain_controller_name placeholder with the name of your domain controller server. If you’re not already logged in to the server then you’ll have to log in using a local administrator account. After running the command it will prompt for a password for the specified account (it’s an odd prompt as it doesn’t show any characters being typed – not even masked). After providing the password reboot the server and you should be good to go.
If you want to prevent the server from changing its password in the first place (or prevent the DC from accepting the password change) you can follow the steps in this support article to disable the setting and avoid the issue altogether: http://support.microsoft.com/kb/154501 (more times than not I forget to do this in new development environments which prompted me to post the reset password fix).
UPDATE 4/12/2013: Seems you can do all this using PowerShell: "Test-ComputerSecureChannel -Repair". Thanks Alexey for pointing this out - learn something new every day!
-Gary
Announcing My SharePoint 2013 Custom Cmdlets
I’ve been putting this off for quite a while but I’ve finally pushed out a SharePoint 2013 build of my custom cmdlets. The reason it took so long was because I had to make a fair bit of changes to my existing stuff so that it would be easier to maintain both builds going forward. Specifically I needed to change the namespace of all the classes (which had 2010 in them) and I wanted to use a different name for the WSPs so the version wasn’t included in it either. So now I have just one WSP name for the SharePoint 2010 and SharePoint 2013 cmdlets for both Server and Foundation: Lapointe.SharePoint.PowerShell.wsp. If you previously had my old 2010 cmdlets deployed you’ll need to fully retract them before installing this new build (technically you can rename the new WSP file to the old name but I’d rather you embrace the change and just suck it up and do the dang retraction – it only takes a minute, so don’t be lazy!)
I’ve updated my downloads page to point to the correct WSP for each environment and I’ve deleted the old WSPs so if you were foolishly linking directly to my WSPs (please don’t do that) then your links are now broken. I’ve also posted the source code which has been upgraded for Visual Studio 2012 and contains a separate project for SharePoint 2010 and SharePoint 2013 (in addition to my custom MAML generator).
Another change I’ve made to help me manage these custom cmdlets better was that I got rid of my old command index page and created a new app for displaying the cmdlet details (the old page is still there, it just redirects to the new page). This new page is actually built dynamically using the PowerShell help file that I generate dynamically from the actual cmdlet classes – so for me this is pretty cool because now all the PowerShell help documentation and online documentation of each cmdlet is generated automatically so I don’t have to do anything other than provide the actual help details in the cmdlet classes themselves and I don’t do anything special to keep them in sync (just copy the help files up to my site).
At present both the SharePoint 2010 and SharePoint 2013 cmdlets are exactly the same (except for a few in code changes to make it work with 2013). I have, however, added a few new cmdlets from what was previously available and I’ll be added some more in the coming weeks (I’m hoping to start converting some of my more frequently used utility scripts and functions to cmdlets so I don’t have to keep hunting around for them). There is however, one breaking change (well, two to be exact) – the first is that I had to rename my Repair-SPSite cmdlet to Repair-SPMigratedSite because SharePoint 2013 introduces a cmdlet of the same name; the second was that I removed the gl-applytheme STSADM command as the functionality that it provided was specific to SharePoint 2007 and is no longer available (but I’m not really supporting the STSADM stuff anyways and contemplated removing them entirely but decided to leave them in, for now).
I haven’t had time to do a ton of testing of all the cmdlets on SharePoint 2013 - there’s just too many of them and I don’t make any money on these things so it’s not a high priority – so, as always, your feedback is appreciated and I’ll do my best to fix any bugs that are discovered but I can’t promise when I’ll get to them.
Happy PowerShelling!
-Gary
Using PowerShell to Manage SharePoint 2013 Online
When SharePoint 2010 was released we had hundreds of cmdlets available for our on-premises deployments but when it came to Office365 we only had cmdlets available for manipulating our subscription details, users in AD, and Exchange Online (http://onlinehelp.microsoft.com/en-us/office365-enterprises/hh125002.aspx). With the release of SharePoint 2013 as part of the Office365 offering we now have the ability to use PowerShell to manipulate our SharePoint Site Collections in the cloud. The capabilities are somewhat limited in that our abilities are limited to manipulating Site Collections, but it’s a start. In this article I’ll walk through the available cmdlets and detail some examples of how to use them.
Getting Started
Before you can start working with the SharePoint Online cmdlets you must first download those cmdlets. Having the cmdlets as a separate download (separate from SharePoint on-premises that is) allows you to use any machine to run the cmdlets. All we have to do is make sure we have PowerShell V3 installed along with the .NET Framework v4 or better (required by PowerShell V3). With these prerequisites in place simply download and install the cmdlets from Microsoft: http://www.microsoft.com/en-us/download/details.aspx?id=35588.
Once installed open the SharePoint Online Management Shell by clicking Start > All Programs > SharePoint Online Management Shell > SharePoint Online Management Shell. Just like with the SharePoint Management Shell for on-premises deployments the SharePoint Online Management Shell is just a standard PowerShell window. You can see this by looking at the target attribute of the shortcut properties:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoExit -Command "Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking;"
As you can see from the shortcut, a PowerShell module is loaded: Microsoft.Online.SharePoint.PowerShell. Unlike with SharePoint on-premises, this is not a snap-in but a module, which is basically the new, better way of loading cmdlets. The nice thing about this is that, like with the snap-in, you can load the module in any PowerShell window and are not limited to using the SharePoint Online Management Shell. (The -DisableNameChecking parameter of the Import-Module cmdlet simply tells PowerShell to not bother checking for valid verbs used by the loaded cmdlets and avoids warnings that are generated by the fact that the module does use an invalid verb – specifically, Upgrade). Note that unlike with the snap-in, there’s no need to specify the threading options because the cmdlets don’t use any unmanaged resources which need disposal.
Getting Connected
Now that you’ve got the SharePoint Online Management Shell installed you are now ready to connect to your tenant administration site. This initial connection is necessary to establish a connection context which stores the URL of the tenant administration site and the credentials used to connect to the site. To establish the connection use the Connect-SPOService cmdlet:
Connect-SPOService -Url https://contoso-admin.sharepoint.com -Credential gary@contoso.com
Running this cmdlet basically just stores a Microsoft.SharePoint.Client.ClientContext object in an internal static variable (or a sub-classed version of it at least). Future cmdlet calls then use this object to connect to the site, thereby negating the need to constantly provide the URL and credentials. (The downside of this object being internal is that we can’t extend the cmdlets to add our own, unless we want to use reflection which would be unsupported). To clear this internal variable (and make the session secure against other code that may attempt to use it) you can run the Disconnect-SPOService cmdlet. This cmdlet takes no parameters.
One tip to help make loading the module and then connecting to the site a tad bit easier would be to encapsulate the commands into a single helper method. In the following example I created a simple helper method named Connect-SPOSite which takes in the user and the tenant administration site to connect to, however, I default those values so that I only have to provide the password when I wish to get connected. I then put this method in my profile file (which you can edit by typing “ise $profile.CurrentUsersAllHosts”):
function Connect-SPOSite() {
param (
$user = "gary@contoso.com",
$site = "https://contoso-admin.sharepoint.com"
)
if ((Get-Module Microsoft.Online.SharePoint.PowerShell).Count -eq 0) {
Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
}
$cred = Get-Credential $user
Connect-SPOService -Url $site -Credential $cred
}
SPO Cmdlets
Now that you’re connected you can finally do something interesting. First let’s look at the cmdlets that are available. There are currently only 30 cmdlets available to us and you can see the list of those cmdlets by typing “Get-Command -Module Microsoft.Online.SharePoint.PowerShell”. Note that all of the cmdlets will have a noun which starts with “SPO”. The following is a list of all the available cmdlets:
- Site Groups
- Get-SPOSiteGroup – Get a Site Collection Site Group.
- New-SPOSiteGroup – Create a new Site Collection Site Group.
- Remove-SPOSiteGroup – Remove an existing Site Collection Site Group.
- Set-SPOSiteGroup – Set the permission level and/or owner of an existing Site Collection Site Group.
- Users
- Add-SPOUser – Add a user to an existing Site Collection Site Group.
- Get-SPOUser – Get an existing user.
- Remove-SPOUser – Remove an existing user from the Site Collection or from an existing Site Collection Group.
- Set-SPOUser – Set whether an existing Site Collection user is a Site Collection administrator or not.
- Get-SPOExternalUser – Returns external users from the tenant’s folder.
- Remove-SPOExternalUser - Removes a collection of external users from the tenancy's folder.
- Site Collections
- Get-SPOSite – Retrieve an existing Site Collection.
- New-SPOSite – Create a new Site Collection.
- Remove-SPOSite – Move an existing Site Collection to the recycle bin.
- Repair-SPOSite – If any failed Site Collection scoped health check rules can perform an automatic repair then initiate the repair.
- Set-SPOSite – Set the Owner, Title, Storage Quota, Storage Quota Warning Level, Resource Quota, Resource Quota Warning Level, Locale ID, and/or whether the Site Collection allows Self Service Upgrade.
- Test-SPOSite – Run all Site Collection health check rules against the specified Site Collection.
- Upgrade-SPOSite – Upgrade the Site Collection. This can do a build-to-build (e.g., RTM to SP1) upgrade or a version-to-version (e.g., 2010 to 2013) upgrade. Use the -VersionUpgrade parameter for a version-to-version upgrade.
- Get-SPODeletedSite – Get a Site Collection from the recycle bin.
- Remove-SPODeletedSite – Remove a Site Collection from the recycle bin (permanently deletes it).
- Restore-SPODeletedSite – Restores an item from the recycle bin.
- Request-SPOUpgradeEvaluationSite - Creates a copy of the specified Site Collection and performs an upgrade on that copy.
- Get-SPOWebTemplate – Get a list of all available web templates.
- Tenants
- Get-SPOTenant – Retrieves information about the subscription tenant. This includes the Storage Quota size, Storage Quota Allocated (used), Resource Quota size, Resource Quota Allocated (used), Compatibility Range (14-14, 14-15, or 15-15), whether External Services are enabled, and the No Access Redirect URL.
- Get-SPOTenantLogEntry – Retrieves company logs (as of B2 only BCS logs are available).
- Get-SPOTenantLogLastAvailableTimeInUtc – Returns the time when the logs are collected.
- Set-SPOTenant – Sets the Minimum and Maximum Compatibility Level, whether External Services are enabled, and the No Access Redirect URL.
- Apps
- Get-SPOAppErrors – Returns application errors.
- Get-SPOAppInfo – Returns all installed applications.
- Connections
- Connect-SPOService – Establishes a connection to a SharePoint Online Tenant Administration Site.
- Disconnect-SPOService – Clears an existing connection.
It’s important to understand that when working with all of the cmdlets which retrieve an object you will only ever be getting a simple data object which has no ability to act upon the source object. For example, the Get-SPOSite cmdlet returns an SPOSite object which has no methods and, though some properties do have a setter, they are completely useless and the object and its properties are not used by any other cmdlet (such as Set-SPOSite). This also means that there is no ability to access child objects (such as SPWeb or SPList items, to name just a couple).
The other thing to note is the lack of cmdlets for items at a lower scope than the Site Collection. Specifically there is no Get-SPOWeb or Get-SPOList cmdlet or anything of the sort. This can be potentially be quite limiting for most real world uses of PowerShell and, in my opinion, limit the usefulness of these new cmdlets to just the initial setup of a subscription and not the long-term maintenance of the subscription.
In the following examples I’ll walk through some examples of just a few of the more common cmdlets so that you can get an idea of the general usage of them.
Get a Site Collection
To see the list of Site Collections associated with a subscription or to see the details for a specific Site Collection use the Get-SPOSite cmdlet. This cmdlet has two parameter sets:
Get-SPOSite [[-Identity] <SpoSitePipeBind>] [-Limit <string>] [-Detailed] [<CommonParameters>]
Get-SPOSite [-Filter <string>] [-Limit <string>] [-Detailed] [<CommonParameters>]
The parameter that you’ll want to pay the most attention to is the -Detailed parameter. If this optional switch parameter is omitted then the SPOSite objects that will be returned will only have their properties partially set. Now you might think that this is in order to reduce the traffic between the server and the client, however, all the properties are still sent over the wire, they simply have default values for everything other than a couple core properties (so I would assume the only performance improvement would be in the query on the server). You can see the difference in the values that are returned by looking at a Site Collection with and without the details:
PS C:\> Get-SPOSite https://contoso.sharepoint.com/ | select *
LastContentModifiedDate : 1/1/0001 12:00:00 AM
Status : Active
ResourceUsageCurrent : 0
ResourceUsageAverage : 0
StorageUsageCurrent : 0
LockIssue :
WebsCount : 0
CompatibilityLevel : 0
Url : https://contoso.sharepoint.com/
LocaleId : 1033
LockState : Unlock
Owner :
StorageQuota : 1000
StorageQuotaWarningLevel : 0
ResourceQuota : 300
ResourceQuotaWarningLevel : 255
Template : EHS#1
Title :
AllowSelfServiceUpgrade : False
PS C:\> Get-SPOSite https://contoso.sharepoint.com/ -Detailed | select *
LastContentModifiedDate : 11/2/2012 4:58:50 AM
Status : Active
ResourceUsageCurrent : 0
ResourceUsageAverage : 0
StorageUsageCurrent : 1
LockIssue :
WebsCount : 1
CompatibilityLevel : 15
Url : https://contoso.sharepoint.com/
LocaleId : 1033
LockState : Unlock
Owner : s-1-5-21-3176901541-3072848581-1985638908-189897
StorageQuota : 1000
StorageQuotaWarningLevel : 0
ResourceQuota : 300
ResourceQuotaWarningLevel : 255
Template : STS#0
Title : Contoso Team Site
AllowSelfServiceUpgrade : True
Create a Site Collection
When we’re ready to create a Site Collection we can use the New-SPOSite cmdlet. This cmdlet is very similar to the New-SPSite cmdlet that we have for on-premises deployments. The following shows the syntax for the cmdlet:
New-SPOSite [-Url] <UrlCmdletPipeBind> -Owner <string> -StorageQuota <long> [-Title <string>] [-Template <string>] [-LocaleId <uint32>] [-CompatibilityLevel <int>] [-ResourceQuota <double>] [-TimeZoneId <int>] [-NoWait] [<CommonParameters>]
The following example demonstrates how we would call the cmdlet to create a new Site Collection called “Test”:
New-SPOSite -Url https://contoso.sharepoint.com/sites/Test -Title "Test" -Owner "gary@contoso.com" -Template "STS#0" -TimeZoneId 10 -StorageQuota 100
Note that the cmdlet also takes in a -NoWait parameter; this parameter tells the cmdlet to return immediately and not wait for the creation of the Site Collection to complete. If not specified then the cmdlet will poll the environment until it indicates that the Site Collection has been created. Using the -NoWait parameter is useful, however, when creating batches of Site Collections thereby allowing the operations to run asynchronously.
One issue you might bump into is in knowing which templates are available for your use. In the preceding example we are using the “STS#0” template, however, there are other templates available for our use and we can discover them using the Get-SPOWebTemplate cmdlet, as shown below:
PS C:\> Get-SPOWebTemplate
Name Title LocaleId CompatibilityLevel
---- ----- -------- ------------------
STS#0 Team Site 1033 15
BLOG#0 Blog 1033 15
BDR#0 Document Center 1033 15
DEV#0 Developer Site 1033 15
DOCMARKETPLACESITE#0 Academic Library 1033 15
OFFILE#1 Records Center 1033 15
EHS#1 Team Site - SharePoint Onl... 1033 15
BICenterSite#0 Business Intelligence Center 1033 15
SRCHCEN#0 Enterprise Search Center 1033 15
BLANKINTERNETCONTAINER#0 Publishing Portal 1033 15
ENTERWIKI#0 Enterprise Wiki 1033 15
PROJECTSITE#0 Project Site 1033 15
COMMUNITY#0 Community Site 1033 15
COMMUNITYPORTAL#0 Community Portal 1033 15
SRCHCENTERLITE#0 Basic Search Center 1033 15
visprus#0 Visio Process Repository 1033 15
Give Access to a Site Collection
Once your Site Collection has been created you may wish to grant users access to the Site Collection. First you may want to create a new SharePoint group (if an appropriate one is not already present) and then you may want to add users to that group (or an existing one). To accomplish these tasks you use the New-SPOSiteGroup cmdlet and the Add-SPOUser cmdlet, respectively.
Looking at the New-SPOSiteGroup cmdlet you can see that it takes only three parameters, the name of the group to create, the permissions to add to the group, and the Site Collection within which to create the group:
New-SPOSiteGroup [-Site] <SpoSitePipeBind> [-Group] <string> [-PermissionLevels] <string[]> [<CommonParameters>]
In the following example I’m creating a new group named “Designers” and giving it the “Design” permission:
$site = Get-SPOSite https://contoso.sharepoint.com/sites/Test -Detailed
$group = New-SPOSiteGroup -Site $site -Group "Designers" -PermissionLevels "Design“
(Note that I’m seeing the Site Collection to a variable just to keep the commands a little shorter, you could just as easily provide the string URL directly).
Once the group is created we can then use the Add-SPOUser cmdlet to add a user to the group. Like the New-SPOSiteGroup cmdlet this cmdlet takes three parameters:
Add-SPOUser [-Site] <SpoSitePipeBind> [-LoginName] <string> [-Group] <string> [<CommonParameters>]
In the following example I’m adding a new user to the previously created group:
Add-SPOUser -Site $site -Group $group.LoginName -LoginName "tessa@contoso.com"
Delete and Recover a Site Collection
If you’ve created a Site Collection that you now wish to delete you can easily accomplish this by using the Remove-SPOSite cmdlet. When this cmdlet finishes the Site Collection will have been moved to the recycle bin and not actually deleted. If you wish to permanently delete the Site Collection (and thus remove it from the recycle bin) then you must use the Remove-SPODeletedSite cmdlet. So to do a permanent delete it’s actually a two step process, as shown in the example below where I first move the “Test” Site Collection to the recycle bin and then delete it from the recycle bin:
Remove-SPOSite "http://contoso.sharepoint.com/sites/test" -Confirm:$false
Remove-SPODeletedSite -Identity "http://contoso.sharepoint.com/sites/test" -Confirm:$false
If you decide that you’d actually like to restore the Site Collection from the recycle bin you can simply use the Restore-SPODeletedSite cmdlet:
Restore-SPODeletedSite http://contoso.sharepoint.com/sites/test
Both the Remove-SPOSite and the Restore-SPODeletedSite cmdlets accept a -NoWait parameter which you can provide to tell the cmdlet to return immediately.
Parting Thoughts
There are obviously many other cmdlets available to explore (per the previous list), however, I hope that in the simple samples shown in this article you will find that working with the cmdlets is quite easy and fairly intuitive. The key thing to remember is that you are working in a stateless environment so changes to an object such as SPOSite will not affect the actual Site Collection in any way and cmdlets like the Set-SPOSite cmdlet will not honor changes made to the properties as it will use nothing more than the URL property to know which Site Collection you are updating.
Though the existence of these cmdlets is definitely a good start and absolutely better than nothing, I have to say that I’m extraordinarily displeased with the number of available cmdlets and with how the module was implemented. My biggest gripe is that the module is not extensible in any way so if I wish to add cmdlets for the management of SPWeb objects or SPList objects I’d have to create a whole new framework which would require an additional login as I wouldn’t be able to leverage the context object created by Connect-SPOService cmdlet. This results in a severely limiting product that prevents community and ISV generated solutions from “fitting in” to the existing model. Perhaps one day I’ll create my own set of cmdlets to show Microsoft how it should have been done…perhaps one day I’ll have time for such frivolities
.
SharePoint 2013 PowerShell Cmdlets: Changes from Public Preview to RTM
In a recent post I detailed all the PowerShell changes from SharePoint 2010 to SharePoint 2013 Public Preview (part 1, part 2) – well, apparently I should have held off a couple of weeks because I’m now running the RTM version of SharePoint 2013 and have found that they have made a ton more changes. I don’t want to go through all the 2010 to 2013 changes again so instead I’ll just detail what has changed since the Public Preview; these changes include new cmdlets, removed cmdlets, and renamed cmdlets. (Note that some of the removed and new cmdlets may actually just be renamed cmdlets – not worth the effort for to verify them all at this point).
Removed Cmdlets
- Add-SPSocialAppPermissions
- Copy-SPAccessServicesDatabase
- Get-SPTrustedSecurityTokenService
- New-SPTrustedSecurityTokenService
- Remove-SPSocialAppPermissions
- Remove-SPTrustedSecurityTokenService
- Repartition-SPEnterpriseSearchLinksDatabases
- Set-SPSecureStoreSystemAccounts
- Set-SPTrustedSecurityTokenService
New Cmdlets
- Add-SPSecureStoreSystemAccount
- Copy-SPAccessServicesDatabaseCredentials
- Move-SPEnterpriseSearchLinksDatabases
- New-SPOnlineApplicationPrincipalManagementServiceApplicationProxy
- Remove-SPSecureStoreSystemAccount
- Set-SPAppSiteDomain
- Set-SPEnterpriseSearchFileFormatState
- Update-SPDistributedCacheSize
Renamed Cmdlets
- Add-SPDistributedCacheServiceInstanceOnLocalServer => Add-SPDistributedCacheServiceInstance
- Clear-SPAppDeniedEndpoints => Clear-SPAppDeniedEndpointList
- Copy-LocalActivitiesToWorkflowService => Copy-SPActivitiesToWorkflowService
- Get-SPAppAcquisitionSettings => Get-SPAppAcquisitionConfiguration
- Get-SPAppDeniedEndpoints => Get-SPAppDeniedEndpointList
- Get-SPAppDisableSettings => Get-SPAppDisablingConfiguration
- Get-SPAppHostingQuotas => Get-SPAppHostingQuotaConfiguration
- Get-SPAppMarketplaceSettings => Get-SPAppStoreConfiguration
- Get-SPBingMapsBlockInAllLocales => Get-SPBingMapsBlock
- Get-SPSecureStoreSystemAccounts => Get-SPSecureStoreSystemAccount
- Get-TranslationThrottlingSettings => Get-SPTranslationThrottlingSetting
- Get-WorkflowServiceApplicationProxy => Get-SPWorkflowServiceApplicationProxy
- Move-SPSocialComments => Move-SPSocialComment
- New-WorkflowServiceApplicationProxy => New-SPWorkflowServiceApplicationProxy
- Remove-SPDistributedCacheServiceInstanceOnLocalServer => Remove-SPDistributedCacheServiceInstance
- Restart-SPAppInstanceJobs => Restart-SPAppInstanceJob
- Set-SPAppAcquisitionSettings => Set-SPAppAcquisitionConfiguration
- Set-SPAppDisableSettings => Set-SPAppDisablingConfiguration
- Set-SPAppHostingQuotas => Set-SPAppHostingQuotaConfiguration
- Set-SPAppMarketplaceSettings => Set-SPAppStoreConfiguration
- Set-SPBingMapsBlockInAllLocales => Set-SPBingMapsBlock
- Set-TranslationThrottlingSettings => Set-SPTranslationThrottlingSetting
- Stop-SPDistributedCacheServiceInstanceGracefullyOnLocalServer => Stop-SPDistributedCacheServiceInstance
- Update-SPAppCatalogSettings => Update-SPAppCatalogConfiguration
Changed Cmdlets
Backup-SPEnterpriseSearchServiceApplicationIndex
- Added the following new parameter set: Backup-SPEnterpriseSearchServiceApplicationIndex -Abort [-SearchApplication] <SearchServiceApplication> [-BackupHandleFile] <string> [[-Retries] <int>]
Copy-SPActivitiesToWorkflowService
- The “[-Force <bool>]” parameter was added.
Get-SPAccessServicesDatabase
- The “[[-AccessAppsOnly] <bool>]” parameter was added.
Get-SPAppHostingQuotaConfiguration
- The “-Identity” parameter was renamed to “-SiteSubscription”.
Install-SPEduSites
- The “[-OwnerAlias]” parameter was removed.
- The “[-MySiteHost] <SPSitePipeBind>” parameter was added.
- The “[-SearchCenter] <SPSitePipeBind>” parameter was added.
Install-SPSolution
- The “[-AddToLatestVersion]” switch parameter was changed to “[-CompatibilityLevel <string>]”.
Install-SPWebPartPack
- The “[-AddToLatestVersion]” switch parameter was changed to “[-CompatibilityLevel <string>]” for all parameter sets.
New-SPAccessServiceApplication
- The “[-RecoveryPointObjective <int>]” parameter was added to all parameter sets.
New-SPEnterpriseSearchMetadataManagedProperty
- The “[-SafeForAnonymous <bool>]” parameter was added.
New-SPWOPISupressionSetting
- The “[-DocType <string>]” parameter was removed.
- The “[-Extension <string>]” parameter was added.
- The “[-ProgId <string>]” parameter was added.
- The “[-WOPIAction <string>]” parameter was renamed to “[-Action <string>]”.
- The “[-WOPIBinding <SPWopiBindingPipeBind>]” parameter set was removed.
Remove-SPAccessServicesDatabaseServer
- The “[-Force]” switch parameter was added.
Remove-SPWOPISuppressionSetting
- The “[-DocType <string>]” parameter was removed.
- The “[-Extension <string>]” parameter was added.
- The “[-ProgId <string>]” parameter was added.
- The “[-WOPIAction <string>]” parameter was renamed to “[-Action <string>]”.
- A new parameter set accepting only the “[-Identity <string>]” parameter was added.
Set-SPAccessServicesApplication
- The “[-RecoveryPointObjective <int>]” parameter was added.
Set-SPAppHostingQuotaConfiguration
- The “-Identity <SPSiteSubscriptionPipeBind>” parameter was renamed to “-SiteSubscription <SPSiteSubscriptionPipeBind>”.
Set-SPEnterpriseSearchMetadataManagedProperty
- The “[-SafeForAnonymous <bool>]” parameter was added.
Set-SPTranslationServiceApplication
- The “[-MachineTranslationCategory <string>]” parameter was added.
Set-SPWorkManagementServiceApplication
- The “[-NumberOfExchangeJobsPerServer <uint32>]” parameter was removed.
- The “[-MinimumTimeBetweenEwsSyncSubscriptionSearches <timespan>]” parameter was added.
- The “[-NumberOfUsersPerEwsSyncBatch <uint32>]” parameter was added.
- The “[-NumberOfUsersEwsSyncWillProcessAtOnce <uint32>]” parameter was added.
- The “[-NumberOfSubscriptionSyncsPerEwsSyncRun <uint32>]” parameter was added.
Stop-SPDistributedCacheServiceInstance
- The “[-Graceful]” parameter was added.
Uninstall-SPSolution
- The “[-CompatibilityLevel <string>]” parameter was added to all parameter sets.
Uninstall-SPWebPartPack
- The “[-CompatibilityLevel <string>]” parameter was added.
Update-SPRepopulateMicroblogFeedCache
- The “[-SiteUrl <string>]” parameter was added.
- The “-AccountName <string>” parameter is now optional.
Update-SPRepopulateMicroblogLMTCache
- The “[-SiteSubscription <SPSiteSubscriptionPipeBind>]” parameter was removed.
PowerShell V3: A Few of My Favorite Things
Now that SharePoint 2013 has been released to manufacturing and will be available for download soon I figured I’d go ahead and put together a quick post pointing out some of my favorite PowerShell V3 enhancements that you can use to improve your command-line usage of PowerShell as well as your automation scripts.
PowerShell V3 + SharePoint 2010
The first thing I wanted to do before I get into some of the new stuff was to answer a question I’ve seen a lot lately via twitter and forum posts – can I use PowerShell V3 with SharePoint 2010? The simple answer is no, you cannot. PowerShell V3 requires the .NET 4 runtime which is not compatible or supported with SharePoint 2010. This is due to an unmanaged COM component that most of the SharePoint APIs wrap. However, if you have installed PowerShell V3 on your SharePoint 2010 servers you need not fret for you can still use PowerShell, just not any of the new stuff. This is because PowerShell V3 is installed in side-by-side mode which means that you can still load PowerShell V2: simply add the “-version 2” command-line switch to the powershell.exe executable: powershell.exe -version 2.
When you need to work with SharePoint you won’t be able to use the Windows PowerShell ISE or any of the new PowerShell language enhancements but at least you’ll still be able to work, and you’ll be able to leverage the new features for any non-SharePoint work, something that your more savvy IT administrators might be very appreciative of. Also, if you install a third party application like PowerGUI (at least the current version 3.2) it will run using the PowerShell V2 runspace so you still get a nice visual editor for your SharePoint 2010 work and you can use the ISE V3 for non-SharePoint work.
Show-Command
Not too long ago Microsoft released an online tool called the Windows PowerShell Command Builder. This tool allowed users to visually construct a command by dragging and dropping tiles representing nouns and verbs and then filling in the various fields provided by the tool. This proved a great way for folks who have never really worked with PowerShell before to start creating commands that performed useful tasks. The problem is that the tool is limited to the set of cmdlets made available within. So the PowerShell team created what I view as the evolution of this tool: Show-Command (I’ve no idea whether or not they used the online tool as the catalyst for this feature but the timing and similarities are such that it’s easy to assume as much).
Show-Command is a new cmdlet which has a visual interface associated with it. The cmdlet allows you to easily see all the parameter sets associated with a cmdlet via a simple form which you can fill out to construct a cmdlet call. Like the online tool, users who aren’t as familiar with using the command-line can now use a nice and familiar form to construct a call – this can then be copied to the clipboard for pasting into an editor or immediately executed.
If you’re proficient with PowerShell then this is a new feature that you can easily gloss over (I personally don’t see myself using it for anything other than demos) but if you’re among the many who are just getting into it then this can really help you – not just in the usage of cmdlets but also in the discovery of them as one of the additional features is a cmdlet search (simply call Show-Command without any parameters). So you might ask, “if you don’t plan on using it then why is it on your favorites list?” Well, it’s on my favorites list because I spend a lot of time helping first timers find and use cmdlets (often over the phone with no way for me to see what’s actually being typed) and a cmdlet like this will make this much easier for me and those I’m helping.
![]() | ![]() |
Windows PowerShell ISE
Yeah! The ISE now has full intellisense!!! I personally have a horrible memory and I live by intellisense so one of the first things I usually install in any environment is PowerGUI – for one reason only, intellisense. But sometimes I get resistance from administrators when it comes to installing third party products like this; but now that I can get intellisense with the ISE I can avoid the need for PowerGUI entirely (only thing it appears to be missing is the ability to copy with syntax highlighting – very useful for blogging – copying as RTF works great but there’s nothing out of the box for copying as HTML).

UPDATE 10/23/2012: I’ve created an add-on for the ISE that allows you to copy as HTML thus addressing my concern raised above.
Member Enumeration
So we’ve gotten the more obvious changes out of the way, now let’s look at some things that aren’t quite as obvious: member enumeration changes. These changes are subtle but fantastic and make working on the command-line with PowerShell so much nicer (they also make scripts a lot easier to read).
Let’s start with a simple example, suppose you want to output the title of all the SharePoint lists within a Site; using PowerShell V2 you’d write something like this (both lines do the same thing and just demonstrate two different approaches – note that the output, though it looks the same, is not the same because the Select-Object cmdlet creates a custom object with a NoteProperty type):
(Get-SPWeb http://demo).Lists | select Title (Get-SPWeb http://demo).Lists | ForEach-Object {$_.Title}
With PowerShell V3 we can do the same thing but we don’t need to use the pipeline. PowerShell V3 is smart enough to realize that if we have a collection of objects and want to see a property value we can simply wrap the collection in parenthesis and then just add the property that we want to output:
((Get-SPWeb http://demo).Lists).Title
You’re not limited to just the immediate child property either:
((Get-SPWeb http://demo).Lists).RootFolder.Url
The cool thing about this is that you're not limited to outputting property values; you can call methods as well. This is probably not quite as useful but it's still kind of cool. In this example suppose you have an event receiver that runs when items are updated and you need to trigger that event receiver for all items in a list (I have to do this a lot when testing event receivers or when deploying a new event receiver to a list with existing data):
(((Get-SPWeb http://demo).Lists["Documents"]).Items).Update()
Every Object Has a Count Property
Sometimes when you call a cmdlet you don’t know whether you’ll get back one item or multiple items. In PowerShell V2 if you got back a collection you could use the Count property determine how many came back and use this to perform some action (perhaps as a stop index for a for loop); however, if you only got back one object the Count property wasn’t available which could result in your script breaking as calling the Count property would just return $null. With PowerShell V3, however, every object now has a Count property which means that we can do something like the following examples which all return a valid count value:
(Get-SPSite -Limit All).Count (Get-SPSite http://demo/*).Count (Get-SPSite http://demo).Count
Again, it’s subtle but when you’re writing scripts that operate on an indeterminate number of objects you don’t want to have to think about the fact that the Count property could be $null. This simple enhancement means that I don’t have to waste time adding lame $null check could in my scripts (something I often forget about until it bites me in the a$$). Also, when I say every object has the Count property I really do mean every object – that includes the $null object; so in the examples above if any of the Get-SPSite calls return no sites (or $null) then I’ll get a value of zero (0) for the Count property.
Almost Every Object Has an Object Indexer
This enhancement goes hand-in-hand with the previous feature and I don’t think you can mention the one without mentioning the other. Just like with the Count property if you had a command such as “Get-SPSite http://demo/*” which could return back zero or more objects you can use the object indexer to access any of those objects. There is one exception though: you cannot index into $null so if the command returned back zero objects (or $null) then the attempt to index into it would fail so our only real benefit here is that single objects do support the indexer.
(Get-SPSite -Limit All)[0] (Get-SPSite http://demo/*)[0] (Get-SPSite http://demo)[0] #This next one will fail: (Get-SPSite http://doesnotexist)[0]
ForEach Statement Does Not Iterate Over $null
Consider the following example:
function Process-SPSite($sites) { foreach ($site in $sites) { Write-Host "Processing $site" } } Process-SPSite (Get-SPSite http://demo/*)
What would you expect to happen if the call to Get-SPSite didn’t actually return any SPSite objects? Most people would think that the Write-Host statement would never be reached; if you’re using PowerShell V2, you’d be wrong. This means that in PowerShell V2 you have to add a check for a $null object condition:
function Process-SPSite($sites) { foreach ($site in $sites) { if ($site -eq $null) { continue } Write-Host "Processing $site" } } Process-SPSite (Get-SPSite http://demo/*)
In PowerShell V3, however, they’ve fixed this issue and the initial example will work just as expected for the Write-Host statement will not be hit if the input is $null (to my great relief because I always forget about this and inevitably am reminded of it while trying to update a production system where I typically get greeted with a ton of red errors thanks to a $null object that should not be $null).
Workflow
The last new feature I wanted to highlight was the new workflow capabilities. That’s right, workflow! It’s now super easy to write a script which performs complex parallel or sequential operations and you can even turn a workflow into a job that can be run on a schedule. There’s a TON of stuff you can do with this new feature and I could easily write several posts about it but I’m not a PowerShell MVP, I’m a SharePoint MVP so I just want to show one simple example of how you can use this new feature to speed up your scripts a bit (for more about what you can do with it see TechNet: http://technet.microsoft.com/en-us/library/jj134242.aspx).
Often times when I deploy custom code to an environment I typically need to activate (or re-activate) a SharePoint Feature across all Sites or Site Collections; in a large environment this can take a considerable amount of time. What I’d like to be able to do is activate the Features in parallel as there is no dependency from one activation to the other so the only thing preventing me from doing it in parallel in the past was that I didn’t have an easy way to do it (the Enable-SPFeature cmdlet blocks until it’s complete). Thankfully, with PowerShell V3 there’s now a concept of parallel foreach statement. In the following example I’m using the –parallel parameter of the foreach keyword to indicate that I want the contents of the foreach block to run in parallel:

Note that I’m not using the function keyword and instead am using the workflow keyword to tell PowerShell that this is in fact a workflow. A key point is that that the commands that are executed within the workflow are actually workflow activities – NOT CMDLETS! This means that you cannot just slap any old cmdlet call in here – you’ll get a nice error stating that the cmdlet was not packaged as part of the workflow. To use a cmdlet that does not exist as an activity (such as all of the SharePoint cmdlets) we must wrap the calls to that cmdlet in an InlineScript activity (again, this isn’t a cmdlet, it’s a workflow activity). The code within the InlineScript activity actually runs outside of the workflow process, though it is possible to change that behavior (see “Running InlineScript in the Workflow Process” in the following TechNet article: http://technet.microsoft.com/en-us/library/jj574197.aspx).
Another interesting point is that you might notice that I did not pass in the SPSite object and instead passed in the URL of the SPSite. This is because whatever you pass into the workflow must be serializable and SPSite cannot be serialized. One final note, notice that in the call to Enable-SPFeature I’m prefacing the $feature and $url variables with the new $using scope indicator; this is new to PowerShell V3 and allows me to pass a variable from one process to another – I can use this to pass variables to workflow activities or to pass variables to jobs or remote sessions when using remoting.
Conclusion
There are a ton of new features with PowerShell V3 and I’ve only just scratched the surface with this article. You can find lots of great information on TechNet and the PowerShell TechNet Wiki. I’ll also be covering these new features and a few others that I like during my introductory PowerShell session at SPLive! so if you’re planning on going to that conference and would like to see more of this then definitely stop by my session. If you have any of your own favorite features please share them by leaving comment – I’m always interesting in learning what others have found to be useful.
-Gary
SharePoint 2013 Public Preview PowerShell Cmdlets (Part 2)
UPDATE 10/25/2012: See SharePoint 2013 PowerShell Cmdlets: Changes from Public Preview to RTM for additional changes with SharePoint 2013 RTM.
In my last post I identified all the new and removed cmdlets in SharePoint 2013 Public Preview. In this post I will identify all the cmdlets which have changed in some way from SharePoint 2010 to SharePoint 2013. This process was extremely tedious so it’s possible I’ve missed some things (in some cases parameters were just in a different order and in other cases I had to deal with differences in how PowerShell V3 outputs syntax information compared with how PowerShell V2 does it so I basically had to look at well over a thousand lines worth of differences to identify the real differences).
Note: To compile this list I used SharePoint 2010 SP1 with no Cumulative Updates (CU) so it is possible that some of the changes identified are actually available in SharePoint 2010 via a CU. Also, this article is based on the Public Preview of SharePoint 2013 released in July 2012 – it is entirely possible and expected that much of this will change with the RTM version.
Farm / General
Connect-SPConfigurationDatabase
- The “[-SkipRegisterAsDistributedCacheHost]” switch parameter was added.
New-SPConfigurationDatabase
- The “[-SkipRegisterAsDistributedCacheHost]” switch parameter was added.
Get-SPWebTemplate
- The “[-CompatibilityLevel <int>]” parameter was added.
Set-SPDiagnosticConfig
- The “[-AppAnalyticsAutomatedUploadEnabled]” parameter was added.
Set-SPUsageDefinition
- The “[-DaysToKeepUsageFiles <int>]” parameter was added.
- The “[-MaxTotalSizeInBytes <long>]” parameter was added.
Set-SPUsageService
- The “[-UsageLogMaxFileSizeKB <UInt32>]” parameter was added.
Databases
Mount-SPContentDatabase
- The “[-UpdateUserExperience]” switch parameter was removed. Visual upgrade is no longer supported so this parameter is no longer necessary.
- The “[-SkipIntegrityChecks]” switch parameter was added.
- The “[-NoB2BSiteUpgrade]” switch parameter was added.
Test-SPContentDatabase
- The “[-ShowLocation]” switch parameter was added to both parameter sets.
- The “[-ExtendedCheck]” switch parameter was added to both parameter sets.
Update-SPContentDatabase
- The “[-UpdateUserExperience]” switch parameter was removed from both parameter sets.
- The “[-UseSnapshot]” switch parameter was added to both parameter sets.
- The “[-SkipIntegrityChecks]” switch parameter was added to both parameter sets.
- The “[-NoB2BSiteUpgrade]” switch parameter was added to both parameter sets.
Features and Solutions
Enable-SPFeature
- A new parameter set was added which now accepts a “[-CompatibilityLevel <int>]” parameter. Interestingly it doesn’t accept an URL parameter so I’m not sure what the intention is in terms of being able to activate the feature. Betting that this one will change with RTM.
Install-SPFeature
- The “[-CompatibilityLevel <int>]” parameter was added to the default parameter set (the one that takes a “-Path” parameter).
Uninstall-SPFeature
- The “[-CompatibilityLevel <int>]” parameter was added.
Install-SPSolution
- The “[-FullTrustBinDeployment]” switch parameter was added to the default parameter set.
- The “[-AddToLatestVersion]” switch parameter was added to the default parameter set.
Update-SPSolution
- The “[-FullTrustBinDeployment]” switch parameter was added.
Install-SPWebPartPack
- The “[-AddToLatestVersion]” switch parameter was added to all parameter sets.
- The “[-Path <string>]” parameter and corresponding parameter set was removed.
Web Applications, Site Collections, and Sites
Export-SPWeb
- The “[-AppLogFilePath <string>]” parameter was added.
Get-SPSite
- The “[-CompatibilityLevel <int>]” parameter was added to all parameter sets.
New-SPSite
- The “[-CompatibilityLevel <int>]” parameter was added.
- The “[-OverrideCompatibilityRestriction]” switch parameter was added.
Restore-SPSite
- The “[-PreserveSiteID]” switch parameter was added to both parameter sets.
Set-SPSite
- The “[-SharingType <string>]” parameter was added to the default parameter set.
New-SPWebApplication
- The “[-UserSettingsProvider <SPUserSettingsProviderPipeBind>]” parameter was added.
User Profile Services
Add-SPProfileSyncConnection
- The “[-ConnectionUseDisabledFilter <bool>]” parameter was added.
- The “[-ConnectionFilterOutUnlicensed <bool>]” parameter was added.
Remove-SPProfileSyncConnection
- The “[-ConnectionForestName <string>]” parameter was added.
- The “[-ConnectionServerName <string>]” parameter was added.
Remove-SPSiteSubscriptionProfileConfig
- A new parameter set was added which adds “-ServiceContext <SPServiceContextPipeBind>” and removes “[-Identity <SPSiteSubscriptionPipeBind>” and “-ProfileServiceApplicationProxy <SPServiceApplicationProxyPipeBind>”.
Update-SPProfilePhotoStore
- The “[-OldBaseUri <Uri>]” parameter was added.
- The “[-NewBaseUri <Uri>]” parameter was added.
Managed Metadata Services
Clear-SPMetadataWebServicePartitionData
- The “[-Identity <SPSiteSubscriptionPipeBind>]” parameter was added to the existing parameter set.
- A new parameter set was added which accepts a new “[-ServiceContext <SPServiceContextPipeBind>]” parameter and the existing -ServiceProxy parameter.
Export-SPMetadataWebServicePartitionData
- The “[-NoCompression]” switch parameter was added.
New-SPMetadataServiceApplication
- A new parameter set was added which adds the following required parameters to those available in the default parameter set: “-GroupsPerPartition <int> -TermSetsPerPartition <int> -TermsPerPartition <int> -LabelsPerPartition <int> -PropertiesPerPartition <int>”.
- A new parameter set was added which adds the “-DisablePartitionQuota” switch parameter to the default parameter set.
Set-SPMetadataServiceApplication
- A new parameter set was added which adds the following required parameters to those available in the default parameter set: “-GroupsPerPartition <int> -TermSetsPerPartition <int> -TermsPerPartition <int> -LabelsPerPartition <int> -PropertiesPerPartition <int>”.
- A new parameter set was added which adds the “-DisablePartitionQuota” switch parameter to the default parameter set.
Search Services
Get-SPEnterpriseSearchMetadataCategory
- The “[-Tenant <Guid>]” parameter was added.
- The “[-SiteCollection <Guid>]” parameter was added.
Get-SPEnterpriseSearchMetadataCrawledProperty
- The “[-Tenant <Guid>]” parameter was added.
- The “[-SiteCollection <Guid>]” parameter was added.
Get-SPEnterpriseSearchMetadataManagedProperty
- The “[-Tenant <Guid>]” parameter was added.
- The “[-SiteCollection <Guid>]” parameter was added.
Get-SPEnterpriseSearchMetadataMapping
- The “[-Tenant <Guid>]” parameter was added.
- The “[-SiteCollection <Guid>]” parameter was added.
Get-SPEnterpriseSearchQueryAuthority
- The “-Owner <SearchObjectOwner>” required parameter was added.
Get-SPEnterpriseSearchQueryDemoted
- The “-Owner <SearchObjectOwner>” required parameter was added.
Get-SPEnterpriseSearchSuggestionCandidates
- The “-Owner <SearchObjectOwner>” required parameter was added.
- The “[-SourceId <Guid>]” parameter was added.
Get-SPEnterpriseSearchRankingModel
- The “-Owner <SearchObjectOwner>” required parameter was added.
New-SPEnterpriseSearchCrawlComponent
- The “[-CrawlTopology <CrawlTopologyPipeBind>]” parameter was removed.
- The “[-CrawlDatabase <CrawlStorePipeBind>]” parameter was removed.
- The “[-IndexLocation <string>]” parameter was removed.
- The “-SearchTopology <SearchTopologyPipeBind>” required parameter was added.
New-SPEnterpriseSearchCrawlDatabase
- The “[-Dedicated]” switch parameter was removed.
New-SPEnterpriseSearchLanguageResourcePhrase
- The “-Owner <SearchObjectOwner>” required parameter was added.
- The “[-SourceId <Guid>]” parameter was added.
New-SPEnterpriseSearchMetadataCrawledProperty
- The “[-Tenant <Guid>]” parameter was added.
- The “[-SiteCollection <Guid>']” parameter was added.
New-SPEnterpriseSearchMetadataManagedProperty
- The “[-Queryable <bool>]” parameter was added.
- The “[-IncludeInAlertSignature <bool>]” parameter was added.
- The “[-Tenant <Guid>]” parameter was added.
- The “[-SiteCollection <Guid>']” parameter was added.
New-SPEnterpriseSearchMetadataMapping
- The “[-Tenant <Guid>]” parameter was added.
- The “[-SiteCollection <Guid>']” parameter was added.
New-SPEnterpriseSearchQueryAuthority
- The “-Owner <SearchObjectOwner>” required parameter was added.
New-SPEnterpriseSearchQueryDemoted
- The “-Owner <SearchObjectOwner>” required parameter was added.
New-SPEnterpriseSearchRankingModel
- The “-Owner <SearchObjectOwner>” required parameter was added.
New-SPEnterpriseSearchServiceApplication
- The “[-SearchApplicationType <Nullable`1>]” parameter was removed.
Remove-SPEnterpriseSearchMetadataManagedProperty
- The “[-Tenant <Guid>]” parameter was added.
- The “[-SiteCollection <Guid>']” parameter was added.
Remove-SPEnterpriseSearchQueryAuthority
- The “-Owner <SearchObjectOwner>” required parameter was added.
Remove-SPEnterpriseSearchQueryDemoted
- The “-Owner <SearchObjectOwner>” required parameter was added.
Remove-SPEnterpriseSearchRankingModel
- The “-Owner <SearchObjectOwner>” required parameter was added.
Restore-SPEnterpriseSearchServiceApplication
- The “[-AdminApplicationPool <SPIisWebServiceApplicationPoolPipeBind>]” parameter was removed from both parameter sets.
Set-SPEnterpriseSearchCrawlContentSource
- The “[-EnableContinuousCrawls <bool>]” parameter was added to all parameter sets.
Set-SPEnterpriseSearchCrawlDatabase
- The “[-Shared]” parameter was removed.
Set-SPEnterpriseSearchMetadataManagedProperty
- The “[-IncludeInAlertSignature <bool>]” parameter was added.
- The “[-Tenant <Guid>]” parameter was added.
- The “[-SiteCollection <Guid>]” parameter was added.
Set-SPEnterpriseSearchMetadataMapping
- The “[-Tenant <Guid>]” parameter was added.
- The “[-SiteCollection <Guid>]” parameter was added.
Set-SPEnterpriseSearchQueryAuthority
- The “-Owner <SearchObjectOwner>” required parameter was added.
Set-SPEnterpriseSearchRankingModel
- The “-Owner <SearchObjectOwner>” required parameter was added.
Excel Services
New-SPExcelServiceApplication
- The “[-UseEffectiveUserName]” switch parameter was added to both parameter sets.
- The “[-WorkbookModelUsageTracker <string>]” parameter was added to both parameter sets.
- A new parameter set was added which removes the "[-UnattendedAccountApplicationId <string>]” parameter and adds the “[UnattendedServiceAccount <PSCredential>]” parameter. This is a great change as it means we can now easily set the unattended service account just by specifying the credentials rather than trying to figure out how to create the target application.
Set-SPExcelServiceApplication
- The “[-UseEffectiveUserName]” switch parameter was added to both parameter sets.
- The “[-WorkbookModelUsageTracker <string>]” parameter was added to both parameter sets.
- A new parameter set was added which removes the "[-UnattendedAccountApplicationId <string>]” parameter and adds the “[UnattendedServiceAccount <PSCredential>]” parameter. This is the same change we see for the New-SPExcelServiceApplication cmdlet.
PerformancePoint Services
New-SPPerformancePointServiceApplication
- The “[-FilterSearchResultsMax <int>]” parameter was added.
- The “[-UseEffectiveUserName <bool>]” parameter was added.
- The “[-DataSourceUnattendedServiceAccountTargetApplication <string>]” parameter was added.
Set-SPPerformancePointServiceApplication
- The “[-FilterSearchResultsMax <int>]” parameter was added.
- The “[-UseEffectiveUserName <bool>]” parameter was added.
- The “[-DataSourceUnattendedServiceAccountTargetApplication <string>]” parameter was added.
Visio Services
Set-SPVisioPerformance
- The “[-MaxCacheSize <long>]” parameter was added.
Word Conversion Services
Set-SPWordConversionServiceApplication
- The “[-MaximumSyncConversionRequests <int>]” parameter was added.
Trusted Tokens and Trusted Root Authorities
New-SPTrustedIdentityTokenIssuer
- Now supports the “[-WhatIf]” and “[-Confirm]” common switch parameters.
- A new parameter set was added which adds “[-MetadataEndPoint <Uri>]” and removes “[-ImportTrustCertificate <X509Certificate2>]”.
Set-SPTrustedIdentityTokenIssuer
- Now supports the “[-WhatIf]” and “[-Confirm]” common switch parameters.
- A new parameter set was added which adds “[-MetadataEndPoint <Uri>]” and removes “[-Certificate <X509Certificate2>]”.
New-SPTrustedServiceTokenIssuer
- Now supports the “[-WhatIf]” and “[-Confirm]” common switch parameters.
- A new parameter set was added which adds “[-MetadataEndPoint <Uri>]” and removes “[-Certificate <X509Certificate2>]”.
Set-SPTrustedServiceTokenIssuer
- Now supports the “[-WhatIf]” and “[-Confirm]” common switch parameters.
- A new parameter set was added which adds “[-MetadataEndPoint <Uri>]” and removes “[-Certificate <X509Certificate2>]”.
New-SPTrustedRootAuthority
- Now supports the “[-WhatIf]” and “[-Confirm]” common switch parameters.
- A new parameter set was added which adds “[-MetadataEndPoint <Uri>]” and removes “[-Certificate <X509Certificate2>]”.
Set-SPTrustedRootAuthority
- Now supports the “[-WhatIf]” and “[-Confirm]” common switch parameters.
- A new parameter set was added which adds “[-MetadataEndPoint <Uri>]” and removes “[-Certificate <X509Certificate2>]”.
Users
New-SPUser
- The “[-MobileNumber <string>]” parameter was removed.
Set-SPUser
- The “[-MobileNumber <string>]” parameter was removed.
SharePoint 2013 Public Preview PowerShell Cmdlets (Part 1)
UPDATE 10/25/2012: See SharePoint 2013 PowerShell Cmdlets: Changes from Public Preview to RTM for additional changes with SharePoint 2013 RTM.
In this first of two articles I will be identifying the cmdlets that have been removed in SharePoint 2013 Public Preview as well as all the new cmdlets that have been added. In my follow-up article I will identify all the cmdlets which have been changed (a much more tedious exercise).
Note: To compile this list I used SharePoint 2010 SP1 with no Cumulative Updates (CU) so it is possible that some of the changes identified are actually available in SharePoint 2010 via a CU. Also, this article is based on the Public Preview of SharePoint 2013 released in July 2012 – it is entirely possible and expected that much of this will change with the RTM version.
Removed Cmdlets
I think that one of the more interesting changes with SharePoint 2013 Public Preview is not so much the number of new cmdlets that were added (which is significant) but rather the number of cmdlets that existed in SharePoint 2010 and have been removed in the SharePoint 2013 Public Preview, specifically in terms of Enterprise Search which has had 32 (that’s right, 32!) cmdlets removed.
Search
The search architecture in SharePoint 2013 Public Preview has changed significantly and is now much easier to configure using PowerShell (though there are still many gaps and issues with the current version – such as the inability to set database names for several components). Because of the architectural changes most of the cmdlets that were removed pertain to the actual topology:
- Get-SPEnterpriseSearchCrawlTopology
- Get-SPEnterpriseSearchExtendedClickThroughExtractorJobDefinition
- Get-SPEnterpriseSearchExtendedConnectorProperty
- Get-SPEnterpriseSearchExtendedQueryProperty
- Get-SPEnterpriseSearchIndexPartition
- Get-SPEnterpriseSearchPropertyDatabase
- Get-SPEnterpriseSearchQueryComponent
- Get-SPEnterpriseSearchQueryTopology
- Get-SPSearchService
- Get-SPSearchServiceInstance
- New-SPEnterpriseSearchCrawlTopology
- New-SPEnterpriseSearchExtendedConnectorProperty
- New-SPEnterpriseSearchPropertyDatabase
- New-SPEnterpriseSearchQueryComponent
- New-SPEnterpriseSearchQueryTopology
- Ping-SPEnterpriseSearchContentService
- Remove-SPEnterpriseSearchCrawlComponent
- Remove-SPEnterpriseSearchCrawlTopology
- Remove-SPEnterpriseSearchExtendedConnectorProperty
- Remove-SPEnterpriseSearchPropertyDatabase
- Remove-SPEnterpriseSearchQueryComponent
- Remove-SPEnterpriseSearchQueryTopology
- Restart-SPEnterpriseSearchQueryComponent
- Set-SPEnterpriseSearchCrawlTopology
- Set-SPEnterpriseSearchExtendedConnectorProperty
- Set-SPEnterpriseSearchExtendedQueryProperty
- Set-SPEnterpriseSearchIndexPartition
- Set-SPEnterpriseSearchPropertyDatabase
- Set-SPEnterpriseSearchQueryComponent
- Set-SPEnterpriseSearchQueryTopology
- Set-SPSearchService
- Set-SPSearchServiceInstance
Performance Point
There was only one cmdlet removed for PerformancePoint and though I can understand the reasoning for it this one rather annoyed me. My issue with the removal of this cmdlet was when it comes to being able to automate the configuration of PowerPoint or to crawl an existing configuration. Without this cmdlet I can no longer see how the unattended service account for the service application is configured which makes an automated installation difficult as you don’t want to create or set something that is already set (and of course it makes the crawl of an existing installation for documentation purposes impossible).
- Get-SPPerformancePointSecureDataValues
Web Analytics
The Web Analytics service application has been removed and is not a component of the search service. You can see more information about what this change means by looking at the Web Analytics section of this technet article: http://technet.microsoft.com/en-us/library/ff607742(v=office.15).aspx. And of course, with the removal of the service we now no longer have the associated cmdlets.
- Get-SPWebAnalyticsServiceApplication
- Get-SPWebAnalyticsServiceApplicationProxy
- New-SPWebAnalyticsServiceApplication
- New-SPWebAnalyticsServiceApplicationProxy
- Set-SPWebAnalyticsServiceApplication
- Set-SPWebAnalyticsServiceApplicationProxy
Web Templates
This one actually took me by surprise as I hadn’t heard that we wouldn’t be able to install templates in this way anymore. I can honestly say that I’ve never actually used these cmdlets in SharePoint 2010 as I do all my template deployments using SharePoint Solution Packages (WSPs), something I’ve always recommended as a best practice.
- Install-SPWebTemplate
- Set-SPWebTemplate
- Uninstall-SPWebTemplate
New Cmdlets
I was definitely surprised by the number of cmdlets that were removed but I was totally taken aback by the number of cmdlets added: 299! (Ugh, and some of them conflict in name with the custom ones that I’ve created!). When you skim through the list of cmdlets note that some of the Microsoft developers didn’t seem to get the memo that all SharePoint cmdlet nouns start with “SP” – sloppy, very sloppy.
I’m not going to bother describing each of these cmdlets as many are likely to change. To get more information about them see the Windows PowerShell for SharePoint 2013 technet article: http://technet.microsoft.com/en-us/library/ee890108(v=office.15).aspx
Education
There’s a lot of great documentation coming out about SharePoint 2013 Public Preview but what appears to be noticeably missing (at least to me) is the documentation for all of the new education related features that come with this version. I have a particular interest in these features as I’ve done a significant amount of work with local school districts here in Colorado so, needless to say, I intend to create some documentation on this blog for these cmdlets in the near future.
- Add-SPEduClassMember
- Add-SPEduUser
- Get-SPEduServiceSetting
- Install-SPEduSites
- New-SPEduClass
- Remove-SPEduClassMember
- Set-SPEduServiceSetting
SharePoint Apps
Everyone is talking about the new SharePoint 2013 Application model – personally, I’m not sold on it but hey, it’s the new flavor of the month and comes with 46 new cmdlets to learn.
- Add-SPAppDeniedEndpoint
- Clear-SPAppDeniedEndpoints
- Disable-SPAppAutoProvision
- Enable-SPAppAutoProvision
- Export-SPAppPackage
- Get-SPAppAcquisitionSettings
- Get-SPAppAutoProvisionConnection
- Get-SPAppDeniedEndpoints
- Get-SPAppDisableSettings
- Get-SPAppDomain
- Get-SPAppHostingQuotas
- Get-SPAppInstance
- Get-SPAppMarketplaceSettings
- Get-SPAppPrincipal
- Get-SPAppScaleProfile
- Get-SPAppSiteSubscriptionName
- Get-SPAppStateSyncLastRunTime
- Get-SPAppStateUpdateInterval
- Import-SPAppPackage
- Install-SPApp
- New-SPAppManagementServiceApplication
- New-SPAppManagementServiceApplicationProxy
- Register-SPAppPrincipal
- Remove-SPAppDeniedEndpoint
- Remove-SPAppPrincipalPermission
- Restart-SPAppInstanceJobs
- Set-SPAppAcquisitionSettings
- Set-SPAppAutoProvisionConnection
- Set-SPAppDisableSettings
- Set-SPAppDomain
- Set-SPAppHostingQuotas
- Set-SPAppManagementDeploymentId
- Set-SPAppMarketplaceSettings
- Set-SPAppPrincipalPermission
- Set-SPAppScaleProfile
- Set-SPAppSiteSubscriptionName
- Set-SPAppStateUpdateInterval
- Uninstall-SPAppInstance
- Update-SPAppCatalogSettings
- Update-SPAppInstance
- Get-SPInternalAppStateSyncLastRunTime
- Get-SPInternalAppStateUpdateInterval
- Set-SPInternalAppStateUpdateInterval
- Get-SPOfficeStoreAppsDefaultActivation
- Set-SPOfficeStoreAppsDefaultActivation
- New-SPMarketplaceWebServiceApplicationProxy
Search
Okay, so we removed 32 cmdlets and added back 50 – but trust me, provisioning search using PowerShell is considerably easier now. Most of these cmdlets are all about configuring it after you’ve provisioned it and that’s something that is definitely a net positive in my eyes.
- Backup-SPEnterpriseSearchServiceApplicationIndex
- Get-SPEnterpriseSearchContentEnrichmentConfiguration
- Get-SPEnterpriseSearchCrawlLogReadPermission
- Get-SPEnterpriseSearchFileFormat
- Get-SPEnterpriseSearchHostController
- Get-SPEnterpriseSearchLinguisticComponentsStatus
- Get-SPEnterpriseSearchLinksDatabase
- Get-SPEnterpriseSearchOwner
- Get-SPEnterpriseSearchPropertyRule
- Get-SPEnterpriseSearchPropertyRuleCollection
- Get-SPEnterpriseSearchQuerySpellingCorrection
- Get-SPEnterpriseSearchResultItemType
- Get-SPEnterpriseSearchServiceApplicationBackupStore
- Get-SPEnterpriseSearchStatus
- Get-SPEnterpriseSearchTopology
- Get-SPEnterpriseSearchVssDataPath
- Import-SPEnterpriseSearchCustomExtractionDictionary
- Import-SPEnterpriseSearchPopularQueries
- Import-SPEnterpriseSearchThesaurus
- New-SPEnterpriseSearchAdminComponent
- New-SPEnterpriseSearchAnalyticsProcessingComponent
- New-SPEnterpriseSearchContentEnrichmentConfiguration
- New-SPEnterpriseSearchContentProcessingComponent
- New-SPEnterpriseSearchFileFormat
- New-SPEnterpriseSearchIndexComponent
- New-SPEnterpriseSearchLinksDatabase
- New-SPEnterpriseSearchQueryProcessingComponent
- New-SPEnterpriseSearchResultItemType
- New-SPEnterpriseSearchTopology
- Remove-SPEnterpriseSearchComponent
- Remove-SPEnterpriseSearchContentEnrichmentConfiguration
- Remove-SPEnterpriseSearchCrawlLogReadPermission
- Remove-SPEnterpriseSearchFileFormat
- Remove-SPEnterpriseSearchLinksDatabase
- Remove-SPEnterpriseSearchResultItemType
- Remove-SPEnterpriseSearchServiceApplicationSiteSettings
- Remove-SPEnterpriseSearchTenantConfiguration
- Remove-SPEnterpriseSearchTenantSchema
- Remove-SPEnterpriseSearchTopology
- Repartition-SPEnterpriseSearchLinksDatabases
- Restore-SPEnterpriseSearchServiceApplicationIndex
- Set-SPEnterpriseSearchContentEnrichmentConfiguration
- Set-SPEnterpriseSearchCrawlLogReadPermission
- Set-SPEnterpriseSearchLinguisticComponentsStatus
- Set-SPEnterpriseSearchLinksDatabase
- Set-SPEnterpriseSearchPrimaryHostController
- Set-SPEnterpriseSearchQuerySpellingCorrection
- Set-SPEnterpriseSearchResultItemType
- Set-SPEnterpriseSearchTopology
- Upgrade-SPEnterpriseSearchServiceApplicationSiteSettings
Workflow Service
Um, where’s the “SP”? I also find it interesting that the technet documentation only lists one of these and in their place are SharePoint Designer related cmdlets.
- Copy-LocalActivitiesToWorkflowService
- Get-WorkflowServiceApplicationProxy
- New-WorkflowServiceApplicationProxy
- Register-SPWorkflowService
Translation Service
Seriously – what’s with the missing “SP”? I’ve done a fair bit with Variations within SharePoint 2007 and 2010 so I’m definitely interested in these guys – expect to see an article about the new Translation Services in the near future.
- New-SPTranslationServiceApplication
- New-SPTranslationServiceApplicationProxy
- Get-TranslationThrottlingSettings
- Remove-SPTranslationServiceJobHistory
- Set-SPTranslationServiceApplication
- Set-SPTranslationServiceApplicationProxy
- Set-TranslationThrottlingSettings
Access 2013 Services
Access Services is dead! Long live Access Services 2013 – from what I’ve seen it should be much better than the last version. The only question I have is will the name stay the same in the next version of SharePoint or will we be always talking about Access Services 2013 in SharePoint 2016 or 2019 or whatever. Seems like the better approach would have been to ditch the old version and create an upgrade path (they did it with search so why not Access?).
- Copy-SPAccessServicesDatabase
- Get-SPAccessServicesApplication
- Get-SPAccessServicesDatabase
- Get-SPAccessServicesDatabaseServer
- Get-SPAccessServicesDatabaseServerGroup
- Get-SPAccessServicesDatabaseServerGroupMapping
- New-SPAccessServicesApplication
- New-SPAccessServicesApplicationProxy
- New-SPAccessServicesDatabaseServer
- Remove-SPAccessServicesDatabaseServer
- Reset-SPAccessServicesDatabasePassword
- Set-SPAccessServicesApplication
- Set-SPAccessServicesDatabaseServer
- Set-SPAccessServicesDatabaseServerGroupMapping
- New-SPAzureAccessControlServiceApplicationProxy
Business Connectivity Services
Don’t know much about these guys yet.
- Clear-SPBusinessDataCatalogEntityNotificationWeb
- Get-SPBusinessDataCatalogEntityNotificationWeb
- Set-SPBusinessDataCatalogEntityNotificationWeb
- New-SPBECWebServiceApplicationProxy (I’ve no idea what this guy does but if you look at the technet documentation for it there’s a big fat warning stating not to use it so I suspect it will go away with RTM (or perhaps it’s just not stable right now).
- Get-SPODataConnectionSetting
- Get-SPODataConnectionSettingMetadata
- New-SPODataConnectionSetting
- Remove-SPODataConnectionSetting
- Set-SPODataConnectionSetting
- Set-SPODataConnectionSettingMetadata
Reporting Services
Hey, look at that, Reporting Services has become a first class citizen within SharePoint!
- Backup-SPRSEncryptionKey
- Dismount-SPRSDatabase
- Get-SPRSDatabase
- Get-SPRSDatabaseCreationScript
- Get-SPRSDatabaseRightsScript
- Get-SPRSDatabaseUpgradeScript
- Get-SPRSExtension
- Get-SPRSProxyUrl
- Get-SPRSServiceApplication
- Get-SPRSServiceApplicationProxy
- Get-SPRSServiceApplicationServers
- Get-SPRSSite
- Install-SPRSService
- Install-SPRSServiceProxy
- Mount-SPRSDatabase
- New-SPRSDatabase
- New-SPRSExtension
- New-SPRSServiceApplication
- New-SPRSServiceApplicationProxy
- Remove-SPRSDatabase
- Remove-SPRSEncryptedData
- Remove-SPRSExtension
- Remove-SPRSServiceApplication
- Restore-SPRSEncryptionKey
- Set-SPRSDatabase
- Set-SPRSExtension
- Set-SPRSServiceApplication
- Update-SPRSEncryptionKey
PerformancePoint Services
Export. Import. Okay.
- Export-SPPerformancePointContent
- Import-SPPerformancePointContent
PowerPivot
I haven’t looked into these yet but I’m pretty sure they’re all about getting Excel Services and PowerPivot working together (there’s no documentation on them that I can find).
- Get-SPExcelBIServer
- New-SPExcelBIServer
- Remove-SPExcelBIServer
- Set-SPExcelBIServer
PowerPoint Conversion Services
We had Word Conversion Services in SharePoint 2010 and now we have what is basically the same feature for PowerPoint in SharePoint 2013.
- New-SPPowerPointConversionServiceApplication
- New-SPPowerPointConversionServiceApplicationProxy
- Set-SPPowerPointConversionServiceApplication
Work Management Services
The new Work Management Services is all about managing tasks. You can find the technet documentation for these cmdlets here: http://technet.microsoft.com/en-us/library/fp161255(v=office.15).aspx. There’s also a short presentation you can watch here: http://blogs.msdn.com/b/webtamer/archive/2012/08/22/the-brilliance-of-sharepoint-2013-s-new-work-management-service-application.aspx.
- New-SPWorkManagementServiceApplication
- New-SPWorkManagementServiceApplicationProxy
- Set-SPWorkManagementServiceApplication
- Set-SPWorkManagementServiceApplicationProxy
Request Management
My buddy Spence has an article series that he’s been working on regarding Request Management (including some scripts to get it all configured): http://www.harbar.net/articles/sp2013rm1.aspx
- Get-SPRequestManagementSettings
- New-SPRequestManagementRuleCriteria
- Set-SPRequestManagementSettings
- Add-SPRoutingMachineInfo
- Add-SPRoutingMachinePool
- Add-SPRoutingRule
- Get-SPRoutingMachineInfo
- Get-SPRoutingMachinePool
- Get-SPRoutingRule
- Remove-SPRoutingMachineInfo
- Remove-SPRoutingMachinePool
- Remove-SPRoutingRule
- Set-SPRoutingMachineInfo
- Set-SPRoutingMachinePool
- Set-SPRoutingRule
- Add-SPThrottlingRule
- Get-SPThrottlingRule
- Remove-SPThrottlingRule
- Set-SPThrottlingRule
Social
Yeah, lots of new social features in SharePoint 2013 – word is though that you might want to hold off spending too much time on this until after RTM (I could have misheard though).
- Add-SPSocialAppPermissions
- Remove-SPActivityFeedItems
- Remove-SPSocialAppPermissions
- Update-SPRepopulateMicroblogFeedCache
- Update-SPRepopulateMicroblogLMTCache
Site Collections
I would have expected to find these under the “Site Collection cmdlets” section of technet but instead they are under the “Site management cmdlets” section. Note all the SPSiteUrl cmdlets – according to the technet documentation these apply only to Site Collections at the root of a Web Application but, as the big push now is to use host named Site Collections I suspect these will work for them as well and are really intended for them (just speculating thought as I’ve not had time to test any theories).
- Copy-SPSite
- Get-SPSiteUpgradeSessionInfo
- Get-SPSiteURL
- Move-SPDeletedSite
- Remove-SPSiteURL
- Repair-SPSite
- Set-SPSiteURL
- Test-SPSite
Scale Out Databases
Clearly a lot of changes have been made to the underlying database capabilities. I’ve not seen any documentation yet which details the architectural considerations of using scale out databases but if you’re doing any kind of large scale deployment I suggest you look into these guys (http://technet.microsoft.com/en-us/library/ee906544(v=office.15).aspx).
- Add-SPScaleOutDatabase
- Add-SPServerScaleOutDatabase
- Clear-SPScaleOutDatabaseDeletedDataSubRange
- Clear-SPScaleOutDatabaseLog
- Clear-SPScaleOutDatabaseTenantData
- Clear-SPServerScaleOutDatabaseDeletedDataSubRange
- Clear-SPServerScaleOutDatabaseLog
- Clear-SPServerScaleOutDatabaseTenantData
- Export-SPScaleOutDatabaseTenantData
- Export-SPServerScaleOutDatabaseTenantData
- Get-SPScaleOutDatabase
- Get-SPScaleOutDatabaseDataState
- Get-SPScaleOutDatabaseInconsistency
- Get-SPScaleOutDatabaseLogEntry
- Get-SPServerScaleOutDatabase
- Get-SPServerScaleOutDatabaseDataState
- Get-SPServerScaleOutDatabaseInconsistency
- Get-SPServerScaleOutDatabaseLogEntry
- Import-SPScaleOutDatabaseTenantData
- Import-SPServerScaleOutDatabaseTenantData
- Remove-SPScaleOutDatabase
- Remove-SPServerScaleOutDatabase
- Set-SPScaleOutDatabaseDataRange
- Set-SPScaleOutDatabaseDataSubRange
- Set-SPServerScaleOutDatabaseDataRange
- Set-SPServerScaleOutDatabaseDataSubRange
- Split-SPScaleOutDatabase
- Split-SPServerScaleOutDatabase
Licensing
This is actually a pretty cool change. Think about scenarios where you have some users who need Enterprise features and some who only need Standard features; with SharePoint 2010 you probably just bought everyone an Enterprise CAL or you just used the product illegally and let Standard users utilize Enterprise features because there was no good way to enforce it (you could use feature sets but few people have the necessary governance in place to enforce it’s proper use). With SharePoint 2013 you can now map a user to a specific license type thereby blocking access to feature that they are not licensed to use. You can find more information about this on technet.
- Add-SPUserLicenseMapping
- Disable-SPUserLicensing
- Enable-SPUserLicensing
- Get-SPUserLicense
- Get-SPUserLicenseMapping
- Get-SPUserLicensing
- New-SPUserLicenseMapping
- Remove-SPUserLicenseMapping
Cache
There was all kinds of issues with how caching was done in previous versions of SharePoint so to address those issues we now have a new distributed caching service. Note that this isn’t a ground up new product – the SharePoint team is leveraging Windows Server AppFrabric. You can find more information about configuring the service on technet.
- Add-SPDistributedCacheServiceInstanceOnLocalServer
- Clear-SPDistributedCacheItem
- Get-SPDistributedCacheClientSetting
- Remove-SPDistributedCacheServiceInstanceOnLocalServer
- Set-SPDistributedCacheClientSetting
- Stop-SPDistributedCacheServiceInstanceGracefullyOnLocalServer
Bing (or, Geolocation Fields)
There’s a new geolocation field type in SharePoint 2013 that can be used to store longitude and latitude coordinates that can then be rendered on a Bing map. You can find more information about using and configuring this field on technet.
- Get-SPBingMapsBlockInAllLocales
- Get-SPBingMapsKey
- Set-SPBingMapsBlockInAllLocales
- Set-SPBingMapsKey
Upgrade
In-place upgrade is no longer an option with SharePoint 2013 (this is a good thing!). And thankfully the team has added some additional cmdlets to help manage the upgrade process so we have more visibility into the process and I don’t have to remember psconfig command line switches.
- Get-SPPendingUpgradeActions
- Get-SPUpgradeActions
- Remove-SPSiteUpgradeSessionInfo
- Request-SPUpgradeEvaluationSite
- Upgrade-SPFarm
- Upgrade-SPSite
Security Related
- Get-SPAuthenticationRealm
- Set-SPAuthenticationRealm
- Get-SPClaimTypeEncoding
- New-SPClaimTypeEncoding
- Get-SPSecureStoreSystemAccounts
- Set-SPSecureStoreSystemAccounts
- Get-SPTrustedSecurityTokenIssuer
- Get-SPTrustedSecurityTokenService
- New-SPTrustedSecurityTokenIssuer
- New-SPTrustedSecurityTokenService
- Remove-SPTrustedSecurityTokenIssuer
- Remove-SPTrustedSecurityTokenService
- Set-SPTrustedSecurityTokenIssuer
- Set-SPTrustedSecurityTokenService
- Convert-SPWebApplication
IRM Settings
- Get-SPIRMSettings
- Set-SPIRMSettings
- Get-SPSiteSubscriptionIRMConfig
- Set-SPSiteSubscriptionIRMConfig
User Settings Provider
- Get-SPUserSettingsProvider
- Get-SPUserSettingsProviderManager
- New-SPUserSettingsProvider
- Remove-SPUserSettingsProvider
Web Application Open Platform Interface (WOPI)
Office Web Applications (OWA) is no longer a SharePoint add-on and instead is a standalone product. So now, instead of all the cmdlets to manage OWA we have a bunch of cmdlets to manage WOPI – which is basically the open protocol that the new Office Web Applications uses. With these cmdlets we can connect our SharePoint Farm to Office Web Applications. (Every time I see WOPI I think of WOPR in War Games – “Would you like to play a game?”).
- Get-SPWOPIBinding
- Get-SPWOPISuppressionSetting
- Get-SPWOPIZone
- New-SPWOPIBinding
- New-SPWOPISuppressionSetting
- Remove-SPWOPIBinding
- Remove-SPWOPISuppressionSetting
- Set-SPWOPIBinding
- Set-SPWOPIZone
- Update-SPWOPIProofKey
Diagnostics
This is cool if you do a lot of scripting and want all of your diagnostic information generated by your script to have the same Correlation ID.
- Start-SPDiagnosticsSession
- Stop-SPDiagnosticsSession
“Stamping” PDF Files Downloaded from SharePoint 2010
First off I want to clarify that the subject of this post is not my idea as it is something that my friend Roman Kobzarev put together for his company and I merely assisted with getting the code to work. The problem that Roman was trying to solve was that his company provided numerous PDF files that registered/paying members could download and, unfortunately, they were finding some of those files being posted to various other sites without their permission; so in an attempt to at least discourage this they wanted to stamp the PDF files with some information about the user who downloaded the file.
There are various ways in which this problem can be solved but perhaps one of the simpler approaches, and the approach outlined here, was to create an HTTP Handler which intercepted requests for any PDF files and then simply retrieve the file from SharePoint, modify it, and then send it on its way. The cool thing about this approach and the pattern shown here is that it can easily be applied to any file type which requires some user or request specific modifications applied to it.
Before I get to the actual code I want to point out one third party dependency that we used: iTextSharp. This is an open source .NET library for PDF generation and manipulation. There are many options available when looking to manipulate PDF files and in this case this one was chosen due to its cost (free). So let’s get to the code.
In terms of code there really isn’t that much which is what makes this such a nice solution. The first piece is the actual implementation of the IHttpHandler interface:
using System.IO; using System.Web; using Microsoft.SharePoint; using iTextSharp.text; using iTextSharp.text.pdf; namespace Aptillon.SharePoint.PDFWatermark { public class PDFWatermarkHttpHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { SPFile file = SPContext.Current.Web.GetFile(context.Request.Url.ToString()); byte[] content = file.OpenBinary(); SPUser currentUser = SPContext.Current.Web.CurrentUser; string watermark = null; if (currentUser != null) watermark = "This download was specially prepared for " + currentUser.Name; if (watermark != null) { PdfReader pdfReader = new PdfReader(content); using (MemoryStream outputStream = new MemoryStream()) using (PdfStamper pdfStamper = new PdfStamper(pdfReader, outputStream)) { for (int pageIndex = 1; pageIndex <= pdfReader.NumberOfPages; pageIndex++) { //Rectangle class in iText represent geometric representation... //in this case, rectangle object would contain page geometry Rectangle pageRectangle = pdfReader.GetPageSizeWithRotation(pageIndex); //PdfContentByte object contains graphics and text content of page returned by PdfStamper PdfContentByte pdfData = pdfStamper.GetUnderContent(pageIndex); //create font size for watermark pdfData.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 8); //create new graphics state and assign opacity PdfGState graphicsState = new PdfGState(); graphicsState.FillOpacity = 0.4F; //set graphics state to PdfContentByte pdfData.SetGState(graphicsState); //indicates start of writing of text pdfData.BeginText(); //show text as per position and rotation pdfData.ShowTextAligned(Element.ALIGN_CENTER, watermark, pageRectangle.Width / 4, pageRectangle.Height / 44, 0); //call endText to invalid font set pdfData.EndText(); } pdfStamper.Close(); content = outputStream.ToArray(); } } context.Response.ContentType = "application/pdf"; context.Response.BinaryWrite(content); context.Response.End(); } public bool IsReusable { get { return false; } } } }
As you can see from the previous code listing, the bulk of the code involves the actual processing of the PDF file but the core SharePoint specific piece is in the beginning of the ProcessRequest() method where we use the SPContext.Current.Web.GetFile() method to retrieve the actual file requested and then, if we can get an actual SPUser object, we create a simple message that will be added to the bottom of the PDF. I’m not going to cover what’s happening with the iTextSharp objects as the point of this article is to demonstrate the pattern which can easily be applied to other file types and not how to use iTextSharp.
To deploy this class I created an empty SharePoint 2010 project using Visual Studio 2010 and added the file to the project. I then created a new Web Application scoped Feature which I use to add the appropriate web.config settings which will register the HTTP Handler. The following screenshot shows the final project structure:

Note that I also added the iTextSharp.dll to the project and added it as an additional assembly to the package by double clicking the Package.package element and then, in the package designer, click Advanced to add additional assemblies:

Before I show the code for the Web Application Feature I first want to show what settings I set for the Feature after adding it:

When you add a new Feature to a project it’s going to name it Feature1 and set the default scope to Web. The first thing I do is rename the Feature to something meaningful – in this case, because I know I’ll only have the one Feature I go ahead and name it the same as the project name: Aptillon.SharePoint.PDFWatermark (I always follow the same naming convention for my projects, which equate to WSP file names and Features: <Company>.SharePoint.<Something Appropriate for the Contained Functionality>). The next thing I do is change the Deployment Path property for the Feature so that it only uses the Feature name and does not prepend the project name; and finally I set the scope and title of the Feature. Now I’m ready to add my Feature activation event receiver.
The code that I want to include in the event receiver will handle the addition and removal of the web.config handler elements. I do this using the SPWebConfigModification class. Now there’s debate on whether this should be used or not; this is one of those classes where you might say (as my friend Spence Harbar puts it), “Just because you should use it doesn’t mean you can.” The simple explanation for this is that ideally you should be using this class to make web.config modifications but the reality is that this guy is fraught with issues and usually doesn’t work. That said, what I usually do is, where it makes sense, use this class to add and remove my entries but work under the premise that it will probably not work and plan on making these changes manually (or write a timer job which will do what this guy is attempting to do, but that’s out of scope of this article). So here’s the FeatureActivated() and FeatureDeactivating() methods that I use to add and remove the appropriate web.config entries which register the previously defined HTTP Handler:
public override void FeatureActivated(SPFeatureReceiverProperties properties) { string asmDetails = typeof(PDFWatermarkHttpHandler).AssemblyQualifiedName; SPWebApplication webApp = properties.Feature.Parent as SPWebApplication; if (webApp == null) return; SPWebConfigModification modification = new SPWebConfigModification("add[@name=\"PDFWatermark\"]", "configuration/system.webServer/handlers"); modification.Value = string.Format("<add name=\"PDFWatermark\" verb=\"*\" path=\"*.pdf\" type=\"{0}\" preCondition=\"integratedMode\" />", asmDetails); modification.Sequence = 1; modification.Owner = asmDetails; modification.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode; webApp.WebConfigModifications.Add(modification); webApp.Update(); webApp.WebService.ApplyWebConfigModifications(); } public override void FeatureDeactivating(SPFeatureReceiverProperties properties) { string asmDetails = typeof(PDFWatermarkHttpHandler).AssemblyQualifiedName; SPWebApplication webApp = properties.Feature.Parent as SPWebApplication; if (webApp == null) return; List<SPWebConfigModification> configModsFound = new List<SPWebConfigModification>(); Collection<SPWebConfigModification> modsCollection = webApp.WebConfigModifications; for (int i = 0; i < modsCollection.Count; i++) { if (modsCollection[i].Owner == asmDetails) { configModsFound.Add(modsCollection[i]); } } if (configModsFound.Count > 0) { foreach (SPWebConfigModification mod in configModsFound) modsCollection.Remove(mod); webApp.Update(); webApp.WebService.ApplyWebConfigModifications(); } }
With all the code in place I can deploy to my Web Application and now any time a PDF is downloaded I’ll have a nice little message displayed on the bottom of each page. Again, the intent here is to show the simplicity of the pattern and approach – with a little imagination you can easily come up with lots of other uses for this (applying security or password protection to the PDF, adding an image watermark, removing pages based on registration status thus providing “sample” versions, prefilling form fields with user data, adding a version history page, etc.). And of course all this can also be applied to other file types such as the Office files or images (though image handling would take a little more logic to ignore images not coming from document libraries).
Resetting SharePoint 2010 Themes
UPDATE 8/20/2011: I’ve reworked this script and included it as part of my SharePoint 2010 cmdlet downloads. See “Resetting SharePoint 2010 Themes – Part 2, the Reset-SPTheme cmdlet” for details.
One of my current clients is a local school district here in Denver and we (Aptillon) have recently helped them release a new public facing site for the main district office as well as all the schools in the district. The district has chosen a somewhat fixed brand which has had full theming support added so that the individual schools can adjust the color scheme to match the school’s colors. The master page, page layouts, CSS files, and associated images were all deployed to the Farm using various Solution Packages (WSPs). This allows us to make corrections/additions to the brand related files and quickly deploy them to the Farm, thereby updating the district and school sites quite easily. The problem, however, is that the way theming works within SharePoint 2010 is that it makes a copy of all the CSS and image files and stores them in the /_catalogs/theme/Themed/{THEMEID} folder, as shown in the following figure:
Whenever you apply a theme it will copy all the necessary CSS and image files to a new folder in the Themed folder. This means that the site is no longer basing its look and feel off of the Feature deployed files. So if a school has gone in and customized their site to use themes then any updates that we push out to the style sheets and images will be ignored. So I needed a way to effectively “reset” the applied theme after we push out an update to our branding solution. By reset I mean preserve the various color and font settings but re-apply them against the Feature deployed files.
I did some digging with my favorite tool, Reflector, and found that the out of the box theme settings page just uses the Microsoft.SharePoint.Utilities.ThmxTheme class to manipulate the themes. So, after a little experimenting I ended up with some code which will regenerate the current theme using all the source files and the user provided theme settings:
#NOTE: Run in a seperate console instance each time otherwise the changes won't get applied function Reset-SPTheme([Microsoft.SharePoint.PowerShell.SPSitePipeBind]$spSite) { $site = $spSite.Read() try { # Store some variables for later use $tempFolderName = "TEMP" $themedFolderName = "$($site.ServerRelativeUrl)/_catalogs/theme/Themed" $themesUrlForWeb = [Microsoft.SharePoint.Utilities.ThmxTheme]::GetThemeUrlForWeb($site.RootWeb) Write-Host "Old Theme URL: $themesUrlForWeb" # Open the existing theme $webThmxTheme = [Microsoft.SharePoint.Utilities.ThmxTheme]::Open($site, $themesUrlForWeb) # Generate a new theme using the settings defined for the existing theme # (this will generate a temporary theme folder that we'll need to delete) $webThmxTheme.GenerateThemedStyles($true, $site.RootWeb, $tempFolderName) # Apply the newly generated theme to the root web [Microsoft.SharePoint.Utilities.ThmxTheme]::SetThemeUrlForWeb($site.RootWeb, "$themedFolderName/$tempFolderName/theme.thmx", $true) # Delete the TEMP folder created earlier $site.RootWeb.GetFolder("$themedFolderName/$tempFolderName").Delete() # Reset the theme URL just in case it has changed (sometimes it will) $site.Dispose() $site = $spSite.Read() $themesUrlForWeb = [Microsoft.SharePoint.Utilities.ThmxTheme]::GetThemeUrlForWeb($site.RootWeb) Write-Host "New Theme URL: $themesUrlForWeb" # Set all child webs to inherit. if ([Microsoft.SharePoint.Publishing.PublishingWeb]::IsPublishingWeb($site.RootWeb)) { $pubWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($site.RootWeb) $pubWeb.ThemedCssFolderUrl.SetValue($pubWeb.Web.ThemedCssFolderUrl, $true) } else { foreach ($web in $site.AllWebs) { if ($web.isRootWeb) { continue } Write-Host "Setting theme for $($web.ServerRelativeUrl)..." try { [Microsoft.SharePoint.Utilities.ThmxTheme]::SetThemeUrlForWeb($web, $themesUrlForWeb) } finally { $web.Dispose() } } } } finally { if ($site -ne $null) { $site.Dispose() } } }
I saved this to a file named Reset-SPTheme so I can then call the function like so:
. c:\Scripts\Reset-SPTheme.ps1 Reset-SPTheme "http://example.com/"
One odd thing I found, however, is that every time I run this it must be run in a new console instance; otherwise the changes are not picked up (this is basically a combination of a threading and caching issue within the code when executed from a PowerShell context). So remember, start a new PowerShell console every time you need to run this script (yeah, I wasted a couple of hours banging my head against the wall trying to figure that little nugget out).
BTW: I intend to add this to my cmdlet extensions as I believe it will be something I’ll need often so look for an updated build to come out this weekend.

