Optimiza tu gestión de TI: supervisión de la replicación en Hyper-V con PowerShell

Principales conclusiones

  • Supervisión automatizada de la replicación de Hyper-V: el script automatiza el proceso de monitorización del estado de replicación de Hyper-V, mejorando la eficiencia en la gestión del entorno virtual.
  • Umbrales de alerta personalizables: los administradores pueden establecer umbrales personalizados para las alertas de replicación utilizando parámetros como -FailedFor.
  • Se requieren permisos elevados: la ejecución del script requiere privilegios de administrador para acceder a la información detallada de replicación de las máquinas virtuales.
  • Personalización específica del entorno: utiliza variables de entorno y campos personalizados para adaptar la funcionalidad del script a entornos informáticos específicos.
  • Herramienta de gestión proactiva de TI: el script sirve como herramienta proactiva para los profesionales de TI, garantizando la identificación y resolución oportunas de los problemas de replicación.
  • Mejora con respecto a los métodos manuales: ofrece un enfoque más completo y automatizado en comparación con las comprobaciones manuales o los scripts básicos.
  • Parte integrante de la gestión de infraestructuras informáticas: cuando se integra con plataformas como NinjaOne, el script añade un valor significativo a la gestión y la seguridad de la infraestructura de TI.
  • Requiere PowerShell 5.1 o versiones posteriores: garantiza la compatibilidad y funcionalidad con la versión adecuada de PowerShell.

La gestión eficaz de los entornos virtuales es crucial para los profesionales de TI, ya que garantiza un rendimiento y una seguridad óptimos. Un aspecto clave es la supervisión y gestión de la replicación de Hyper-V, una función muy utilizada en redes virtualizadas con fines de redundancia y conmutación por error. La supervisión eficaz del estado de replicación de Hyper-V garantiza la continuidad de la actividad y la integridad de los datos en caso de fallos inesperados.

Contexto

La replicación de Hyper-V es un mecanismo que permite a las máquinas virtuales (VM) replicarse de un host Hyper-V a otro, proporcionando una solución crucial de recuperación ante desastres. Los profesionales de TI y los proveedores de servicios gestionados (MSP) necesitan herramientas sólidas para supervisar este proceso de replicación. El script que estamos analizando sirve exactamente para este propósito, permitiendo a los administradores realizar un seguimiento eficiente del estado de las réplicas de máquinas virtuales y reaccionar rápidamente ante cualquier anomalía.

El script:

#Requires -Version 5.1

<#
.SYNOPSIS
    This will get information about the current status of Hyper-V Replication. If its abnormal it'll check the last replication time to see if it should alert on it.
.DESCRIPTION
    This will get information about the current status of Hyper-V Replication. If its abnormal it'll check the last replication time to see if it should alert on it.
.EXAMPLE 
    (No Parameters)
    Replication is currently failing!
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorExcep 
   tion
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorExceptio 
   n,customscript_gen_2.ps1
 

    VMName      PrimaryServer            State   Health LastReplicationTime 
    ------      -------------            -----   ------ ------------------- 
    WIN10-TEST  SRV16-TEST.test.lan      Error Critical 4/13/2023 8:20:11 AM
    Win10-TEST2 SRV16-TEST.test.lan      Error Critical 4/13/2023 8:20:11 AM

PARAMETER: -FailedFor "30"
    Time in minutes any given vm replication is allowed to be abnormal.
    Ex. "20" will alert on a vm replication after its been in the abnormal state for 20 minutes.
.EXAMPLE
    -FailedFor "20"
    WARNING: Some of the vm's currently have replication paused!
 

    VMName      PrimaryServer                  State  Health LastReplicationTime 
    ------      -------------                  -----  ------ ------------------- 
    WIN10-TEST  SRV16-TEST.test.lan      Replicating  Normal 4/13/2023 8:40:04 AM
    Win10-TEST2 SRV16-TEST.test.lan        Suspended Warning 4/13/2023 8:32:06 AM

PARAMETER: -IncludePaused
    Script will consider paused vm's abnormal if this parameter is used.    
.EXAMPLE
    -IncludePaused
    Replication is currently failing!
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorExcep 
   tion
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorExceptio 
   n,customscript_gen_2.ps1
 

    VMName      PrimaryServer                  State  Health LastReplicationTime 
    ------      -------------                  -----  ------ ------------------- 
    WIN10-TEST  SRV16-TEST.test.lan      Replicating  Normal 4/13/2023 8:40:04 AM
    Win10-TEST2 SRV16-TEST.test.lan        Suspended Warning 4/13/2023 8:32:06 AM

PARAMETER: -FromCustomField "ReplaceMeWithAnyIntegerCustomField"
    Name of an integer custom field that contains your desired FailedFor threshold.
    ex. "ReplicationAlertThreshold" where you have entered in your desired alert limit in the "ReplicationAlertThreshold" custom field rather than in a parameter.
.EXAMPLE
    -FromCustomField "ReplaceMeWithAnyIntegerCustomField"
    WARNING: Some of the vm's currently have replication paused!
 

    VMName      PrimaryServer                  State  Health LastReplicationTime 
    ------      -------------                  -----  ------ ------------------- 
    WIN10-TEST  SRV16-TEST.test.lan      Replicating  Normal 4/13/2023 8:40:04 AM
    Win10-TEST2 SRV16-TEST.test.lan        Suspended Warning 4/13/2023 8:32:06 AM
.OUTPUTS
    None
.NOTES
    Minimum OS Architecture Supported: Windows 10, Server 2016
    Release Notes: Renamed script and added Script Variable support
By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://www.ninjaone.com/terms-of-use.
    Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. 
    Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. 
    Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. 
    Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. 
    Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. 
    Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. 
    EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).
#>

[CmdletBinding()]
param (
    [Parameter()]
    [int]$FailedFor = "60",
    [Parameter()]
    [String]$FromCustomField,
    [Parameter()]
    [Switch]$IncludePaused = [System.Convert]::ToBoolean($env:includePausedReplications)
)
begin {

    if ($env:allowedToFailForxMinutes -and $env:allowedToFailForxMinutes -notlike "null") { $FailedFor = $env:allowedToFailForxMinutes }
    if ($env:retrieveAllowedFailureTimeFromCustomField -and $env:retrieveAllowedFailureTimeFromCustomField -notlike "null" ) { $FromCustomField = $env:retrieveAllowedFailureTimeFromCustomField }

    function Test-IsElevated {
        $id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
        $p = New-Object System.Security.Principal.WindowsPrincipal($id)
        $p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
    }

    function Test-IsSystem {
        $id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
        return $id.Name -like "NT AUTHORITY*" -or $id.IsSystem
    }

    if (!(Test-IsElevated) -and !(Test-IsSystem)) {
        Write-Error -Message "Access Denied. Please run with Administrator privileges."
        exit 1
    }

    # This function is to make it easier to parse Ninja Custom Fields.
    function Get-NinjaProperty {
        [CmdletBinding()]
        Param(
            [Parameter(Mandatory = $True, ValueFromPipeline = $True)]
            [String]$Name,
            [Parameter()]
            [String]$Type,
            [Parameter()]
            [String]$DocumentName
        )

        # If we're requested to get the field value from a Ninja document we'll specify it here.
        $DocumentationParams = @{}
        if ($DocumentName) { $DocumentationParams["DocumentName"] = $DocumentName }

        # These two types require more information to parse.
        $NeedsOptions = "DropDown","MultiSelect"

        # Grabbing document values requires a slightly different command.
        if ($DocumentName) {
            # Secure fields are only readable when they're a device custom field
            if ($Type -Like "Secure") { throw "$Type is an invalid type! Please check here for valid types. https://ninjarmm.zendesk.com/hc/en-us/articles/16973443979789-Command-Line-Interface-CLI-Supported-Fields-and-Functionality" }

            # We'll redirect the error output to the success stream to make it easier to error out if nothing was found or something else went wrong.
            Write-Host "Retrieving value from Ninja Document..."
            $NinjaPropertyValue = Ninja-Property-Docs-Get -AttributeName $Name @DocumentationParams 2>&1

            # Certain fields require more information to parse.
            if ($NeedsOptions -contains $Type) {
                $NinjaPropertyOptions = Ninja-Property-Docs-Options -AttributeName $Name @DocumentationParams 2>&1
            }
        }
        else {
            # We'll redirect error output to the success stream to make it easier to error out if nothing was found or something else went wrong.
            $NinjaPropertyValue = Ninja-Property-Get -Name $Name 2>&1

            # Certain fields require more information to parse.
            if ($NeedsOptions -contains $Type) {
                $NinjaPropertyOptions = Ninja-Property-Options -Name $Name 2>&1
            }
        }

        # If we received some sort of error it should have an exception property and we'll exit the function with that error information.
        if ($NinjaPropertyValue.Exception) { throw $NinjaPropertyValue }
        if ($NinjaPropertyOptions.Exception) { throw $NinjaPropertyOptions }

        # This switch will compare the type given with the quoted string. If it matches, it'll parse it further; otherwise, the default option will be selected.
        switch ($Type) {
            "Attachment" {
                # Attachments come in a JSON format this will convert it into a PowerShell Object.
                $NinjaPropertyValue | ConvertFrom-Json
            }
            "Checkbox" {
                # Checkbox's come in as a string representing an integer. We'll need to cast that string into an integer and then convert it to a more traditional boolean.
                [System.Convert]::ToBoolean([int]$NinjaPropertyValue)
            }
            "Date or Date Time" {
                # In Ninja Date and Date/Time fields are in Unix Epoch time in the UTC timezone the below should convert it into local time as a datetime object.
                $UnixTimeStamp = $NinjaPropertyValue
                $UTC = (Get-Date "1970-01-01 00:00:00").AddSeconds($UnixTimeStamp)
                $TimeZone = [TimeZoneInfo]::Local
                [TimeZoneInfo]::ConvertTimeFromUtc($UTC, $TimeZone)
            }
            "Decimal" {
                # In ninja decimals are strings that represent a decimal this will cast it into a double data type.
                [double]$NinjaPropertyValue
            }
            "Device Dropdown" {
                # Device Drop-Downs Fields come in a JSON format this will convert it into a PowerShell Object.
                $NinjaPropertyValue | ConvertFrom-Json
            }
            "Device MultiSelect" {
                # Device Multi-Select Fields come in a JSON format this will convert it into a PowerShell Object.
                $NinjaPropertyValue | ConvertFrom-Json
            }
            "Dropdown" {
                # Drop-Down custom fields come in as a comma-separated list of GUIDs; we'll compare these with all the options and return just the option values selected instead of a GUID.
                $Options = $NinjaPropertyOptions -replace '=', ',' | ConvertFrom-Csv -Header "GUID", "Name"
                $Options | Where-Object { $_.GUID -eq $NinjaPropertyValue } | Select-Object -ExpandProperty Name
            }
            "Integer" {
                # Cast's the Ninja provided string into an integer.
                if($NinjaPropertyValue){
                    [int]$NinjaPropertyValue
                }else{
                    $NinjaPropertyValue
                }
            }
            "MultiSelect" {
                # Multi-Select custom fields come in as a comma-separated list of GUID's we'll compare these with all the options and return just the option values selected instead of a guid.
                $Options = $NinjaPropertyOptions -replace '=', ',' | ConvertFrom-Csv -Header "GUID", "Name"
                $Selection = ($NinjaPropertyValue -split ',').trim()

                foreach ($Item in $Selection) {
                    $Options | Where-Object { $_.GUID -eq $Item } | Select-Object -ExpandProperty Name
                }
            }
            "Organization Dropdown" {
                # Turns the Ninja provided JSON into a PowerShell Object.
                $NinjaPropertyValue | ConvertFrom-Json
            }
            "Organization Location Dropdown" {
                # Turns the Ninja provided JSON into a PowerShell Object.
                $NinjaPropertyValue | ConvertFrom-Json
            }
            "Organization Location MultiSelect" {
                # Turns the Ninja provided JSON into a PowerShell Object.
                $NinjaPropertyValue | ConvertFrom-Json
            }
            "Organization MultiSelect" {
                # Turns the Ninja provided JSON into a PowerShell Object.
                $NinjaPropertyValue | ConvertFrom-Json
            }
            "Time" {
                # Time fields are given as a number of seconds starting from midnight. This will convert it into a datetime object.
                $Seconds = $NinjaPropertyValue
                $UTC = ([timespan]::fromseconds($Seconds)).ToString("hh\:mm\:ss")
                $TimeZone = [TimeZoneInfo]::Local
                $ConvertedTime = [TimeZoneInfo]::ConvertTimeFromUtc($UTC, $TimeZone)

                Get-Date $ConvertedTime -DisplayHint Time
            }
            default {
                # If no type was given or not one that matches the above types just output what we retrieved.
                $NinjaPropertyValue
            }
        }
    }
}
process {
    if ($FromCustomField) {
        try{
            $CustomFieldValue = Get-NinjaProperty -Name $FromCustomField -Type "Integer"
        }catch{
            Write-Warning "$($_.ToString())"
        }

        if($CustomFieldValue){
            $FailedFor = $CustomFieldValue
        }else{
            Write-Warning "Custom Field $FromCustomField was empty?"
        }
    }

    if($FailedFor -gt 0){
        $FailedFor = $FailedFor * -1
    }

    $Threshold = (Get-Date).AddMinutes($FailedFor)
    Write-Host "Checking vm's that have not replicated prior to $Threshold."

    $Failed = New-Object System.Collections.Generic.List[string]
    $UnhealthyVMs = Get-VMReplication | Where-Object { $_.Health -notlike "Normal" -and $_.LastReplicationTime -lt $Threshold -and $_.State -notlike "Suspended" }
    $PausedVMs = Get-VMReplication | Where-Object { $_.LastReplicationTime -lt $Threshold -and $_.State -like "Suspended" }

    if ($UnhealthyVMs) {
        $Failed.Add($UnhealthyVMs)
    }
    
    if ($PausedVMs) {
        Write-Warning "Some of the vm's currently have replication paused!"

        if(-not $IncludePaused){
            Write-Warning "Please use 'Include Paused Replications' to include paused replications in the alert. Otherwise, they will be skipped."
        }
    }

    if ($PausedVMs -and $IncludePaused) {
        $Failed.Add($PausedVMs)
    }

    if ($Failed) {
        Write-Error "Hyper-V Replication is currently failing!"
        Get-VMReplication | Format-Table -Property VMName, PrimaryServer, State, Health, LastReplicationTime | Out-String | Write-Host
        exit 1
    }
    else {
        Write-Host "No failing replications detected prior to $Threshold."

        Get-VMReplication | Format-Table -Property VMName, PrimaryServer, State, Health, LastReplicationTime | Out-String | Write-Host
        exit 0
    }
}end {
    
    
    
}

 

