Dave's Technophorical Times

A blog about Microsoft's Technologies!
SharePoint :: MVC :: ASP.NET :: IIS :: SQL Server :: Visual Studio :: MS Access

What he said! Works 100%

http://get-spscripts.com/2011/06/removing-features-from-content-database.html?showComment=1409706064396#c8164895157536909785



Recently I had a request from a client to add a custom site collection column to all document libraries. This is pretty easy though the SharePoint UI of course, by creating a custom Site Column in the collection and adding it to the ‘Document’ content type.

However, in doing this the column is not added to the default view for any document libraries. This can be easily done using PowerShell using the script below. This adds the column to the default view in every document library throughout the entire site collection (referenced here).

$site = Get-SPSite “http://sharepoint.com”
$column = “Column”

$site | Get-SPWeb -limit all | ForEach-Object {

# Get all document libraries
$lists = $_.Lists | where  {$_.BaseType -eq “DocumentLibrary”}

# Loop libraries
for ($i = 0; $i -lt $lists.Count; $i++)
{

try
{

# Get current view
$view = $lists[$i].DefaultView

if($view)
{

# Delete if already exist
while($view.ViewFields.ToStringCollection().Contains($column))
{

$view.ViewFields.delete($column)
$view.Update()

}

# Add column
if(!$view.ViewFields.ToStringCollection().Contains($column))
{

$view.ViewFields.add($column)
$view.Update()

}

}

}
catch [Exception]
{

write-output (”  Error: ” + $_.Exception.ToString())

}

}

}

$site.Dispose()

You can also add views to a view by URL and view name for one specific view or list (a nice tip I found here). Here is another option by using GetViewFromUrl:

$spWeb = Get-SPWeb -Identity "http://mySharePoint"
$spView = $spWeb.GetViewFromUrl("/Lists/MyList/AllItems.aspx")
$spField = $spList.Fields["MyField"]
$spView.ViewFields.Add($spField)
$spView.Update()

You can also try to use SPList object as below:

$spList = Get-SPList -Url "http://mySharePoint/Lists/MyList"
$spView = $spList.Views["All Items"]
$spField = $spList.Fields["MyField"]
$spView.ViewFields.Add($spField)
$spView.Update()

Adding multiple columns to a view can also be done with PowerShell, and even create a new view and set it as the default view. This is really awesome if you want to leave the default ‘All Items’ view in tact, but create a new custom view and set it as default (found here):

Add-PSSnapin Microsoft.SharePoint.PowerShell -erroraction SilentlyContinue
$siteURL = "http://dev1share"
 $site = Get-SPSite($siteURL)
foreach($web in $site.AllWebs) {
$listCounter = $web.Lists.Count
 for($i=0;$i -le $listCounter;$i++) {
    $list = $web.Lists[$i]
     if($list.BaseType -eq "DocumentLibrary") {
     $newList = $web.Lists.item($list.ID);
  $viewfields = New-Object System.Collections.Specialized.StringCollection
   $viewfields.Add("DocIcon")
   $viewfields.Add("LinkFilename")
   $viewfields.Add("_UIVersionString")
   $viewfields.Add("Modified")
   $viewfields.Add("Created")
   $viewfields.Add("Editor")
   $viewfields.Add("FileSizeDisplay")
  [void]$newList.Views.Add("Detailed", $viewfields, "", 100, $true, $true)
   $newList.Update();
  $view=$newList.Views["Detailed"]
   $view.DefaultView = $true
   $view.Update()
 }
 }
$web.Dispose();
 }
 $site.Dispose();

 



The following PowerShell script crawls the specified lists, copies the fields from the All Items views and creates a new view named "Created By Me" and sets it as default. Tested with SharePoint 2010 but should work with 2013 as well. Tested with list but not with Document Libraries.

I used this script as a base.

$ver = $host | select version

if ($ver.Version.Major -gt 1) {$host.Runspace.ThreadOptions = "ReuseThread"} 

if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) 

{

 Add-PSSnapin "Microsoft.SharePoint.PowerShell"

}

 

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") 

 

$web = Get-SPWeb -Identity "http://portal/sites/Requests"

$lists=$web.Lists["User Request", "Hardware Request",  "Employee Request"]

$SourceView="All Items"

$NewViewName="Created By Me"

$NewViewDefault=$true

 

 

