Functions/Get-RSC/Get-RSCSAPDatabases.ps1
################################################ # Function - Get-RSCSAPDatabases - Getting all SAP Databases connected to the RSC instance ################################################ Function Get-RSCSAPDatabases { <# .SYNOPSIS A Rubrik Security Cloud (RSC) Reporting Module Function returning a list of all SAP Databases. .DESCRIPTION Makes the required GraphQL API calls to RSC via Invoke-RestMethod to get the data as described, then creates a usable array of the returned information, removing the need for the PowerShell user to understand GraphQL in order to interact with RSC. .LINK GraphQL schema reference: https://rubrikinc.github.io/rubrik-api-documentation/schema/reference .OUTPUTS Returns an array of all the available information on the GraphQL endpoint in a uniform and usable format. .EXAMPLE Get-RSCSAPDatabases This example returns an array of all the information returned by the GraphQL endpoint for this object type. .NOTES Author: Joshua Stenhouse Date: 05/11/2023 #> ################################################ # Importing Module & Running Required Functions ################################################ # Importing the module is it needs other modules Import-Module RSCReporting # Checking connectivity, exiting function with error if not connected Test-RSCConnection # Getting SAP systems $RSCSAPSystems = Get-RSCSAPSystems ################################################ # Getting All Objects ################################################ # Creating array for objects $RSCObjectList = @() # Building GraphQL query $RSCGraphQL = @{"operationName" = "SapHanaDatabaseListQuery"; "variables" = @{ "first" = 1000 }; "query" = "query SapHanaDatabaseListQuery(`$after: String, `$first: Int) { sapHanaDatabases(after: `$after, first: `$first) { edges { cursor node { cdmId id name isRelic slaPauseStatus ...EffectiveSlaColumnFragment info { logBackupIntervalSecs restoreConfiguredSrcDatabaseId __typename } logicalPath { fid name objectType __typename } replicatedObjectCount sapHanaSystem { id sid status hosts { hostType id: hostUuid hostName host { id __typename } __typename } __typename } effectiveSlaSourceObject { fid name objectType __typename } ...SlaAssignmentColumnFragment cluster { name id status version __typename } primaryClusterLocation { id name __typename } __typename dataPathSpec { name } dataPathType effectiveSlaDomain { id name } forceFull latestUserNote { objectId time userNote userName } logSnapshotConnection(first: 10, sortOrder: DESC) { nodes { date } } newestSnapshot { id date } newestArchivedSnapshot { id date } numWorkloadDescendants objectType oldestSnapshot { date id } onDemandSnapshotCount physicalPath { fid name objectType } newestReplicatedSnapshot { date id } protectionDate recoverableRangeConnection { edges { node { baseFullSnapshotId cdmId dbId clusterUuid endTime fid isArchived startTime } } } slaAssignment systemId } __typename } pageInfo { endCursor hasNextPage hasPreviousPage __typename } __typename } } fragment EffectiveSlaColumnFragment on HierarchyObject { id effectiveSlaDomain { ...EffectiveSlaDomainFragment ... on GlobalSlaReply { description __typename } __typename } ... on CdmHierarchyObject { pendingSla { ...SLADomainFragment __typename } __typename } __typename } fragment EffectiveSlaDomainFragment on SlaDomain { id name ... on GlobalSlaReply { isRetentionLockedSla __typename } ... on ClusterSlaDomain { fid cluster { id name __typename } isRetentionLockedSla __typename } __typename } fragment SLADomainFragment on SlaDomain { id name ... on ClusterSlaDomain { fid cluster { id name __typename } __typename } __typename } fragment SlaAssignmentColumnFragment on HierarchyObject { slaAssignment __typename }" } ################################################ # API Call To RSC GraphQL URI ################################################ # Querying API $RSCObjectListResponse = Invoke-RestMethod -Method POST -Uri $RSCGraphqlURL -Body $($RSCGraphQL | ConvertTo-JSON -Depth 20) -Headers $RSCSessionHeader # Setting variable $RSCObjectList += $RSCObjectListResponse.data.sapHanaDatabases.edges.node # Getting all results from paginations While ($RSCObjectListResponse.data.sapHanaDatabases.pageInfo.hasNextPage) { # Getting next set $RSCGraphQL.variables.after = $RSCObjectListResponse.data.sapHanaDatabases.pageInfo.endCursor $RSCObjectListResponse = Invoke-RestMethod -Method POST -Uri $RSCGraphqlURL -Body $($RSCGraphQL | ConvertTo-JSON -Depth 20) -Headers $RSCSessionHeader $RSCObjectList += $RSCObjectListResponse.data.sapHanaDatabases.edges.node } ################################################ # Processing DBs ################################################ # Creating array $RSCDBs = [System.Collections.ArrayList]@() # For Each Object Getting Data ForEach ($RSCDB in $RSCObjectList) { # Setting variables $DBName = $RSCDB.name $DBID = $RSCDB.id $DBCDMID = $RSCDB.cdmId $DBSystemCDMID = $RSCDB.systemId $DBForceFull = $RSCDB.forceFull $DBIsRelic = $RSCDB.isRelic $DBInfo = $RSCDB.info $DBType = $RSCDB.objectType # DB location $DBLocation = $RSCSAPSystems | Where-Object {$_.SystemCDMID -eq $DBSystemCDMID} $DBHostName = $DBLocation.System $DBHostID = $DBLocation.SystemID # Log backup info $DBLogBackupFrequencySeconds = $DBInfo.logBackupIntervalSecs $DBLogBackupFrequency = $DBLogBackupFrequencySeconds/60;$DBLogBackupFrequencyMinutes=[Math]::Round($DBLogBackupFrequencyMinutes) $DBLogBackupFrequencyUnit = "MINUTES" # Recovery range $DBRecoverableRange = $RSCDB.recoverableRangeConnection.edges.node | Select-Object -Last 1 $DBRecoverableRangeStartUNIX = $DBRecoverableRange.startTime $DBRecoverableRangeEndUNIX = $DBRecoverableRange.endTime IF($DBRecoverableRangeStartUNIX -ne $null){$DBRecoverableRangeStartUTC = Convert-RSCUNIXTime $DBRecoverableRangeStartUNIX}ELSE{$DBRecoverableRangeStartUTC = $null} IF($DBRecoverableRangeEndUNIX -ne $null){$DBRecoverableRangeEndUTC = Convert-RSCUNIXTime $DBRecoverableRangeEndUNIX}ELSE{$DBRecoverableRangeEndUTC = $null} # Log snapshot $DBLogSnapshots = $RSCDB.logSnapshotConnection.nodes $DBLogSnapshotCount = $DBLogSnapshots | Measure-Object | Select-Object -ExpandProperty Count $DBLastLogSnapshotUNIX = $DBLogSnapshots | Select-Object -ExpandProperty date -Last 1 IF($DBLastLogSnapshotUNIX -ne $null){$DBLastLogSnapshotUTC = Convert-RSCUNIXTime $DBLastLogSnapshotUNIX}ELSE{$DBLastLogSnapshotUTC = $null} # Calculating minutes since last log backup $UTCDateTime = [System.DateTime]::UtcNow IF($DBLastLogSnapshotUTC -ne $null){$DBLastLogSnapshotTimepsan = New-TimeSpan -Start $DBLastLogSnapshotUTC -End $UTCDateTime;$DBLastLogSnapshotMinutesSince = $DBLastLogSnapshotTimepsan | Select-Object -ExpandProperty TotalMinutes;$DBLastLogSnapshotMinutesSince = [Math]::Round($DBLastLogSnapshotMinutesSince)}ELSE{$DBLastLogSnapshotMinutesSince = $null} # SLA info $DBSLADomainInfo = $RSCDB.effectiveSlaDomain $DBSLADomain = $DBSLADomainInfo.name $DBSLADomainID = $DBSLADomainInfo.id $DBSLAAssignment = $RSCDB.slaAssignment $DBSLAPaused = $RSCDB.slaPauseStatus # Rubrik cluster info $DBRubrikClusterInfo = $RSCDB.primaryClusterLocation $DBRubrikCluster = $DBRubrikClusterInfo.name $DBRubrikClusterID = $DBRubrikClusterInfo.id # User note info $DBNoteInfo = $RSCDB.latestUserNote $DbNote = $DBNoteInfo.userNote $DBNoteCreator = $DBNoteInfo.userName $DBNoteCreatedUNIX = $DBNoteInfo.time IF($DBNoteCreatedUNIX -ne $null){$DBNoteCreatedUTC = Convert-RSCUNIXTime $DBNoteCreatedUNIX}ELSE{$DBNoteCreatedUTC = $null} # DB snapshot info $DBOnDemandSnapshots = $RSCDB.onDemandSnapshotCount $DBSnapshotDateUNIX = $RSCDB.newestSnapshot.date $DBSnapshotDateID = $RSCDB.newestSnapshot.id $DBReplicatedSnapshotDateUNIX = $RSCDB.newestReplicatedSnapshot.date $DBReplicatedSnapshotDateID = $RSCDB.newestReplicatedSnapshot.id $DBArchiveSnapshotDateUNIX = $RSCDB.newestArchivedSnapshot.date $DBArchiveSnapshotDateID = $RSCDB.newestArchivedSnapshot.id $DBOldestSnapshotDateUNIX = $RSCDB.oldestSnapshot.date $DBOldestSnapshotDateID = $RSCDB.oldestSnapshot.id # Converting snapshot dates IF($DBSnapshotDateUNIX -ne $null){$DBSnapshotDateUTC = Convert-RSCUNIXTime $DBSnapshotDateUNIX}ELSE{$DBSnapshotDateUTC = $null} IF($DBReplicatedSnapshotDateUNIX -ne $null){$DBReplicatedSnapshotDateUTC = Convert-RSCUNIXTime $DBReplicatedSnapshotDateUNIX}ELSE{$DBSnDBReplicatedSnapshotDateUTCapshotDateUTC = $null} IF($DBArchiveSnapshotDateUNIX -ne $null){$DBArchiveSnapshotDateUTC = Convert-RSCUNIXTime $DBArchiveSnapshotDateUNIX}ELSE{$DBArchiveSnapshotDateUTC = $null} IF($DBOldestSnapshotDateUNIX -ne $null){$DBOldestSnapshotDateUTC = Convert-RSCUNIXTime $DBOldestSnapshotDateUNIX}ELSE{$DBOldestSnapshotDateUTC = $null} # Calculating hours since each snapshot $UTCDateTime = [System.DateTime]::UtcNow IF($DBSnapshotDateUTC -ne $null){$DBSnapshotTimespan = New-TimeSpan -Start $DBSnapshotDateUTC -End $UTCDateTime;$DBSnapshotHoursSince = $DBSnapshotTimespan | Select-Object -ExpandProperty TotalHours;$DBSnapshotHoursSince = [Math]::Round($DBSnapshotHoursSince,1)}ELSE{$DBSnapshotHoursSince = $null} IF($DBReplicatedSnapshotDateUTC -ne $null){$DBReplicatedSnapshotTimespan = New-TimeSpan -Start $DBReplicatedSnapshotDateUTC -End $UTCDateTime;$DBReplicatedSnapshotHoursSince = $DBReplicatedSnapshotTimespan | Select-Object -ExpandProperty TotalHours;$DBReplicatedSnapshotHoursSince = [Math]::Round($DBReplicatedSnapshotHoursSince,1)}ELSE{$DBReplicatedSnapshotHoursSince = $null} IF($DBArchiveSnapshotDateUTC -ne $null){$DBArchiveSnapshotTimespan = New-TimeSpan -Start $DBArchiveSnapshotDateUTC -End $UTCDateTime;$DBArchiveSnapshotHoursSince = $DBArchiveSnapshotTimespan | Select-Object -ExpandProperty TotalHours;$DBArchiveSnapshotHoursSince = [Math]::Round($DBArchiveSnapshotHoursSince,1)}ELSE{$DBArchiveSnapshotHoursSince = $null} IF($DBOldestSnapshotDateUTC -ne $null){$DBOldestSnapshotTimespan = New-TimeSpan -Start $DBOldestSnapshotDateUTC -End $UTCDateTime;$DBOldestSnapshotDaysSince = $DBOldestSnapshotTimespan | Select-Object -ExpandProperty TotalDays;$DBOldestSnapshotDaysSince = [Math]::Round($DBOldestSnapshotDaysSince,1)}ELSE{$DBOldestSnapshotDaysSince = $null} # Getting URL $DBURL = Get-RSCObjectURL -ObjectType "SapHanaDatabase" -ObjectID $DBID # Adding To Array $Object = New-Object PSObject $Object | Add-Member -MemberType NoteProperty -Name "RSCInstance" -Value $RSCInstance # DB info $Object | Add-Member -MemberType NoteProperty -Name "DB" -Value $DBName $Object | Add-Member -MemberType NoteProperty -Name "DBID" -Value $DBID $Object | Add-Member -MemberType NoteProperty -Name "DBCDMID" -Value $DBCDMID $Object | Add-Member -MemberType NoteProperty -Name "Type" -Value $DBType $Object | Add-Member -MemberType NoteProperty -Name "ForceFull" -Value $DBForceFull # Log backups and recoverable ranges $Object | Add-Member -MemberType NoteProperty -Name "LogBackups" -Value $DBLogSnapshotCount $Object | Add-Member -MemberType NoteProperty -Name "LastLogBackupUTC" -Value $DBLastLogSnapshotUTC $Object | Add-Member -MemberType NoteProperty -Name "MinutesSince" -Value $DBLastLogSnapshotMinutesSince $Object | Add-Member -MemberType NoteProperty -Name "RecoverableRangeStart" -Value $DBRecoverableRangeStartUTC $Object | Add-Member -MemberType NoteProperty -Name "RecoverableRangeEnd" -Value $DBRecoverableRangeEndUTC # Location information $Object | Add-Member -MemberType NoteProperty -Name "System" -Value $DBHostName $Object | Add-Member -MemberType NoteProperty -Name "SystemID" -Value $DBHostID $Object | Add-Member -MemberType NoteProperty -Name "SystemCDMID" -Value $DBSystemCDMID # Protection $Object | Add-Member -MemberType NoteProperty -Name "SLADomain" -Value $DBSLADomain $Object | Add-Member -MemberType NoteProperty -Name "SLADomainID" -Value $DBSLADomainID $Object | Add-Member -MemberType NoteProperty -Name "SLAAssignment" -Value $DBSLAAssignment $Object | Add-Member -MemberType NoteProperty -Name "SLAPaused" -Value $DBSLAPaused $Object | Add-Member -MemberType NoteProperty -Name "IsRelic" -Value $DBIsRelic # Log backup info $Object | Add-Member -MemberType NoteProperty -Name "LogFrequency" -Value $DBLogBackupFrequency $Object | Add-Member -MemberType NoteProperty -Name "LogFrequencyUnit" -Value $DBLogBackupFrequencyUnit # Snapshot dates $Object | Add-Member -MemberType NoteProperty -Name "LatestSnapshotUTC" -Value $DBSnapshotDateUTC $Object | Add-Member -MemberType NoteProperty -Name "LatestSnapshotUTCAgeHours" -Value $DBSnapshotHoursSince $Object | Add-Member -MemberType NoteProperty -Name "ReplicatedSnapshotUTC" -Value $DBReplicatedSnapshotDateUTC $Object | Add-Member -MemberType NoteProperty -Name "ReplicatedSnapshotUTCAgeHours" -Value $DBReplicatedSnapshotHoursSince $Object | Add-Member -MemberType NoteProperty -Name "ArchivedSnapshotUTC" -Value $DBArchiveSnapshotDateUTC $Object | Add-Member -MemberType NoteProperty -Name "ArchivedSnapshotUTCAgeHours" -Value $DBArchiveSnapshotHoursSince $Object | Add-Member -MemberType NoteProperty -Name "OldestSnapshotUTC" -Value $DBOldestSnapshotDateUTC $Object | Add-Member -MemberType NoteProperty -Name "OldestSnapshotUTCAgeDays" -Value $DBOldestSnapshotDaysSince # DB note info $Object | Add-Member -MemberType NoteProperty -Name "LatestRSCNote" -Value $DBNote $Object | Add-Member -MemberType NoteProperty -Name "LatestNoteCreator" -Value $DBNoteCreator $Object | Add-Member -MemberType NoteProperty -Name "LatestNoteDateUTC" -Value $DBNoteCreatedUTC # Rubrik cluster info $Object | Add-Member -MemberType NoteProperty -Name "ObjectID" -Value $DBID $Object | Add-Member -MemberType NoteProperty -Name "RubrikCluster" -Value $DBRubrikCluster $Object | Add-Member -MemberType NoteProperty -Name "RubrikClusterID" -Value $DBRubrikClusterID # URL $Object | Add-Member -MemberType NoteProperty -Name "URL" -Value $DBURL # Adding $RSCDBs.Add($Object) | Out-Null # End of for each object below } # End of for each object above # Returning array Return $RSCDBs # End of function } |