Advertisement
Guest User

Untitled

a guest
Mar 20th, 2019
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.93 KB | None | 0 0
  1. Add-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
  2.  
  3. function Move-ContentDatabaseToNewDrive
  4. {
  5. [cmdletbinding()]
  6. param
  7. (
  8. [parameter(Mandatory=$true)][Microsoft.SharePoint.Administration.SPContentDatabase]$Database,
  9. [parameter(Mandatory=$true)][string]$DataPath,
  10. [parameter(Mandatory=$true)][string]$LogPath,
  11. [parameter(Mandatory=$true)][string]$BackupPath
  12. )
  13.  
  14. begin
  15. {
  16. $maximumSiteCount = $Database.MaximumSiteCount
  17. $warningSiteCount = $Database.WarningSiteCount
  18. $availabilityGroup = $Database.AvailabilityGroup
  19. $availabilityGroupName = $availabilityGroup.Name
  20. $availabilityGroupShare = $null
  21. $databaseName = $Database.Name
  22. $databaseServer = $Database.Server
  23. $webApplication = $Database.WebApplication
  24. $backupFullFilePath = Join-Path -Path $BackupPath -ChildPath "$databaseName.bak"
  25. $fileShare = $null
  26.  
  27. $backupTSQLCommand = "IF DB_ID('{0}') IS NOT NULL
  28. BEGIN
  29. BACKUP DATABASE [{0}] TO DISK = N'{1}' WITH COPY_ONLY, FORMAT, INIT, SKIP, REWIND, NOUNLOAD, COMPRESSION
  30. END"
  31.  
  32. $dropTSQLCommand = "IF DB_ID('{0}') IS NOT NULL
  33. BEGIN
  34. EXEC msdb.dbo.sp_delete_database_backuphistory @database_name = N'{0}'
  35. ALTER DATABASE [{0}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
  36. DROP DATABASE [{0}]
  37. END"
  38.  
  39. $restoreTSQLCommand = "IF DB_ID('{0}') IS NULL
  40. BEGIN
  41. RESTORE DATABASE [{0}] FROM DISK = N'{1}' WITH FILE = 1, MOVE '{2}' TO '{3}', MOVE '{4}' TO '{5}', NOUNLOAD
  42. END"
  43.  
  44. $logicalNameTSQLCommand = "SELECT [type_desc], [name], [physical_name] FROM sys.[master_files] WHERE [database_id] = DB_ID('{0}')"
  45.  
  46. $inAvailabilityGroupTSQLCommand = "SELECT COUNT(*) AS 'Count' FROM sys.availability_groups g JOIN sys.availability_databases_cluster c ON g.group_id = c.group_id WHERE database_name = '{0}'"
  47.  
  48. $inMirroringGroupTSQLCommand = "SELECT COUNT(*) AS 'Count' FROM sys.database_mirroring_witnesses WHERE database_name = '{0}'"
  49. }
  50. process
  51. {
  52. # get existing database properties before doing anything invasive
  53.  
  54. try
  55. {
  56. Write-Verbose -Message "Querying for content database properties"
  57.  
  58. $tsql = $logicalNameTSQLCommand -f $databaseName
  59. $logicalFileInfo = Get-DataTable -DatabaseServer $databaseServer -DatabaseName "master" -Query $tsql
  60.  
  61. # get the logical name for the data and log file
  62. $logicalDataFileName = $logicalFileInfo | ? type_desc -eq "ROWS" | SELECT -First 1 -ExpandProperty Name
  63. $logicalLogFileName = $logicalFileInfo | ? type_desc -eq "LOG" | SELECT -First 1 -ExpandProperty Name
  64.  
  65. # get the full path for the data and log file
  66. $physicalDataFileFullPath = $logicalFileInfo | ? type_desc -eq "ROWS" | SELECT -First 1 -ExpandProperty physical_name
  67. $physicalLogFileFullPath = $logicalFileInfo | ? type_desc -eq "LOG" | SELECT -First 1 -ExpandProperty physical_name
  68.  
  69. # pull out the data and log file names
  70. $physicalDataFileName = (New-Object System.IO.FileInfo($physicalDataFileFullPath)).Name
  71. $physicalLogFileName = (New-Object System.IO.FileInfo($physicalLogFileFullPath)).Name
  72.  
  73. # build new path to data and log files
  74. $newPhysicalDataFileFullPath = [System.IO.Path]::Combine($DataPath, $physicalDataFileName)
  75. $newPhysicalLogFileFullPath = [System.IO.Path]::Combine($LogPath, $physicalLogFileName)
  76.  
  77. if( -not $logicalDataFileName -or -not $logicalLogFileName -or -not $physicalDataFileFullPath -or -not $physicalLogFileFullPath )
  78. {
  79. throw "The required database properties name where not found."
  80. }
  81. }
  82. catch
  83. {
  84. Write-Error "Failed to discover database properties. Exception: $($_.Exception)"
  85. return
  86. }
  87.  
  88. if( $VerbosePreference -ne "SilentlyContinue" )
  89. {
  90. [PSCustomObject] @{
  91. BackupFilePath = $backupFullFilePath
  92. LogicalDataFileName = $logicalDataFileName
  93. LogicalLogFileName = $logicalLogFileName
  94. NewLogFilePath = $newPhysicalLogFileFullPath
  95. NewDataFilePath = $newPhysicalDataFileFullPath
  96. CurrentDataFilePath = $physicalDataFileFullPath
  97. CurrentLogFilePath = $physicalLogFileFullPath
  98. }
  99. }
  100.  
  101.  
  102. # remove from AG
  103.  
  104. if( $availabilityGroup )
  105. {
  106. try
  107. {
  108. # get the file share location for this availalbity group
  109. $availabilityGroupShare = $availabilityGroup.GetType().GetProperty("FileShare", "NonPublic,Instance").GetValue($availabilityGroup)
  110.  
  111. if( -not $availabilityGroupShare -or -not (Test-Path -Path $availabilityGroupShare))
  112. {
  113. throw "The Availability Group file share path '$availabilityGroupShare' was not found."
  114. }
  115.  
  116. Write-Verbose -Message "Removing database from Availability Group"
  117. Remove-DatabaseFromAvailabilityGroup -DatabaseName $Database.Name -AGName $availabilityGroup.Name
  118.  
  119. # get the instance name not that the database is not in the AG
  120. $Database = Get-SPContentDatabase -Identity $Database.Name
  121. $databaseServer = $Database.Server
  122. }
  123. catch
  124. {
  125. Write-Error "Failed to remove database from Availability Group. Exception: $($_.Exception)"
  126. return
  127. }
  128. }
  129. else
  130. {
  131. # verify the database is not in a Availability Group or using SQL Mirroring not registered with SharePoint
  132.  
  133. try
  134. {
  135. Write-Verbose -Message "Verifying Content Database is not a member of other HADR solutions"
  136.  
  137. $tsql = $inAvailabilityGroupTSQLCommand -f $databaseName
  138. if( (Get-DataTable -DatabaseServer $databaseServer -DatabaseName "master" -Query $tsql).Count -ne 0 )
  139. {
  140. Write-Error "Content database is in a SQL Availability Group but it is not configured in SharePoint"
  141. return
  142. }
  143.  
  144. $tsql = $inMirroringGroupTSQLCommand -f $databaseName
  145. if( (Get-DataTable -DatabaseServer $databaseServer -DatabaseName "master" -Query $tsql).Count -ne 0 )
  146. {
  147. Write-Error "Content database is using SQL mirroring."
  148. return
  149. }
  150. }
  151. catch
  152. {
  153. Write-Error "Failed to validate database is not in an Availability Group or Mirroring Group. Exception: $($_.Exception)"
  154. return
  155. }
  156. }
  157.  
  158.  
  159. # dismount from SharePoint farm
  160.  
  161. try
  162. {
  163. Write-Verbose -Message "Dismounting database from SharePoint farm"
  164. $Database | Dismount-SPContentDatabase -Confirm:$false
  165. }
  166. catch
  167. {
  168. Write-Error "Failed to remove database from SharePoint farm. Exception: $($_.Exception)"
  169. return
  170. }
  171.  
  172.  
  173. # backup database
  174.  
  175. try
  176. {
  177. $tsql = $backupTSQLCommand -f $databaseName, $backupFullFilePath
  178.  
  179. Write-Verbose -Message "Backing up content database to $BackupPath"
  180. Invoke-NonQuery -DatabaseName $databaseName -DatabaseServer $databaseServer -Query $tsql
  181. }
  182. catch
  183. {
  184. Write-Error "Failed to backup database to $backupFullFilePath. Exception: $($_.Exception)"
  185. return
  186. }
  187.  
  188.  
  189. # drop database
  190.  
  191. try
  192. {
  193. $tsql = $dropTSQLCommand -f $databaseName
  194.  
  195. Write-Verbose -Message "Dropping content database"
  196. Invoke-NonQuery -DatabaseName "master" -DatabaseServer $databaseServer -Query $tsql
  197. }
  198. catch
  199. {
  200. Write-Error "Failed to drop database. Exception: $($_.Exception)"
  201. return
  202. }
  203.  
  204.  
  205. # restore database
  206.  
  207. try
  208. {
  209. $tsql = $restoreTSQLCommand -f $databaseName, $backupFullFilePath, $logicalDataFileName, $newPhysicalDataFileFullPath, $logicalLogFileName, $newPhysicalLogFileFullPath
  210. Write-Verbose -Message "Restoring content database from $backupFullFilePath"
  211. Invoke-NonQuery -DatabaseName "master" -DatabaseServer $databaseServer -Query $tsql
  212. }
  213. catch
  214. {
  215. Write-Error "Failed to restore database. Exception: $($_.Exception)"
  216. return
  217. }
  218.  
  219.  
  220.  
  221. # mount to SharePoint
  222.  
  223. try
  224. {
  225. Write-Verbose -Message "Mounting database to SharePoint farm"
  226. Mount-SPContentDatabase -Name $databaseName -DatabaseServer $databaseServer -WebApplication $webApplication -SkipSiteUpgrade -MaxSiteCount $maximumSiteCount -WarningSiteCount $warningSiteCount | Out-Null
  227. }
  228. catch
  229. {
  230. Write-Error "Failed to add database to SharePoint farm. Exception: $($_.Exception)"
  231. return
  232. }
  233.  
  234.  
  235.  
  236. # add to AG
  237.  
  238. if( $availabilityGroupShare )
  239. {
  240. try
  241. {
  242. Write-Verbose -Message "Adding database to Availability Group"
  243. Add-DatabaseToAvailabilityGroup -AGName $availabilityGroupName -DatabaseName $databaseName -FileShare $availabilityGroupShare
  244. }
  245. catch
  246. {
  247. Write-Error "Failed to add database to Availability Group. Exception: $($_.Exception)"
  248. return
  249. }
  250. }
  251. }
  252. end
  253. {
  254. }
  255. }
  256.  
  257.  
  258. #$database = Get-SPContentDatabase -Identity "SP2016_CONTENT_002"
  259. $dataPath = "E:\Program Files\Microsoft SQL Server\MSSQL13.SHAREPOINT\MSSQL\DATA"
  260. $logPath = "F:\Program Files\Microsoft SQL Server\MSSQL13.SHAREPOINT\MSSQL\DATA"
  261. $backupPath = "E:\backups"
  262.  
  263. Move-ContentDatabaseToNewDrive -Database $database -DataPath $dataPath -LogPath $logPath -BackupPath $backupPath -Verbose
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement