Archive for the 'Scripting' Category

How to export and import lists and libraries from a SharePoint 2010 site using Powershell

Let’s imagine this scenario:

You have an old SharePoint 2010 site and you need to copy its content to another SharePoint farm.  The site is heavily customized and moving it using traditional methods (backup/restore, export/import, save site as a template) are not going to work well.  Plus you only want content – no need to bring in all of that custom branding baggage.

You can copy the content using PowerShell and two scripts shown below.

Script # 1:   Export all lists and libraries from the source site.


add-pssnapin microsoft.sharepoint.powershell

# specify the site URL to export

$web = Get-SPWeb "http://sharepointURL/sites/site1/web1"

# specify output folder to store exported lists

$path = "c:\admin\export\"

foreach($list in $web.lists)

{

"Exporting " + $list.RootFolder.URL

export-spweb $web.URL -ItemUrl $list.RootFolder.URL -IncludeUserSecurity -IncludeVersions All -path ($path + $list + ".cmp") -nologfile

}

The output of this script should be a number of CMP files in the output directory.  Review these files and remove the lists that should not be imported (such as various Gallery lists).

Script # 2:  Import CMP files into the destination site.


add-pssnapin microsoft.sharepoint.powershell

# specify target SharePoint site to import into

$site = "http://sharepoint/sites/test1"

# specify folder containing exported lists

$folder = "C:\Admin\Import\"

$Files = Get-ChildItem $folder

foreach ($file in $files)
{

$name = $file.Name

"Importing: " + "$folder$name"

import-spweb $site -path ("$folder$name") -includeusersecurity -nologfile

}

Advertisements

How to enumerate user profiles and their properties in SharePoint 2010 using PowerShell

When administering a large SharePoint 2010 deployment, there are times when you may need to take an inventory of the user profiles in your profile store – perhaps to find users with a common property or characteristic, run some comparisons of your SharePoint profiles to Active Directory, or do some other administrative task.

Here’s a simple PowerShell script that enumerates all user profiles in the context of your SharePoint site and emits some of their properties, such as Display Name, AccountName, and workEmail.

Note:  The account which will be executing this script needs to have Full Control access to the User Profile Service application.   Follow these two steps:

1) Go to  Central Administration > Manage service applications > select (highlight) your user profile application > click on Administrators button on the ribbon and add your account.

2) Go to  Central Administration > Manage service applications > select (highlight) your user profile application > click on Permissions button on the ribbon and add your account with Full Control – make sure to check the “Full Control” checkbox!


[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.UserProfiles")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
# Enter your SharePoint site URL here...
$site = new-object Microsoft.SharePoint.SPSite("http://...");

$ServiceContext = [Microsoft.SharePoint.SPServiceContext]::GetContext($site);

$ProfileManager = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($ServiceContext)

$AllProfiles = $ProfileManager.GetEnumerator()

write-host "Display Name ;  AccountName ; Email ; "

foreach($profile in $AllProfiles)
{

$DisplayName = $profile.DisplayName

$AccountName = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::AccountName].Value

$workEmail = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::workEmail].Value

write-host $DisplayName, ";", $AccountName, ";" , $workEmail, ";"

}
write-host "Finished."

$site.Dispose()

A full list of SP 2010 user profile properties is available on MSDN here:

http://msdn.microsoft.com/en-us/library/microsoft.office.server.userprofiles.propertyconstants_members.aspx

Locating files and pages with URLs that are too long for SharePoint

As you may already know, SharePoint has a limitation on how long a page or file path (or URL) can be.  This was an issue with SharePoint 2007 -Joel Oleson blogged about it back in June 2007:

“When storing files the structure and files (entire path including sites, folders, and file name) cannot add up to more than 260 characters or they will see an error message or form validation error with the explanation around the URL length. “ 

Official Microsoft documentation states that the same limit holds for SharePoint 2010:

“SPSite.MaxFullUrlLength Field

Represents the maximum number of characters that can be used in the absolute URL for a site collection.

Remarks
——————————————————————————–

The value of this constant is 260.

The MaxFullUrlLength field is static and cannot be called on an instance object. To call this field, use SPSite.MaxFullUrlLength.”

Source:

http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spsite.maxfullurllength.aspx)

When you’re moving, upgrading, or migrating SharePoint sites, you may run into problems with URLs that are too long for SharePoint.  You may see failures or errors when executing STSADM commands such as “stsadm -o export” or “stsadm -o import”.

