Sign In
 
 
Go Search
 
SharePoint 2010 PowerShell Permissions Explained

SharePoint 2010 has increased flexibility for administrative privileges of command line operations.  The end result is that there is a bit more complexity in setting up your administrative privileges, so I wanted to create a post to try and clear up administration permissions for SharePoint 2010. 

Foremost, please keep in mind that I’m going to discuss the minimum required privileges for each role—so there are lots of additional configurations; this is the just bare requirements.

First we need to talk about Central Administration, as the different permissions often lead to confusion.  To access Central Administration, you need to be a Farm Administration—aka, a member of the “Farm Administrators Group”.  This is really a UI only permission (I recommend you think of “Farm Adminstration Privs” as “The ability to use Central Admin”.  The reason for this is that Farm Administrators have the ability to run operations via-the Central Administation Web Application; keep in mind that no operation actually runs against the Configuration Database as the user but rather as the App Pool account for the Web App.

With STSADM and PowerShell, all commands are run as the user who executes the command (not through the Central Admin Web Application).  The good part about this is that any command can be run from any machine (no CA required), but this means that the user themselves needs the proper permissions.  With STSADM, the user required Box, Farm, and SQL permissions—way too much to run a truly “Least Privs” environment.  With 2010 there is the flexibility to only require PowerShell & SQL permissions*. 

                *Note: Box permissions are required for a small subset of commands that touch the Windows filesystem or registry.  Also, Box and SQL are required for all “setup” operations.

On that note, there are only two requirements for most commands.  The user must be:

·         A member of the WSS_ADMIN_WGP group (this is a Windows Group on the machine the user is executing commands on)

·         A member of the “SharePoint_Shell_Access” role on the configuration database (this is a SQL Role)

To simplify the management of these roles we have created a set of PowerShell commands (noun is “SPShellAdmin”) to add and remove Shell Administrators.  You’ll notice that the commands allow you to designate a specific database, this is because the “Shell Admin” role by default only gives the user access to the Configuration Database; the shell admin must be given access to each individual service and content database they are “allowed to manipulate” (i.e.: to delete a content database, the user must be a shell admin on that database).

                *IMPORTANT: The Shell Admin commands in SharePoint 2010 Beta do not fully setup these roles; you need to add the WSS_ADMIN_WGP role manually.

Please keep in mind that each command is just running object model, so additional permissions may be required for specific commands.  For example, you may need Service Application permissions to run commands against a certain service application.

Hopefully I’ve made permissions a little easier to understand—but if you’ve still got questions, put them in the comments section below.

Thanks,
Zach

Remote Install of SharePoint (with SPModule)

Earlier in the week I posted about SPModule, which greatly simplifies setting up a SharePoint farm.  But when you pair this functionality with PowerShell remoting—the real “power” shines.   I’m going to show you how, after a couple of initial setup concepts, you can setup a multi-machine farm with just a few lines of PowerShell!

Prereqs: Remoting
The only pre-requisite for this exercise is having PowerShell 2.0 RTM installed and enabled for remoting.  PowerShell bits are available for earlier versions of Windows Server
here—but should already be ready on your Windows 2k8 R2 installs.

Then, to enable PowerShell Remoting for SharePoint you need to open up the SharePoint Console “As an Administrator” on EACH machine that will be receiving remote commands (i.e.: all machines for the farm) and run the following commands:

      Enable-PSRemoting -force

      Enable-WSManCredSSP –role Server -force

      Set-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB 1000

 

                Note - the above commands are doing the following in this order:
                                1. Enabling Remoting  (WSMan)
                                2. Enable CredSSP support in WSMan
                                3. Increases the local memory limit to 1000 MB (I recommend somewhere between 512 to 1000 MB)

Finally, from the machine that will be executing the remote commands, you need to run the following commands to enable client-remoting.  I’m going to use the “Admin Machine” (which is essentially the first machine in my farm) as the initiator of the script—but you can also use a machine that is not going to be part of the farm. 

Enable-PSRemoting -force

      Enable-WSManCredSSP –role Client –DelegateComputer “<MACHINE>” -force

 

The DelegateComputer parameter needs to be updated with an expression or machine(s) that will be delegated to.  If you want to delegate across the domain, you could write “*.mydomain.com”.  Additionally “*” can be used to easily pass this step, but this is very bad security-wise (it allows credential delegation to all machines). 

Share SPModule
The last step to getting prepared—is sharing out the folder that contains SPModule (e.g.: \\servername\spmodule), which you can
install according to my last post. 

The Install
Now for the fun! The script is really split into two pieces, installing SharePoint and creating the farm on the local machine (my “Admin Box”) and then joining the rest of the machines to the farm.   So, let’s begin.  I’ll go through all the steps and then present the whole script together—keep in mind I’ve kept his pretty simply so error handling and additional logic is “an exercise for the reader”:

1.       Define the additional machines we are using

$machinelist = ('machine1','machine2')

 

2.       Get the credential to use for remoting

$cred = Get-Credential

 

3.       Load the Modules (from our share)

$env:PSModulePath = “\\ServerName\SPModule;” + $env:PSModulePath

Import-Module SPModule.misc

Import-Module SPModule.setup

 

4.       Install SharePoint on the local box:

Install-SharePoint -SetupExePath \\servername\SharePoint2010-Beta\setup.exe” -PIDKey “PKXTJ-DCM9D-6MM3V-G86P8-MJ8CY”

 

5.       Install SharePoint on the remote boxes, which means:

a.       Create our script to run remotely which will load the modules and call “install”

b.      Connect to the remote machines and execute the script:

$script = {$env:PSModulePath = \\ServerName\SPModule;” + $env:PSModulePath;

Import-Module SPModule.misc; Import-Module SPModule.setup;

Install-SharePoint -SetupExePath \\servername\SharePoint2010-Beta\setup.exe -PIDKey “PKXTJ-DCM9D-6MM3V-G86P8-MJ8CY”

}

$machinelist |%{ Invoke-Command -ComputerName $_ -Credential $cred -Authentication Credssp -ScriptBlock $script -AsJob  }

 

                Helpful Hints: If your jobs are failing right away, remove the “AsJob” to see the error inline.  Also, if your jobs are failing after a long period of time, you may be needing a reboot during your install.  You can do this by sending a restart-computer to the script block above, then waiting for the remote machine to reboot and call install again.  Alternatively you can make sure your initial Windows image has enough prereqs to avoid a reboot.

6.       We did the above commands as a job (so they could run in parallel) so now we need to wait for them to complete…

While((Get-Job -State Running) -ne $null){ Write-Progress "Install Jobs are being completed" -Status "Please Wait..." -PercentComplete 0; sleep 30 }

 

7.       And now we can deploy the farm locally:

   New-SharePointFarm –DatabaseAccessAccount ($cred) –DatabaseServer “SQL01” –FarmName “TestFarm”

 

8.       And then join the rest of the machines (we need to do this one at a time on this one to keep things “okay”!).  Unfortunately, this will prompt you for the passphrase (it’s the password of the user account you’re prompted for in step 2).  You can add “-PassPhrase <yourpassword>” to keep this from prompting, but it will put your password in plaintext; I’ll try to blog about a workaround for this in another post.

$script = {$env:PSModulePath = “\\ServerName\SPModule;” + $env:PSModulePath;

Import-Module SPModule.misc; Import-Module SPModule.setup;

      Join-SharePointFarm -DatabaseServer “SQL01” -ConfigurationDatabaseName “TestFarm_SharePoint_Configuration_Database”

}

$machinelist |%{ Invoke-Command -ComputerName $_ -Credential $cred -Authentication Credssp -ScriptBlock $script }

 

9.       Done!

Here’s the full script—just change the machines, paths, sql machine name, and farm name (highlighted items)—then go grab some coffee!  When you return you'll be a couple PassPhrases away from a multi-machine farm!

$machinelist = ('machine2','machine3'#machine1 is the local machine

$cred = Get-Credential

$env:PSModulePath = \\ServerName\SPModule;” + $env:PSModulePath

Import-Module SPModule.misc

Import-Module SPModule.setup

 

Install-SharePoint -SetupExePath \\servername\SharePoint2010-Beta\setup.exe” -PIDKey “PKXTJ-DCM9D-6MM3V-G86P8-MJ8CY”

 

$script = {

$env:PSModulePath = \\ServerName\SPModule;” + $env:PSModulePath;

Import-Module SPModule.misc; Import-Module SPModule.setup;

Install-SharePoint -SetupExePath \\servername\SharePoint2010-Beta\setup.exe” -PIDKey “PKXTJ-DCM9D-6MM3V-G86P8-MJ8CY”

}

$machinelist |%{ Invoke-Command -ComputerName $_ -Credential $cred -Authentication Credssp -ScriptBlock $script -AsJob  }

 

While((Get-Job -State Running) -ne $null){ Write-Progress "Install Jobs are being completed" -Status "Please Wait..." -PercentComplete 0; sleep 30 }

 

   New-SharePointFarm –DatabaseAccessAccount ($cred) –DatabaseServer SQL01 –FarmName TestFarm

 

$script = {$env:PSModulePath = \\ServerName\SPModule;” + $env:PSModulePath;

Import-Module SPModule.misc; Import-Module SPModule.setup;

            Join-SharePointFarm -DatabaseServer SQL01 -ConfigurationDatabaseName TestFarm_SharePoint_Configuration_Database”

}

$machinelist |%{ Invoke-Command -ComputerName $_ -Credential $cred -Authentication Credssp -ScriptBlock $script }

 

Note: for the truly adventurous, you can enhance this script greatly by including VM management.  I’d recommend looking at this project for ideas…

SPModule.HelloWorld()

Welcome to the introduction of SPModule.  SPModule is a Windows PowerShell module written by members of the SharePoint Product Group in our spare time.   SPModule is an example of how we would envision you accomplish various common tasks within Windows PowerShell in a SharePoint 2010 environment.  We hope to position various best practices from these scripts and we hope in the long term to reference these also within technet.  These blog posts serve simply as our first location of sharing them, and this post will be updated once we have the samples hosted within technet.  The scripts themselves are not officially supported, but we will entertain questions and suggestions through this blog until we get it onto technet. 

How do I get started?

First download the zip that contains the scripts from here:

http://sharepoint.microsoft.com/blogs/zach/Script%20Library/Modules/SPModule/SPModule.zip

Next, unpack the zip file onto a share in your environment.  Before you get to use the scripts, you’ll need to make a decision around signing.  By default, Windows PowerShell is configured securely such that it will not run unsigned scripts.  You can choose to either sign them yourself with a self-signed certificate or run Windows PowerShell in a mode where you do not verify signatures.  We do not recommend running Windows PowerShell in this state.  However if you are in an isolated environment, you may choose to do so.  If you follow my last post about signing files, you can use those instructions to sign the entire “Module” in a single command:

function Add-Signing($file){ Set-AuthenticodeSignature $file @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0] }

ls -r -Include ("*.ps1","*.psd1","*.psm1") |%{ Add-Signing $_ }

 

Please note that if you have not installed SharePoint, then you need to lower the Execution Policy to “AllSigned” using this command: Set-ExecutionPolicy AllSigned.  This is done by installing the SharePoint bits so if you’ve already installed this is not needed.

 

Then open Windows PowerShell as an administrator (right click on the link and select “Run as administrator”).  If you already have SharePoint 2010 installed, you could use the SharePoint 2010 Management Shell instead.  Once the window opens, the first thing we need to do is add the path to the module to your Windows PowerShell module path (presuming you created a folder called “SPModule” on your server):

       $env:PSModulePath = “C:\SPModule;” + $env:PSModulePath

Next we need to import the modules:

Import-Module SPModule.misc

Import-Module SPModule.setup

When you import the SPModule.misc module, you will invoke a update check.  In 1.0, this will check a file in the script library above to see if there is a newer version available.  If you are notified that there is, you can go to that location and download the newer version.  Once the Import-Module commands are done, you’re ready to use SPModule.

So, what does SPModule give me?

The 1.0 version of SPModule provides a few major new commands and a number of smaller supporting commands.  Here’s how you can get the list of commands in the module:

Get-Command –Module SPModule.*

The major commands of 1.0 are Install-SharePoint, New-SharePointFarm, Join-SharePointFarm, and Backup-Logs.  They do exactly what their names would lead you to expect (Backup-Logs collects all the logs on the local machine not the whole farm).  The rest are for more advanced scenarios or are used by these larger functions—please be careful using commands you don’t understand  Here’s some quick examples to get you started:

Install SharePoint Bits (including Prereqs) on a

      Install-SharePoint -SetupExePath “\\servername\SharePoint2010-Beta\setup.exe” -PIDKey “PKXTJ-DCM9D-6MM3V-G86P8-MJ8CY”

   

      New-SharePointFarm –DatabaseAccessAccount (Get-Credential DOMAIN\username) –DatabaseServer “SQL01” –FarmName “TestFarm”

   

      Join-SharePointFarm -DatabaseServer “SQL01” -ConfigurationDatabaseName “TestFarm_SharePoint_Configuration_Database”

 

      Backup-Logs -outp “$env:userprofile\Desktop\SharePointLogs.zip”

 

Note:  Backup-Logs may have trouble putting the subzip files into the final zip.  We are aware of this issue and are working on this for the next release.  For now, we will detect the situation and keep the subzip files that had a problem

Please post your comments, questions, or ideas in the comments section of this post.

Thanks,

Dan Winter & Zach Rosenfield
SharePoint Program Managers

AllSigned: Signing Your PowerShell Scripts

You may have noticed by now that the default for SharePoint PowerShell is to change the restrictions on running PowerShell scripts to use AllSigned.  A good explaination of “Why” is here on Lee Holmes’s blog, but this leaves you needing to sign your own scripts in order to run them.   Don’t worry--it’s not as complicated as it sounds! Let’s look at how to do this in an easy way (especially for those of you without a real “Cert” of your own).

ONE TIME STEPS -- This portion of the walkthrough only needs to be done once (note that i'll post later on how to use this same cert on multiple machines):

First we need to create a cert. You can do this on any machine—it requires makecert.exe which is part of the Microsoft Windows Platform SDK.  Once you install the SDK you can find MakeCert (you can run this command from “Program Files” to find the exe: ls -Recurse -Filter "makecert.exe"). 

For a full walkthrough see Scott Hanselman’s post, but in short, we can create a local certificate authority for your computer by running this command in PowerShell from the folder that contains Makecert.exe:

./makecert.exe -n "CN=PowerShell Local Certificate Root" -a sha1 -eku 1.3.6.1.5.5.7.3.3 -r -sv root.pvk root.cer -ss Root -sr localMachine

You’ll be prompted for a private key—provide one you’ll remember (or write it down!):

Then you are prompted to enter the key you just created.

This has created a certificate authority (if you have issues see Scott’s Post).  Now we can create a personal Certificate using our new Cert Authority by running this command from the same folder (you’ll be prompted for the same key as above):

./makecert.exe -pe -n "CN=PowerShell User" -ss MY -a sha1 -eku 1.3.6.1.5.5.7.3.3 -iv root.pvk -ic root.cer

You can make sure the certificate was properly generated using this command:

Get-ChildItem cert:\CurrentUser\My –codesign

You can now delete the two temporary files root.pvk and root.cer in your working directory.  The certificate info is stored with that of others, in "C:\Documents and Settings\<your username>\Application Data\Microsoft\SystemCertificates\My\".

Now—the above steps only need to be done once as we can use this cert to sign all our scripts.  To Sign a script, simply point the following command to your script.

  Set-AuthenticodeSignature “c:\foo.ps1” @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0]


Here’s a function I use (it’s in my profile.ps1 file) to sign my scripts:

function Add-Signing($file){

  Set-AuthenticodeSignature $file @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0]

}

