Compare Features and WSP Solutions between farms using PowerShell

Posted: August 12, 2014 in SharePoint PowerShell

When working on a specific farm, you may find that you have multiple farms per environment, for example:

Production, Stage, Test and Development farms.

It could be nice to be able to compare WSP packages and features across farms.

I’ve written a script (MapCheckFeature&WSP_Global.ps1) that has two options of MAP and COMPARE a farms’ (the ideal farm, FarmA) enabled features and its WSP solution status.

Instructions:

  1. Run MapCheckFeature&WSP_Global.ps1 and Choose MAP on ideal farm, FarmA. (A reference file is created on the path C:\)
  2. Copy over Reference file to the farm (FarmB) you want to compare to.  You want the file located on C:\On FarmB; Run MapCheckFeature&WSP_Global.ps1 and Choose CHECH
  3. Look at the results.
  4. Done!

Options:

You may want to add Site Collections that have other URLs than the WebApplications. To add these, simply choose the option in the script. It will ask if you want to add custom URLs. But remember to add the same custom URLs when mapping and checking if you want the costum Site Collection features to be compared.

Basically adding URLs would be like:

MAPPING (Production FarmA): http://portal.com/ITdep

CHECKING (Stage FarmB): http://portal.com-stage/ITdep

The script splits the URL at “-“, and “/”, getting the right name for the site collection to compare to the other site collection.

File:

newdl

Code:


<#====================================================================
 Copyright © 2014, february. Bjørn Roalkvam
 www.SharePointbjorn.com, bjorn80@gmail.com 
 
 Description:
 
 MapFeature&WSP_Global.ps1 - Maps the farm feature/wsp packages (Creates a reference file on C:\).
 CheckFeature&WSP_Global.ps1 - Checks the farm the script is running on using the reference file (which has to be on c:\).
 
 
 Always test all scripts you find in an test environment prior to production:-), 
 you are a responsible SharePoint Administrator afterall!
====================================================================#>
 
#Check features and WSP packages
 
#--------------------------------
#Add SharePoint tools:
#--------------------------------
if (!(Get-PSSnapin -Name microsoft.sharepoint.powershell -EA "SilentlyContinue"))
{
    Add-PsSnapin microsoft.sharepoint.powershell
}
 
 
Write-Host -f Yellow "Would you like to to MAP or CHECK current farm?"
Write-Host -f Yellow "Type <M> for MAP"
Write-Host -f Yellow "Type <C> for Check"
$answer = Read-Host "Choose M or C"
 
 
 
