How PowerShell Works Internally in SharePoint

Background Information:

This article will dig deeper into the internals of PowerShell for SharePoint. It describes how SharePoint specific Cmdlets are defined and provides you with information to extend the default set of PowerShell Cmdlets that are made available by default to SharePoint administrators on a given SharePoint server. I will give an overview of how the various cmdlets and assemblies are defined in the SharePoint internal files, as well as give a quick overview of what these files contain. This article will be using a local SharePoint 2010 environment I have setup for demo purposes, but note that this also applies entirely to any SharePoint 2013 environment as well.

PowerShell Registration Folder:

​With every SharePoint installation, comes a specific folder under C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\ called the Hive. The hive normally contains all physical media files required by the SharePoint product to run properly on the server. A hive folder is always named by the version of the major Office release associated with it. For example, SharePoint 2007, which was associated with the 12th version of Microsoft Office (Office 2007) has a folder called the 12 Hive. For SharePoint 2010, Microsoft decided to jump over number 13 because of bad luck and had a folder called the 14 Hive, and one called the 15 Hive for SharePoint 2013. As mentionned above, in this article we will be using SharePoint 2010 as our base platform, therefore we will be looking at files under the 14 Hive (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\).

20140815-1.png

Figure 1 – Folders contained within the 14 Hive

What we are particularly interested in, is the PowerShell configuration folder found under [Hive]\CONFIG\POWERSHELL. This folder contains various subfolders that each serve a specific purpose. The one we are going to be covering with this article is the Registration folder which contains a list of various XML files that declare the available SharePoint Cmdlets we can use in our PowerShell sessions. By default, whenever you load the Microsoft.SharePoint.PowerShell snapin in a PowerShell console, all of the Cmdlets contained within the XML files in t​he Registration folder are loaded into the current PowerShell session. Figure 2 below shows the default XML files that will be registered for SharePoint 2010 SP2.

20140815-2.png

Figure 2 – Files under the PowerShell Registration folder in a SharePoint installation

​We can see, by the name of the files, that the Cmdlets are divided into various functional files. The core file we are interested in is the one that contains all the Cmdlets definition for Windows SharePoint Services (WSS). WSS used to be the name of SharePoint Foundation in versions prior to SharePoint 2010 and it contains the core of all SharePoint Server operations. Thesecond node contained in that XML file are used to declare the assembly used to retrieve the logic behind the Cmdlets that are declared in the current file. For the Windows SharePoint Services XML file, the assembly is the core SharePoint one Microsoft.SharePoint.PowerShell. This assembly is actually registered in something we developer geeks refer to as the GAC, the Global Assembly Cache. Assemblies that are registered in the GAC can be accessed by Strong name only, meaning that we don’t have to specify their full local paht on disk in order to register them in memory. Figure 3 below shows the node, from the WSS XML file that makes a call out to the Microsoft.SharePoint.PowerShell assembly.

20140815-3.png

Figure 3 – PowerShell XML Registration file registering the Microsoft.SharePoint.PowerShell assembly

If we were to take a look at another PowerShell XML Registration file, OfficeServerCmdlets.xml for example, we would see that we are actually calling out to a different assembly, the Microsoft.Office.Server assembly.

Taking a closer look at that file, we realize that it is simply made up of the same type of tags over and over again. Figure 4 below shows the declaration node for the Get-SPSite Cmdlet we all know and love.

20140815-4.png

Figure 4 – ​Get-SPSite declaration from the Windows SharePoint Services PowerShell XML Registration file

What this tells us is that the Get-SPSite PowerShell cmdlet, when called upon, internally makes a call to the SPCmdletGetSite class inside of the Microsoft.SharePoint.PowerShell assembly. It also provides a link to a second related XML file that contains help related information describing what the cmdlet is actually about.

Adding your Own PowerShell Cmdlets to Extend SharePoint:

