Change the URL of a site collection in SharePoint 2013

So, your manager/the business asks you to create a few site collections for some departments in your organization. You quickly spin up some site collections for them to use. After a few weeks, the business decides (of course) SharePoint is great, but the URL’s we chose weren’t all that great. Can you please change them?

There are alot of blog posts out there that describe the different possibilities in this scenario:
– Using backup and restore.
– A great article by Todd Klindt that tells you how to use the Copy-SPSite cmdlet to achieve the same goal but easier!

There is another (easier) way in some scenario’s in which you can change the site collection URL by just using 2 lines of PowerShell with only a second of waiting time!

The solution
Let’s get down to it.. I created this very nice Marketing site collection, using the url: http://sharepoint/sites/marketing. Now I would like to change this to http://sharepoint/sites/sales. Just use the following 2 lines of PowerShell code and you are done!

 $site = Get-SPSite http://sharepoint/sites/marketing
$site.Rename("http://sharepoint/sites/sales")

That is all.. try it out and see that your new URL is working, and the old URL is not working anymore!

A little catch
There is a little catch to this. You can only use this to rename site collection URL’s that
– Use “Wildcard inclusion” Managed Paths.
– Are Host named site collections (In which case you could also use Set-SPSiteURL)

You can’t use it to change http://sharepoint/sites/marketing to http://sharepoint/marketing (Even if the Explicit inclusion managed path exists).

Hope this helps anyone out there!

Download all content in a site collection

Hi,

I’ve been working on a script that will allow you to download all files that are stored in SharePoint in a given site collection.

If the path does not exist, the script will prompt you to create it for you. Before the script runs, it also checks if the site collection exists.

Run the script like this:

.\Get-SPContent.ps1 -SiteCollection "<SiteCollectionURL>" -Destination "<Path>"

Preview

The console shows which libraries were exported to your file system.

—– * Advanced * —–

If you have specific requirements as to which (type of) libraries you want to export, you can change the following line to fit your requirements:

$lists = $web.lists | ?{$_.itemcount -ge "1" -And $_.Hidden -eq $false -And $_.BaseType -eq "DocumentLibrary"} #Excludes all hidden libraries and empty libraries

Below is the code you can save as Get-SPContent.ps1

param
(
[Parameter(Mandatory=$true)]
[ValidateScript({asnp *sh* -EA SilentlyContinue;if (Get-SPSite $_){$true}else{Throw "Site collection $_ does not exist"}})]
[string]$SiteCollection,
[Parameter(Mandatory=$true)]
[ValidateScript(
{
if (Test-Path $_)
{$true}
else{
$d = $_
$title = "Create Folder?";
$message = "$_ doesn't exist, do you want the script to create it?";
$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Creates directory $_";
$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "Exits script";
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes,$no);
$result = $host.ui.PromptForChoice($title,$message,$options,1);
switch($result)
{
0 {New-Item $d -Type Directory;$true}
1 {Throw "Please create the folder before running the script again. `nExiting script"}
}
}
})]
[string]$Destination
)

Asnp *sh* -EA SilentlyContinue

Start-SPAssignment -Global | Out-Null

function Get-SPWebs($SiteCollection){
$SiteCollection = Get-SPSite $SiteCollection
$webs = @()
$SiteCollection.allwebs | %{$webs += $_.url}
return $webs
}

function Get-SPFolders($webs)
{
foreach($web in $webs)
{
$web = Get-SPWeb $web
Write-Host "`n$($web.url)"

$lists = $web.lists | ?{$_.itemcount -ge "1" -And $_.Hidden -eq $false -And $_.BaseType -eq "DocumentLibrary"} #Excludes all hidden libraries and empty libraries
#$lists = $web.lists | ?{$_.title -eq "Documents" -and $_.itemcount -ge "1" -And $_.BaseType -eq "DocumentLibrary"} #Change any identifier here
foreach($list in $lists)
{
Write-Host "- $($list.RootFolder.url)"

#Download files in root folder
$rootfolder = $web.GetFolder($list.RootFolder.Url)
Download-SPContent($rootfolder)

#Download files in subfolders
foreach($folder in $list.folders)
{
$folder = $web.GetFolder($folder.url)
Download-SPContent($folder)

}

}
$web.dispose()
}
}