if($answer -eq "M")
{
 
#==========================================================================================
#==========================================================================================
#==========================================================================================
#MAP SYSTEM
#==========================================================================================
#==========================================================================================
#==========================================================================================
 
 
 
#==========================================================================================
# Set Window Size
#==========================================================================================
$pshost = get-host
$pswindow = $pshost.ui.rawui
 
$newsize = $pswindow.buffersize
$newsize.height = 3000
$newsize.width = 110
$pswindow.buffersize = $newsize
 
$newsize = $pswindow.windowsize
$newsize.height = 65
$newsize.width = 110
$pswindow.windowsize = $newsize
 
 
#==========================================================================================
# URL management
#==========================================================================================
#WebAPplications:
[Array]$WebApplications = get-spwebapplication -ErrorAction "SilentlyContinue" | ForEach-Object {$_.url}
 
 
foreach ($sites in $WebApplications)
    {
    if($sites[-1] -eq "/"){$sites = $sites -replace ".$"}
    if(get-spsite $sites -ErrorAction "SilentlyContinue")
        {
        [Array]$SiteCollections += $sites
        }  
    }
 
 
 
#==========================================================================================
# Variables
#==========================================================================================
#SCript automatically runs on the site collections that have the same URL as the webapplication. Define other site collection URLS under. Seperate with comma:
 
Write-Host ""
Write-Host -f DarkYellow "Script will automatically map all webapplication WSP & feature status."
Write-Host -f DarkYellow "Script will automatically map all Site collection that have the exact same url as the webapplications."
Write-Host ""
$addSiteURL = Read-host "Would you like to add more Site collections? Type <Y> for Yes or any other key for NO"
Write-Host ""
 
#The network folder where the WSP solution packages lie
$WSPFilePath = '\\sgm810\Drops\Full deploy\' #The File path where the deploy package are located.
 
if($addSiteURL -eq "y" -or $addSiteURL -eq "Y")
{
 
    if(!($addmoreSiteCollections))
    {
    #Give the user an option to input custom site collection URL
    $addmoreSiteCollections = Read-Host '"Type inn site collection url with http://portal.com"'
 
    #Check if real
        foreach ($testSite in $addmoreSiteCollections)
        {
        if(!(get-spsite $testSite -ea "SilentlyContinue")){Write-Host -f Yellow "The custom site collection does not exist. Please run script again!!"; Read-Host; exit}
        }
    }
}
 
 
 
 
 
#==========================================================================================
# Custom URL management
#==========================================================================================
#Add user urls
 
if($addmoreSiteCollections)
{
$SiteCollections += $addmoreSiteCollections
}
 
 
 
#==========================================================================================
#Reference file and path
#=========================================================================================
$Referencefile = "c:\referenceFile.ps1"
 
#If reference file already exists, delete it.
if(Test-Path c:\referenceFile.ps1){write-host -ForegroundColor Yellow "An old Reference file has been found, removing it.."; Remove-Item c:\referenceFile.ps1}
 
 
 
#==========================================================================================
#Created a function for removing the comma in the last object of an array
#=========================================================================================
 
Function RemoveLastComma ([Array]$Arraylist,$VarName)
{
#Find last object in array:
[Array]$LastArrayObj = $Arraylist[-1]
 
#Remove last object that has a comma from array:
$Arraylist = $Arraylist | ?{$_ -ne $Arraylist[-1]}
 
#Remove the last character in this last object
$LastArrayObj = $LastArrayObj -replace ".$"
 
#Add last object back into array:
$Arraylist += $LastArrayObj
 
#add array to reference file:
 
if($Arraylist){ add-content $Referencefile ("[Array]" +"$" + $VarName + " = " + $Arraylist) }
 
}
 
 
 
#==========================================================================================
#Collect farm features
#==========================================================================================
 
#Get Farm Features from environment and save it into an variable:
$FarmFeatures = Get-SPFeature -farm | ?{$_.status -eq "online" -and $_.hidden -eq $false} | ForEach-Object {$_.Displayname}
$FarmFeatures = $FarmFeatures | ForEach-Object {'"' + $_ + '"' + ','}
 
#Remove comma in last object with function
RemoveLastComma $FarmFeatures "FarmFeatures"
 
 
 
#==========================================================================================
#Collect Web Application features
#==========================================================================================
 
 
foreach ($WebApp in $WebApplications)
    {
    $TheVar = $false
    $compareToArray = $false
    $Name = $false    
    $WebappURL = $false
    $WebappURL = get-spwebapplication $WebApp -ErrorAction "SilentlyContinue" | ForEach-Object {$_.url}    
 
    #Clean url to $Name and Create a variable based on the $Name
    #-----------
    $Name = $WebappURL
    $Name = $Name.split("/")
 
    #If the custom WEbapplication is at the http://portal.com/webapplicationName meaning its on line 3 of the array:
    if($Name[3]){$Name = $Name[3]}
 
    #if not use the same name as the webapplication:
    if(!($Name[3])){$Name = $Name[2]}
 
    if($Name -like "*-*"){$Name = $Name.split("-"); $Name = $Name[0]}
    if(!($Name -like "*-*")){$Name = $Name.split("."); $Name = $Name[0]}
    #-----------
 
    $TheVar = (Get-SPFeature -WebApplication $WebappURL -ErrorAction "SilentlyContinue" | ?{$_.status -eq "online" -and $_.hidden -eq $false} | ForEach-Object {$_.Displayname})
    $TheVar = $TheVar | ForEach-Object {'"' + $_ + '"' + ','}
    #Remove comma in last object with function
    if($TheVar){ RemoveLastComma $TheVar ($Name + "WebappFeatures") }
    }
 
 
 
 
 
#==========================================================================================
#Collect SiteScope site collection features
#==========================================================================================
 
 
 
foreach ($Site in $SiteCollections)
    {
    $TheVar = $false
    $compareToArray = $false
    $Name = $false    
    $SiteURL = $false
    $SiteURL = get-spsite $Site -EA "SilentlyContinue" | ForEach-Object {$_.url}    
 
    #Clean url to $Name and Create a variable based on the $Name
    #-----------
    $Name = $SiteURL
    $Name = $Name.split("/")
 
    #If the custom site collection is at the http://portal.com/customsitecollectionname meaning its on line 3 of the array:
    if($Name[3]){$Name = $Name[3]}
 
    #if not use the same name as the webapplication:
    if(!($Name[3])){$Name = $Name[2]}
 
    if($Name -like "*-*"){$Name = $Name.split("-"); $Name = $Name[0]}
    if(!($Name -like "*-*")){$Name = $Name.split("."); $Name = $Name[0]}
    #-----------
 
    $TheVar = Get-SPFeature -site $SiteURL -ErrorAction "SilentlyContinue" | ?{$_.status -eq "online" -and $_.hidden -eq $false -and $_.scope -eq "site"} | ForEach-Object {$_.Displayname}
    $TheVar = $TheVar | ForEach-Object {'"' + $_ + '"' + ','}
    #Remove comma in last object with function
    if($TheVar){ RemoveLastComma $TheVar ($Name + "SITEFeatures") }
    }
 
 
 
 
 
#==========================================================================================
#Collect WebScope site collection features
#==========================================================================================
 
 
 
foreach ($Site in $SiteCollections)
    {
    $TheVar = $false
    $compareToArray = $false
    $Name = $false    
    $SiteURL = $false
    $SiteURL = get-spsite $Site -EA "SilentlyContinue" | ForEach-Object {$_.url}    
 
    #Clean url to $Name and Create a variable based on the $Name
    #-----------
    $Name = $SiteURL
    $Name = $Name.split("/")
 
    #If the custom site collection is at the http://portal.com/customsitecollectionname meaning its on line 3 of the array:
    if($Name[3]){$Name = $Name[3]}
 
    #if not use the same name as the webapplication:
    if(!($Name[3])){$Name = $Name[2]}
 
    if($Name -like "*-*"){$Name = $Name.split("-"); $Name = $Name[0]}
    if(!($Name -like "*-*")){$Name = $Name.split("."); $Name = $Name[0]}
    #-----------
 
    $TheVar = (Get-SPFeature -web $Site -EA "SilentlyContinue" | ?{$_.status -eq "online" -and $_.hidden -eq $false -and $_.scope -eq "web"} | ForEach-Object {$_.Displayname})
    $TheVar = $TheVar | ForEach-Object {'"' + $_ + '"' + ','}
    #Remove comma in last object with function
    if($TheVar){ RemoveLastComma $TheVar ($Name + "WEBFeatures") }
    }
 
 
 
 
#==========================================================================================
#Collect WSP info
#==========================================================================================
 
#All WSP
$AllWSP = Get-SPSolution | ForEach-Object {$_.Name}
$AllWSP = $AllWSP | ForEach-Object {'"' + $_ + '"' + ','}
#Remove comma in last object with function
RemoveLastComma $AllWSP "AllWSP"
 
 
#Deployed WSP
$DeployedWSP = Get-SPSolution | ? {$_.deployed -eq $true} | ForEach-Object {$_.Name}
$DeployedWSP = $DeployedWSP | ForEach-Object {'"' + $_ + '"' + ','}
#Remove comma in last object with function
RemoveLastComma $DeployedWSP "DeployedWSP"
 
 
$NotDeployedWSP = Get-SPSolution | ? {$_.deployed -eq $false} | ForEach-Object {$_.Name}
$NotDeployedWSP = $NotDeployedWSP | ForEach-Object {'"' + $_ + '"' + ','}
#Remove comma in last object with function
RemoveLastComma $NotDeployedWSP "NotDeployedWSP"
 
 
 
 
Write-Host -ForegroundColor Green "New WPS & Features list recorded in c:\referenceFile.ps1"
ii c:\
sleep 4
read-host
exit
 
 
}
 
 
 
 
if($answer -eq "C")
{
 
 
#==========================================================================================
#==========================================================================================
#==========================================================================================
#CHECK AND COMPARE
#==========================================================================================
#==========================================================================================
#==========================================================================================
 
 
 
 
#==========================================================================================
# Set Window Size
#==========================================================================================
$pshost = get-host
$pswindow = $pshost.ui.rawui
 
$newsize = $pswindow.buffersize
$newsize.height = 3000
$newsize.width = 110
$pswindow.buffersize = $newsize
 
$newsize = $pswindow.windowsize
$newsize.height = 65
$newsize.width = 110
$pswindow.windowsize = $newsize
 
 
#--------------------------------
#Add SharePoint tools:
#--------------------------------
 
if (!(Get-PSSnapin -Name microsoft.sharepoint.powershell -EA "SilentlyContinue"))
{
    Add-PsSnapin microsoft.sharepoint.powershell
}
 
cls
 
 
#==========================================================================================
# URL management
#==========================================================================================
#WebAPplications:
[Array]$WebApplications = get-spwebapplication -ErrorAction "SilentlyContinue" | ForEach-Object {$_.url}
 
 
foreach ($sites in $WebApplications)
    {
    if($sites[-1] -eq "/"){$sites = $sites -replace ".$"}
    if(get-spsite $sites -ea "SilentlyContinue")
        {
        [Array]$SiteCollections += $sites
        }  
    }
 
 
 
#==========================================================================================
# Variables
#==========================================================================================
 
#The script checks for the newest folder in the location you specify. The idea behind this was that developers create new versions of the solution files and put these in new folders.
#If you have a single folder at "\\share\WSP_Packages\newestWSP", it is enough to specify "\\share\WSP_Packages\.
 
#So if your WSP package are located in the folder  "\\share\WSP_Packages\newestWSP"
#You will want to put the location "\\share\WSP_Packages\" in the variable.
 
 
#The network folder where the WSP solution packages lie, if this path does not exist the WSP packages against this location will not be checked.
$WSPFilePath = '\\hostname\wspfolder\' #The File path where the deploy package are located.
 
 
 
#==========================================================================================
#Feature compare function!:P
#==========================================================================================
 
 
Function CompareFeature ($currentfeatures, $ListetFeatures, $FeatureScope)
    {
    [Array]$A = ""
    [Array]$B = ""
 
 
    $CompareFeatures = Compare-Object $currentfeatures $ListetFeatures
    $CompareFeatures | ForEach-Object {if($_.SideIndicator -eq "<="){$A += ($_.InputObject)}}
    $CompareFeatures | ForEach-Object {if($_.SideIndicator -eq "=>"){$B += ($_.InputObject)}}
     
    if($A)
        {
        Write-Host ""
        Write-Host -f DarkGray ("Feature Scope: " + $FeatureScope)
        Write-Host ("You need to DEACTIVATE the following feature(s):")
        Write-Host "------------------";
        $A = $A | ?{$_ -ne $A[0]}
        $A | ForEach-Object { write-host -ForegroundColor Cyan $_}
        Write-Host "------------------"
        Write-Host ""
        }
 
    if($B)
        {
        Write-Host ""
        Write-Host -f DarkGray ("Feature Scope: " + $FeatureScope)
        Write-Host ("You need to ACTIVATE the following feature(s):")
        Write-Host "------------------";
        $B = $B | ?{$_ -ne $B[0]}
        $B | ForEach-Object { write-host -ForegroundColor Cyan $_}
        Write-Host "------------------"
        Write-Host ""
        }
      
            
    }#End of function
 
 
 
#==========================================================================================
# WSP SOlution compare function!:P
#==========================================================================================
 
 
Function CompareWSP ($currentWSP, $ListetWSP)
    {
    [Array]$A = ""
    [Array]$B = ""
 
 
    $CompareFeatures = Compare-Object $currentWSP $ListetWSP
    $CompareFeatures | ForEach-Object {if($_.SideIndicator -eq "<="){$A += ($_.InputObject)}}
    $CompareFeatures | ForEach-Object {if($_.SideIndicator -eq "=>"){$B += ($_.InputObject)}} 
     
    if($A)
        {
        if($InstalledWSP){$message = ("You need to install the following solution(s):")}
        if($ActiveWSP){$message = "You need to deploy the following solution(s):"}
        Write-Host ""
        Write-Host $message
        Write-Host "------------------";
        $A = $A | ?{$_ -ne $A[0]}
        $A | ForEach-Object { write-host -f Cyan $_}
        Write-Host "------------------"
        Write-Host ""
        }
 
    if($B)
        {
        if($InstalledWSP){$message = ("You need to Uninstall the following solution(s):")}
        if($ActiveWSP){$message = "You need to Retract the following solution(s):"}
        Write-Host ""
        Write-Host $message
        Write-Host "------------------";
        $B = $B | ?{$_ -ne $B[0]}
        $B | ForEach-Object { write-host -f Cyan $_}
        Write-Host "------------------"
        Write-Host ""
        }
      
            
    }#End of function
 
#==========================================================================================
# Feature/WSP reference file
#==========================================================================================
 
if(Test-Path c:\referencefile.ps1){write-host ""; Write-Host -ForegroundColor DarkYellow "Reference file - Found - OK"; . C:\referenceFile.ps1; write-host ""; write-host ""; } #$listfile = "the reference file"
 
if(!(Test-Path c:\referencefile.ps1)){write-host ""; Write-Host -ForegroundColor DarkYellow "Can't find reference file. You will need to run the MapFeature&WSP.PS1 to map evenvironment first. Press the any key to quit";Read-Host; exit}
 
 
 
#==========================================================================================
# User input
#==========================================================================================
 
Write-Host ""
Write-Host "------------------------------------------------------------------------------------"
Write-Host -f DarkGray "Script will automatically check all webapplication WSP & feature status against the reference file."
Write-Host -f DarkGray "Script will automatically check all Site collection that have the exact same url as the webapplications against the reference file."
Write-Host "------------------------------------------------------------------------------------"
Write-Host ""
$addSiteURL = Read-host "Would you like to add more Site collections? Type <Y> for Yes or any other key for NO"
Write-Host ""
 
 
if($addSiteURL -eq "y" -or $addSiteURL -eq "Y")
{
 
    if(!($addmoreSiteCollections))
    {
    #Give the user an option to input custom site collection URL
    $addmoreSiteCollections = Read-Host '"Type inn site collection url with http://portal.com/siteCollection"'
 
    #Check if real
        foreach ($testSite in $addmoreSiteCollections)
        {
        if(!(get-spsite $testSite -ea "SilentlyContinue")){Write-Host "The custom site collection does not exist. Please run script again!!"; Read-Host; exit}
        }
    }
}
 
 
 
#==========================================================================================
# Custom URL management
#==========================================================================================
 
 
if($addmoreSiteCollections)
{
$SiteCollections += $addmoreSiteCollections
}
 
 
#==========================================================================================
# Check to see that the custom site collection exists in the reference file
#==========================================================================================
 
 
if($addmoreSiteCollections)
{
    foreach ($addmoreSite in $addmoreSiteCollections)
    {
    $addmoreSite = $addmoreSite.split("/")
 
    #If the custom site collection is at the http://portal.com/customsitecollectionname meaning its on line 3 of the array:
    if($addmoreSite[3]){$addmoreSite = $addmoreSite[3]}
 
    #if not use the same name as the webapplication:
    if(!($addmoreSite[3])){$addmoreSite = $addmoreSite[2]}
 
    if($addmoreSite -like "*-*"){$addmoreSite = $addmoreSite.split("-"); $addmoreSite = $addmoreSite[0]}
    if(!($addmoreSite -like "*-*")){$addmoreSite = $addmoreSite.split("."); $addmoreSite = $addmoreSite[0]}
 
    $referenceContent = Get-Content C:\referenceFile.ps1
 
    if(!($referenceContent -like "*$addmoreSite*")) { Write-Host -f Yellow "$addmoreSite does not exist in the reference file. You will need to run the MapFeature&WSP.PS1 again and add this URL first. press any key to exit"; Read-Host; exit}
    }
 
}
 
 
#==========================================================================================
# Compare WSP packages to solutions on network (WSP share folder)
#==========================================================================================
 
 
 
Write-Host ""
Write-Host "=========================================================================================="
Write-Host -ForegroundColor green "WSP PACKAGE SECTION"
Write-Host "=========================================================================================="
 
#Checks if the path is $null, if not, then continues.
if($WSPFilePath)
{
    #Checks if the path is valid.
    if(!(Test-Path $WSPFilePath -EA "SilentlyContinue")){write-host -f yellow "Valid WSP folder location not specified, this check is skipped."}
    Write-Host ""
 
 
    if(Test-Path -ea "SilentlyContinue" $WSPFilePath)
    {
 
        #Finding the newest WSP package folder:
        $WSPFolder = Get-ChildItem $WSPFilePath | ? { $_.PSIsContainer } | sort CreationTime -desc | select -f 1
        $WSPPAckages = $WSPFolder.name
 
        #Filtering WSP files and getting their file name:
        $DeployFolder = Get-ChildItem ($WSPFilePath + $WSPPAckages) | ?{$_.name -like "*wsp*"} | foreach { $_.Name }
 
        #Installed WSP packages:
        $InstalledWSP = Get-SPSolution | foreach { $_.Name }
 
        #Compare the two:
        [Array]$A = ""
        [Array]$B = ""
        $comparing = Compare-Object $DeployFolder $InstalledWSP
        $comparing | ForEach-Object {if($_.SideIndicator -eq "<="){$A += ($_.InputObject)}}
 
        #Check to see if the installed solutions are deployed:
        $comparingEqual = Compare-Object $DeployFolder $InstalledWSP -IncludeEqual
        $comparingEqual | ForEach-Object {if($_.SideIndicator -eq "=="){$B += ($_.InputObject)}}
 
        #Check to see of the current packages are all deployed:
 
 
        if(Get-SPSolution | ?{$_.deployed -eq $False}) #If there are solutions that are not deployed, then execute code in "if" bracket.
            {
            Get-SPSolution | ForEach-Object {if (-not $_.deployed){write-host "";write-host ""; write-host "The following Solutions are not deployed:"; write-host "------------------";Write-Host -ForegroundColor Cyan $_.name; write-host "------------------";}}
     
            }
 
        if(!(Get-SPSolution | ?{$_.deployed -eq $False})) #If there are solutions that are not deployed, then execute code in "if" bracket.
            {
            write-host ""
            write-host "Deployed WSP Package status:"
            write-host "------------------"
            write-host -ForegroundColor Cyan "A-okay!"; 
            write-host "------------------"
            }
 
 
        #Filter away "Microsoft.Practices.SharePoint.Common.LoggerProxy.wsp"
        if($A -eq "Microsoft.Practices.SharePoint.Common.LoggerProxy.wsp"){ $A = $A | ?{$_ -ne "Microsoft.Practices.SharePoint.Common.LoggerProxy.wsp"}
        }
 
        Write-Host " "
 
 
        #Check if there are any values in $A, if yes then do code in bracket.
        if($A) 
            {
            write-host "";
            Write-Host ("You are missing the following packages compared to the $WSPFilePath" + $WSPPAckages + " folder")
            write-host "------------------";
            $A | foreach-object {write-host -ForegroundColor Cyan $_}
            write-host "------------------";
            }
 
        #Check if there are any values in $A, if NO then do code in bracket.
        if(!$A) 
            {
            write-host "";
            write-host "WSP Package Count:"
            write-host "------------------";
            Write-Host -ForegroundColor Cyan ("A-Okay! No packages missing compared to the $WSPFilePath" + $WSPPAckages + " folder.")
            write-host "------------------";}
            write-host ""
    }
 
}
#==========================================================================================
#Comparing WSP solutions to reference file *******************************************************************************************må se litt her
#==========================================================================================
if($DeployedWSP)
{
    if($InstalledWSP -and $AllWSP)
    {
    #All WSP installed comared to reference file
    CompareWSP $AllWSP $InstalledWSP
    }
 
    #All deployed WSP compared to reference file, compare if both arrays exist
 
    $ActiveWSP = Get-SPSolution -ErrorAction "SilentlyContinue" | ? {$_.deployed -eq $true} | ForEach-Object {$_.Name}
    if($ActiveWSP -and $DeployedWSP)
    {
    CompareWSP $DeployedWSP $ActiveWSP
    }
 
}
 
 
#==========================================================================================
#Comparing FARM features to our list of features:
#==========================================================================================
Write-Host ""
Write-Host ""
Write-Host "=========================================================================================="
Write-Host -ForegroundColor green "FARM FEATURE SECTION"
Write-Host "=========================================================================================="
Write-Host ""
 
$CurrentFarmFeatures = Get-SPFeature -farm | ?{$_.status -eq "online" -and $_.hidden -eq $false} | ForEach-Object {$_.Displayname}
 
#Parametere:  Aktive-features listet-features og type-features
CompareFeature $CurrentFarmFeatures $FarmFeatures "Farm"
     
 
#==========================================================================================
#Comparing Webapplication features list of features:
#==========================================================================================
Write-Host "=========================================================================================="
Write-Host -ForegroundColor green "WEBAPPLICATION FEATURE SECTION"
Write-Host "=========================================================================================="
Write-Host ""
 
foreach ($WebApp in $WebApplications)
    {
    $TheVar = $false
    $compareToArray = $false
    $newVAr = $false
    $Name = $false
    $WebappURL = get-spwebapplication $WebApp -ErrorAction "SilentlyContinue" | ForEach-Object {$_.url}    
 
    #Clean url to $Name and Create a variable based on the $Name
    $Name = $WebappURL
    $Name = $Name.split("/")
    $Name = $Name[2]
    if($Name -like "*-*"){$Name = $Name.split("-"); $Name = $Name[0]}
    if(!($Name -like "*-*")){$Name = $Name.split("."); $Name = $Name[0]}
 
 
    #Adding feature array list to our magical variable 
    $TheVar = (Get-SPFeature -WebApplication $WebApp -ErrorAction "SilentlyContinue" | ?{$_.status -eq "online" -and $_.hidden -eq $false} | ForEach-Object {$_.Displayname})
 
    #Get the list variable or reference variable:
    $compareToArray = Get-Variable -Name $($Name + "WebappFeatures") -EA "SilentlyContinue" | ForEach-Object {$_.Value}
    if($TheVar){ CompareFeature $TheVar $compareToArray ("Webapplication - "  + $WebappURL) }
    }
 
     
    write-host ""
 
#==========================================================================================
#Comparing Site Collection SITEScope features to our list:
#==========================================================================================
Write-Host "=========================================================================================="
Write-Host -ForegroundColor green "SITE FEATURE SECTION"
Write-Host "=========================================================================================="
Write-Host ""
 
foreach ($Site in $SiteCollections)
    {
    $TheVar = $false
    $compareToArray = $false
    $Name = $false    
    $SiteURL = $false
    $SiteURL = get-spsite $Site -EA "SilentlyContinue" | ForEach-Object {$_.url}    
 
    #Clean url to $Name and Create a variable based on the $Name
    #-----------
    $Name = $SiteURL
    $Name = $Name.split("/")
 
    #If the custom site collection is at the http://portal.com/customsitecollectionname meaning its on line 3 of the array:
    if($Name[3]){$Name = $Name[3]}
 
    #if not use the same name as the webapplication:
    if(!($Name[3])){$Name = $Name[2]}
 
    if($Name -like "*-*"){$Name = $Name.split("-"); $Name = $Name[0]}
    if(!($Name -like "*-*")){$Name = $Name.split("."); $Name = $Name[0]}
    #-----------
 
    #Adding feature array list to our magical variable 
    $TheVar = (Get-SPFeature -site $Site -EA "SilentlyContinue" | ?{$_.status -eq "online" -and $_.hidden -eq $false -and $_.scope -eq "site"} | ForEach-Object {$_.Displayname})
 
    #Get the list variable or reference variable:    
    $compareToArray = Get-Variable -Name $($Name + "SITEFeatures") -EA "SilentlyContinue" | ForEach-Object {$_.Value}
 
    if($TheVar){ CompareFeature $TheVar $compareToArray ("Site - "  + $SiteURL) }
    }
 
 
 
Write-Host ""
#==========================================================================================
#Comparing Site Collection WEBScope features to our list:
#==========================================================================================
Write-Host "=========================================================================================="
Write-Host -ForegroundColor green "WEB FEATURE SECTION"
Write-Host "=========================================================================================="
Write-Host ""
 
foreach ($Site in $SiteCollections)
    {
    $TheVar = $false
    $compareToArray = $false
    $Name = $false    
    $SiteURL = $false
    $SiteURL = get-spsite $Site -EA "SilentlyContinue" | ForEach-Object {$_.url}    
 
    #Clean url to $Name and Create a variable based on the $Name
    #-----------
    $Name = $SiteURL
    $Name = $Name.split("/")
 
    #If the custom site collection is at the http://portal.com/customsitecollectionname meaning its on line 3 of the array:
    if($Name[3]){$Name = $Name[3]}
 
    #if not use the same name as the webapplication:
    if(!($Name[3])){$Name = $Name[2]}
 
    if($Name -like "*-*"){$Name = $Name.split("-"); $Name = $Name[0]}
    if(!($Name -like "*-*")){$Name = $Name.split("."); $Name = $Name[0]}
    #-----------
     
        
    #Adding feature array list to our magical variable 
    $TheVar = (Get-SPFeature -web $Site -EA "SilentlyContinue" | ?{$_.status -eq "online" -and $_.hidden -eq $false -and $_.scope -eq "web"} | ForEach-Object {$_.Displayname})
 
     
    #Get the list variable or reference variable:   
    $compareToArray = Get-Variable -Name $($Name + "WEBFeatures") -EA "SilentlyContinue" | ForEach-Object {$_.Value}
 
    if($TheVar){ CompareFeature $TheVar $compareToArray ("Web - "  + $SiteURL) }
    }
 
Write-Host ""
Write-Host ""
Write-Host -ForegroundColor DarkYellow "Script Completed! - Press the anykey to get out of here!"
read-host
exit
 
}
 
else {Write-Host "You did not pick C or M"; Read-Host;exit}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s