As part of the SPPoSh project, my goal had always been to have it plug in seemlessly into an existing SharePoint installation and have it extend the out-of-the-box cmdlet in a way that is almost transparent to the users. In order to achieve this, I had to develop my own PowerShell XML Registration file and have it call upon custom classes I had developped in the SPPoSh assembly. In order for you to be able to automatically register new custom PowerShell cmdlets, you’ll need to add your own custom PowerShell XML Registration file into the Registration folder of your SharePoint installation. By simply adding the file in the folder, PowerShell will take care of picking it up upon loading the SharePoint snapins in a PowerShell session. For SPPoSh what I did was create a new file from scratch and named it SPPoShCmdlets.xml​. For the purpose of this article, I will keep the content of this file to a minimum and will​​​ pretend like we are only declaring the SPPoSh specific Get-SPList cmdlet. Figure 5 shows the content of what my file would look like.

20140815-5.png
Figure 5 – Custom PowerShell cmdlet XML Registration File
From the figure above, we can see, that for the demo’s purpose I have left the <ps:HelpFile> value to point to the default core XML help file. Ideally, you would want to make sure you develop your own custom help file and have it point to it. If we were to read what my file says, it would go somehint like the following: “From a GAC assembly named SPPoSh.Cmdlets, declare a new PowerShell cmdlet called Get-SPList that, when called, will execute the main logic contained in class SPPosh.Cmdlets.Artefacts.Lists.GetSPListCmdlet of the assembly.”
Note: For it to work, you first need to make sure the assembly you are calling (in my case SPPoSh.Cmdlets.dll) is loaded in the .NET 2.x GAC. Having it loaded in the new .NET 4.x GAC is not going to cut it for SharePoint 2010 since it uses .NET 2.0 in the backend.
With this file now in the Registration folder, I can go ahead and lunch a new SharePoint Management Console (or open any PowerShell session and add the SharePoint snapins) and verify that my methods have been properly loaded into memory. If anything went wrong, you’ll get an error message at the beginning of your PowerShell session. Figure 6 below shows a new SharePoint Management (PowerShell) console in which our Get-SPList cmdlet is available by default.
20140815-6.png
Figure 6 – Using the SPPoSh Get-SPList PowerShell cmdlets
​Now this is some neat stuff! Expect more development on the SPPoSh project to come up within the next few months. I am working on an installer that will take care of automatically setting up all required files for the SPPoSh extended SharePoint PowerShell cmdlets to be configured properly!

List All Services in a SharePoint Farm

If you were to manually open Central Administration (pfff who does that now that PowerShell exists), and were to navigate to the System Settings subsection, under the Manage services​ on server option, you would find a list of all services that are available in your SharePoint farm, and their status (Started or Stopped). From that page, you are also provided with the ability to manually turn each service instance On or Off. Using PowerShell, this can also be easily achieved with only a few lines of code.

To begin, we need to get a reference to the current SPServer object. Remember that service instances in the SharePoint world are associated with a specific SharePoint server. If you had a farm with 3 servers in it, you could make a decision to run the Search Service for example on two of them but don’t have it run on the third one. Using the Get-SPServer cmdlet, we retrieve the list of all servers in our farm (see Figure 1).

$servers = Get-SPServer

20140814-1.png

Figure 1 – Retrieving a list of all SharePoint servers in the SharePoint farm using PowerShell

Once the list of SharePoint server is obtained, we can access any SPServer object directly from the collection of server obtained, and then retrieve the ServiceInstances property from it. This will return a collection of SPServiceInstance objects where each item contained in it represent a specific service (see Figure 2).

$services = ​$servers[0].ServiceInstance

20140814-2.png

Figure 2 – Listing all SharePoint Service Instances of a specific SharePoint Server using PowerShell

The status column, even though it shows Online and Disabled as statuses, really represents the Started and Stopped​ statuses we are seeing through the Central Aministration web interface. You can retrieve the instance of a specific service instance by simply Querying the collection object (see Figure 3). For example, if I wanted to retrieve an instance of the Visio Graphis Service I could simply execute the following line of code:

$visioService = ​$services | Where{$_.TypeName -like “*Visio*”}

20140814-3.png

Figure 3 –  Obtaining a reference to the SharePoint Visio Graphics Service Instance using PowerShell

Once you have obtained a reference to a service instance, you can start or stop it by setting its Status property. However, doing so is not as simple as simply setting it to a boolean (true or false). It requires you to actually set it to a Microsoft.SharePoint.Administration.SPObjectStatus object valid status (in string). This object is actually an enumeration of various statuses:

  • ​Online
  • Disabled
  • Provisioning
  • Upgrading​
  • Unprovisioning
  • Offline
We are really only interested in the two first items. In my example (Visio Graphics Service), if I wanted to enable the service on my server, I would do it using the following line of PowerShell code (see Figure 4).
​$visioService.Status = “Online”
20140814-4.png
Figure 4 – ​​Visio Graphics Services Enabled via PowerShell for SharePoint 2013

Querying a SQL Database using PowerShell

As I mentionned in previous blog posts, I am currently messing around with PowerShell for SQL. For all of us newcomers in the PoShSQL world, it can very quickly become overwhelming when we start looking at all the various snapins and modules that are made available to us to interact with Microsoft SQL Server. Today I’d like to discuss a very short script (4 lines) that I have produced and that allows anyone to connect to a database and to execute any SQL Query against it to retrieve data. My script requires that you are executing it on a machine that has Microsoft SQL Server 2008 or greater installed on it. In my case, I am running it from my local machine which has an instance of Microsoft SQL server 2014 installed on.

For the purpose of this demo, I have created a local database named Inventory which contains a table Fruits as shown in Figure 1 below.

20140813-2.png

Figure 1 – Table Fruits shown via the SQL Server Management Studio

My script uses SQL Integrated Security to authenticate my user (local admin account). For my purposes, I have hardcoded the name of the SQL Server Instance, as well as the name of the table I want to execute my SQL Query against. I then ask for the user executing the PowerShell Script to type in the SQL Query to exectue as a parameter. I then pass these three value over to the Invoke-SQLCmd cmdlet provided by the SQL Server Provider snapin. My script looks like the following:

$instance = “localhost\SharePoint”
$dbName = “Inventory”
$query = Read-Host “Query”
Invoke-SQLCmd -Query $query -ServerInstance $instance -Database $dbName

Executing this script will return the values out of my Fruits table as shown in Figure 2. I have passed it the following SQL Query to retrieve all items from my Fruits table: Select * from Fruits

20140813-1.png

Figure 2 – Retrieving values from SQL Server using PowerShell

Enjoy!

Listing Unique Values and Sorting them using PowerShell

I always like to dig deeper into the various products I am using. Today, I wanted to get my hands dirty and start playing with PowerShell for SQL Server. One of the things I wanted to do was to get a figure out how to quickly produce a list of all the various Modules that were currently loaded in one of my PowerShell session. If you ever get started with PowerShell for SQL Server, you’ll soon realize how easy it is to get lost in all the various modules that are made available to you to interact with the database server.

We all know the good old Get-Command PowerShell cmdlet that retruns a complete list of all cmdlets that are currently available in a PowerShell session. You can quickly extend this and only return the list of module names from which each cmdlet belongs to. Something like:

Get-Command | Select ModuleName

Will still return an extensive list, but will ensure it only contains the Modules’ name. What we really want is to get a list of unique values. The Select operation in PowerShell offers a switch called -Unique that will do just that. Then all that is left is to have the list sorted in alphabetical order using the Sort operation and we are done. So my complete PowerShell command will look like the following:

Get-Command | Select ModuleName – Unique | Sort ModuleName

Listing Unique Values and Sorting them using PowerShell

I always like to dig deeper into the various products I am using. Today, I wanted to get my hands dirty and start playing with PowerShell for SQL Server. One of the things I wanted to do was to get a figure out how to quickly produce a list of all the various Modules that were currently loaded in one of my PowerShell session. If you ever get started with PowerShell for SQL Server, you’ll soon realize how easy it is to get lost in all the various modules that are made available to you to interact with the database server.

We all know the good old Get-Command PowerShell cmdlet that retruns a complete list of all cmdlets that are currently available in a PowerShell session. You can quickly extend this and only return the list of module names from which each cmdlet belongs to. Something like:

Get-Command | Select ModuleName

Will still return an extensive list, but will ensure it only contains the Modules’ name. What we really want is to get a list of unique values. The Select operation in PowerShell offers a switch called -Unique that will do just that. Then all that is left is to have the list sorted in alphabetical order using the Sort operation and we are done. So my complete PowerShell command will look like the following:

Get-Command | Select ModuleName – Unique | Sort ModuleName

20140811-01.png