PowerShell - Iterate through all webs, then iterate through all lists , then add a column where a list is a certain name

sharepoint.stackexchange https://sharepoint.stackexchange.com//questions/96719

  •  10-12-2019
  •  | 
  •  

Question

I'm trying to put together a script that should iterate through all webs in a site collection, then iterate through all lists in those webs, then add a column where a list has a certain name.

This is what I have so far:

[CmdletBinding()]
Param
(
[Parameter(Mandatory=$True,Position=1)]
[string]$sc
)

$spsite = Get-SPsite $sc 

foreach ($web in $spsite.AllWebs)
{   
        foreach ($list in $spsite.AllWebs)
        {
            $splist = $list.Lists["PSList"]
            $splist.Fields.Add("Calc", "Calculated", 0)
            $spfield = $splist.Fields.Getfield("Calc")
            $spfield.formula = "=TEXT([Start Date],`"mm/dd/yyyy`")`&`" - `"`&TEXT([End Date],`"mm/dd/yyyy`")"
            $spfield.outputtype = "Text"
            $spfield.update()
        }
}
$spsite.dispose()

This is the error I get:

You cannot call a method on a null-valued expression. At C:\scripts\addcalc.ps1:24 char:22 + $splist.Fields.Add <<<< ("Calc", "Calculated", 0) + CategoryInfo : InvalidOperation: (Add:String) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull

I'm sure it's because I'm not iterating through the webs and then through the lists property. What's the correct way to achieve what I'm trying to do?

Was it helpful?

Solution

First - you must delete foreach ($list in $spsite.AllWebs) then find list using

$list = $web.Lists["InternalNameOfTheList"]

or

$list = $web.GetList($web.Url + "/Lists/" + $ListName) and after that add column using

$spFieldType = [Microsoft.SharePoint.SPFieldType]::Text //change to your field type

$list.Fields.Add("YourColumn",$spFieldType,$false)
$list.Update()

And dispose SPWeb object after using it, like you do for SPSite object .

OTHER TIPS

Thanks Andrey. Your suggestion led me down the right path. Here's the final working version of the script that solves the original question.

[CmdletBinding()]
Param(
  [Parameter(Mandatory=$True,Position=1)]
   [string]$sc
)
$site = Get-SPSite $sc
$webs = Get-SPWeb $sc
$count = 0
foreach ($web in $site.AllWebs)
{   
            if (($webs.Count -le $Count) -and ($list = $web.Lists["PSList"]))
            {   

                $list.Fields.Add("Calc", "Calculated", 0)
                $field = $list.Fields.Getfield("Calc")
                $field.formula = "=TEXT([Start Date],`"mm/dd/yyyy`")`&`" - `"`&TEXT([End Date],`"mm/dd/yyyy`")"
                $field.outputtype = "Text"
                $field.update()
            }           
$count ++       
}
$site.dispose()
$webs.dispose()
Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top