Note: the first time you run your own “untrusted” script you’ll get this prompt below—just say “Always Run” to avoid seeing it in the future.

PowerShell Demo Tools

Several people who attended my PowerShell talk at SPC09 have been asking for the “Start-Demo” Script I used to demo PowerShell commands without having to type them in front of a live audience.  The script I used is really just a slightly modified version of this one http://blogs.msdn.com/powershell/archive/2007/06/03/new-and-improved-start-demo.aspx -- i recommend just using the version provided by the PowerShell team.

 

Also, I recommend pairing this with the Sysinternals tool ZoomIt to allow for zooming and underlining elements on the screen.  This is a free tool available from the Sysinternals website: http://technet.microsoft.com/en-us/sysinternals/default.aspx

 

 

SharePoint 2010 Beta: ThreadOptions error
Before everyone starts sending in messages about the "ThreadOptions" error you may be seeing when you open up the SharePoint Management Shell, let me explain:  this is a known issue.

Why are you seeing it?  Well, because the Beta of SharePoint 2010 includes the PowerShell CTP3 of their 2.0 product; which does not have support for the ThreadOptions functionality we use to fix the "threading issue" discussed many months ago in my blog.  Since this is not available, then the threading issue still applies--but when using the RTM build of PowerShell, this problem is no longer applicable!
 