function Download-SPContent($folder)
{
foreach($file in $folder.Files)
{
$binary = $file.OpenBinary()
$stream = New-Object System.IO.FileStream($destination + "/" + $file.Name), Create
$writer = New-Object System.IO.BinaryWriter($stream)
$writer.write($binary)
$stream.Close()
$writer.Close()
}
}

$webs = Get-SPWebs -SiteCollection $Sitecollection
Get-SPFolders -Webs $webs

Stop-SPAssignment -Global

Encrypting your text-based files using PowerShell

Hi folks,

It has been a while since my last post, but here it is.

Please find the script in the TechNet Gallery here. All updates to this script will also be managed here: https://gallery.technet.microsoft.com/Encrypting-your-text-based-d939876b.

As a SharePoint administrator I am often asked to script certain tasks. Of course, PowerShell does a great job at this, as it allows me to automate repetitive tasks.

One commonly faced issue (for me), is that whenever I am using a XML file for those tasks, I sometimes have to include a password in the XML file for some scripts to run. An example is AutoSPInstaller. Personally, I don’t think you should have your passwords in an unencrypted XML file just sitting around for some developer to find and possibly abuse it. To work around this, I created some scripts to help me address this issue.

 

 

Add-PSSnapIn Microsoft.SharePoint.PowerShell shortcut

Are you tired of typing Add-PSSnapIn Microsoft.SharePoint.PowerShell every time you open your PowerShell console?
You can do this by Adding/Editing profile.ps1 (I don’t do this because I have too many machines where I should change this)

If you find you do not want to change the profile.ps1 on every server you are working on, you can type this:

asnp *sh*

This adds all SnapIns that contain *sh*. In most cases, this will only add the Microsoft.SharePoint.PowerShell SnapIn.
Credits go to Koen Zomers!

Happy PowerShelling!

 

Restore deleted site collections SharePoint 2013

In SharePoint 2013 it is possible to restore a accidently deleted site collection. For more information, read this article: http://technet.microsoft.com/en-us/library/hh272537.aspx

You can use the Restore-SPDeletedSite cmdlet to restore a site collection.

However, if you removed the site collection using the Remove-SPSite cmdlet using PowerShell, the site collection will not be stored in a SPDeletedSite object.

This means you cannot restore a site collection that has been removed using PowerShell.

 

Add PDF mimetype for all Web Applications one-liner

By default, PDF files cannot be opened directly from SharePoint 2010/SharePoint 2013.

To add the PDF mimetype to all Web Applications (Instead of doing it seperately for each Web Application), you can use the following one-liner:

Get-SPWebApplication | %{$_.AllowedInlineDownloadedMimeTypes.Add("application/pdf");$_.Update()}

Get all subsites of a subsite

Getting a list of all subsites of a particular site (not a site collection) was a little more work than I expected, so here is how I did it.

Let’s say we have the following situation site structure:

SiteStructure

What if we want an overview of all sites under “Https://portal.sharepointrelated.com/Projects”?

My first thought was to use the “Webs” property of the SPWeb object. Unfortunately, this only shows the direct subsites for this site. This means that for “Https://portal.sharepointrelated.com/projects”, it only shows the Level 3 sites.

Solution

To work around this, I used the “AllWebs” property of the SPSite object and filtered the URL’s starting with “Https://portal.sharepointrelated.com/projects”.

Here is the code used: (Download .zip file)


param ( [Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()] [String]$StartWeb, [Boolean]$IncludeStartWeb = $true )

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

$subsites = ((Get-SPWeb $StartWeb).Site).allwebs | ?{$_.url -like "$StartWeb*"}

foreach($subsite in $subsites) { Write-Host $subsite.url }

As you can see in the source code, I added 2 parameters to the script:

StartWeb: String. This is the starting URL. All subsites under this site will be showed in the result.

IncludeStartWeb: Boolean. When set to $false, the output will not include the URL provided in the StartWeb parameter.