########################################################################## # # On Demand Snapshot for all Oracle DBs with a specific SLA # Created by Rubrik PS for McDermott, September 2025 # # Must be run with a Global service account. # # Requires RubrikSecurityCloud module to be installed and working with # a Global Service Account with the following rights: # # - Data Management / Oracle / On-Demand Snapshot # - Data Management / SLAs / Both Source and Target SLAs # # Create the service account file with: # Set-RscServiceAccountFile sa.json -OutputFilePath Global.xml # # Example invocation # .\monthlySnap.ps1 -sourceSla "Prod Oracle SLA" -triggerSla "Oracle Monthly Only" # # v0.1 Initial Release # ########################################################################## param ( [Parameter(Mandatory=$False, HelpMessage="Instance to claim")] [string]$sourceSla, [Parameter(Mandatory=$False, HelpMessage="Do not change the MV")] [switch]$dryrun ) # SA File must be an absolute path $GlobalSAFile = "C:\Rubrik\scripts\sa.xml" $logFile = "C:\Rubrik\scripts\claimInstance.log" $mvName = "JP-ZF-SQL" $sqlInstance = "sqlfcsql\TESTINST" $checkCluster = $true ########################### # Script begins ########################### $ErrorActionPreference = 'Stop' function Write-Log($message) { $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $logEntry = "$timestamp $message" Add-Content -Path "C:\Rubrik\monthlySnap.log" -Value $logEntry Write-Host $logEntry } Import-Module RubrikSecurityCloud if ($checkCluster) { # Check if SQL instance is running locally $localNode = $env:COMPUTERNAME $instanceName = $sqlInstance.Split('\')[1] $clusterInstance = Get-ClusterResource | Where-Object { $_.ResourceType -eq "SQL Server" -and $_.Name -eq "SQL Server ($instanceName)" } if ($clusterInstance) { $ownerNode = $clusterInstance.OwnerNode if ($ownerNode -ne $localNode) { Write-Log "SQL instance '$sqlInstance' is not running on local node '$localNode'. Exiting script." exit 1 } else { Write-Log "SQL instance '$sqlInstance' is running on local node '$localNode'. Proceeding." } } else { Write-Log "ERROR: SQL instance '$sqlInstance' not found in cluster resources." exit 1 } } else { Write-Log "INFO: Cluster check is disabled. Proceeding without verification." } Connect-Rsc -ServiceAccountFile $GlobalSAFile Write-Log "Connected to Rubrik Security Cloud." $myHost = Get-RscHost -Name $env:COMPUTERNAME -OsType WINDOWS $query = New-RscQuery -GqlQuery slaManagedVolumes -AddField Nodes.HostDetail, Nodes.SmbShare, Nodes.ClientConfig, Nodes.ClientConfig.BackupScript $query.var.filter = @(Get-RscType -Name Filter) $query.var.filter[0].field = "NAME_EXACT_MATCH" $query.var.filter[0].Texts = $mvName #$query.Field.Nodes = @(Get-RscType -Name ManagedVolume -InitialProperties name, Id, hostDetail.Id, hostDetail.Status, hostDetail.Name) $mvDetail = $query.Invoke().nodes[0] Write-Log "Found Managed Volume: $($mvDetail.Name) (ID: $($mvDetail.Id), Status: $($mvDetail.hostDetail.Status), HostDetail Name: $($mvDetail.hostDetail.Name))" if ($myHost.Id -ne $mvDetail.hostDetail.Id) { Write-Log "WARNING: Host ID ($($myHost.Id)) does not match Managed Volume HostDetail ID ($($mvDetail.hostDetail.Id))." $query = New-RscMutation -GqlMutation updateManagedVolume $query.Var.input = Get-RscType -Name UpdateManagedVolumeInput $query.Var.input.update = Get-RscType -Name ManagedVolumeUpdateInput $query.Var.input.update.config = Get-RscType -Name ManagedVolumePatchConfigInput $query.Var.input.update.slaClientConfig = Get-RscType -Name ManagedVolumePatchSlaClientConfigInput $query.Var.input.Id = $mvDetail.Id $query.Var.input.update.Name = $mvName $query.Var.input.update.config.SmbDomainName = $mvDetail.SmbShare.DomainName $query.Var.input.update.config.SmbValidIps = $mvDetail.SmbShare.ValidIps $query.Var.input.update.config.SmbValidUsers = $mvDetail.SmbShare.ValidUsers + $mvDetail.SmbShare.ActiveDirectoryGroups $query.Var.input.update.slaClientConfig.clientHostId = $myHost.Id $query.Var.input.update.slaClientConfig.channelHostMountPaths = $mvDetail.ClientConfig.ChannelHostMountPaths $query.Var.input.update.slaClientConfig.backupScriptCommand = $mvDetail.ClientConfig.BackupScript.ScriptCommand $query.Var.input.update.slaClientConfig.shouldDisablePostBackupScriptOnBackupFailure = $true $query.Var.input.update.slaClientConfig.shouldDisablePostBackupScriptOnBackupSuccess = $true $query.Var.input.update.slaClientConfig.shouldDisablePreBackupScript = $true $query.gqlRequest().Variables if (-not $dryrun) { $result = $query.Invoke() } else { Write-Log "Dry run mode: Managed Volume update not invoked." } } else { Write-Log "Host ID ($($myHost.Id)) matches Managed Volume HostDetail ID ($($mvDetail.hostDetail.Id)). No action needed." } Disconnect-Rsc