The RTM SharePoint 2010 product will install the RTM Build of PowerShell 2.0--which is actually available now (so if you can't wait, feel free to install 2.0 instead to avoid both this issue and the pre-req installer block).
 
The issue:
SP+PS 2010: PowerShell to Create a Service Application

One of the principles that PowerShell offers is the ability to “discover” what commands you need to run to do your tasks.  This principle mostly holds up—with on caveat: you have to “Know” the concepts about the task upfront for the commands to make sense.  I’m going to both demonstrate what this discovery means at the same time as showing how to create a service application.  The idea behind the discovery concept is that you should be able to take the knowledge behind creating 1 specific type of service application and re-use it to create any other type of service application*.   Note that Search can be a bit more difficult because of all the flexibility built into 2010—the more flexible the system gets the more detailed setup can be.

First, you need to understand the concept of what is required to create a Service Application (I’m only going to discuss non-federated, so running on the same farm that is using it).  In the most simplified form: the following items are required for every service application:

1.       The SPServiceApplication: this is the actual definition in the configuration database that will contain information like related databases and settings.  Note that this requires providing a web service Application Pool (More on this later).

2.       The SPServiceApplicationProxy: This is the “service connection” that is used for Web Applications to “talk” to the Service Application

3.       Start at least one SPServiceInstance: This is the actual “process” that will be used to run the Service Application code.  This can run on multiple servers to share load and provide high-availability—but only 1 is “required”.

4.       Attach the service to a SPServiceApplicationProxyGroup: This is the ‘group’ of service applications that a web application can be set to use.  There is a “Default” group that you can add services to that all web apps will be associated with by default.

Each service obviously has it’s own requirements (for example, you need to create databases for the User Profile service), but PowerShell will actually Prompt you for the “required” parameters and will give defaults for as many as it can.  Feel free to provide alternates to the defaults.

So, with that, let’s use the four requirements above to create a service app!  Metadata Service is a good starting point…

1.       Start one or more service instances.  Note that these exist regardless of whether they have any service applications to actually run.  We also want to wait for this to fully provision before continuing.

$MetadataServiceInstance = (Get-SPServiceInstance |Where{$_.TypeName -eq "Managed Metadata Web Service"})   #Get a pointer to the Service Instance

      if($MetadataserviceInstance.Status -eq "Disabled"){  $MetadataserviceInstance | Start-SPServiceInstance  }  #Start the Service Instance

      while(-not ($MetadataServiceInstance.Status -eq "Online")){                                                 #wait for provisioning to finish

            write-host -ForegroundColor Yellow "Waiting for Metadata service to provision"; sleep 5;

}

     

Add-SPServiceApplicationProxyGroupMember -Identity $ProxyGroup -Member $MetaDataServiceAppProxy

2.       Get or Create an Application Pool.  If you already have one running other services you can get an existing one using the GET command, or create a new one like this.

$ManagedAccount = Get-SPManagedAccount | select -First 1  #Get a managed account. I RECOMMEND YOU CHANGE THIS LINE TO GET THE RIGHT ACCOUNT FOR YOU!
$ApplicationPool = New-SPIisWebServiceApplicationPool "SharePoint Hosted Services" -account $ManagedAccount

 

*Note: this is NOT a Web Application “app pool”.  Do NOT create one of these for a web application –it will NOT work.

3.       Create the Service Application

$MetaDataServiceApp = New-SPMetadataServiceApplication -Name "Metadata Service Application" -ApplicationPool $ApplicationPool

 

4.       Create the proxy.  I also “attach it to the default proxy group using the -DefaultProxyGroup flag.

   $MetaDataServiceAppProxy = New-SPMetadataServiceApplicationProxy -Name "Metadata Service Application Proxy" -ServiceApplication $MetaDataServiceApp –DefaultProxyGroup

 

That’s it!  It’s a little basic, and can’t be part of a larger script that is going to be “re-run” very easily, so here’s a full script with some error handling to wrap the action…

try{

      #Managed Account

      $ManagedAccount = Get-SPManagedAccount | select -First 1

      if ($ManagedAccount -eq $NULL) { throw "No Managed Accounts" }

     

      #App Pool

      $ApplicationPool = Get-SPIisWebServiceApplicationPool "SharePoint Hosted Services" -ea SilentlyContinue

      if($ApplicationPool -eq $null){

            $ApplicationPool = New-SPIisWebServiceApplicationPool "SharePoint Hosted Services" -account $ManagedAccount

            if (-not $?) { throw "Failed to create an application pool" }

      }

     

      #Create a Taxonomy Service Application

      if((Get-SPServiceApplication |?{$_.TypeName -eq "Managed Metadata Service"})-eq $null){     

            Write-Progress "Creating Taxonomy Service Application" -Status "Please Wait..."

            #get the service instance

            $MetadataServiceInstance = (Get-SPServiceInstance |?{$_.TypeName -eq "Managed Metadata Web Service"})

            if (-not $?) { throw "Failed to find Metadata service instance" }

           

             #Start Service instance

            if($MetadataserviceInstance.Status -eq "Disabled"){ 

                  $MetadataserviceInstance | Start-SPServiceInstance 

                  if (-not $?) { throw "Failed to start Metadata service instance" }

            }

            #Wait

            while(-not ($MetadataServiceInstance.Status -eq "Online")){ #wait for provisioning

                  write-host -ForegroundColor Yellow "Waiting for Metadata service to provision"; sleep 5;

            }

            #Create Service App

            $MetaDataServiceApp  = New-SPMetadataServiceApplication -Name "Metadata Service Application" -ApplicationPool $ApplicationPool

            if (-not $?) { throw "Failed to create Metadata Service Application" }

           

            #create proxy

            $MetaDataServiceAppProxy  = New-SPMetadataServiceApplicationProxy -Name "Metadata Service Application Proxy" -ServiceApplication $MetaDataServiceApp -DefaultProxyGroup

            if (-not $?) { throw "Failed to create Metadata Service Application Proxy" }

      }

}

catch

    {

            Write-Output $_

      }

 

SharePoint 2010 Beta Pre-Req Installer Error
If you're seeing a failure with the SharePoint 2010 Beta Pre-Req Installer--it's most likely related to an existing PowerShell install.  In the Beta of 2010, the pre-req installer will attempt to install the PowerShell 2.0 CTP3.  The CTP does not support being installed "over" an existing PowerShell installation--which means that if you have PowerShell 1.0 installed you have two options:
 
  • Remove the Windows PowerShell feature prior to running the pre-req installer
  • Manually download and install the RTM version of PowerShell 2.0. The RTM version CAN be installed over an existing 1.0 install.

I recommend the second option as SharePoint 2010 RTM will be using the RTM of PowerShell 2.0.

Hope this helps anyone who is seeing this issue!

SP+PS 2010: Understanding Features

SharePoint PowerShell was designed with Administrators in mind—so those of you who understand the difference between a “Feature” and a “FeatureDefiniton” might be a little concerned when you only see one feature related “noun”: “SPFeature”.   This is really because we could simplify this concept for PowerShell to only need one set of commands to manage functionality in your farms.    The important thing to realize is that no command will return an “SPFeature”, but rather an SPFeatureDefinition.  I’ll try to expect the rest of the concepts by example… Here’s what you can expect from the following commands:

Starting with Get-SPFeature; this cmdlet will behave differently depending on the way it’s called.  Simply calling the command with no parameters will return all features installed in the farm.

PS> Get-SPFeature

If you wanted to see what features are installed at a specific scope, use “Client Side Filtering”:

PS> Get-SPFeature |Where{ $_.Scope –eq “Web” }

To get information about a specific feature, provide the Name or ID to the identity parameter of Get-SPFeature:

PS> Get-SPFeature BaseWeb | select *

If you wanted to get the list of features that are Enabled at a specific scope, you have to provide the Scope and object of interest.  The farm scoped features only require a flag—here’s the command to get all Enabled features at an SPFarm level:

PS> Get-SPFeature -Farm

To get the features enabled on a site collection use this:

PS> Get-SPFeature –Site “http://sitename”

Or on a specific SPWeb:

PS> Get-SPFeature –Web “httP://sitename/blog”

For those you who really wanted to know the details, the three previous commands are returning the SPFeatureDefinition for all the SPFeatures (which is really all Enabled features) at the provided scope.

The other important commands are:

·         Install-SPFeature:  Use this command to install an SPFeatureDefinition into the farm. The files should already be deployed in the proper location (FEATURE directory) so you can just provide the “name” of the feature to be installed (Name is just the containing folder’s name)

·         Uninstall-SPFeature: removes an installed SPFeatureDefinition from the farm.  Use just like Install

·         Enable-SPFeature: turns on an SPFeature on the given Web, Site, Web Application, or the local Farm.  All that is required is the feature identity and the desired URL for the site, web or web app (for Farm level features you do not need to provide any URL)

·         Disable-SPFeature: turns off an SPFeature at the given scope.  Use just like Enable.

As a final bonus—here’s a quick demo of how to use this knowledge to compare the features enabled on a given SPSite to the list of Site-Scoped features in the local SPFarm:

$s1 = Get-SPFeature -site "http://mysitetolookat"  #Get the list of features on our site

$s2 = Get-SPFeature |?{$_.Scope -eq "Site"}  | sort DisplayName  #Get the list of available features (sorted)

$results = Compare-Object $s1 $s2  #Compare them

 

foreach($row in $results){   #Print the features in the master list not enabled on the site.

  switch ($row.SideIndicator){

    =>{ $row.InputObject }

  }

}

*Note that the above script only looks at “=>”, but there could be Sandboxed Solutions that are unique to the site.  These would show with a “<=” SideIndicator instead.

SP+PS 2010: Custom Parameters

Today’s post is one of my favorite new capabilities… custom parameters!  With SharePoint’s previous admin console (STSADM) you could create your own custom commands (Which you can still do with PowerShell in 2010—see Gary’s post on Custom Cmdlets for a good starting point); but these required you to create your own command entirely in code from scratch, even if existing commands got you 90% of the way.  But in 2010, you can add only the parameters you need to existing commands by wrapping the existing cmdlet inside a function.  If you use this to make your own commands, please let me know!  I’m always interested to see what other parameters people are creating for themselves.  And with that, let’s begin!

Now those of you who read my blog know that my other main area of focus is Master Page design.  I’m a big fan of scripting all my repetitive steps—so when testing a new master page I want to deploy all possible templates that exist with my master page; but when you get ahold of your SharePoint 2010 beta you’ll not find a “MasterPage” setting on the SPWeb cmdlets…  Not to worry, we can add our own!

Here’s the initial syntax of Set-SPWeb (as of the 2010 Beta):

First we need to take a copy of the New-ScriptCmdlet.ps1 file from the script library.  This is essentially a copy of James Brundage’s script from his Fun with Script Cmdlets blog post.  Essentially this script will “auto generate” a wrapper function based on the cmdlet passed into it.   For this situation I saved the New-ScrpitCmdlet.ps1 file to my C: drive and dot source the “New-ScriptCmdlet” function into my session so that I can call this command to generate the Set-SPWeb wrapper function:

PS> Get-Command Set-SPWeb | New-ScriptCmdlet Set-SPWeb | Set-Content Set-SPWeb.ps1

Now that we generated the Set-SPWeb.ps1 function that we can add our logic to!  Open up this file and you’ll see a function that has the same syntax as the cmdlet…

What we’re going to do today is add a “MasterPageRelativeUrl” to the cmdlet which takes a string to represent the relative path to the master page to apply.  First, we add the parameter to the “Param” list (I’ll highlight any “new” scripting I introduce):

param(

    [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)][Microsoft.SharePoint.PowerShell.SPWebPipeBind] ${Identity},

    [System.String]${RelativeUrl},

    [System.String]${Description},

    [Microsoft.SharePoint.PowerShell.SPWebTemplatePipeBind]${Template},

    [System.String]${Theme},

    [Parameter(ValueFromPipeline=$true)][Microsoft.SharePoint.PowerShell.SPAssignmentCollection]${AssignmentCollection},

    [System.String] $MasterPageRelativeURL

)

Then we need to handle this parameter being passed into the script.  Add the highlighted code to the Try block of the BEGIN section to collect the value and remove this from the parameters passed to the actual cmdlet.  Also, we need the Identity stored locally to use later so we’ll store that too:

begin

{

    try {

        $outBuffer = $null

  $m_Identity = $null; $m_MasterPage = $null;

        if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))

        {

            $PSBoundParameters['OutBuffer'] = 1

        }

        if ($PSBoundParameters.TryGetValue('masterpagerelativeurl', [ref]$m_MasterPage))

        {

            [void]$PSBoundParameters.Remove('masterpagerelativeurl')

            [void]$PSBoundParameters.TryGetValue('identity', [ref]$m_Identity)

        }

        $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Set-SPWeb', [System.Management.Automation.CommandTypes]::Cmdlet)

        $scriptCmd = {& $wrappedCmd @PSBoundParameters }

        $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)

        $steppablePipeline.Begin($PSCmdlet)

    } catch {

        throw

    }

}

And the last step—we use one line of OM to set the master page on a given SPWeb object.  However, I’m going to wrap the command in a ShouldProcess and some other logic to handle poorly formed Master Page URLs. Just realize that only the line starting in Get-SPWeb is actually required.

The Process section should now look like this:

process

{

    try {

        $steppablePipeline.Process($_)

        if($pscmdlet.ShouldProcess($m_Identity.webUrl, "MasterURL=$m_MasterPage")){

        if(!($masterpage.StartsWith("/_catalogs/masterpage/"))){ Write-Warning "Master Page paths generally start with the page /_catalogs/masterpage/"; }

           Get-SPWeb $m_Identity.webURL |%{ $_.MasterUrl = $m_MasterPage; $_.Update() }

        }

    } catch {

        throw

    }

}

So now if we dot-source this new Set-SPWeb script we’ll see that the MasterPageRelativeURL is now shown!

So now I can run Set-SPWeb to change the Master Page! If I use WhatIf I’ll see two entries, once for the cmdlet and once for my custom script:

Command to change a master page:

PS C:\> Set-SPWeb http://mybrandingsite -MasterPageRelativeUrl "/_catalogs/masterpage/zcustom.master"

I've posted the final Set-SPWeb.ps1 file in the Script Library as well.

NOTE: you can still force PowerShell to use the CMDLET directly by calling “Microsoft.sharepoint.powershell\Set-SPWeb” or the Function directly using “\Set-SPWeb”.

1 - 10 Next

 ‭(Hidden)‬ Admin Links

 
 
   
Real Time Web Analytics