Accede a más de 300 scripts en el Dojo de NinjaOne

Obtén acceso

Análisis detallado

El script es una utilidad de PowerShell diseñada para llevar a cabo la supervisión de la replicación de Hyper-V. Comprueba el estado de replicación y el estado de cada máquina virtual, alertando a los administradores si hay algún problema. Los componentes clave del script incluyen:

  • Vinculación y parámetros del cmdlet: el script utiliza funciones avanzadas, permitiendo parámetros como -FailedFor, -FromCustomField y -IncludePaused.
  • Variables de entorno y funciones: utiliza funciones personalizadas y variables de entorno para determinar permisos elevados y recuperar valores de campos personalizados.
  • Proceso principal: el script evalúa el estado y el tiempo de replicación de cada máquina virtual, comparándolos con los umbrales especificados. Si alguna máquina virtual no se ha replicado en el plazo designado o se encuentra en un estado anormal, se activa una alerta.

Este script podría representarse visualmente en un diagrama de flujo, detallando los pasos desde la inicialización, la parametrización, la comprobación de permisos, hasta el análisis final y la alerta.

Posibles casos de uso

Imagina un administrador de TI en una empresa mediana con un entorno virtualizado robusto que utiliza Hyper-V. Desplegaría este script para supervisar regularmente el estado de replicación de las máquinas virtuales, identificando y resolviendo rápidamente cualquier problema de replicación, garantizando así la continuidad del negocio.

