In my post “Five Simple But Powerful PowerShell Functions/Filters for SharePoint” I demonstrated five functions and filters that when stung together allowed you to access many of the key SharePoint objects. This post assumes you read Five Simple But Powerful PowerShell Functions/Filters for SharePoint. The five functions and filters are interesting because we can access key SharePoint objects which we will use later in scripts. The problem with the five functions and filters is they lack specificity. They will bring back every object of a specific type on the a SharePoint farm. In some cases this is what you want but in others it simply produces a lot of noise.
I should throw in a note here that lets the readers know that I chose to “design” these functions and filters to be chain-able and return all the objects of a certain type . I certainly could have created functions and filters that would allow the reader to target a very specific object. By including limiting parameters. I felt that design would have created more functions that would require parameters and might be more confusing to administrators that do not have much scripting experience.
Back to the topic of limiting our output. PowerShell has provided an important cmdlet, Where-Object, that can be used for limiting the output to the pipeline. Strategically placing this cmdlet in our existing pipeline will control which objects continue through the pipeline to the next cmdlet and ultimately the host (i.e. the console). First lets look at the syntax for the Where-Object
Where-Object { <Script Block> }
The Where-Object is standard cmdlet verb-noun syntax that we have seen before. The Script Block is new. The author of the PowerShell script provides a block of script that the Where-Object uses to select which objects makes it thought the pipeline. Lets look at a very simple example again using the Get-Process cmdlet.
Now lets look at the output to the host when we execute Get-Process ( the canonical demo example)
Output of Get-Process
Now compare the output when we execute Get-Process | Where-Object { $_.ProcessName -like “SQL*”}
Output of Get-Process | Where-Object { $_.ProcessName -like “SQL*”}
The second example containing the Where-Object cmdlet only passes objects though the pipeline when the current object (referenced by $_ ) has a ProcessName property that begins with the string ‘SQL’ as defined in the scriptblock delineated by braces. All other objects passed via the pipeline to the Where-Object cmdlets that does not meet the Where-Object criteria is dropped and not passed on to the next cmdlet in the pipeline. In this example is not passed to the default format cmdlet before being sent to the PowerShell console.
So now lets see how we can use the Where-Object to provide some selectivity for our 5 filters and functions. These scripts assume you have followed the Five Simple But Powerful PowerShell Functions/Filters for SharePoint post. Lets start with this example that will return all webs (SPWeb objects) on the local farm ( remember you must run this on a SharePoint server).
Get-localfarm |get-webservice | get-webapplication | get-sitecollection | get-web | format-table title, url
Results of Get-localfarm |get-webservice | get-webapplication | get-sitecollection | get-web | format-table title, url
Now lets add a Where-Object cmdlet:
Get-localfarm |get-webservice | get-webapplication | get-sitecollection | get-web | Where-Object{$_.url -like “*dev*”} | format-table title, url
Results after piping to Where-Object{$_.url -like “*dev*”}
Notice we can now limit what webs are passed on to the next cmdlet. In the last example we limited the SPWeb objects passed to the end of the pipeline to those that contained the substring ‘dev’.
[Hint: Not sure what properties of the SPWeb objects to filter on? The Windows SharePoint Services SDK has them all. Another way is to run the following:
$webs = Get-localfarm |get-webservice | get-webapplication | get-sitecollection | get-web
$webs[0] | Get-Member
This set of cmdlets retrieves all the webs (SPWeb) objects on the local farm and places them in a variable ($webs). The second line will send the first SPWeb to the Get-Member cmdlet and dump the properties and methods to the screen]
Try running this set of cmdlets:
Get-localfarm |get-webservice | get-webapplication | get-sitecollection | get-web | Where-Object{$_.webtemplate -eq ‘Wiki’} | format-table title, url, WebTemplate
You will display the title, url and WebTemplate values for webs that were created from the Wiki template.
Need to get a list of all the team site webs? Try:
Get-localfarm |get-webservice | get-webapplication | get-sitecollection | get-web | Where-Object{$_.webtemplate -eq ‘STS’} | format-table title, url, WebTemplate
How about a list of all webs that allow anonymous access? Try:
Get-localfarm |get-webservice | get-webapplication | get-sitecollection | get-web | Where-Object{$_.allowAnoymousAccess -eq $true} | format-table title, url, WebTemplate
Now a list of site collections:
Get-localfarm |get-webservice | get-webapplication | get-sitecollection | format-table url, owner
And now only site collections on port 8090
Get-localfarm |get-webservice | get-webapplication |Where-Object {$_.Port -eq 8090} | format-table url, owner
Now expand the last set of cmdlets to include a get-web before you end with Format-Table and you will get all webs for site collections on port 8090.
Get-localfarm |get-webservice | get-webapplication | get-sitecollection | Where-Object {$_.Port -eq 8090} | get-web | format-table title, url
Ok, these are very simple examples of limiting the output from our five filters and functions. Working with the Get-Member cmdlet or the SDK will allow you to effectively filter and cut down on the noise.