Wednesday, October 19, 2011

Script to change Site Collection Administrators in SharePoint 2007 with PowerShell

Where I work, we receive several requests for site collection admin change per week, so that's something that always bothered me, since it's not a quick task to be done when you take care of a huge number of sites. That's why I managed to create this script today, it will help me (and my team) to save some time to do other more important (and more interesting) things. Here we go:

First of all, you need to create a ps file named Set-SiteCollectionAdmin.ps1 and paste the code below. You must have another file to put the sites which will have their SCA changed, let's name this one as Site-CollectionAdmin-List.txt.

Here's how the file should be formatted:

 http://mysite1,user1@company.com,user2@company.com  
 http://mysite2,,user3@company.com  
 http://mysite1,user4@company.com,  

Note that on the first line, we are changing both the primary and the secondary SCAs, on the second one we are changing only the secondary SCA and on the third one only the primary.

Below is the source code, commented.

 # Declaring SharePoint assembly so PowerShell can use the SP object model  
 # Read more about Developing a PowerShell Script for SharePoint 2007  
 [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")  
   
 # Getting the info from the file Set-SiteCollectionAdmin-List.txt  
 # Read also about Batch process in PowerShell - Get-Content and Import-CSV cmdlets  
 get-content Set-SiteCollectionAdmin-List.txt | foreach {  
      # Splitting the row by the commas and assigning each part to one variable  
      $row = $_.split(",")  
      # Site URL  
      $url = $row[0].Trim()  
      # Primary SCA email/username  
      $prim = $row[1].Trim()  
      # Secondary SCA email/username  
      $sec = $row[2].Trim()  
        
      Write-Host ""  
   
      # Creating an URI variable to be used on the next method  
      $uri = New-Object Uri($url)  
        
      # Checking whether the mentioned site exists  
      if([Microsoft.SharePoint.SPSite]::Exists($uri))  
      {  
           # Instantiating the site collection  
           $site = New-Object Microsoft.SharePoint.SPSite($url)  
           # Opening the top level web  
           $web = $site.OpenWeb()  
        
           Write-Host $site.URL -foregroundcolor Green  
             
           # Checking whether the primary SCA will be changed  
           if($prim -ne "")  
           {  
                # Checking whether the user already exists in the site.  
                # EnsureUser() will add the user to the site collection if he doesn't exist yet.  
                $primAdm = $web.EnsureUser($prim)  
                # Changing the site owner (primary SCA) to the user.  
                $site.Owner = $primAdm  
                Write-Host "New SCA: $prim"  
           }  
             
           # Same process of the primary SCA  
           if($sec -ne "")  
           {  
                # Checking whether the user already exists in the site.  
                # EnsureUser() will add the user to the site collection if he doesn't exist yet.  
                $secAdm = $web.EnsureUser($sec)  
                # Changing the site secondary contact (secondary SCA) to the user.  
                $site.SecondaryContact = $secAdm  
                Write-Host "New Sec SCA: $sec"  
           }  
      }  
      else # if the site doesn't exist, just jump to the next row  
      {  
           Write-Host "Site $url not found. Jumping to next row." -ForegroundColor Red  
      }  
        
      # Disposing web and site objects from memory  
      $web.Dispose()  
      $site.Dispose()  
 }  

Important: I could only make this work by running powershell as the farm account. Any suggestions of how to do it without needing the would be great.
Ler o texto inteiro ►

Batch process in PowerShell - Get-Content and Import-CSV cmdlets

One of the most important, easy and useful things I see in PowerShell is the possibility to easily process several requests in batch, saving a lot of time. In this article I'm going to explain in this article how to get information from a TXT file and process anything with it using Get-Content cmdlet and also how to get information from a CSV file using the Import-CSV cmdlet.

Get-Content cmdlet:

 PS C:\> Get-Content MyTextFile.txt  
 Line0  
 Line1  
 Line2  
 Line3  
 Line4    

This first example shows us just how to show the file content, however, the most interesting utilization is with a loop, which will allow us to do several tasks in a row for each line of the file as follows (let's say I have 3 computer names on MyTextFile.txt now):

 PS C:\> Get-Content MyTextFile.txt | ForEach { IISRESET $_ }  
 Attempting stop...  
 Internet services successfully stopped  
 Attempting start...  
 Internet services successfully restarted  
 Attempting stop...  
 Internet services successfully stopped  
 Attempting start...  
 Internet services successfully restarted  
 Attempting stop...  
 Internet services successfully stopped  
 Attempting start...  
 Internet services successfully restarted  

You can also limit the number of rows you want to be fetched from the file by using the parameter TotalCount if you want to get the x first records, or using the Select-Object cmdlet with the parameter -Last to have the x last records, as follows:

 PS C:\> Get-Content .\MyTextFile.txt -TotalCount 3  
 Computer0  
 Computer1  
 Computer2  
 PS C:\> Get-Content .\MyTextFile.txt | Select-Object -Last 3  
 Computer7  
 Computer8  
 Computer9  

Import-CSV cmdlet:

Let's say we have a CSV file, an Excel file (which can be easily saved as CSV), or even data exported from any application in comma-separated-values. This can be handled by PowerShell just as easily as the TXT file, plus the possibility to search the records you want to work with by quickly building queries to get information from the file content.

 PS C:\> Import-CSV .\MyCSVFile.csv | Format-Table -AutoSize  
 FullName        Extension CreationTime  LastAccessTime LastWriteTime  
 --------        --------- ------------  -------------- -------------  
 C:\install.res.1028.dll .dll   11/7/2006 9:03 5/6/2011 17:29 11/7/2006 9:03  
 C:\install.res.1031.dll .dll   11/7/2007 9:03 5/6/2011 17:29 11/7/2007 9:03  
 C:\install.res.1033.dll .dll   11/7/2008 9:03 5/6/2011 17:29 11/7/2008 9:03  
 C:\install.res.1036.dll .dll   11/7/2009 9:03 5/6/2011 17:29 11/7/2009 9:03  
 C:\install.res.1040.dll .dll   11/7/2010 9:03 5/6/2011 17:29 11/7/2010 9:03  

First example shows how to just get the file content and using Format-Table cmdlet to have the outcome formatted. Next, let's see how to filter only the ones with date greather than 1/1/2009 by using the Where-Object cmdlet an then again Format-Table for the outcome.

 PS C:\> Import-CSV .\MyCSVFile.csv | Where-Object {[datetime]::Parse($_.CreationTime) -gt '1/1/2009' } | Format-Table -AutoSize  
 FullName        Extension CreationTime  LastAccessTime LastWriteTime  
 --------        --------- ------------  -------------- -------------  
 C:\install.res.1036.dll .dll   11/7/2009 9:03 5/6/2011 17:29 11/7/2009 9:03  
 C:\install.res.1040.dll .dll   11/7/2010 9:03 5/6/2011 17:29 11/7/2010 9:03  

More info:

Get-Content cmdlet
Import-CSV cmdlet
Ler o texto inteiro ►

Tuesday, October 18, 2011

Developing a PowerShell Script for SharePoint 2007

Since I started working with SharePoint infrastructure and administration, I've been thinking on a solution to automatize some daily tasks that ever since I was able only to perform either via Central Administration or STSADM command.

So today, I started studying how to work with PowerShell scripting for SharePoint, and it seems to be pretty easy and cool :)

The first thing you must do so PowerShell can access SharePoint assemblies is to load them using below code line:

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

Once you have the assemblies loaded, you can invoke all methods of SP object model, just like if you were developing with any .NET programming language. Below example shows how to get both the primary and secondary Site Collection Administrators from a given URL:

$site = New-Object Microsoft.SharePoint.SPSite("http://mysite")
$priSCALogin = $site.Owner.LoginName
$secSCALogin = $site.SecondaryContact.LoginName

write "-Primary SCA: $priSCALogin"
write "-Secondary SCA: $secSCALogin"

I'll keep working and studying about this and obviously, posting.

Ler o texto inteiro ►

Monday, October 10, 2011

OCS Conversation History saved on the wrong mailbox

These days I've been working on an issue related to the OCS Conversation History, and where it was saving its instant messaging records. The user in case has an additional mailbox set in Outlook and Communicator was saving all conversation histories in the additional mailbox, which can cause several problems, since the users conversation were being stored into a shared folder.

After several frustrated attempts of solving the problem, a teammate of mine found out a solution, and here it is:

  1. In Communicator, go to Tools > Options...
  2. In Office Communicator - Options window, uncheck Save my instant message conversations in the Outlook Conversation History folder;
  3. Restart Communicator;
  4. Remove all the additional mailboxes as explained here;
  5. Restart Outlook;
  6. Check again "Save my instant message conversations in the Outlook Conversation History folder" in Communicator > Tools > Options;
  7. Chat with someone and double check whether the conversations are being stored in the correct folder;
  8. Add the secondary mailboxes back, as explained here;
  9. Check again whether the conversations are yet being saved at the correct location.


Ler o texto inteiro ►

How to add/remove additional mailboxes in Outlook


How to add an additional mailbox in Outlook:
  1. In Outlook 2010, Go to File > Account Settings > Account Settings...
    • In Outlook 2007, Tools > Account Settings...
  2. On Account Settings window, Select Default, then click Change...
  3. On Change Account window, click More Settings...
  4. On Microsoft Exchange window, go to Advanced tab and click Add...
  5. On Add Mailbox window, type the mailbox name in Add mailbox field.
  6. Click Ok, Ok, Next, Finish.

How to remove the additional mailbox:
  1. In Outlook 2010, Go to File > Account Settings > Account Settings...
    • In Outlook 2007, Tools > Account Settings...
  2. On Account Settings window, Select Default, then click Change...
  3. On Change Account window, click More Settings...
  4. On Microsoft Exchange window, go to Advanced tab
  5. If the mailbox is listed in Open these additional mailboxes, select it and click Remove
  6. Click OK, Next, Finish
Ler o texto inteiro ►
Related Posts Plugin for WordPress, Blogger...