MOSS MVP

I've moved my blog to http://blog.falchionconsulting.com!. Please update your links. This blog is no longer in use--you can find all posts and comments at my new blog; I will no longer be posting to this site and comments have been disabled.

Sunday, April 26, 2009

Getting an SPWebApplication object using PowerShell

A SharePoint deployment isn’t much of a deployment if there are no web applications.  A web application in SharePoint contains one or more content databases, each of which can contain one or more site collections, etc., etc.  The SPWebApplication class has tons of methods and properties for directly or indirectly manipulating all things related to web applications - you can do backups, add content databases and site collections, set alert settings, manipulate the web.config file, etc.

There are a couple of different ways in which we can work with the SPWebApplication using PowerShell.  The first is to get a specific object using the static Lookup method and the second, which is useful for looping through all web applications, is to use the SPFarm object’s Service property.  The first approach is shown below:

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
$webapp = [Microsoft.SharePoint.Administration.SPWebApplication]::Lookup("http://portal")
If you need to loop through all web applications you would write something like the following:
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
$farm = [Microsoft.SharePoint.Administration.SPFarm]::Local
$websvcs = $farm.Services | where -FilterScript {$_.GetType() -eq [Microsoft.SharePoint.Administration.SPWebService]}
$webapps = @()
foreach ($websvc in $websvcs) {
    foreach ($webapp in $websvc.WebApplications) {
        $webapps = $webapps + $webapp
    }
}

The code above isn’t the most intuitive but could be easily wrapped into a function to abstract out the complexity (note that there may be a better way to do the above - I’m still figuring this whole PowerShell thing out:) ).  Personally I think the above sucks - it’s not intuitive and it’s difficult to maintain and forces me to do additional filtering if I want a subset of the items returned - thus the motivation behind my Get-SPWebApplication cmdlet.  Here’s a couple examples that do the same thing as the above two examples but using my cmdlet instead:

$webapp = Get-SPWebApplication http://portal
$webapps = Get-SPWebApplication *

On the first line I’m retrieving a specific web application and on the second line I’m using a wildcard character to retrieve all web applications in the farm.  You could easily utilize the wildcard capabilities to reduce the set of web applications that are returned to those matching a specific pattern.   You can also pass in multiple, comma separated URLs such as in the following example:

$webapps = Get-SPWebApplication http://portal,http://mysites

The code for the cmdlet is reasonably simple - most of the work is in dealing with the fact that wildcards are allowed thus making it necessary to loop through all the web applications and the corresponding alternate URL mappings in order to identify the web applications to return:

   1: using System;
   2: using System.Management.Automation;
   3: using Lapointe.SharePoint.PowerShell.Commands.OperationHelpers;
   4: using Lapointe.SharePoint.PowerShell.Commands.Validators;
   5: using Microsoft.SharePoint;
   6: using Microsoft.SharePoint.Administration;
   7:  
   8: namespace Lapointe.SharePoint.PowerShell.Commands.WebApplications
   9: {
  10:     [Cmdlet(VerbsCommon.Get, "SPWebApplication", SupportsShouldProcess=true, DefaultParameterSetName = "Url")]
  11:     public class GetSPWebApplicationCommand : PSCmdletBase
  12:     {
  13:         /// <summary>
  14:         /// Gets or sets the URL.
  15:         /// </summary>
  16:         /// <value>The URL.</value>
  17:         [Parameter(
  18:             ParameterSetName = "Url",
  19:             Mandatory = true,
  20:             Position = 0,
  21:             ValueFromPipeline = true,
  22:             ValueFromPipelineByPropertyName = true,
  23:             HelpMessage = "The URL of the web application to return.  Supports wildcards.")]
  24:         [ValidateNotNullOrEmpty]
  25:         [ValidateUrl(true)]
  26:         public string[] Url { get; set; }
  27:  
  28:  
  29:         /// <summary>
  30:         /// Processes the record.
  31:         /// </summary>
  32:         protected override void ProcessRecordEx()
  33:         {
  34:             foreach (string url in Url)
  35:             {
  36:                 if (!WildcardPattern.ContainsWildcardCharacters(url))
  37:                 {
  38:                     string webApp = url.TrimEnd('/');
  39:                     WriteObject(SPWebApplication.Lookup(new Uri(webApp)));
  40:                 }
  41:                 else
  42:                 {
  43:                     WildcardPattern wildCard = new WildcardPattern(url.TrimEnd('/'), WildcardOptions.IgnoreCase);
  44:                     if (SPFarm.Local == null)
  45:                         throw new SPException(
  46:                             "The SPFarm object is null.  Make sure you are running as a Farm Administrator.");
  47:  
  48:                     foreach (SPService svc in SPFarm.Local.Services)
  49:                     {
  50:                         if (!(svc is SPWebService))
  51:                             continue;
  52:  
  53:                         foreach (SPWebApplication webApp in ((SPWebService) svc).WebApplications)
  54:                         {
  55:                             foreach (SPAlternateUrl altUrl in webApp.AlternateUrls)
  56:                             {
  57:                                 if (wildCard.IsMatch(altUrl.Uri.AbsolutePath.TrimEnd('/')))
  58:                                 {
  59:                                     WriteObject(webApp);
  60:                                     break;
  61:                                 }
  62:                             }
  63:                         }
  64:                     }
  65:                 }
  66:             }
  67:         }
  68:     }
  69: }
