Automating SharePoint 2010 Administration with PowerShell: Renaming the Admin Content DB

If you don’t like the GUID that trails the Central Admin Content DB, you have 2 options, create the Farm with PowerShell / scripting and create the databases with names that you like OR if you already have a Farm, you can use the scripts below to change the Admin Content (Central Admin Content Database). Needless to say during this operation your Central Admin site is not accessible. These scripts also call IISRESET and hence plan for downtime.

There are 2 examples of this script, both are 100% automated. The only thing the Script expects the User to provide is the name of the New Content Database. I would love to automate it with Read-YourMind cmdlet… but let’s leave it for now J.

Method 1 – Using Move-SPSite cmd-let.

What we are doing here:

1. Getting the Central Admin URL and the New Content DB Name from the User

2. Populating the variables we need to perform the operation like the Current Admin Content DB Name, SQL Server Name and the Database ID

3. Creating a New Content Database and Attaching it to the Central Admin Web Application

4. Calling SP-MoveSite to Move 2 sites from Old Content Database to the New one

5. Lastly, we ask the user if he wants to Detach the Content DB from the web application or completely delete it from SQL

The operation can be screen in the below screenshots:

clip_image002

Current Content DB with 2 Site Collections

clip_image004

New Content DB Attached to the same Web App and Site Collections have been moved to the New Content DB

This is the Script. For convenience, you can also download the zip file attached to this post. The zip file contains 2 scripts RenameAdminContentDB_Method1.PS1 (Move-SPSite Method) and RenameAdminContentDB_Method1.PS1 (Backup – restore methos described later in the post.)

  1: Clear-Host
  2: ############################################################################################################################ DO NOT EDIT ANYTHING BELOW THIS LINE ###########################
  3: #############################################################################################
  4: # Start Loading SharePoint Snap-in
  5: $snapin = (Get-PSSnapin -name Microsoft.SharePoint.PowerShell -EA SilentlyContinue)
  6: IF ($snapin -ne $null){write-host -f Green "SharePoint Snapin is loaded... No Action taken"}
  7: ELSE  {write-host -f Yellow "SharePoint Snapin not found... Loading now"
  8: Add-PSSnapin Microsoft.SharePoint.PowerShell
  9: write-host -f Green "SharePoint Snapin is now loaded"}
  10: # END Loading SharePoint Snapin
  11: #Detect CA Site URL 
  12: $CA = (Get-SPWebApplication -IncludeCentralAdministration | where {$_.DisplayName -eq "SharePoint Central Administration v4"}).Url
  13: #Get New Content DB Name from User
  14: $NewContentDB = Read-Host "Enter the New Content Database Name for your Central Admin Site"
  15: IF ($NewContentDB -eq ''){Write-Host -f Red "Blank value for Content DB. Cannot proceed. Exiting..."
  16: break}
  17: # grab SQL Server Name
  18: $SQLServer = (Get-SPContentDatabase -WebApplication $CA -EA Stop).Server
  19: $OldDB = (Get-SPContentDatabase -WebApplication $CA -EA Stop).DB
  20: $OldDBID = (Get-SPContentDatabase -WebApplication $CA -EA Stop).ID
  21: #Create new SP_contentDB
  22: Write-Host -f Green "Creating Content DB..."
  23: New-SPContentDatabase -Name $NewContentDB -WebApplication $CA -DatabaseServer $SQLServer -ErrorAction STOP
  24: Write-Host -f Green "New Content DB Created and Attached to your Central Admin Site"
  25: #Grab ID of the New Content DB
  26: $NewContentDBID = (Get-SPContentDatabase -WebApplication $CA | ?{$_.Name -eq $NewContentDB}).id
  27: #Get and Move SP-Site
  28: Get-SPSite -ContentDatabase $OldDBID | Move-SPSite -DestinationDatabase $NewContentDBID -Confirm:$False -EA Stop
  29: Write-Host -f Green "Site Move complete."
  30: Write-Host -f Green "Resetting IIS now..."
  31: IISRESET
  32: $RemoveOption = Read-Host "
  33: Choose Remove Database Option:
  34: 1 - Remove (DELETES the Database from SQL)
  35: 2 - Dismount (Detach the DB from Web Application)"
  36: IF ($RemoveOption -eq '1') {Remove-SPContentDatabase -Identity $OldDBID -EA Stop
  37: Write-Host -F Green "Database deleted from SQL Server."}
  38: ElseIF ($RemoveOption -eq '2') {Dismount-SPContentDatabase -Identity $OldDBID -Confirm:$False -EA Stop
  39: Write-Host -F Yellow "Database detached from SharePoint Web Application. Please delete the Database manually from SQL Server."}
  40: Else {Write-Host -f Yellow "Invalid Option chosen. No action was taken."}
  41: Write-Host -F Green "All Opearation Completed Successfully."
  42: ################### END SCRIPT ###########################

 

Method 2 – Using SQL Backup and Restore.

