Showing posts with label PowerShell Deployments. Show all posts
Showing posts with label PowerShell Deployments. Show all posts

Friday, January 22, 2016

PowerShell: Activate Nintex Workflow For a Site Collection (Includes all Sub Sites)

Recently I was on a project which was using Nintex Workflow 2013 and we needed to have the site collection feature activated, as well as the Nintex Workflow 2013 site feature on all of the sub sites within this particular site collection.  Well this was an intranet site which was comprised of 50 sub sites which would all need to be enabled.

In order to use Nintex Workflow the site collection feature must be activated as well as the site feature for any sub site which wishes to use the Workflow Product.  As much fun as manually clicking through 50+ sites and activating the feature would be, I found a script online and tweaked it a bit to be a bit more robust.  Original script author Vadim Tabakman wrote the bulk of the script, my additions are noted in the script comments.



Best Regards,
Dan


#Orignal Script Author: Vadim Tabakman
#http://www.vadimtabakman.com/nintex-workflow-enable-the-nintex-workflow-feature-on-all-subsites.aspx

#Updates By Dan Adams
    #Added a param for re-usablilty rather than have a set path
    #Added the logic to enable the Site Collection Nintex Workflow Feature before enabling the sites
    #Wrapped the Enable-SPFeature calls to handle errors if the Feature was already activated on the site

param($url = $(Read-Host -prompt "Root Site Collection Path"))

#Get the PowerShell Snapin
Add-PSSnapin "Microsoft.SharePoint.PowerShell"

#Get Web
$web = get-spweb $url
#Get Site
$rootSite = Get-SPSite $url

#Activate Site Collection Feature If Not Activated
$nintexWFCollectionFeature = "0561d315-d5db-4736-929e-26da142812c5"
(Enable-SPFeature -Identity $nintexWFCollectionFeature -ErrorAction SilentlyContinue -Url $url) -$null


#Loops Through the SubSites and Activates Nintex Workflow Web Feature
function EnableNintexWorkflowSiteFeature( $w )
{
    $ws = $w.Webs;
    foreach( $subweb in $ws)
    {
        EnableNintexWorkflowSiteFeature($subweb)
    }
    echo 'Enabling Nintex Workflow on site : ' $w.Url
    (Enable-SPFeature NintexWorkflowWeb -ErrorAction SilentlyContinue -url $w.Url) -ne $null
}

echo 'Enabling Nintex Workflow on site : ' + $web.Url
EnableNintexWorkflowSiteFeature $web

PowerShell: Loop Through All Sub Sites in a Site Collection

So this post will be extremely short, but hopefully useful.  The below script is a good starting point if you have a repetitive task that you need to complete on all of your sub sites within a particular site collection.  This script will loop through all of the sub sites, including sub sites of sub sites and print out the site's title and URL.  To use the script you simply need to run the script and input the site’s root URL without quotes.  So if my site collection was http://danssandbox.com/sites/dansSand , I would simply need to input that URL when prompted by the script for the “Root Site Collection Path.”  

This script is meant as a starting point to include actual logic rather than the Write-Hosts, but it should get you on the right track!  Enjoy the loops!


Dan


param($url = $(Read-Host -prompt "Root Site Collection Path"))

#Get the PowerShell Snapin
Add-PSSnapin "Microsoft.SharePoint.PowerShell"

#Get Root Site
$root = Get-SPSite $url

#If site was found / valid
if($root -ne $null)
{

     foreach($subSite in $root.AllWebs)
      {
       $subSiteTitle = $subSite.Title
                Write-Host $subSiteTitle -ForegroundColor Magenta
                $subSiteURL = $subSite.Url
                Write-Host $subSiteURL -ForegroundColor Cyan
       $subSite.Dispose()
      }

        $root.Dispose()

}

Monday, July 27, 2015

Apply a Retention Policy to a Set of Content Types Via PowerShell

Hello Readers!

Recently it seems that I have been doing more and more PowerShell, this time I needed to apply a retention policy to a set of Content Types.  In order to do this I wrote a PowerShell script which checks all of the content types within your site against a list of content types stored in an array.  If the content type name matches the name within the array we apply the policy.  My policy is extremely simple and simply marks the item as a record when today is equal to my field ExpirationDate.

Many users will need a policy much more robust than this and my advice is to download SharePoint 2013 manager in order to create them https://spm.codeplex.com/.  With SharePoint Manager 2013 you can open an existing policy that you have made via the GUI and extract the XML.  The script needs the XML markup in order to create the policy and writing it by hand is horrible!

So you may be wondering, what do I need to change?  The only parts of the script which would require modification would be the content type names within $parentCtypes and the XML for the retention policy.  After you have updated the XML for your policy and selected which Content Types to apply the policy to, you simply need to run the script.  The script will prompt you for the root site collection URL.

I actually struggled the most with trying to decipher the correct markup of the XML, the script itself was actually pretty simple.  Again, in order to get the markup for the policy I would create it via the GUI and then find the policy with SharePoint 2013 Manager and view the XML for the policy, it is way easier with a copy paste!  I wasted a ton of time trying to write the XML from scratch and advise you not to do the same!

param($url = $(Read-Host -prompt "Root Site Collection Path"))

#Get the PowerShell Snapin
Add-PSSnapin "Microsoft.SharePoint.PowerShell"

#Search Service Application
$ssa = Get-SPEnterpriseSearchServiceApplication
Write-Host $ssa.Name -ForegroundColor Magenta

#Get Site
$site = Get-SPSite $url

#Get Root Web
$web = $site.RootWeb

#Write Out That The Web Was Found
if($web -ne $null)
{
    Write-Host "The web is" $web "and the site is" $site.HostName -ForegroundColor Magenta

}

#Fill the array with base content types i.e. Exelon Content Page
$parentCtypes = @("Content Page");

foreach ($ctype in $web.ContentTypes)
{
    foreach($i in $parentCtypes)
    {
        if($ctype.Name -eq $i)
        {
            Write-Host $ctype.Name "is the same as" $i -ForegroundColor Magenta
            $ctypePolicy = [Microsoft.Office.RecordsManagement.InformationPolicy.Policy]::GetPolicy($ctype);
            if($ctypePolicy -ne $null)
            {
                Write-Host $ctype.Name "Has an existing Policy" $ctypePolicy "and is being deleted" -ForegroundColor Magenta
                [Microsoft.Office.RecordsManagement.InformationPolicy.Policy]::DeletePolicy($ctype);
            }
            [Microsoft.Office.RecordsManagement.InformationPolicy.Policy]::CreatePolicy($ctype, $null);
            $ctypePolicy = [Microsoft.Office.RecordsManagement.InformationPolicy.Policy]::GetPolicy($ctype);
            $ctypePolicy.Items.Add("Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration",
                "<Schedules nextStageId='2'>"+
                    "<Schedule type='Default'>"+
                        "<stages>"+
                            "<data stageId='1'>"+
                                "<formula id='Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration.Formula.BuiltIn'>"+
                                    "<number>0</number>"+
                                    "<property>ExpirationDate</property>"+
                                    "<propertyId>8c06beca-0777-48f7-91c7-6da68bc07b69</propertyId>"+
                                    "<period>days</period>"+
                                "</formula>"+
                                "<action type='action' id='Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration.Action.Record' />"+
                            "</data>"+
                        "</stages>"+
                    "</Schedule>"+
                "</Schedules>");
                $ctypePolicy.Update();
                $ctype.Update();
            Write-Host "The Policy For" $ctype.Name "Has Been Created And Applied!" -ForegroundColor Green
        }
    }
}

Good Luck!

Dan

Thursday, April 9, 2015

SharePoint 2013: Create Result Sources With PowerShell

Hello Readers!

Sorry for the delay in posts recently, between work and personal events I have been totally swamped (in a good way)!

What I wanted to share today is PowerShell script which provisions result sources at the Site Collection level.  The script will loop through each result source within the script, check to see if it exists, if it does it will blow it away and re-create it or if it is brand new just create   This script is useful for automating deployments or if you need to create the same result sources on multiple site collections.