foreach($list in $lists) {

 

 $view = $list.Views[$SourceView]

 $Viewfields = $list.Views[$SourceView].ViewFields.ToStringCollection()

 $viewRowLimit="100"

 $viewPaged=$true

 $viewDefaultView=$NewViewDefault

 

# Setting the Query for the View

 $viewQuery = "<ORDERBY><FIELDREF name="" false="" ascending=""></FIELDREF></ORDERBY><WHERE><EQ><FIELDREF author="" name=""><VALUE type="" integer=""><USERID type="" integer=""></USERID></VALUE></FIELDREF></EQ></WHERE>"

 $viewName = $NewViewName

 

# Finally – Provisioning the View

 $myListView = $list.Views.Add($viewName, $viewFields, $viewQuery, 100, $True, $False, "HTML", $False)

 

# You need to Update the View for changes made to the view

# Updating the List is not enough

 $myListView.DefaultView = $True

 $myListView.Update()

 $list.Update()

}

$web.Dispose()



Use $PSVersionTable.PSVersion to determine the engine version. If the variable does not exist, it is safe to assume the engine is version 1.0.

Note that $Host.Version and (Get-Host).Version are not reliable - they reflect the version of the host only, not the engine. PowerGUI, PowerShellPLUS, etc. are all hosting applications, and they will set the host's version to reflect their product version, which is entirely correct.



Here is a script that I wrote for backing up some very important files to an off-site ftp location. It backs up only files that are new OR have changed in the last 24 hours. That number of days could be a parameter based on when the backup last ran, however this is the base code that you can start using right away. Just add it to a Task Schedule that runs one a day.


# ==============================================================================================
#Set the Date/Time
# ==============================================================================================
$BackUpdateTime  = (Get-Date).Year.ToString()
$BackUpdateTime += (Get-Date).Month.ToString()
$BackUpdateTime += (Get-Date).Day.ToString()
$BackUpdateTime += (Get-Date).Hour.ToString()
$BackUpdateTime += (Get-Date).Minute.ToString()
$BackUpdateTime += (Get-Date).Second.ToString()
$today = (Get-Date -Format yyyy-MM-dd)

try {
 $ftp = "ftp://ftp.mysite.ca/"
 $user = "ftpuser"
 $pass = "ftppassword" 
 
 $webclient = New-Object System.Net.WebClient
 $webclient.Credentials = New-Object System.Net.NetworkCredential($user,$pass) 

 #we specify the directory where all files that we want to upload 
 $Dir="Y:\LocalDirectory\"
 $LogFile="I:\PowerShell\MyBackup_"+$today+".txt"
 Clear-Host
 #Write-Host $LogFile
 "From:"+$Dir+" (on server01) To:"+$ftp | Out-File $LogFile -Append
 "Start: "+(Get-Date) | Out-File $LogFile -Append

 $files = @(Get-ChildItem -Path  $Dir -Recurse | ?{ !$_.PSIsContainer } |Where-Object { $_.lastwritetime -gt (get-date).AddDays(-1)} | Select-Object -ExpandProperty FullName )
 foreach($item in $files)
 {
     if($item -ne $null)
  {
   $uri = New-Object System.Uri($ftp+$item.Substring(3))
   $webclient.UploadFile($uri, $item)
   #Write-Host (Get-Date)$item
   "$(Get-Date): "+$item | Out-File $LogFile -Append
  }
 }
 $webclient.Dispose()

 "End:"+(Get-Date) | Out-File $LogFile -Append
 
 $msg = new-object Net.Mail.MailMessage
 
 # Edit the From Address as per your environment. 
 $msg.From = "Backup (server01) <my.email@mysite.ca>"

 # Edit the mail address to which the Notification should be sent. 
 $msg.To.Add("my.email@mysite.ca")

 # Subject for the notification email. The + “$today” part will add the date in the subject. 
 $msg.Subject = "Backup was Successful for " + "$today"

 # Body or the notification email. The + “$today” part will add the date in the subject. 
 $msg.Body = "Backup was Successful for " + $today + "`r`n`r`n" 
 
 $att = new-object Net.Mail.Attachment($LogFile)
 $msg.Attachments.Add($att)
 
 # IP address of your SMTP server.
 $smtpServer = "smtp.mysite.ca" 
 $smtp = new-object Net.Mail.SmtpClient($smtpServer) 

 $smtp.Send($msg)
 $msg.Dispose()
}
Catch { 
 $ErrorMessage = $_.Exception.Message 

 # Configure the below parameters as per the above. 
 $msg = new-object Net.Mail.MailMessage
 $msg.From = "Backup (server01) <my.email@mysite.ca>" 
 $msg.To.Add("my.email@mysite.ca") 
 $msg.Subject = "Backup Job failed on " + "$today" 
 $msg.Body = "Job failed on " + "$today and the reason for failure was $ErrorMessage." 
 
 $att = new-object Net.Mail.Attachment($LogFile)
 $msg.Attachments.Add($att)
 
 $smtpServer = "smtp.mysite.ca" 
 $smtp = new-object Net.Mail.SmtpClient($smtpServer) 
 
 $smtp.Send($msg)
 $msg.Dispose()
}



