Monday, February 25, 2013

Compare dynamic arrays with Powershell and some SharePoint

Today was a day I got to work on a revision to a script that I thought was working but apparently was not tested as well as I thought, not uncommon with pretty much everything I have done thus far. :) This is pretty well commented. I am starting to make use of templates when working with scripts to keep them looking a bit easier to understand.


## DESCRIPTION
## ------------------------------------------------
## Script to loop through a set of Subsites and a 
## SharePoint List of items and then either
## create a new item or update it in your SharePoint List.
## 
## EXPLAINATION
## ------------------------------------------------
## This example illustrates how to compare 2 dynamically 
## created arrays, look for the difference between
## the two, then do something like update a SharePoint list, 
## this could also apply to updating a text file
## or csv/excel file
##
## BEGIN
## ------------------------------------------------
## Load up the snapin so Powershell can work with SharePoint
## if the snapin was already loaded don't alert the user
Add-PSSnapin microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
## Clear any errors
CLS
## Set variables
## This variable will be the site where all the subsites 
## are that I want to get an array of
$parentSite = "http://sp2010/clients"
$rollupSite = "http://sp2010"
## Define the name of the SharePoint List we want to work with
$rollupListName = "Orders"
## Initialize and create empty arrays
$listOfSites = @()
$listOfItems = @()

function GetListOfSites
{
 ## Create a variable to hold the SharePoint site, invoke the connection
 ## to the site we defined in the $parentSite variable
 $web = Get-SPWeb $parentSite
 ## Check to make sure that url exists
 if($web -ne $true)
 {
  ## Loop through all the sub sites of the site url we got
  foreach($webSite in $web.Webs)
  {
   ## We have to use @() around the items we are going
   ## to add to the array. The += means we want to 
   ## keep adding items into our array named $listOfSites
   $listOfSites += @($webSite.Title)
  }
  ## Calling a function inside another function will allow you to make
  ## use of variables defined in functions that call it. Normally variable
  ## values are only accessible in the scope they were created. We need
  ## to pass off $listOfSites to the function GetLIstOfItems so it can process 
  ## the array
  GetListOfItems
 }
 else
 {
  ## Gracefully let the user know that the site they requested
  ## was not available or was not found.
  Write-Host "$web not found, check the url and try again."
 }
}

function GetListOfItems
{
 $listWeb = Get-SPWeb $rollupSite
 $listName = $listWeb.Lists[$rollupListName]
 foreach($rollupListItem in $listName.Items)
 {
  $listOfItems += @($rollupListItem.Title)
 }
 CompareItems
}

function CompareItems
{
 foreach($foundSite in $listOfSites)
 {
  ## Filter out anything that already exists in the Rollup List
  ## We have to use -notcontains/-contains when analyizng arrays
  if($listOfItems -notcontains $foundSite)
  {
   ## Item not found so lets create new item
   foreach($value in $foundSite)
   {
    $rollupListWeb = Get-SPWeb $rollupSite
    $rollupList = $rollupListWeb.Lists[$rollupListName]
    $rollupListItems = $rollupList.Items.Add()
    $rollupListItems["Title"] = $value
    $rollupListItems.Update()
    Write-Host "Creating $value"
   }
  }
  else
  {
   ## Item was found so lets update it
   foreach($value in $foundSite)
   {
    $rollupListWeb = Get-SPWeb $rollupSite
    $rollupList = $rollupListWeb.Lists[$rollupListName]
    $rollupListItems = $rollupList.Items
    
    if($rollupListItems.Title  -notmatch $value)
    {
     $rollupListItem["Title"] = $value
     $rollupListItem.Update()
     Write-Host "Updating $value"
    }
   } 
  }
 }
}
Start-SPAssignment -Global
GetListOfSites
Stop-SPAssignment -Global

No comments: