Skip to content

Commit 3fc7496

Browse files
Restore-CohesityRemoteMSSQLObject-Wrapper.ps1 is newly to Restore the DB (#178)
* Restore-CohesityRemoteMSSQLObject-Wrapper.ps1 is newly to Restore the DB based on SqlHost, SqlObjectName and TargetHost. Restore-CohesityRemoteMSSQLObject.ps1 : DbRestoreOverwritePolicy option is newly added * Updated markdown file for MSSQL remote restore. * Included switch parameter to return result as object. --------- Co-authored-by: KavishreeShanmugam11 <kshanmugam.maplelabs@cohesity.com>
1 parent 257367e commit 3fc7496

7 files changed

+330
-41
lines changed

docs/cmdlets-reference/restore-cohesityremotemssqlobject.md

+64-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ Restore-CohesityRemoteMSSQLObject [-TaskName <String>] -SourceId <Int64> -HostSo
2323
[-DbRestoreOverwritePolicy] [-TargetHostId <Int64>] [-WhatIf] [-Confirm] [<CommonParameters>]
2424
```
2525

26+
### SQL Host
27+
```
28+
Restore-CohesityRemoteMSSQLObject [-TaskName <String>] [-SqlHost <String>] [-SqlObjectName <String>] [-JobId <Int64>]
29+
[-CaptureTailLogs] [-KeepCDC] [-NewDatabaseName <String>] [-NewInstanceName <String>]
30+
[-RestoreTimeSecs <Int64>] [-TargetDataFilesDirectory <String>] [-TargetLogFilesDirectory <String>]
31+
[-TargetSecondaryDataFilesDirectoryList <Object[]>] [-DbRestoreOverwritePolicy] [-TargetHost <String>]
32+
[-WhatIf] [-Confirm] [<CommonParameters>]
33+
```
34+
2635
## DESCRIPTION
2736
From remote cluster restores the specified MS SQL object from a previous backup.
2837

@@ -33,7 +42,7 @@ From remote cluster restores the specified MS SQL object from a previous backup.
3342
Restore-CohesityRemoteMSSQLObject -SourceId 1279 -HostSourceId 1277 -JobId 31520 -TargetHostId 770 -CaptureTailLogs:$false -NewDatabaseName CohesityDB_r1 -NewInstanceName MSSQLSERVER -TargetDataFilesDirectory "C:\temp" -TargetLogFilesDirectory "C:\temp" -DbRestoreOverwritePolicy:$true
3443
```
3544

36-
Restore MSSQL database from remote cluster with database id 1279 , database instance id 1277 and job id as 31520
45+
Restore MSSQL database from remote cluster with database id 1279 , database instance id 1277 and job id as 31520 with the latest recoverable snapshot information.
3746
$mssqlObjects = Find-CohesityObjectsForRestore -Environments KSQL
3847
Get the source id, $mssqlObjects\[0\].SnapshottedSource.Id
3948
Get the source instance id, $mssqlObjects\[0\].SnapshottedSource.SqlProtectionSource.OwnerId
@@ -58,6 +67,13 @@ $pattern2 = @{filePattern = "*.ldf"; targetDirectory = "c:\test1"}
5867
$patternList += $pattern1
5968
$patternList += $pattern2
6069

70+
### EXAMPLE 4
71+
```
72+
Restore-CohesityRemoteMSSQLObject -SqlHost x.x.x.x -JobId 31520 -SqlObjectName instance/databse_1 -TargetHost y.y.y.y -CaptureTailLogs:$false -NewDatabaseName CohesityDB_r1 -NewInstanceName MSSQLSERVER -TargetDataFilesDirectory "C:\temp" -TargetLogFilesDirectory "C:\temp" -DbRestoreOverwritePolicy:$true
73+
```
74+
75+
Restore MSSQL database from remote cluster with database name database_1 from the sql host x.x.x.x, and job id as 31520 to the target host y.y.y.y with latest recoverable snapshot information.
76+
6177
## PARAMETERS
6278

6379
### -TaskName
@@ -84,7 +100,7 @@ Type: Int64
84100
Parameter Sets: (All)
85101
Aliases:
86102

87-
Required: True
103+
Required: False
88104
Position: Named
89105
Default value: 0
90106
Accept pipeline input: False
@@ -99,7 +115,7 @@ Type: Int64
99115
Parameter Sets: (All)
100116
Aliases:
101117

102-
Required: True
118+
Required: False
103119
Position: Named
104120
Default value: 0
105121
Accept pipeline input: False
@@ -217,6 +233,51 @@ Accept pipeline input: False
217233
Accept wildcard characters: False
218234
```
219235
236+
### -SqlHost
237+
Specifies the SQL host from which database need to be restored.
238+
239+
```yaml
240+
Type: String
241+
Parameter Sets: (All)
242+
Aliases:
243+
244+
Required: False
245+
Position: Named
246+
Default value: 0
247+
Accept pipeline input: False
248+
Accept wildcard characters: False
249+
```
250+
251+
### -SqlObjectName
252+
Specifies the name of the SQL Object to be restored.
253+
254+
```yaml
255+
Type: String
256+
Parameter Sets: (All)
257+
Aliases:
258+
259+
Required: False
260+
Position: Named
261+
Default value: 0
262+
Accept pipeline input: False
263+
Accept wildcard characters: False
264+
```
265+
266+
### -TargetHost
267+
Specifies the target host if the application is to be restored to a different host.
268+
269+
```yaml
270+
Type: String
271+
Parameter Sets: (All)
272+
Aliases:
273+
274+
Required: False
275+
Position: Named
276+
Default value: 0
277+
Accept pipeline input: False
278+
Accept wildcard characters: False
279+
```
280+
220281
### -RestoreTimeSecs
221282
Specifies the time in the past to which the SQL database needs to be restored.
222283
This allows for granular recovery of SQL databases.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
<#
2+
Use the generic cmdlet to create an MSSQL remote restore task
3+
4+
Example usage:
5+
Restore-CohesityRemoteMSSQLObject-Wrapper.ps1 -JobId 1234 -SqlHost x.x.x.x -SqlObjectName "MSSQLSERVER/database" -TargetHost y.y.y.y -CaptureTailLogs:$false -NewDatabaseName database_new -NewInstanceName SQL2016 -TargetDataFilesDirectory "C:\" -TargetLogFilesDirectory "C:\temp" -DbRestoreOverwritePolicy:$true
6+
#>
7+
[CmdletBinding(DefaultParameterSetName = "Default", SupportsShouldProcess = $True, ConfirmImpact = "High")]
8+
Param(
9+
[Parameter(Mandatory = $false)][switch]$CaptureTailLogs, # Specifies if the tail logs are to be captured before the restore operation. This is only applicable if restoring the SQL database to its hosting Protection Source and the database is not being renamed.
10+
[Parameter(Mandatory = $false)][switch]$DbRestoreOverwritePolicy, # This field will overwrite the existing db contents if it sets to true. By default the db overwrite policy is false.
11+
[Parameter(Mandatory = $true)][ValidateRange(1, [long]::MaxValue)][long]$JobId, # Specifies the job id that backed up this MS SQL instance and will be used for this restore
12+
[Parameter(Mandatory = $false)][switch]$KeepCDC, # This field prevents "change data capture" settings from being reomved. When a database or log backup is restored on another server and database is recovered.
13+
[Parameter(Mandatory = $false)][string]$NewDatabaseName, # Specifies a new name for the restored database.
14+
[Parameter(Mandatory = $false)][string]$NewInstanceName, # Specifies the instance name of the SQL Server that should be restored.
15+
[Parameter(Mandatory = $false)][long]$RestoreTimeSecs = 0, # Specifies the time in the past to which the SQL database needs to be restored. This allows for granular recovery of SQL databases. If not specified, the SQL database will be restored from the full/incremental snapshot.
16+
[Parameter(Mandatory = $true)][string]$SqlHost, # Specifies the SQL Host information
17+
[Parameter(Mandatory = $true)][string]$SqlObjectName, # Specifies the SQL Object Name
18+
[Parameter(Mandatory = $false)][string]$TargetDataFilesDirectory, # Specifies the directory where to put the database data files. Missing directory will be automatically created. This field must be set if restoring to a different target host.
19+
[Parameter(Mandatory = $true)][string]$TargetHost, # Specifies the target host to restore
20+
[Parameter(Mandatory = $false)][string]$TargetLogFilesDirectory, # Specifies the directory where to put the database log files. Missing directory will be automatically created. This field must be set if restoring to a different target host.
21+
[Parameter(Mandatory = $false)][Object[]]$TargetSecondaryDataFilesDirectoryList # Specifies the secondary data filename pattern and corresponding directories of the DB. Secondary data files are optional and are user defined. The recommended file extension for secondary files is ".ndf". If this option is specified and the destination folders do not exist they will be automatically created. This field can be set only if restoring to a different target host.
22+
)
23+
24+
# Check if specified job exists
25+
$job = Get-CohesityProtectionJob -Ids $JobId
26+
if (-not $job) {
27+
Write-Output "Cannot proceed, the job id '$JobId' is invalid"
28+
return
29+
}
30+
31+
$HostSourceId
32+
$JobRunId
33+
$SourceId = 0
34+
$StartTime
35+
$TargetHostId = 0
36+
37+
# Get the list of SQL objects that can be restored and fetch the id of the specified SQL host
38+
$sqlRecords = Find-CohesityObjectsForRestore -Environments KSQL -JobIds $JobId | Where-Object { $_.ObjectName -eq $SqlObjectName }
39+
40+
$searchedVMDetails = $null
41+
$searchIndex = 0
42+
$continuePagination = $true
43+
$searchTotalCount = 0
44+
45+
# Loop through the result to fetch the specified SQL host id and parent id
46+
foreach ($record in $sqlRecords) {
47+
while ($continuePagination) {
48+
$searchURL = '/irisservices/api/v1/searchvms?from=' + $searchIndex + '&environment=SQL&entityTypes=kSQL&showAll=false&onlyLatestVersion=true&jobIds=' + $JobId
49+
$searchVMResult = Invoke-RestApi -Method Get -Uri $searchURL
50+
51+
if ($Global:CohesityAPIStatus.StatusCode -ne 200) {
52+
Write-Output "Could not search MSSQL objects associated with the job id $JobId"
53+
return
54+
}
55+
56+
$vmList = $searchVMResult.vms
57+
foreach ($vm in $vmList) {
58+
if ($vm.vmDocument.objectAliases[0] -eq $SqlHost) {
59+
$SourceId = $record.SnapshottedSource.Id
60+
$HostSourceId = $record.SnapshottedSource.ParentId
61+
break
62+
}
63+
}
64+
65+
$searchedVMDetails = $searchVMResult.vms | Where-Object { ($_.vmDocument.objectId.jobId -eq $JobId) -and ($_.vmDocument.objectId.entity.id -eq $SourceId) }
66+
67+
if ($searchTotalCount -eq 0) {
68+
# find the expected number of search result items
69+
$searchTotalCount = $searchVMResult.count
70+
}
71+
72+
if ($searchedVMDetails) {
73+
$infoMsg = "Found database with search index " + $searchIndex + ", and total item count " + $searchTotalCount
74+
CSLog -Message $infoMsg
75+
$continuePagination = $false
76+
}
77+
78+
# the number of items skimmed
79+
$searchIndex += $searchVMResult.vms.Count
80+
81+
if ($searchIndex -ge $searchTotalCount) {
82+
$continuePagination = $false
83+
}
84+
if ($continuePagination -eq $false) {
85+
break
86+
}
87+
}
88+
if ($null -eq $searchedVMDetails) {
89+
Write-Output "Could not find details of MSSQL host '$SqlHost'."
90+
return
91+
}
92+
}
93+
94+
if ($SourceId -eq 0) {
95+
Write-Output "Cannot proceed, Unable to find source id for SQL host '$SqlHost'"
96+
return
97+
}
98+
99+
# Fin dthe Id of specified target host
100+
$protectionSources = Get-CohesityProtectionSource -Environments KSQL
101+
foreach ($record in $protectionSources) {
102+
if ($record.protectionSource.Name -eq $TargetHost) {
103+
$TargetHostId = $record.protectionSource.id
104+
}
105+
}
106+
107+
if ($TargetHostId -eq 0) {
108+
Write-Output "Unable to find host if for $TargetHost"
109+
return
110+
}
111+
112+
# Identifying the JobRunId and StartTime based on the last known unexpired snapshot
113+
# here the curent system time should be less than the recent successful snapshot expiry time
114+
$runs = Get-CohesityProtectionJobRun -JobId $JobId -ExcludeErrorRuns:$true
115+
foreach ($record in $runs) {
116+
117+
$expiryEpocTime = $record.copyRun[0].expiryTimeUsecs
118+
$currentTime = Get-Date
119+
$currentEpocTime = Get-Date $currentTime -UFormat %s
120+
if ($currentEpocTime -le $expiryEpocTime) {
121+
122+
$JobRunId = $record[0].backupRun.jobRunId
123+
$StartTime = $record.copyRun[0].runStartTimeUsecs
124+
break
125+
}
126+
}
127+
128+
$sqlRestoreParams = @{
129+
JobID = $JobId
130+
SourceID = $SourceId
131+
HostSourceID = $HostSourceId
132+
TargetHostID = $TargetHostId
133+
JobRunId = $JobRunId
134+
StartTime = $StartTime
135+
CaptureTailLogs = $CaptureTailLogs.IsPresent
136+
KeepCDC = $KeepCDC.isPresent
137+
NewDatabaseName = $NewDatabaseName
138+
NewInstanceName = $NewInstanceName
139+
Verbose = $true
140+
Confirm = $false
141+
TargetDataFilesDirectory = $TargetDataFilesDirectory
142+
TargetLogFilesDirectory = $TargetLogFilesDirectory
143+
TargetSecondaryDataFilesDirectoryList = $TargetSecondaryDataFilesDirectoryList
144+
RestoreTimeSecs = $RestoreTimeSecs
145+
DbRestoreOverwritePolicy = $DbRestoreOverwritePolicy
146+
}
147+
148+
Restore-CohesityRemoteMSSQLObject @sqlRestoreParams

src/Cohesity.Powershell/Cohesity.PowerShell.Core.psd1

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
RootModule = 'Cohesity.PowerShell.Core.dll'
99

1010
# Version number of this module.
11-
ModuleVersion = '1.9.5'
11+
ModuleVersion = '1.9.6'
1212

1313
# Supported PSEditions
1414
# CompatiblePSEditions = @()
@@ -76,7 +76,7 @@ FunctionsToExport = @(
7676
'Copy-CohesityView',
7777
'Copy-CohesityVMwareVM',
7878
'Find-CohesityFileSnapshot',
79-
'Find-CohesityRemoteRestFileSnapshot',
79+
'Find-CohesityRemoteFileSnapshot',
8080
'Get-CohesityActiveDirectory',
8181
'Get-CohesityCmdletConfig',
8282
'Get-CohesityExternalClient',
@@ -132,7 +132,7 @@ FunctionsToExport = @(
132132
'Remove-CohesityVirtualIP',
133133
'Remove-CohesityVlan',
134134
'Restore-CohesityBackupToView',
135-
'Restore-CohesityFileV2'
135+
'Restore-CohesityFileV2',
136136
'Restore-CohesityRemoteFile',
137137
'Restore-CohesityRemoteFileV2',
138138
'Restore-CohesityOracleDatabase',

src/Cohesity.Powershell/Cohesity.PowerShell.psd1

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
RootModule = 'Cohesity.PowerShell.dll'
99

1010
# Version number of this module.
11-
ModuleVersion = '1.9.5'
11+
ModuleVersion = '1.9.6'
1212

1313
# Supported PSEditions
1414
# CompatiblePSEditions = @()

src/Cohesity.Powershell/Scripts/ProtectionJob/Get-CohesityProtectionJobStatus.ps1

+16-7
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ function Get-CohesityProtectionJobStatus {
5454
#>
5555
[CmdletBinding()]
5656
Param(
57+
[Parameter(
58+
Position = 1,
59+
HelpMessage = "Return Output as Object")]
60+
[Switch]$ReturnObject
5761
)
5862

5963
Begin {
@@ -146,13 +150,18 @@ function Get-CohesityProtectionJobStatus {
146150
}
147151

148152
$columnWidth = 20
149-
$protectionJobStatusList | Sort-Object -Property startTime -Descending |
150-
Format-Table @{ Label = 'ID'; Expression = { $_.jobId }; },
151-
@{ Label = 'NAME'; Expression = { $_.jobName }; Width = $columnWidth; },
152-
@{ Label = 'REMOTE COPY'; Expression = { $_.remoteCopy }; Width = $columnWidth },
153-
@{ Label = 'STARTED AT'; Expression = { $_.GetStartTime() }; Width = $columnWidth },
154-
@{ Label = 'ESTIMATED TIME'; Expression = { $_.GetEstimatedTime() }; Width = $columnWidth },
155-
@{ Label = 'COMPLETED(%)'; Expression = { $_.percentCompleted }; Width = $columnWidth }
153+
if ($ReturnObject -eq $true) {
154+
return $protectionJobStatusList
155+
}
156+
else {
157+
$protectionJobStatusList | Sort-Object -Property startTime -Descending |
158+
Format-Table @{ Label = 'ID'; Expression = { $_.jobId }; },
159+
@{ Label = 'NAME'; Expression = { $_.jobName }; Width = $columnWidth; },
160+
@{ Label = 'REMOTE COPY'; Expression = { $_.remoteCopy }; Width = $columnWidth },
161+
@{ Label = 'STARTED AT'; Expression = { $_.GetStartTime() }; Width = $columnWidth },
162+
@{ Label = 'ESTIMATED TIME'; Expression = { $_.GetEstimatedTime() }; Width = $columnWidth },
163+
@{ Label = 'COMPLETED(%)'; Expression = { $_.percentCompleted }; Width = $columnWidth }
164+
}
156165
}
157166

158167
End {

src/Cohesity.Powershell/Scripts/ProtectionSource/Register-CohesityProtectionSourceHyperV.ps1

+17-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
function Register-CohesityProtectionSourceHyperV {
2-
<#
2+
<#
33
.SYNOPSIS
44
Registers a new HyperV protection source with the Cohesity Cluster. The HyperV type can be a SCVMM server or HyperV Host.
55
.DESCRIPTION
@@ -29,15 +29,18 @@ function Register-CohesityProtectionSourceHyperV {
2929
[Parameter(Mandatory = $false)]
3030
[ValidateNotNullOrEmpty()]
3131
# User credentials for the SCVMM server.
32-
[System.Management.Automation.PSCredential]$Credentials
32+
[System.Management.Automation.PSCredential]$Credentials,
33+
# Set to true, if result need to returned in object format
34+
[Parameter(Position = 1, HelpMessage = "Return Output as Object", Mandatory = $false)]
35+
[Switch]$ReturnObject
3336
)
3437

3538
Begin {
3639
}
3740

3841
Process {
3942

40-
$uri = '/irisservices/api/v1/public/protectionSources/register'
43+
$uri = '/irisservices/api/v1/public/protectionSources/register'
4144

4245
if ($HyperVType -eq 'KSCVMMServer') {
4346
$reqParameters = @{
@@ -58,10 +61,16 @@ function Register-CohesityProtectionSourceHyperV {
5861

5962
$columnWidth = 20
6063
$request = $reqParameters | ConvertTo-Json
61-
Invoke-RestApi -Method Post -Uri $uri -Body $request |
62-
Format-Table @{ Label = 'ID'; Expression = { $_.id }; },
63-
@{ Label = 'Name'; Expression = { $_.name }; Width = $columnWidth; },
64-
@{ Label = 'Environment'; Expression = { $_.environment }; Width = $columnWidth },
65-
@{ Label = 'Type'; Expression = { $_.hypervProtectionSource.type }; Width = $columnWidth }
64+
$result = Invoke-RestApi -Method Post -Uri $uri -Body $request
65+
66+
if ($ReturnObject -eq $true) {
67+
return $result
68+
}
69+
else {
70+
$result | Format-Table @{ Label = 'ID'; Expression = { $_.id }; },
71+
@{ Label = 'Name'; Expression = { $_.name }; Width = $columnWidth; },
72+
@{ Label = 'Environment'; Expression = { $_.environment }; Width = $columnWidth },
73+
@{ Label = 'Type'; Expression = { $_.hypervProtectionSource.type }; Width = $columnWidth }
74+
}
6675
} # End of process
6776
} # End of function

0 commit comments

Comments
 (0)