The files that you attach to an email become locked until the instance of Powershell you are running has exited completely. So if you run a script through Powershell ISE that attaches a file to an email, that file will remain locked until you exit Powershell ISE.

If the file is locked by Powershell, you will get an error/warning message similar to the following if you try to modify it in any way;

The process cannot access the file 'c:\filename.txt' because it is being used by another process

By using the following command, you can ensure that Powershell 'disposes' of the email message once it has been sent and does not continue to 'lock' any files you attach and send via email;

$mailmessage.dispose()

Note: this is assuming that $MailMessage = New-Object system.net.mail.mailmessage



Adding Columns to a SharePoint List across an entire Site Collection should be done like this using PowerShell (with Power GUI):
 
Note that the use of the following works with all the defaults... 
$fieldDateTime = [Microsoft.SharePoint.SPFieldType]::DateTime
$list.Fields.Add("Compliance Date",$fieldDateTime,$false) 

However, you get MORE Control over Field Attributes using this method:
$fldXml = "<Field Type='DateTime' DisplayName='Report Sign Off Date' Format='DateOnly' Name='Report Sign Off Date'/>"     
$list.Fields.AddFieldAsXml($fldXml) 
 
Both methods are used in the code block below. 
if ((Get-PSSnapin | ? { $_.Name -eq "Microsoft.SharePoint.PowerShell" }) -eq $null) {
    Add-PSSnapin Microsoft.SharePoint.PowerShell
}
[Microsoft.SharePoint.SPSecurity]::RunWithElevatedPrivileges( 
{
 $site =  Get-SPSite -Identity "https://mysite.com/sites/thissite"
 Write-Host "Script Started"
 [array]$ListNames = "ListA", "ListB"
 $NumberofReportsinRecordFound = $false
 $ReportSignOffDateFound = $false
 $ComplianceDateFound = $false
 foreach($web in $site.AllWebs)
 {
  #Get number if Lists rather than using foreach as we will be modifying the List
  
  for($i=0; $i -lt $web.Lists.Count; $i++)
  {
   $list = $web.Lists[$i]
   if($list.BaseType -eq "DocumentLibrary" -and $list.BaseTemplate -notmatch "Catalog")
   {
    Write-Host $web.Title
    Write-Host $list
        
    $NumberofReportsinRecordFound = $false
    $ReportSignOffDateFound = $false
    $ComplianceDateFound = $false
      
    if($ListNames -contains $list.Title)
    {
     for($j=0; $j -lt $list.Fields.Count; $j++)
     {
      $field = $list.Fields[$j]
      if($field.Title -like "*do not use*")
      {
          Write-Host "do not use deleted!"
       $list.Fields.Delete($field)
       $list.Update() 
      }
      
      if($field.Title -like "Number of Reports in Record")
      {
       $NumberofReportsinRecordFound = $true
      }
      if($field.Title -like "Report Sign Off Date")
      {
       $ReportSignOffDateFound = $true
      }
      
      if($field.Title -like "Compliance Date")
      {
       $ComplianceDateFound = $true
      }
     }
        $fieldNumber = [Microsoft.SharePoint.SPFieldType]::Number

     if(!$NumberofReportsinRecordFound){
      $list.Fields.Add("Number of Reports in Record",$fieldNumber,$false)
      $fld = $list.Fields["Number of Reports in Record"]
     }
     
     if(!$ReportSignOffDateFound){
      $fldXml = "<Field Type='DateTime' DisplayName='Report Sign Off Date' Format='DateOnly' Name='Report Sign Off Date'/>"
      $list.Fields.AddFieldAsXml($fldXml)
     }
     
     if(!$ComplianceDateFound){
      $fldXml = "<Field Type='DateTime' DisplayName='Compliance Date' Format='DateOnly' Name='Compliance Date'/>"
      $list.Fields.AddFieldAsXml($fldXml)
     }
     $list.Description = "Inspection Reports"
     $list.Update()
    }
   }
  }
 }
 $web.Dispose()
 $site.Dispose()
 Write-Output "Script Ended"
}
)


The Blogger

Dave Stuart I'm a Developer with a passion for coding. I enjoy the challengers that come with the job! SharePoint is one of my expert areas along with .NET Web Development with MVC and good old MS Access VBA coding. I Blog so that I can remember how I did that way back when; PLUS all this stuff is searchable! I constantly study and run my own business, Dafran Inc. I have passed 22 Microsoft Exams since 1998 when I first jumped on the treadmill of knowledge. I hope that you enjoy this Blog as much as I enjoy updating it. All the very best from Calgary, Alberta, Canada. contact me at linkedin @ dafran.ca

Calendar

<<  February 2017  >>
MoTuWeThFrSaSu
303112345
6789101112
13141516171819
20212223242526
272812345
6789101112

View posts in large calendar

Sign in