If you need to deploy result sources at the Search Service Application Level, simply swap out: SPSite with Ssa at our $searchOwner line.  Your site collection URL and Search Service Application are both params which will be prompted.


$searchOwner = New-Object Microsoft.Office.Server.Search.Administration.SearchObjectOwner([Microsoft.Office.Server.Search.Administration.SearchObjectLevel]::SPSite, $site.RootWeb)

The real question though, what do you need to update in order to use this script?  Luckily, the only parts you need to update are the actual result sources themselves!  This is under the Result Sources Start Here Section.  The below example is for a result source which finds anything with the ContentTypeId matching Article.  For the below section I did not need a sort order, but if you do un-comment out the sortCollection and queryProperties line.  You can swap out "Created" with the Managed property you need to sort by.  You can also swap out Descending with Ascending if desired.  The name of the result source is input between the single quotes, my example result source below will be called Articles.


# Articles
Write-Host -ForegroundColor Green "Starting To Build  Articles Result Source"
# define query and sorting
$query = "ContentTypeId:0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF39003F11102A7C0343B0836EDF8DA14F33ED00B679312D96584105BCFD3A33F39BD3AF*"
$queryProperties = New-Object Microsoft.Office.Server.Search.Query.Rules.QueryTransformProperties
$sortCollection = New-Object Microsoft.Office.Server.Search.Query.SortCollection    
##This can be updated if a sort order is required
#$sortCollection.Add("Created", [Microsoft.Office.Server.Search.Query.SortDirection]::Descending) 
#$queryProperties["SortList"] = [Microsoft.Office.Server.Search.Query.SortCollection]$sortCollection
# create result source
CreateResultSource $searchOwner $fedManager ' Articles' $queryProperties $query 
Write-Host -ForegroundColor Yellow " Articles Result Source Complete"

How to use this script:
  1. Update the script to include each result source you need created, you can swap out my example result sources with your own
  2. Run the script
  3. When prompted: input your root site collection url: i.e. http://danstestsite.local
  4. When prompted: input your search service application name (make sure to put it in double quotes) i.e. "Search Service Application"
  5. Check out the new result sources at your site collection level!
Full Script:


## Getting the ducks in a row
param($url = $(Read-Host -prompt "Site Colleciton Root URL"), $ssaName = $(Read-Host -prompt "Search Service Application Name"))

#Funciton To Create Result Sources
function CreateResultSource($searchOwner, $fedManager, $name, $queryProperties, $query)
{  
   # check if result source already exists
   $resultSource = $fedManager.GetSourceByName($name, $searchOwner)

   if ($resultSource -eq $null) 
   {    
        Write-Host -f cyan "Creating Result Source <"$name">."
        
        #create result source
        $resultSource = $fedManager.CreateSource($searchOwner)      
        $resultSource.Name = $name
        $resultSource.CreateQueryTransform($queryProperties, $query)
        $resultSource.ProviderId = $fedManager.ListProviders()["Local SharePoint Provider"].Id
        $resultSource.Commit()
   }
   else
   {
        Write-Host -f Green "Result Source" $name "already exists, updating" $name "result source"

        # print properties of existing result source 
        $source = $fedManager.GetSourceByName($name, $searchOwner) 
        $fedManager.RemoveSource($source)
          #create result source
        $resultSource = $fedManager.CreateSource($searchOwner)      
        $resultSource.Name = $name
        $resultSource.CreateQueryTransform($queryProperties, $query)
        $resultSource.ProviderId = $fedManager.ListProviders()["Local SharePoint Provider"].Id
        $resultSource.Commit()
   }
   return $resultSource
}

Write-Host -ForegroundColor Green "Script Warming Up And Adding Snapins"
Add-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue

Start-SPAssignment -Global

#Get SP Site and SP Web
##$url = (Read-Host -Prompt "Site Collection URL")
$url = $url.Trim()
$web = get-spweb $url
$site = get-spsite $url -WarningAction SilentlyContinue