I wrote a PowerShell script (see below) that allows you to take an inventory of all files in your web application and flag those files where the path (or URL) is longer than 260 characters.

You can call this script from a command line as follows:


powershell   C:\Inventory.ps1  "http://sharepointURL" >   C:\output.txt

 

Source code


 # This script enumerates all files at the specified URL,
 # and outputs full URL for each file,
 # along with the length of the URL.

# define EnumPages function

function EnumPages
{
param ($URL, $objFolder)

 # enumerate files in the root folder

 foreach ($file in $objFolder.Files)
 {

 $result = "OK"
 $output = $URL + "/" + $objFolder.URL + "/" + $file.Name

# evaluate string length
 if ($output.length -ge 260) { $result = "TOO LONG" }

# write output

 write-host $output, ";" , $output.length, ";" $result, ";"
 }
 # enumerate subfolders

 foreach ($subfolder in $objFolder.SubFolders)
 {

 EnumPages $URL $subfolder
 }

 }

 # begin script body
[System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c") | out-null

 $siteURL = $args[0]

# create a new SPSite object

$site=new-object Microsoft.SharePoint.SPSite($siteURL)

 # enumerate files in the Rootweb

 foreach ($file in $site.Rootweb.Files)
 {

$result = "OK"

 $output = $site.Rootweb.URL + "/" + $file.Name 

 if ($output.length -ge 260) { $result = "TOO LONG" }

  write-host $output, ";", $output.length, ";" , $result

 }

 # enumerate folders in the Rootweb

 foreach ($folder in $site.Rootweb.Folders)
 {

 EnumPages $site.Rootweb.URL $folder

 }

 # enumerate subsites

 foreach ($web in $site.Allwebs)
 {

  # enumerate files in the root web

  foreach ($file in $web.Files)
  {

$result = "OK"

$output = $web.URL + "/" + $file.Name 

 if ($output.length -ge 260) { $result = "TOO LONG" }

 write-host $output, ";", $output.length, ";" , $result

  }

  # enumerate folders

  foreach ($folder in $web.Folders)
  {

  EnumPages $web.URL $folder

  }

   }

$site.Dispose(); ##ENFORCED DISPOSAL!!!    

 


Create and delete SharePoint list views with PowerShell

Here’s how you can create and delete views in a SharePoint list or library using PowerShell (Is there anything that can’t be done through a PowerShell script?)

The script below creates a view called “TestView”.  It expects three command-line arguments:  site collection URL, the name of the view to create, and the list GUID.  The view that’s created is an exact replica of the “All Items” view (you can certainly modify the code as needed).  Here’s how you would call this script from the command line:


powershell  CreateView.ps1 "your_site_collection_URL" "TestView" "List GUID 6865306f-60e0-4889-addd-4fb9862e72e0"

Script code (use the button in the top right corner to copy it to the clipboard):


[System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c") | out-null

# reading command line arguments

$siteURL = $args[0]

$strViewName = $args[1]

$ListGUID = $args[2]

# enter your CAML query for the view here...

$strQuery = "<Where><Gt><FieldRef Name='ID'/><Value Type='Counter'>0</Value></Gt></Where>"

 # create a new SPsite object and recursively go through all webs

# until a matching list GUID is found

$site=new-object Microsoft.SharePoint.SPSite($siteURL)

foreach ($web in $site.AllWebs)
{
 

foreach ($list in $web.Lists)
{

$ListTempGUID = $list.ID.ToString()
  

if ($ListTempGUID.Contains($ListGUID))
{

write-host "**********************************************"
write-host "Match found. Preparing to create a view: ", $strViewName
write-host "List Title: ", $list.Title
write-host "List GUID: ", $list.ID

$fields = $list.Views["All Items"].ViewFields.ToStringCollection()

$result = $list.Views.Add($strViewName, $fields, $strQuery, 100, $True, $False , "HTML", $False)

write-host "View ", $strViewName , " was created successfully."

break

}
}

} 

write-host "Done."

$site.Dispose(); ##ENFORCED DISPOSAL!!!

    

So far, so good?  Well, now that you’ve created a view, how do you delete it?  Follow the same logic, only instead of using the Add method of SPViewCollection object, we’ll be using the Delete method.

Same command line arguments as before:  site collection URL, name of the view, and list GUID.

Calling script from the command line:


powershell  DeleteView.ps1 "your_site_collection_URL" "TestView" "List GUID 6865346f-60e0-4889-addd-4fb3862572e0"

 


[System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c") | out-null

# reading command line arguments...

$siteURL = $args[0]

$strViewName = $args[1]

$ListGUID = $args[2] 
# creating a new site object and recursively searching through its lists

# until a matching list GUID is found

$site=new-object Microsoft.SharePoint.SPSite($siteURL)

foreach ($web in $site.AllWebs)
{
 

foreach ($list in $web.Lists)
{

$ListTempGUID = $list.ID.ToString()
  

if ($ListTempGUID.Contains($ListGUID))
{
foreach ($view in $list.Views)
{

If ( $view.Title.Contains($strViewName))
{

write-host "**********************************************"
write-host "Match found. Preparing to DELETE a view: ", $view.Title
write-host "List Title: ", $list.Title
write-host "List GUID: ", $list.ID

# you can insert a pause here if you like...

$list.Views.Delete($view.ID)

write-host "View ", $view.Title , " has been deleted successfully."

break

}
}

break

}

}

}
write-host "Done."

$site.Dispose(); ##ENFORCED DISPOSAL!!! 
 

Finally,  how do you find out the GUID of your list?  It’s fairly straightforward – you just need to access the SPList.ID property of your list.  Here’s a simple script that will output the GUIDs of all lists in your site collection:


[System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c") | out-null
# write column headings

write-host "List URL ; Web URL ; Web Title ; List Title; List GUID ;"

# create a site object and recursively list all of its list objects and their details
 $site=new-object Microsoft.SharePoint.SPSite("http://your_site_collection_URL)  

  foreach ($web in $site.AllWebs)
 {
  foreach ($list in $web.Lists)
 {
 write-host $list.DefaultViewURL, ";", $web.URL , ";",  $web.Title , ";" , $list.Title , ";" , $list.ID

 }

 }

$site.Dispose(); ##ENFORCED DISPOSAL!!!

Calling STSADM from within a PowerShell script

For various SharePoint admin tasks, there are times when you need to execute an STSADM command from within a PowerShell script. 

Before you can do that, you’ll need to tell PowerShell where to find STSADM executable. You can do that by adding the following line to your profile.ps1 file (usually located in C:\WINDOWS\system32\windowspowershell\v1.0 ):

Set-Alias -Name stsadm -Value $env:CommonProgramFiles”\Microsoft Shared\Web Server Extensions\12\BIN\STSADM.EXE”

Now you can use stsadm in your scripts and it should work beautifully…

Refreshing TFS list in Excel using VBscript

Ok, this post isn’t even SharePoint-related, but since it took me 2 hours to figure out how to do this task (and since there’s little documentation on the subject), I’m going to post it here anyway. Maybe it’ll save someone hours of research and coding.

My task today was to programmatically refresh a Team Foundation Server list that was embedded into an Excel workbook. The process had to be completely automated. I found John Lawrence’s post and also the TFS team blog post. The problem with these solutions, they only work within an Excel VBA macro. I needed a way to open Excel, perform the TFS list refresh, and close it, without any user intervention.

Placing the macro into the workbook start-up didn’t work – apparently, the Team toolbar (and the accompanying Refresh button) don’t activate until AFTER all the start-up macros have run (which caused a problem for me).

So here’s a simple solution using my good old friend VBScript:

Const INPUT_FILE = “your_file_path”

Dim objWorkbook
Dim Controls

Set objWorkbook = CreateObject(“Excel.Application”)
objWorkbook.Visible = True
objWorkbook.Workbooks.Open INPUT_FILE

Set Controls = objWorkbook.CommandBars

For Each objControl in Controls

If Instr(objControl.Name, “Team”) Then

For Each objButton in objControl.Controls

If Instr(objButton.Tag, “IDC_REFRESH”) Then

objButton.Execute

End If

Next

End If

Next


RSS Information Week Headlines

  • An error has occurred; the feed is probably down. Try again later.

RSS SharePoint Team Blog

  • An error has occurred; the feed is probably down. Try again later.

RSS InfoPath Team Blog

  • An error has occurred; the feed is probably down. Try again later.

RSS Joel Oleson Blog

  • An error has occurred; the feed is probably down. Try again later.

RSS Susan Hanley’s KM Blog

  • An error has occurred; the feed is probably down. Try again later.

Blog Stats

  • 353,732 hits