Comparaciones

Tradicionalmente, la supervisión de la replicación de Hyper-V implica comprobaciones manuales o scripts menos sofisticados. Este script, sin embargo, automatiza el proceso y proporciona una supervisión más completa y personalizable. Supera en eficacia y escalabilidad a los comandos básicos de PowerShell o a las comprobaciones manuales de la interfaz gráfica de usuario.

FAQ

P: ¿Este script se puede ejecutar en cualquier versión de PowerShell?
R: Requiere PowerShell 5.1 o versiones posteriores.

P: ¿Es necesario ejecutar el script con privilegios de administrador?
R: Sí, el script comprueba si hay privilegios elevados, ya que necesita acceder a los detalles de replicación de la máquina virtual.

P: ¿Cómo puedo personalizar el umbral de alerta?
R: Utiliza el parámetro -FailedFor para establecer un intervalo de tiempo personalizado en minutos.

Implicaciones

Aunque este script mejora la supervisión de la replicación de Hyper-V, también subraya la necesidad de adoptar medidas proactivas de seguridad informática. La detección y resolución rápidas de los problemas de replicación son vitales para mantener la integridad y disponibilidad de los datos.

Recomendaciones

  • Ejecuta regularmente el script para garantizar una supervisión continua.
  • Ajusta el parámetro -FailedFor en función de las necesidades específicas del entorno.
  • Asegúrate de que PowerShell 5.1 o una versión posterior está instalado y en ejecución con los permisos necesarios.

Reflexiones finales

En el contexto de la gestión de entornos virtualizados, herramientas como NinjaOne proporcionan una plataforma integral para supervisar y gestionar la infraestructura de TI. La incorporación de un script como este en un conjunto más amplio de herramientas de NinjaOne puede mejorar la capacidad de una organización para gestionar entornos Hyper-V de manera eficiente, garantizando la fiabilidad y el rendimiento.

Próximos pasos

La creación de un equipo de TI próspero y eficaz requiere contar con una solución centralizada que se convierta en tu principal herramienta de prestación de servicios. NinjaOne permite a los equipos de TI supervisar, gestionar, proteger y dar soporte a todos sus dispositivos, estén donde estén, sin necesidad de complejas infraestructuras locales.

Obtén más información sobre NinjaOne Remote Script Deployment, echa un vistazo a un tour en vivo, o comienza tu prueba gratuita de la plataforma NinjaOne.

Categorías:

Quizá también te interese…