#Get Search Service Applicaiton
$ssa = Get-SPEnterpriseSearchServiceApplication $ssaName -ErrorAction SilentlyContinue
if($ssa -eq $null) {
    $ssa = @(Get-SPEnterpriseSearchServiceApplication)[0]
}

#Output results from SSA
Write-host -ForegroundColor Cyan ("Using search app {0}" -f $ssa.Name)

# load Search assembly
Write-Host -ForegroundColor Green "Loading Search Assemblies"
[void] [Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.Search")

# create manager instances
$fedManager = New-Object Microsoft.Office.Server.Search.Administration.Query.FederationManager($ssa)
    Write-Host -ForegroundColor Green "The fed manager is" $fedManager


#Update SPSite to Ssa if you want them provisioned at Search Service Level
$searchOwner = New-Object Microsoft.Office.Server.Search.Administration.SearchObjectOwner([Microsoft.Office.Server.Search.Administration.SearchObjectLevel]::SPSite, $site.RootWeb)
    Write-Host -ForegroundColor Cyan "The Search Owner is" $searchOwner

###################################################################################
#Result Sources Start Here
###################################################################################


# Articles
Write-Host -ForegroundColor Green "Starting To Build  Articles Result Source"
# define query and sorting
$query = "ContentTypeId:0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF39003F11102A7C0343B0836EDF8DA14F33ED00B679312D96584105BCFD3A33F39BD3AF*"
$queryProperties = New-Object Microsoft.Office.Server.Search.Query.Rules.QueryTransformProperties
$sortCollection = New-Object Microsoft.Office.Server.Search.Query.SortCollection    
##This can be updated if a sort order is required
#$sortCollection.Add("Created", [Microsoft.Office.Server.Search.Query.SortDirection]::Descending) 
#$queryProperties["SortList"] = [Microsoft.Office.Server.Search.Query.SortCollection]$sortCollection
# create result source
CreateResultSource $searchOwner $fedManager ' Articles' $queryProperties $query 
Write-Host -ForegroundColor cyan " Articles Result Source Complete"


#Statistic
Write-Host -ForegroundColor Green "Starting To Build Statistic Result Source"
$query = "ContentTypeId:0x0100AAF9B8EBA36A47F6BB7BA54A5D01B1B8001B7C18A4B6C343C88F4D4293F72F397400ABFD858ADE3B44A0988105611D2187B1*"
$queryProperties = New-Object Microsoft.Office.Server.Search.Query.Rules.QueryTransformProperties
$sortCollection = New-Object Microsoft.Office.Server.Search.Query.SortCollection    
CreateResultSource $searchOwner $fedManager ' Statistics' $queryProperties $query 
Write-Host -ForegroundColor cyan "Statistic Result Source Complete"

#Event Documents
Write-Host -ForegroundColor Green "Starting To Build Call To Event Documents Result Source"
$query = "ContentTypeId:0x01010069411AE48AE74A3096A71D0C77BC6CBD* AND ManagedTerm:{Term.Id}"
$queryProperties = New-Object Microsoft.Office.Server.Search.Query.Rules.QueryTransformProperties
$sortCollection = New-Object Microsoft.Office.Server.Search.Query.SortCollection    
CreateResultSource $searchOwner $fedManager 'Event Documents' $queryProperties $query 
Write-Host -ForegroundColor cyan "Event Documents Result Source Complete"

#Event Images
Write-Host -ForegroundColor Green "Starting To Build Event Images Result Source"
$query = "ContentTypeId:0x010102002042E861E3D14C70B595912F16571C8C* AND ManagedTerm:{Term.Id}"
$queryProperties = New-Object Microsoft.Office.Server.Search.Query.Rules.QueryTransformProperties
$sortCollection = New-Object Microsoft.Office.Server.Search.Query.SortCollection    
CreateResultSource $searchOwner $fedManager 'Event Images' $queryProperties $query 
Write-Host -ForegroundColor cyan "Event Images Result Source Complete"



###################################################################################
#Result Sources End Here
###################################################################################
Well that is really it folks, hopefully this helps to automate some deployments or at the very least was an interesting read! Dan