Here’s the full help for the cmdlet:
NAME
    Get-SPWebApplication
    
SYNOPSIS
    Gets one or more SPWebApplication objects representing a SharePoint 2007 Web Application.
    
SYNTAX
    Get-SPWebApplication [-Url] <String[]> [-WhatIf] [-Confirm] [<CommonParameters>]
    
    
DETAILED DESCRIPTION
    Pass in a comma separated list of URLs or a string array of URLs to obtain a collection of SPWebAppl
    ication objects.
    
    Copyright 2008 Gary Lapointe
      > For more information on these PowerShell cmdlets:
      > http://stsadm.blogspot.com/
      > Use of these cmdlets is at your own risk.
      > Gary Lapointe assumes no liability.
    

PARAMETERS
    -Url <String[]>
        Specifies the URL of the web application(s) to retrieve. Wildcards are permitted. If you specify
         multiple URLs, use commas to separate the URLs.
        
        Required?                    true
        Position?                    1
        Default value                
        Accept pipeline input?       true (ByValue, ByPropertyName)
        Accept wildcard characters?  false
        
    -WhatIf
        
        
        Required?                    false
        Position?                    named
        Default value                
        Accept pipeline input?       false
        Accept wildcard characters?  false
        
    -Confirm
        
        
        Required?                    false
        Position?                    named
        Default value                
        Accept pipeline input?       false
        Accept wildcard characters?  false
        
    <CommonParameters>
        This cmdlet supports the common parameters: -Verbose, -Debug,
        -ErrorAction, -ErrorVariable, and -OutVariable. For more information,
        type, "get-help about_commonparameters".
    
INPUT TYPE
    String
     
    
RETURN TYPE
    Collection of SPWebApplication objects.
     
    
NOTES
    
    
        For more information, type "Get-Help Get-SPWebApplication -detailed". For technical information,
         type "Get-Help Get-SPWebApplication -full".
    
    --------------  EXAMPLE 1 --------------
    
    C:\PS>$webapp = get-spwebapplication -url http://portal
    
    
    This example returns back a single SPWebApplication object.
    
    
    
    
    
    
RELATED LINKS
    http://stsadm.blogspot.com

1 comment:

Anonymous said...

Hi Garry ,
In PS the onliner solution is

$WA = [Microsoft.SharePoint.Administration.Spwebapplication]::Lookup($URL)

HTH
Jos Verlinde