Unable to Add the App – The App domain for this site has already been assigned


Recently I was working on configuring SharePoint hosted apps for our customer and while testing I saw this issue.  After completing the configuration of Apps I uploaded an app to app catalog and added the app to a site. The app worked without any issue but there was one gotcha.  I missed to replace an S in App Prefix which was set to Apps so my app url was https://apps-1234.apps.contoso.com but the orignal plan was to use “app” as prefix. 

So I removed the app from the site and app catalog.  Then went to CA and changed the app prefix to app from “apps”.  Uploaded the test app to catalog and then tried to add to the site and it failed with error. “Unable to add the app to the site please retry”

I started ULS Viewer and started live log stream and clicked retry and saw an amazing message.  SharePoint app was still using “apps” while I have updated it app.  I knew something was goofy and traditionally UI is that good with me when it comes to SharePoint. 

SPException thrown: Message: The App domain for this site has already been assigned.. Stack:    at Microsoft.SharePoint.Utilities.SPUtility.ThrowSPExceptionWithTraceTag(UInt32 tagId, ULSCat traceCategory, String resourceId, Object[] resourceArgs) 

Here is what I did.
Open SharePoint Management Shell as administrator (Farm Account).

Set-SPAppDomain -AppDomain apps.contoso.com
Set-SPAppSiteSubscriptionName -Name "app" -Confirm:$false

#Open Command Prompt as Administrator. Run the commands below.
net stop sptimerv4
iisreset
net start sptimerv4
#Repeat the above 3 on all servers in the farm.

I closed all the browsers and opened the site and click Retry from Site content page.  Bingo the app was added without any problem.

Add and Remove Web Site Binding using PowerShell


Windows Server 2008 R2 does not allow us to add a binding to same port twice.  Additionally you can not select a different SSL certificate for web app that is configured with https.  To do so you have to add binding by adding another IP address on the server and then add the binding on the IP and use a different SSL cert.  I saw people using a comand line utility like appcmd but frankly the syntax was pretty rough to use it.  So I tried wth PowerShell.  I was able to make a script that allows you to add a remove a binding as required.  The below script is used when I configured SharePoint Hosted apps on Windows server 2008 R2 environment where apps are configured to use different app domain.  Customer was getting certificate error so they wanted to use different SSL cert on App Web (No Host Header Web Application).  Just like I said before you just need an addition IP address on the WFES and then add a binding with * on that IP.  You can then remove the default binding using the same PowerShell script.

Import-Module WebAdministration
Get-Website
#Note the Web application Name
$ADFSApp = Get-Website -Name "NoHostHeader"
New-WebBinding -Name "NoHostHeader" -Protocol https -Port 443 -HostHeader "*" -IPAddress 35.0.0.11
#List the binding of the web appGet-WebBinding -Name "NoHostHeader" | Select *
#Remove the default Binding
Remove-WebBinding -Name "NoHostHeader" -BindingInformation "*:443:"

You can change the commands the way you want.  Do not try to modify the values of  https binding from UI as the changes apply to all web applications.  Be careful.  The script only targets one web app it is safe to execute.

Update Hidden View with PowerShell


Here is quick fix for an issue where AllItems view was set to blank and was set to hidden.  Here is how I fixed it.  Nothing fancy just some old Server OM calls in PowerShell.

First you have to list all the views to find it out what’s going wrong and put it in a list.

$SiteUrl = https://portal.contoso.com     
$ListUrl = "Discussions List"            

$Databases = @();
       
$Web = Get-SPWeb -Identity $SiteUrl            
if ($Web -ne $null)            
{
    $List = $Web.Lists[$ListUrl]
    foreach($view in $List.Views)
    {
        $ViewFile = $targetUrl.GetFile($view.Url)
        $Viewobj = New-Object PSObject
        Add-Member -input $Viewobj noteproperty 'ID'  $view.ID
        Add-Member -input $Viewobj noteproperty 'Title'  $view.Title
        Add-Member -input $Viewobj noteproperty 'CreatedBy'  $ViewFile.Author
        Add-Member -input $Viewobj noteproperty 'Modified' $ViewFile.TimeLastModified 
        Add-Member -input $Viewobj noteproperty 'ModifiedBy' $ViewFile.ModifiedBy 
        Add-Member -input $Viewobj noteproperty 'CreatedOn' $ViewFile.TimeCreated  
        Add-Member -input $Viewobj noteproperty 'Private' $view.PersonalView  
        Add-Member -input $Viewobj noteproperty 'Url' $view.Url  
        Add-Member -input $Viewobj noteproperty 'Hidden' $view.Hidden  
        $Databases += $Viewobj
          
    }
    #Export If Needed.        
    #$Databases  | Out-File C:\View.txt

}
#Select the View and Click OK in GridView
$aBadView= $Databases | Out-GridView -PassThru
$aBadView.ID

Now You have the View ID you have do it like below

$ID = [guid]("0b57d149-dbcc-4652-b72f-2fa024238301")    #$ID = [guid]($aBadView.ID)
$BadView = $List.Views[$ID]
$BadView.Title = "Subject"
$BadView.Hidden = $false
$BadView.Update()

Run the first part of script again to verify.