I'm having a very strange problem with the Scopes.GetDisplayGroup() method returning a "Specified cast is not valid" error.

This is a cut-down version of the code I've been using:

$SPWebApp = Get-SPWebApplication $spSiteUrl
$displayGroupName = "Search Dropdown"
$ssa = Get-SPEnterpriseSearchServiceApplication "Search Service Application"
$scopes=New-Object Microsoft.Office.Server.Search.Administration.Scopes($ssa)

foreach ($SPSite in $SPWebApp.Sites) {
    $displayGroup = $scopes.GetDisplayGroup($SPSite.Url, $displayGroupName)

Through testing this on multiple environments and a lot of trial and error (as the issue was sporadic and didn't always occur consistently), I found that the way around it was to visit the /_layouts/viewscopes.aspx page for each site collection in-browser first before running the script. Once the page had been visited, the .GetDisplayGroup method works for that site collection without error and everything is hunky-dory.

This doesn't seem to make sense to me - does anyone have any idea why this could be happening? Is there any background code fired by that page when it's accessed? Thanks in advance.

  • Did you check if it is an issue of access rights for the account you are using to run the powershell script? Commented Jan 9, 2014 at 17:05

1 Answer 1


I have come across this too, and yes, viewscopes.aspx causes the standard display groups to be created. I have written a post about my findings, and the work around I used: http://danielflint.im/2014/01/working-around-getdisplaygroup-throwing-invalid-cast-via-powershell/

Here's the work around:

Add-PSSnapIn Microsoft.SharePoint.Powershell -ErrorAction:SilentlyContinue
[reflecton.assembly]::LoadWithPartialName("Microsoft.Office.Server") | Out-Null

# Get our site, search context and scopes
$site = Get-SPSite $siteUrl
$siteId = $site.Id.ToString("D")
$ctx = [Microsoft.Office.Server.Search.Administration.SearchContext]::GetContext($site)
$scopes = New-Object Microsoft.Office.Server.Search.Administration.Scopes($ctx)

# Here's the cool stuff. We're really just calling $scopes.Consumers.EnsureRegistered($siteId)
$BindingFlags = [Reflection.BindingFlags] "NonPublic,Instance"

$consumers = $scopes.GetType().GetMember("Consumers",$BindingFlags)[0].GetValue($scopes, $null)
$consumer = $consumers.GetType().GetMethod("EnsureRegistered",$BindingFlags).Invoke($consumers, $siteId)
  • Thanks a lot for your input Daniel - some interesting stuff there. Still a bit of a mystery as to why it behaves in this way to begin with, but good to know there's a workaround!
    – Vassal
    Commented Jan 15, 2014 at 15:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.