Modify SharePoint web.config using PowerShell

​Assume you are trying to automate changes to one of your SharePoint web application’s web.config file using PowerShell. In order for you to be able to achieve this, you will need to instaiis-certificate-logo.pngntiate a new object from the Microsoft.SharePoint.Administration namespace called SPWebConfigModification. This object will take in several properties such as the path to the key you are trying to modify, the name of your key, its value, the sequence in which it will appear in the parent node, as well as the name of the owner of that key.

 

As an example, assume we are trying to add a new AppSettings key  name “MyContosoLicense” to store information about a license key for a third party we have installed in our farm. Our current web.config file looks like the following:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>  
[…]    
    <appSettings>
      <add key="Key1" value="Value1" />
      <add key="Key2" value="Value2" />
    </appSettings>
 […]
</configuration>
Using the following PowerShell code, we will be able to insert our new "MyContosoLicense" key after the existing key.
$appSettingsModifications = New-Object Microsoft.SharePoint.Administration.SPWebConfigModification
$appSettingsModifications.Path = “configuration/appSettings”
$appSettingsModifications.Name = “add[@key=’MyContosoLicense’][@value=’MyContosoValue’]”
$appSettingsModifications.Value = “<add key=’MyContosoLicense’ value=’MyContosoValue’ />”
$appSettingsModifications.Sequence = 0
$appSettingsModifications.Type = 0       
$appSettingsModifications​.Owner = “Admin”      
 
Once you have created a web.config modification object using the lines of code above, you need to get a reference to the SharePoint Web Application on which you wish to make the changes. Remember that in the context of SharePoint, every web application gets its own web.config file.
 
$webApp = Get-SPWebApplication http://localhost
$​WebConfigModifications.Add($appSettingsModifications)
$webApp.Update()
$webApp.Parent.ApplyWebConfigModifications()
 
The resulting web.config node will be as follow:
 
<?xml version="1.0" encoding="utf-8" ?>
<configuration>  
[…]    
    <appSettings>
      <add key="Key1" value="Value1" />
      <add key="Key2" value="Value2" />
      <add key="MyContosoLicense" value="MyContosoValue" />
    </appSettings>
 […]
</configuration>


Enjoy!
 

Creating Custom PowerShell Cmdlets for SharePoint

Something that a lot of people don’t realize with PowerShell for SharePoint is that it only provides cmdlets down to the list level. Meaning that you do not have any Powershell cmdlets available out-of-the-box to help you interact with Lists and below (e.g. Items, Fields, etc). In order to interact with these, you need to understand the SharePoint Object Model and this very often requires some high level development skills, which unfortunately is not something a lot of IT Pros have. For example, you can use the following cmdlet to get a reference to the root SharePoint web on http://localhost:

​$web = Get-SPWeb http://localhost
But if you wish to get a reference to the library “Documents” that exist under that web, you’ll need to call the List property on the object and reference its collection to get the appropriate reference back (see code below):
​$list = $web.Lists[“Documents”]
​While this may prove to be obvious for some, it is not a syntaxt most administrators will be used to, as it forces you to switch your mindset from a typical scripting logic to an object oriented one. Wouldn’t it be cool if there was a Get-SPList cmdlet available? Well friends, there is always the option to build it our selves, and this is exactly what this blog post will be covering. Off course my goal here is not to steal the thunder from fellow @GLapointe​ who’s been offering a list of such custom cmdlets (including his version of Get-SPList). My goal is to teach you all how to do it yourselves.

​​What do I need?

​A development machine that has both Visual Studio and SharePoint (any version) installed on. Yes, that’s right, there will be Visual Studio development involved. Basically, what we will do is created a new assembly (.dll) file that will be imported into our Powershell session and that will exposed methods as cmdlets (methods such as Get-SPList).

​​​Code

​We will start by creating a new C# Class Library project in Visual Studio. For the sake of this example, I’ve used Visual Studio 2013 with update 2, but really, any version supporting .NET 3.5 will do. The first thing you will need to do with your Visual Studio project is add references to the PowerShell core assemblies. These are System.Management and System.Management.Automation. The first one should be part of the default Visual Studio list of available assemblies in the GAC, while the second one will be located under C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0. ​We also need to make sure we add a reference to the Microsoft.SharePoint assembly because our PowerShell cmdlet will ultimately require us to interact with SharePoint (see Figure 1).
SolExplorerSPPS.png
Figure 1 – Solution Explorer showing referenced Assemblies and default class
Next, we will need to make our main class inherit from the Cmdlet class. This is what will allow Powershell to recognize that the methods and logic included in our class is to be exposed as a cmdlet. For my example, I named my main class GetSPList to make it clear that the code it contain was to expose the Get-SPList cmdlet. The next thing you’ll need to do in you code, is to declare your class as a cmdlet by specifying the verb to use, and the noun. In our case, our verb is “Get” and our noun “SPList, meaning that our cmdlet will be accessed using the Get-SPList method (see blue line below).
​After declaring our class as a cmdlet, we need to specify what parameters our method will accept. This is done by declaring class variables as being cmdlet parameters (see green lines). For each paramter, we will need to mention what their default input order should be, and mention if they are mandatory or not.
​Last but none the least, we need to override the ProcessRecord method (line in orange), which is the method that truly performs an action based on the parameters that were passed. In our case, We will use the URL received to create a new SPWeb object, we will get a reference to a list it contains using either its name (because we’ve specified string as the variable type, we should use GUID if we want to access the list based o a GUID), and will return the list instance.
​​​​using System;