This method is primary for demonstration purposes. It shows how you can call SQL Commands and SMO (SQL Server Management Objects) directly from PowerShell along with SharePoint. I will use the same method in future posts on automating tasks for Database mirroring. Though this script can be used for any content database, I have tested this with the Central Admin Content Database only. Also, the script below you will see that when we restore the database, we are getting the LogicalName of the SQL MDF and LDF File from the backup set (your original SharePoint_AdminContent_GUID). Though it’s possible to fire a Alter Database Statement to change the names, running Alter Database statement on SharePoint Databases are not supported and you should refrain from doing that.

This script also has the following prerequisite:

To use this script you need SQL Server Client Components to be installed on the Server and you need the required permissions for backup / restore on SQL. It’s also possible to run the SQL Section of the script on the SQL Box, or put it on the SQL Box as a ps1 file and call it form the script below with –session parameter if you do not have SQL Server Client Components installed on the server.

This script is fully automated and performs the following steps:

  • Loads SharePoint and SQL Snap-in
  • Detects the Central Admin Site URL
  • Populates the required variables like SQL Server Name, Database Name
  • Loads SQL Assemblies to get SQL Server Defaults for Backup Location and MDF / LDF File Locations
  • Constructs a new Backup File name with TimeStamp
  • Creates the Backup Statement and stores it in a String
  • Invokes SQLCmd to execute the backup statement – this first runs a full backup and then a Transaction Log backup so that we don’t lose the Tail of the Log (required for all databases with FULL Recovery Model)
  • Enters Restore Operation block
  • Grabs the LogicalName of the MDF and LDF File from the BackupSet through SQLSMO.Restore object
  • Gets the Name of the New Content DB from the User
  • Generates the Restore Statement
  • Invokes SQLCmd to execute the Restore statement – First the Full backup with NORECOVERY option and then the Transaction Log File
  • Comes back to SharePoint Loop – First step is to dismount the Old Content DB
  • Mounts the new Content DB to the Web App
  • Runs IISRESET
  • Provides a remove option to the user – if user selects that option, the database is permanently deleted.
  1: Clear-Host
  2: ############################################################################################################################ DO NOT EDIT ANYTHING BELOW THIS LINE ###########################
  3: #############################################################################################
  4: # Start Loading SharePoint Snap-in
  5: $snapin = (Get-PSSnapin -name Microsoft.SharePoint.PowerShell -EA SilentlyContinue)
  6: IF ($snapin -ne $null){write-host -f Green "SharePoint Snapin is loaded... No Action taken"}
  7: ELSE  {write-host -f Yellow "SharePoint Snapin not found... Loading now"
  8: Add-PSSnapin Microsoft.SharePoint.PowerShell
  9: write-host -f Green "SharePoint Snapin is now loaded"}
  10: # END Loading SharePoint Snapin
  11: # Start Loading SQL Snap-in
  12: ## Check to see if SQL Server Provider for Windows PowerShell is installed 
  13: # Add the SQL Server Provider. Ref: https://technet.microsoft.com/en-us/library/cc281962.aspx 
  14: $ErrorActionPreference = "Stop"
  15: $sqlpsreg="HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.SqlServer.Management.PowerShell.sqlps"
  16: if (Get-ChildItem $sqlpsreg -ErrorAction "SilentlyContinue")
  17: {    throw "SQL Server Provider for Windows PowerShell is not installed. Please install Client Components first."}
  18: Else{    $item = Get-ItemProperty $sqlpsreg
  19:     $sqlpsPath = [System.IO.Path]::GetDirectoryName($item.Path)}
  20: $snapin = (Get-PSSnapin -name SqlServerCmdletSnapin100  -EA SilentlyContinue)
  21: IF ($snapin -ne $null){write-host -f Green "SQL Snapin is loaded... No Action taken"}
  22: ELSE  {write-host -f Yellow "SQL Snapin not found... Loading now"
  23: Add-PSSnapin SqlServerCmdletSnapin100
  24: write-host -f Green "SQL Snapin is now loaded"}
  25: # END Loading SQL Snap-in
  26: ######################### START SharePoint Loop ##################################
  27: # Detect CA Site
  28: $CA = (Get-SPWebApplication -IncludeCentralAdministration | where {$_.DisplayName -eq "SharePoint Central Administration v4"}).Url
  29: # Get Content DB Name
  30: $CACurrentdb  = (Get-SPContentDatabase -WebApplication $CA).Name
  31: $SQLServer = (Get-SPContentDatabase -WebApplication $CA).Server
  32: Write-Host -f Green "Central Admin Content DB Name: " $CACurrentdb
  33: Write-Host -f Green "Detected SQL Server: " $SQLServer
  34: Write-Host -f Green " Entering SQL Loop Now..."
  35: ######################### END SharePoint Loop ##################################
  36: ######################### START SQL Loop ##################################
  37: [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO")  | out-null
  38: [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMOExtended")  | out-null
  39: [Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null
  40: [Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum") | Out-Null
  41: #get server defaults for Backup, MDF and LDF Locations
  42: $smosql=New-Object ('Microsoft.SqlServer.Management.Smo.Server') $sqlserver
  43: $ServerDefaultBackupLocation = $smosql.Settings.BackupDirectory 
  44: Write-Host -f green "Captured Default Backup Directory: " $ServerDefaultBackupLocation
  45: $GetMDFFileLocation = $smosql.MasterDBPath
  46: $GetLDFFileLocation = $smosql.MasterDBLogPath
  47: $timestamp = Get-Date -format yyyyMMddHHmmss
  48: # Construct a new Backup File name to avoid any conflics
  49: $bkSetName = $ServerDefaultBackupLocation +"\CA_Backup_DB_"+$timestamp +  ".bak"
  50: # Creating Backup Statement for Database and Transaction Log Backup
  51: [String] $bkupstmt ="BACKUP DATABASE [" + $CACurrentdb + "]
  52: TO  DISK = N'" + $bkSetName + "' WITH NOFORMAT, NOINIT, NAME = N'SharePoint_AdminContent_BackUp', SKIP, NOREWIND, NOUNLOAD, STATS = 10
  53: GO
  54: BACKUP LOG [" + $CACurrentdb + "] 
  55: TO  DISK = N'" + $bkSetName + "' WITH NOFORMAT, NOINIT, NAME = N'SharePoint_AdminContent_BackUp', SKIP, NOREWIND, NOUNLOAD, STATS = 10
  56: GO"
  57: # Firing the SQL Query
  58: Invoke-Sqlcmd -Query $bkupstmt -ServerInstance $sqlserver
  59: Write-Host -F Green "Backup Completed Successfully"
  60: # Start Restore Operation
  61: #Grab Logical File Names from Backup Set
  62: $res = new-object Microsoft.SqlServer.Management.Smo.Restore
  63: $res.Devices.AddDevice($bkSetName, [Microsoft.SqlServer.Management.Smo.DeviceType]::File)
  64: $LogicalDataFileName = $res.ReadFileList($smosql).Rows[0]["LogicalName"]
  65: $LogicalLogFileName = $res.ReadFileList($smosql).Rows[1]["LogicalName"]
  66: #Get New Content DB Name from User
  67: $NewContentDBName = Read-Host "Enter the name of the New Content Database "
  68: # Start Restore Operation... Create the Query
  69: [String] $restoreStmt = "
  70: RESTORE DATABASE [" + $NewContentDBName + "] FROM DISK = N'"+ $bkSetName+"' WITH FILE = 1, MOVE N'" + $LogicalDataFileName + "' 
  71: TO N'"+ $GetMDFFileLocation +"\"+ $NewContentDBName + ".mdf', MOVE N'"+ $LogicalLogFileName + "' 
  72: TO N'" + $GetLDFFileLocation +"\" + $NewContentDBName + "_log.LDF', NORECOVERY, NOUNLOAD, STATS = 10
  73: GO
  74: RESTORE LOG ["+ $NewContentDBName +"] FROM DISK = N'"+ $bkSetName +"' WITH FILE = 2, NOUNLOAD, STATS = 10
  75: GO"
  76: # Fire the SQL Query
  77: Invoke-Sqlcmd -Query $restoreStmt -ServerInstance $SQLServer
  78: Write-Host -f Green "Retore Completed Successfully... "
  79: # END SQL Loop
  80: # Back to SP Loop to attach the new content DB to Central Admin Site
  81: # First - Dismounting DB
  82: Dismount-SPContentDatabase -Identity (Get-SPContentDatabase -WebApplication $CA) -Confirm:$false
  83: Mount-SPContentDatabase $NewContentDBName -DatabaseServer $SQLServer -WebApplication $CA
  84: Write-Host -f green "New Content Database Attached to Central Admin Site.
  85: "
  86: # reset IIS
  87: Write-Host -f green "Running IISRESET now..."
  88: iisreset
  89: $RemoveOption = Read-Host "
  90: Choose Remove Database Option:
  91: 1 - Remove (DELETES the Database from SQL)
  92: 2 - Exit (Do Nothing)"
  93: IF ($RemoveOption -eq '1') { 
  94: [String] $DropDB = "
  95: ALTER DATABASE ["+ $CACurrentdb + "]
  96: SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
  97: DROP DataBase [" + $CACurrentdb+ "]"
  98: Invoke-Sqlcmd -Query $DropDB -ServerInstance $SQLServer
  99: Write-Host -F green "Database Removed from SQL"}
  100: Else {Write-Host -f Yellow "Exiting Remove Operation... Database was not Dropped from SQL Server."}
  101: Write-Host -F Green "All Opearation Completed Successfully."
  102: #################### END SCRIPT ####################

 

Cheers Smile

Priyo

Scripts.zip