DESCRIPTION - Run this script to deploy/retract the farm level solution and activate/deactivate features

GOAL - Build the most generic farm level soution deployment script

ASSUMPTION - Batch files, log files, and WSPs exists in same directory during deployment process

MAJOR FEATURES IMPLEMENTED

HOW TO Use It using Batch Files?

powershell -Command "& {Set-ExecutionPolicy bypass}" -NoExit
powershell -Command "& {.\SPSolutionDeploymentScript.ps1 -solutionName:CustomHomePage.wsp -webAppUrl:http://sp2010vm -siteUrl:http://sp2010vm -siteFeatureNames:@('CustomHomePage_CustomHomeWidgets') -webFeatureNames:@('CustomHomePage_CustomHomePage') -logFileName:DeploySolution.log -action:SD}" -NoExit
pauseRetraction Step

powershell -Command "& {Set-ExecutionPolicy bypass}" -NoExit
powershell -Command "& {.\SPSolutionDeploymentScript.ps1 -solutionName:CustomHomePage.wsp -webAppUrl:http://sp2010vm -siteUrl:http://sp2010vm -siteFeatureNames:@('CustomHomePage_CustomHomeWidgets') -webFeatureNames:@('CustomHomePage_CustomHomePage') -logFileName:RetractSolution.log -action:SR}" -NoExit
pause 

 

PowerShell
Edit|Remove
param ( 
    [string]$solutionName = "$(Read-Host 'Enter the Solution WSP Name. [e.g. Sample.wsp]')", 
    [string]$webAppUrl = "$(Read-Host 'Enter the Web Application URL. [e.g. http://sp2010vm]')", 
    [string]$siteUrl = "$(Read-Host 'Enter the Site Collection URL. [e.g. http://sp2010vm/sites/site]')", 
    [string[]]$siteFeatureNames = $null#"$(Read-Host 'Enter the Site Level Features. [e.g. @('Feature1', 'Feature2')]')", 
    [string[]]$webFeatureNames = $null#"$(Read-Host 'Enter the Web Level Features. [e.g. @('Feature1', 'Feature2')]')", 
    [string]$logFileName = "$(Read-Host 'Enter the Log File Name. [e.g. Sample.log]')", 
    [string]$action = "$(Read-Host 'Enter [SD] to deploy solutions or [SR] to retract the solution')" 
) 
 
# Defination of main function 
function main() { 
    # find the current directory  
    $currentDirectory = Get-Location 
             
    # delete existing logfile 
    $logFilePath = "$currentDirectory\$logFileName" 
    if (Test-Path $logFilePath) 
    { 
        Remove-Item $logFilePath 
    } 
     
    # create new log file and start logging  
    Start-Transcript $logFilePath 
 
    # check to ensure Microsoft.SharePoint.PowerShell is loaded 
    $snapin = Get-PSSnapin | Where-Object {$_.Name -eq 'Microsoft.SharePoint.Powershell'} 
    if ($snapin -eq $null)  
    { 
        Write-Host "Loading SharePoint Powershell Snapin" 
        Add-PSSnapin "Microsoft.SharePoint.Powershell" 
    } 
     
    # deploy the solution 
    if ($action -eq "SD") 
    { 
        Write-Host "Step 1 - Add Solution Package: " $solutionName -foregroundcolor Green 
        AddSolution 
         
        Write-Host "Step 2 - Deploy Solution Package: " $solutionName -foregroundcolor Green 
        InstallSolution 
         
        Write-Host "Step 3 - Timer Job to deploy the Solution Package" -foregroundcolor Green 
        Wait4TimerJob 
 
        Write-Host "Step 4 - Activate Site Collection Level Features" -foregroundcolor Green 
        ActivateSiteFeatures 
         
        Write-Host "Step 5 - Activate Web Level Features" -foregroundcolor Green 
        ActivateWebFeatures 
    }     
     
    # retract the solution 
    if ($action -eq "SR") 
    { 
        Write-Host "Step 1 - Deactivate Web Level Features" -foregroundcolor Green 
        DeactivateWebFeatures 
         
        Write-Host "Step 2 - Deactivate Site Collection Level Features" -foregroundcolor Green 
        DeactivateSiteFeatures 
         
        Write-Host "Step 3 - Uninstall Solution Package: " $solutionName -foregroundcolor Green 
        UnInstallSolution 
         
        Write-Host "Step 4 - Timer Job to Retract the Solution Package" -foregroundcolor Green 
        Wait4TimerJob 
         
        Write-Host "Step 5 - Remove Solution Package: " $solutionName -foregroundcolor Green 
        RemoveSolution 
    } 
     
    # stop the logging 
    Stop-Transcript 
} 
 
