i want to input one site collection and want to get all the lists of that site as well as subsites. but i am unable to iterate through all subsites. Please suggest. I am using csom in powershell for SharePoint 2013
4 Answers
The following PowerShell code with CSOM for your reference.
#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
#Variables for Processing
$SiteUrl= "http://sp2013/sites/team"
$username="administrator"
$password="**"
$domain="lz"
#Setup Credentials to connect
$Credentials = New-Object System.Net.NetworkCredential($username, $password, $domain)
Try {
#Function to Get all lists from the web
Function Get-SPOList($Web)
{
#Get All Lists from the web
$Lists = $Web.Lists
$Context.Load($Lists)
$Context.ExecuteQuery()
#Get all lists from the web
ForEach($List in $Lists)
{
#Get the List Name
Write-host $List.Title
}
}
#Function to get all webs from given URL
Function Get-SPOWeb($WebURL)
{
#Set up the context
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($WebURL)
$Context.Credentials = $Credentials
$Web = $context.Web
$Context.Load($web)
#Get all immediate subsites of the site
$Context.Load($web.Webs)
$Context.executeQuery()
#Call the function to Get Lists of the web
Write-host "Processing Web :"$Web.URL
Get-SPOList $Web
#Iterate through each subsite in the current web
foreach ($Subweb in $web.Webs)
{
#Call the function recursively to process all subsites underneaththe current web
Get-SPOWeb($SubWeb.URL)
}
}
#Call the function to get all sites
Get-SPOWeb $SiteUrl
}
catch {
write-host "Error: $($_.Exception.Message)" -foregroundcolor Red
}
You can use following powershell script.
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue;
cls
$webApp=Get-SPWebApplication "http://sharepointwebapplication"
foreach($siteColl in $webApp.Sites)
{
#Write-Host $siteColl.URL
foreach($web in $siteColl.AllWebs)
{
Write-Host $web.URL $web.ParentWeb.URL
}
}
-
Note that this provides empty values for
$web.URL
if it's the root site. And it will iterate through each site collection, but because you're doing$siteColl.AllWebs
, every time you do a site collection, you're re-running through EVERY web on the site, not just the webs under that SC. You should do:foreach ($site in $siteColl) { ... }
and then get each collection of webs, specifically:$subsites = Get-SPWeb -site $site
and then iterate:foreach ($web in $subsites) { ... }
– vapcguyApr 4, 2019 at 18:51
The following CSOM will work to iterate through all the subsites and its List/Libraries. You can modify it as per your requirement
ClientContext clientContext = new ClientContext(siteUrl);
Web web = clientContext.Web;
clientContext.Load(web);
clientContext.Load(web.Webs);
clientContext.ExecuteQuery();
foreach (Web subWeb in web.Webs)
{
string newpath = subWeb.Url;
Console.WriteLine(subWeb.Title + "-------" + subWeb.Url);
ClientContext clientContext2 = new ClientContext(subWeb.Url);
var libraries = clientContext2.LoadQuery(clientContext2.Web.Lists);
clientContext2.ExecuteQuery();
foreach (List list in libraries)
{
string libTitle = list.Title;
Console.WriteLine(" --List/Library: " + libTitle);
}
}
Hope that helps..
-
Thanks Ankit, But we cant use lambda expressions to load objects in powershell. Is there any other way without which we can access same output without using website => website.Webs, website => website.Title? Nov 29, 2018 at 10:10
-
This code should do the job.
$snapin = Get-PSSnapin | Where-Object {$_.Name -eq 'Microsoft.SharePoint.Powershell'}
if ($snapin -eq $null) { Add-PSSnapin Microsoft.SharePoint.Powershell }
$site = $null
$site = Get-SPSite "https://contoso.com"
foreach($web in $site.AllWebs)
{
Write-Host " Web:" $web.Url
foreach($list in $web.Lists)
{
Write-host " List:" $list.Title
}
$web.Dispose()
}
$site.Dispose()
Write-Host "End" -b DarkGreen -f Green