using System.Management;
using System.Management.Automation;
using Microsoft.SharePoint;
 
namespace SPPS
{
    [System.Management.Automation.Cmdlet(System.Management.Automation.VerbsCommon.Get, “SPList”)]
    public class GetSPList:Cmdlet
    {
        [System.Management.Automation.Parameter(Position = 0, Mandatory = true)]
        public string Web;
        [System.Management.Automation.Parameter(Position = 1, Mandatory = true)]
        public string List;
        protected override void ProcessRecord()
        {
            using(SPSite site = new SPSite(this.Web))
            {
                using(SPWeb web = site.OpenWeb())
                {
                    SPList list = web.Lists[this.List];
                    this.WriteObject(list, false);
                }
            }
        }
    }
}​
​​​​​All that is left now is to compile​ our code into a reusable assembly (.dll file). In my case I’ve copied the resulting SPPS.dll file into the C:\Script\ repository on my development machine.

Make PowerShell Use Our Custom Cmdlet

To tell PowerShell to load the logic contained in our custom assembly, we will need to use the Import-Module  and reference the custom .dll. In my case, I will be calling the following line of Powershell to load my assembly in the session:
Import-Module c:\Script\SPPS.dll
Once this is done, I can verify that everything is working as expected by calling the Get-SPList cmdlet that is contained within that assembly. Figure 2 below shows a PowerShell session in which I have loaded my custom assembly and used my custom PowerShell cmdlet to get a reference to the library “Documents” located at the root of the http://localhost site collection.
SPPSGetListInAction.png
Figure 2 – Using a custom PowerShell cmdlet to get a reference to a SharePoint list.
What we’ve just learned in this article is extremely powerfull and can be extended to bridge many gaps that currently exist in the SharePoint/PowerShell world. Before you dig too deep in this, however, I recommend taking a look at what Gary Lapointe has already made available to us all on his site (visit Gary’s site). Enjoy!

Use PowerShell to Interact with Office 365

One of my biggest frustration with Office 365 over the past few months, is the fact that we are now prohibited from creating new subsites under the main Internet Public facing site collection that is given to us by SharePoint online. Using SharePoint Online Management Shell only gives us 30 PowerShell cmdlets to use, and none of them allow us to create new SPWeb objects. The only option left to create a subsite on an Office 365 ​public site is to write custom code, but custom code also means that this can be archived using PowerShell. Remember that PowerShell is able to leverage all of the .NET framework components. We can then use the .NET Managed Client-Side Object Model (CSOM) of SharePoint and make remote calls to the Office 365 SharePoint Online object model. The following PowerShell script will prompt you to enter the URL of your SharePoint Online public site collection (using the https:// prefix), the credentials for your account, as well as the name and relative URL for this new Web you are trying to create (see Figure 1 for a real-life example).

CreateO365Web.png

Figure 1 – Creating a new Office 365 SharePoint online Web using a custom PowerShell script

Full PowerShell Script:

​​​[System.Reflection.Assembly]::LoadWithPartialName(“Microsoft.SharePoint.Client”)

[System.Reflection.Assembly]::LoadWithPartialName(“Microsoft.SharePoint.Client.Runtime”)
$url = Read-Host -Prompt “Site Collection URL”
$username = Read-Host -Prompt “Username” 
$password = Read-Host -Prompt “Password” -AsSecureString
$webTitle = Read-Host -Prompt “Name of new Web”
$webUrl = Read-Host -Prompt “Relative URL of new Web”
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($url)
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $password)
$webInfo = New-Object Microsoft.SharePoint.Client.WebCreationInformation
$webInfo.Title = $webTitle
$webInfo.Url = $webUrl
$webInfo.WebTemplate = “STS#0”
$webInfo.Language = 1033
$newWeb = $ctx.Web.Webs.Add($webInfo)
$ctx.Web.Update()
$ctx.Load($newWeb)
$ctx.ExecuteQuery()

InfoPath is dead! Long live InfoPath!

Since the release of its 2013 version, Microsoft InfoPath was perseived has having an uncertain future. For those who don’t know, InfoPath is part of the Office suite and allows users to create both on-premises and web forms. Yesterday, the Microsoft Office team officially announced that they were stopping the development on the InfoPath line of product. The tool is scheduled to be replaced by a new product in the near future. Microsoft announced that people attending the SharePoint 2014 Conference will get a sneak peek of what is Microsoft’s vision for form technology. You can read the full announcement made by Microsoft at:griminfopath.jpg

http://blogs.office.com/2014/01/31/update-on-infopath-and-sharepoint-forms/​​​