Get-IdracRemoteServiceApiStatusREDFISH.ps1
|
<#
_author_ = Texas Roemer <Texas_Roemer@Dell.com> _version_ = 6.0 Copyright (c) 2020, Dell, Inc. This software is licensed to you under the GNU General Public License, version 2 (GPLv2). There is NO WARRANTY for this software, express or implied, including the implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 along with this software; if not, see http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt #> <# .Synopsis Cmdlet used to get iDRAC remote services status. .DESCRIPTION Cmdlet using Redfish API with OEM extension to get iDRAC remote service status. The output will return LC (Lifecycle controller) status, RT (real time monitoring) status, server status (examples, in POST or in in BIOS boot manager) and overall status. - idrac_ip: Pass in iDRAC IP address - idrac_username: Pass in iDRAC username - idrac_password: Pass in iDRAC username password - x_auth_token: Pass in iDRAC X-Auth token session to execute cmdlet instead of username / password (recommended). .EXAMPLE .\Get-IdracRemoteServiceApiStatusREDFISH -idrac_ip 192.168.0.120 -username root -password calvin This example will return remote services status for the iDRAC. .\Get-IdracRemoteServiceApiStatusREDFISH -idrac_ip 192.168.0.120 This example will first prompt to enter username/password using Get-Credential, then return remote services status for the iDRAC. .EXAMPLE .\Get-IdracRemoteServiceApiStatusREDFISH -idrac_ip 192.168.0.120 -x_auth_token 163490d51b708f8dc24ca853ef2fc6e7 This example will return remote services status for the iDRAC using X-auth token session. #> #function Get-IdracRemoteServiceApiStatusREDFISH { param( [Parameter(Mandatory=$False)] [string]$idrac_ip, [Parameter(Mandatory=$False)] [string]$idrac_username, [Parameter(Mandatory=$False)] [string]$idrac_password, [Parameter(Mandatory=$False)] [string]$x_auth_token ) # Function to ignore SSL certs function Ignore-SSLCertificates { $Provider = New-Object Microsoft.CSharp.CSharpCodeProvider $Compiler = $Provider.CreateCompiler() $Params = New-Object System.CodeDom.Compiler.CompilerParameters $Params.GenerateExecutable = $false $Params.GenerateInMemory = $true $Params.IncludeDebugInformation = $false $Params.ReferencedAssemblies.Add("System.DLL") > $null $TASource=@' namespace Local.ToolkitExtensions.Net.CertificatePolicy { public class TrustAll : System.Net.ICertificatePolicy { public bool CheckValidationResult(System.Net.ServicePoint sp,System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Net.WebRequest req, int problem) { return true; } } } '@ $TAResults=$Provider.CompileAssemblyFromSource($Params,$TASource) $TAAssembly=$TAResults.CompiledAssembly $TrustAll = $TAAssembly.CreateInstance("Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll") [System.Net.ServicePointManager]::CertificatePolicy = $TrustAll } $global:get_powershell_version = $null function get_powershell_version { $get_host_info = Get-Host $major_number = $get_host_info.Version.Major $global:get_powershell_version = $major_number } get_powershell_version [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::TLS12 if ($idrac_username -and $idrac_password) { $user = $idrac_username $pass= $idrac_password $secpasswd = ConvertTo-SecureString $pass -AsPlainText -Force $credential = New-Object System.Management.Automation.PSCredential($user, $secpasswd) } elseif ($x_auth_token) { } else { $get_creds = Get-Credential $credential = New-Object System.Management.Automation.PSCredential($get_creds.UserName, $get_creds.Password) } # Function to check iDRAC API status, confirm iDRAC is back in ready state after reboot function check_iDRAC_API_status_check { Write-Host "- INFO, checking to confirm iDRAC is fully back up, all services in ready state" $retry_count = 0 while ($true) { if ($retry_count -eq 30) { Write-Host "- INFO, retry count of 30 has been hit, cmdlet will now exit" return } $JsonBody = @{} | ConvertTo-Json -Compress $uri = "https://$idrac_ip/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/DellLCService/Actions/DellLCService.GetRemoteServicesAPIStatus" if ($x_auth_token) { try { if ($global:get_powershell_version -gt 5) { $post_result = Invoke-WebRequest -UseBasicParsing -SkipHeaderValidation -SkipCertificateCheck -SkipHttpErrorCheck -Uri $uri -Body $JsonBody -Method Post -ContentType 'application/json' -Headers @{"Accept" = "application/json"; "X-Auth-Token" = $x_auth_token} -ErrorVariable RespErr } else { Ignore-SSLCertificates $post_result = Invoke-WebRequest -UseBasicParsing -Uri $uri -Method Post -ContentType 'application/json' -Headers @{"Accept" = "application/json"; "X-Auth-Token" = $x_auth_token} -Body $JsonBody -ErrorVariable RespErr } } catch { if ($_.Exception.Response.StatusCode -eq "ServiceUnavailable" -or $RespErr -match "ServiceTemporarilyUnavailable") { Write-Host "- INFO, iDRAC service temporarily unavailable, retry in 5 seconds" Start-Sleep 5 $retry_count ++ continue } Write-Host $RespErr return } } else { try { if ($global:get_powershell_version -gt 5) { $post_result = Invoke-WebRequest -UseBasicParsing -SkipHeaderValidation -SkipCertificateCheck -SkipHttpErrorCheck -Uri $uri -Credential $credential -Body $JsonBody -Method Post -ContentType 'application/json' -Headers @{"Accept"="application/json"} -ErrorVariable RespErr } else { Ignore-SSLCertificates $post_result = Invoke-WebRequest -UseBasicParsing -Uri $uri -Credential $credential -Method Post -ContentType 'application/json' -Headers @{"Accept"="application/json"} -Body $JsonBody -ErrorVariable RespErr } } catch { if ($_.Exception.Response.StatusCode -eq "ServiceUnavailable" -or $RespErr -match "ServiceTemporarilyUnavailable") { Write-Host "- WARNING, iDRAC service temporarily unavailable, retry in 10 seconds" Start-Sleep 10 $retry_count ++ continue } Write-Host "- WARNING, iDRAC service temporarily unavailable, retry in 10 seconds" Start-Sleep 10 $retry_count ++ continue } } if ($post_result.StatusCode -eq 200 -or $post_result.StatusCode -eq 204) { } elseif ($result.StatusCode -eq 400) { [String]::Format("- FAIL, status code 400 returned for bad request, POST request will retry in 30 seconds") $retry_count ++ Start-Sleep 30 continue } elseif ($result.StatusCode -eq 404) { [String]::Format("- FAIL, status code 404 returned for resource not found, POST request will retry in 30 seconds") $retry_count ++ Start-Sleep 30 continue } elseif ($result.StatusCode -eq 500) { [String]::Format("- FAIL, status code 500 returned for internal server error, POST request will retry in 30 seconds") $retry_count ++ Start-Sleep 30 continue } elseif ($result.StatusCode -eq 503) { [String]::Format("- FAIL, status code 503 returned for service unavailable, POST request will retry in 30 seconds") $retry_count ++ Start-Sleep 30 continue } elseif ($result.StatusCode -eq 401) { [String]::Format("- FAIL, status code 401 detected for authentication credential failure. If iDRAC component erased, default password has now been set, cmdlet will exit") return } else { [String]::Format("- FAIL, general POST request failure, retry in 10 seconds") Start-Sleep 10 $retry_count ++ continue } $get_post_result = $post_result.Content | ConvertFrom-Json if ($get_post_result.error) { $message_id = $get_post_result.error.'@Message.ExtendedInfo'[0].MessageId if ($message_id -match "ServiceTemporarilyUnavailable") { $retry_secs = [int]$get_post_result.error.'@Message.ExtendedInfo'[0].MessageArgs[0] Write-Host "- INFO, iDRAC service temporarily unavailable, retry in $retry_secs seconds" Start-Sleep $retry_secs $retry_count ++ continue } } if ($get_post_result.LCStatus -eq "Ready" -and $get_post_result.Status -eq "Ready") { Write-Host "- PASS, iDRAC in ready state, both LC status and server status properties report Ready" break } else { Write-Host "- INFO, iDRAC not ready, both LC status and server status properties report NotReady, retry in 10 seconds" Start-Sleep 10 $retry_count ++ } } } # Function to ping iDRAC and confirm the network is back up after iDRAC reboot function check_iDRAC_network_up { $retry_interval = 10 # Ping every 10 seconds $connection_loss_timeout = 5 * 60 # 5 minutes $recovery_timeout = 10 * 60 # 10 minutes $connection_loss_start = $null $recovery_start = $null $retry_count = 0 Write-Host "- INFO, starting iDRAC ping check to validate success, lose connection due to iDRAC reboot and success once again" # Phase 1: Wait for initial successful ping while ($true) { if (Test-Connection -ComputerName $idrac_ip -Count 1 -Quiet) { #Write-Host "- PASS, successfully pinged iDRAC IP" break } else { Write-Host "- INFO, initial ping to iDRAC IP failed, retrying in $retry_interval seconds" Start-Sleep -Seconds $retry_interval } } Write-Host "- INFO, iDRAC is currently reachable, monitoring for connection loss to confirm iDRAC reboot did occur" # Part 2: Wait for the connection to fail $connection_loss_start = Get-Date while ($true) { if (-not (Test-Connection -ComputerName $idrac_ip -Count 1 -Quiet)) { $downtime_start = Get-Date Write-Host "- INFO, ping to iDRAC IP has failed, starting 10-minute recovery timeout" break } $elapsed = ((Get-Date) - $connection_loss_start).TotalSeconds if ($elapsed -ge $connection_loss_timeout) { Write-Host "- WARNING, iDRAC ping never failed within 5 minutes, cmdlet will exit" return } Write-Host "- INFO, iDRAC ping still successful, waiting for connection loss, $([math]::Round($elapsed)) seconds elapsed" Start-Sleep -Seconds $retry_interval } # Part 3: Wait for connection to recover $recovery_start = Get-Date $retry_count = 0 while ($true) { if (Test-Connection -ComputerName $idrac_ip -Count 1 -Quiet) { $downtime = ((Get-Date) - $downtime_start).TotalSeconds Write-Host "- PASS, successfully pinged iDRAC IP again after $([math]::Round($downtime)) seconds" Write-Host "- INFO, iDRAC network connection has been restored" return } $retry_count++ $elapsed = ((Get-Date) - $recovery_start).TotalSeconds if ($elapsed -ge $recovery_timeout) { Write-Host "- WARNING, failed to successfully ping iDRAC IP for 10 minutes, cmdlet will exit" return } Write-Host "- INFO, attempt $retry_count failed to ping iDRAC IP, iDRAC has been unreachable for $([math]::Round($elapsed)) seconds, retry in $retry_interval seconds" Start-Sleep -Seconds $retry_interval } } #check_iDRAC_network_up check_iDRAC_API_status_check |