# Add the solution package 
# Adds a SharePoint solution package to the farm Solution gallery, It doesn't deploy the uploaded solution yet. 
function AddSolution() 
{ 
    $solution = Get-SPSolution | where-object {$_.Name -eq $solutionName} 
    if ($solution -eq $null)  
    { 
        Write-Host "Adding solution package" -foregroundcolor Yellow 
        $solutionPath = "$currentDirectory\$solutionName" 
        Add-SPSolution -LiteralPath $solutionPath -Confirm:$false 
    } 
} 
 
# Deploy the solution package     
# Deploys an installed SharePoint solution on all the WFE servers in the farm.  
# Deploying solution in the farm installs the feature automatically. It installs all the features  
# on each server at the farm, web, site collection, and site level but It doesn't activate them. 
# Since it provisions the file on each WFE, it is a timer job. 
function InstallSolution() 
{ 
    $solution = Get-SPSolution | where-object {$_.Name -eq $solutionName} 
    $solutionId = $solution.Id 
    if ($solution -ne $null) 
    { 
        $solutionDeployed = Get-SPSolution -Identity $solutionId | where-object {$_.Deployed -eq "False"} 
        if ($solutionDeployed -eq $null)  
        { 
            if ( $solution.ContainsWebApplicationResource )  
            { 
                Write-Host "Deploying solution package to web application: " $webAppUrl -foregroundcolor Yellow 
                Install-SPSolution -Identity $solutionName -WebApplication $webAppUrl -GACDeployment -Confirm:$false 
            } 
            else 
            { 
                Write-Host "Deploying solution package to all web applications" -foregroundcolor Yellow 
                Install-SPSolution -Identity $solutionName -GACDeployment -Confirm:$false 
            } 
        } 
    } 
} 
 
# Activate the Site level features 
function ActivateSiteFeatures() 
{     
    if ($siteFeatureNames -ne $null) 
    { 
        $spSite = Get-SPSite $siteUrl         
        foreach($siteFeatureName in $siteFeatureNames) 
        { 
            Write-Host "Trying to Activate Site Collection Level Feature: " $siteFeatureName -foregroundcolor Yellow 
            $siteFeature = Get-SPFeature -site $spSite.url | where-object {$_.displayname -eq $siteFeatureName} 
            if ($siteFeature -eq $null)  
            { 
                Write-Host "Activating Site Level Features at " $spSite.url -foregroundcolor Yellow 
                Enable-SPFeature –identity $siteFeatureName -URL $spSite.url -Confirm:$false 
            } 
        }         
        $spSite.Dispose() 
    } 
} 
 
# Activate the Web level features 
function ActivateWebFeatures() 
{ 
    if ($webFeatureNames -ne $null) 
    { 
        $spSite = Get-SPSite $siteUrl  
     
        #Cycle through all webs in the collection and activate all the features 
        foreach($spWeb in $spSite.AllWebs) 
        {   
            foreach($webFeatureName in $webFeatureNames) 
            {         
                Write-Host "Trying to Activate Web Level Features: " $webFeatureName -foregroundcolor Yellow 
                $webFeature = Get-SPFeature -web $spWeb.url | where-object {$_.displayname -eq $webFeatureName}     
                if ($webFeature -eq $null)  
                { 
                    Write-Host "Activating " $webFeatureName " at " $spWeb.url -foregroundcolor Yellow 
                    Enable-SPFeature –identity $webFeatureName -URL $spWeb.url -Confirm:$false 
                } 
            } 
        } 
         
        $spWeb.Dispose() 
        $spSite.Dispose() 
    } 
} 
 
# Deactivate the Web level features 
function DeactivateWebFeatures() 
{ 
    if ($webFeatureNames -ne $null) 
    { 
        $spSite = Get-SPSite $siteUrl  
     
        #Cycle through all webs in the collection and deactivate all the features 
        foreach($spWeb in $spSite.AllWebs) 
        {   
            foreach($webFeatureName in $webFeatureNames) 
            {         
                Write-Host "Trying to Deactivate Web Level Features: " $webFeatureName -foregroundcolor Yellow 
                $webFeature = Get-SPFeature -web $spWeb.url | where-object {$_.displayname -eq $webFeatureName}     
                if ($webFeature -ne $null)  
                { 
                    Write-Host "Deactivating " $webFeatureName " at " $spWeb.url -foregroundcolor Yellow 
                    Disable-SPFeature –identity $webFeatureName -URL $spWeb.url -Confirm:$false 
                } 
            } 
        } 
         
        $spWeb.Dispose() 
        $spSite.Dispose() 
    } 
} 
 
# Deactivate the Site level features 
function DeactivateSiteFeatures() 
{ 
    if ($siteFeatureNames -ne $null) 
    { 
        $spSite = Get-SPSite $siteUrl 
        foreach($siteFeatureName in $siteFeatureNames) 
        { 
            Write-Host "Trying to Deactivate Site Collection Level Feature: " $siteFeatureName -foregroundcolor Yellow 
            $siteFeature = Get-SPFeature -site $spSite.url | where-object {$_.displayname -eq $siteFeatureName} 
            if ($siteFeature -ne $null)  
            { 
                Write-Host "Deactivating Site Level Features at " $spSite.url -foregroundcolor Yellow 
                Disable-SPFeature –identity $siteFeatureName -URL $spSite.url -Confirm:$false 
            }    
        }     
        $spSite.Dispose() 
    } 
} 
 
# Retract the solution package 
# Retracts a deployed SharePoint solution from the farm entirely for all web application or given web application. 
# This step removes files from all the front-end Web server. 
# Please note that retracting solution in the farm uninstalls the feature automatically, if it hasn't uninstalled using UnInstall-SPFeature.  
# Since it removes the file on each WFE, it is a timer job. 
function UnInstallSolution() 
{ 
    $solution = Get-SPSolution | where-object {$_.Name -eq $solutionName} 
    $solutionId = $solution.Id 
    if ($solution -ne $null) 
    { 
        $solutionDeployed = Get-SPSolution -Identity $solutionId | where-object {$_.Deployed -eq "True"} 
        if ($solutionDeployed -ne $null)          
        {     
            if ( $solution.ContainsWebApplicationResource )  
            { 
                Write-Host "Retracting solution package from web application: " $webAppUrl -foregroundcolor Yellow 
                UnInstall-SPSolution -Identity $solutionName -WebApplication $webAppUrl -Confirm:$false 
            } 
            else 
            { 
                Write-Host "Retracting solution package from all web applications" -foregroundcolor Yellow 
                UnInstall-SPSolution -Identity $solutionName -Confirm:$false 
            } 
        } 
    } 
} 
 
# Remove the solution package 
# Deletes a SharePoint solution from a farm solution gallery 
function RemoveSolution() 
{ 
    $solution = Get-SPSolution | where-object {$_.Name -eq $solutionName} 
    if ($solution -ne $null)  
    { 
        Write-Host "Deleting the solution package" -foregroundcolor Yellow 
        Remove-SPSolution $solutionName -Confirm:$false 
    } 
} 
 
# Wait for timer job during deploy and retract 
function Wait4TimerJob() 
{  
    $solution = Get-SPSolution | where-object {$_.Name -eq $solutionName} 
    if ($solution -ne $null)  
    { 
        $counter = 1    
        $maximum = 50    
        $sleeptime = 2   
         
        Write-Host "Waiting to finish soultion timer job" 
        while( ($solution.JobExists -eq $true ) -and ( $counter -lt $maximum ) )  
        {    
            Write-Host "Please wait..." 
            sleep $sleeptime   
            $counter++    
        } 
         
        Write-Host "Finished the solution timer job"          
    } 
} 
 
#Run the Main Function 
main