diff --git a/sanityCheck.ps1 b/sanityCheck.ps1 new file mode 100644 index 0000000..800871a --- /dev/null +++ b/sanityCheck.ps1 @@ -0,0 +1,196 @@ +param( + [string]$RscUrl = "https://zf-prod.my.rubrik.com/", + [string]$ServiceAccountFile = "C:\Rubrik\scripts\local.xml", + [string]$LogPath = ".\RscSanityCheck-{0}.log" -f (Get-Date -Format "yyyyMMdd-HHmmss") +) + +#-----------------------------# +# Helper: logging +#-----------------------------# +function Write-Log { + param( + [AllowEmptyString()][string]$Message = "" + ) + $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss.fff" + $line = "[{0}] {1}" -f $timestamp, $Message + $line | Out-File -FilePath $LogPath -Encoding UTF8 -Append + Write-Host $line +} + +#-----------------------------# +# Helper: dump exception + inners +#-----------------------------# +function Write-ExceptionDetails { + param( + [Parameter(Mandatory=$true)][System.Exception]$Exception, + [string]$Prefix = "EX" + ) + + Write-Log "${Prefix}: Type = $($Exception.GetType().FullName)" + Write-Log "${Prefix}: Message = $($Exception.Message)" + Write-Log "${Prefix}: HResult = $($Exception.HResult)" + if ($Exception.StackTrace) { + Write-Log "${Prefix}: StackTrace:" + $Exception.StackTrace -split "`r?`n" | ForEach-Object { Write-Log " $_" } + } + + # Aggregate inner exceptions + if ($Exception -is [System.AggregateException] -and $Exception.InnerExceptions) { + $i = 0 + foreach ($inner in $Exception.InnerExceptions) { + Write-Log "${Prefix}: Inner[$i] ------------------------------" + Write-ExceptionDetails -Exception $inner -Prefix "$Prefix.Inner[$i]" + $i++ + } + } + elseif ($Exception.InnerException) { + Write-Log "${Prefix}: Inner ------------------------------" + Write-ExceptionDetails -Exception $Exception.InnerException -Prefix "$Prefix.Inner" + } +} + +#-----------------------------# +# Start log +#-----------------------------# +Write-Log "=== Rubrik RSC PowerShell Sanity Check ===" +Write-Log "Log file: $LogPath" +Write-Log "RSC URL: $RscUrl" +Write-Log "SA file: $ServiceAccountFile" +Write-Log "" +if (-not (Test-Path -LiteralPath $ServiceAccountFile -PathType Leaf)) { + Write-Log "WARNING: Service account file does not exist: $ServiceAccountFile" +} else { + Write-Log "Service account file found." +} +Write-Log "" + +#-----------------------------# +# Environment info +#-----------------------------# +Write-Log "=== Environment ===" + +Write-Log "--- PowerShell Version Table ---" +$PSVersionTable.GetEnumerator() | Sort-Object Name | ForEach-Object { + Write-Log ("PSVersionTable.{0} = {1}" -f $_.Name, $_.Value) +} + +try { + $framework = [System.Runtime.InteropServices.RuntimeInformation]::FrameworkDescription + Write-Log "RuntimeInformation.FrameworkDescription = $framework" +} catch { + Write-Log "Failed to get RuntimeInformation.FrameworkDescription" + Write-ExceptionDetails $_.Exception "RuntimeInfo" +} + +Write-Log "" +Write-Log "--- TLS Settings ---" +try { + Write-Log ("Current SecurityProtocol = {0}" -f [Net.ServicePointManager]::SecurityProtocol) + # Force TLS 1.2 for tests + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + Write-Log ("Updated SecurityProtocol = {0}" -f [Net.ServicePointManager]::SecurityProtocol) +} catch { + Write-Log "Failed to read/set SecurityProtocol" + Write-ExceptionDetails $_.Exception "TLS" +} + +Write-Log "" +Write-Log "--- TLS 1.2 Cipher Suites (if available) ---" +try { + if (Get-Command Get-TlsCipherSuite -ErrorAction SilentlyContinue) { + $ciphers = Get-TlsCipherSuite | Where-Object { $_.Name -match 'TLS' } + foreach ($c in $ciphers) { + Write-Log ("Cipher: {0} | Protocols: {1} | Kex: {2} | CipherAlgo: {3} | HashAlgo: {4}" -f ` + $c.Name, ($c.Protocols -join ","), $c.KeyExchangeAlgorithm, $c.CipherAlgorithm, $c.HashAlgorithm) + } + if (-not $ciphers) { + Write-Log "No cipher suites returned by Get-TlsCipherSuite." + } + } else { + Write-Log "Get-TlsCipherSuite not available on this OS/PowerShell." + } +} catch { + Write-Log "Failed to enumerate cipher suites." + Write-ExceptionDetails $_.Exception "Ciphers" +} + +Write-Log "" +Write-Log "--- Rubrik RSC PowerShell Module ---" +try { + $modules = @(Get-Module RubrikSecurityCloud -ListAvailable) + if ($modules) { + $modules | Sort-Object Version -Descending | ForEach-Object { + Write-Log ("Module: {0} | Version: {1} | Path: {2}" -f $_.Name, $_.Version, $_.ModuleBase) + } + } else { + Write-Log "RubrikSecurityCloud module not found in module path." + } +} catch { + Write-Log "Failed to query Rubrik RSC module." + Write-ExceptionDetails $_.Exception "Module" +} + +#-----------------------------# +# Test Invoke-WebRequest +#-----------------------------# +Write-Log "" +Write-Log "=== Invoke-WebRequest Tests ===" + +function Test-Http { + param( + [Parameter(Mandatory=$true)][string]$Url, + [string]$Name + ) + + Write-Log "--- $Name : $Url ---" + try { + $resp = Invoke-WebRequest -Uri $Url -UseBasicParsing -TimeoutSec 15 -ErrorAction Stop + Write-Log "StatusCode: $($resp.StatusCode) $($resp.StatusDescription)" + Write-Log "Headers:" + foreach ($k in $resp.Headers.Keys) { + Write-Log (" {0}: {1}" -f $k, $resp.Headers[$k]) + } + } catch { + $isExpectedGraphQl405 = $Url.TrimEnd('/').EndsWith('/api/graphql') -and $_.Exception.Message -match '\(405\)' + if ($isExpectedGraphQl405) { + Write-Log "Invoke-WebRequest to $Url returned 405 Method Not Allowed (expected for GET on GraphQL endpoint)." + } else { + Write-Log "Invoke-WebRequest to $Url failed." + Write-ExceptionDetails $_.Exception "InvokeWebRequest" + } + } +} + +Test-Http -Url $RscUrl -Name "RSC Root" +Test-Http -Url ($RscUrl.TrimEnd('/') + "/api/graphql") -Name "RSC GraphQL" + +#-----------------------------# +# Test Connect-Rsc +#-----------------------------# +Write-Log "" +Write-Log "=== Connect-Rsc Test ===" + +try { + Import-Module RubrikSecurityCloud -ErrorAction Stop + Write-Log "RubrikSecurityCloud imported successfully." +} catch { + Write-Log "Failed to import Rubrik RSC module." + Write-ExceptionDetails $_.Exception "ImportModule" +} + +try { + if (-not (Test-Path -LiteralPath $ServiceAccountFile -PathType Leaf)) { + throw "Service account file not found: $ServiceAccountFile" + } + + Write-Log "Attempting Connect-Rsc with service account file..." + $VerbosePreference = "Continue" + Connect-Rsc -ServiceAccountFile $ServiceAccountFile -Verbose -ErrorAction Stop | Out-Null + Write-Log "Connect-Rsc succeeded." +} catch { + Write-Log "Connect-Rsc failed." + Write-ExceptionDetails $_.Exception "ConnectRsc" +} + +Write-Log "" +Write-Log "=== Sanity Check Complete ==="