Powershell: rastrear la ubicación de un dispositivo a través de la API de GeoLocation de Google

Puntos clave

  • El script obtiene la ubicación geográfica de un dispositivo utilizando la API de GeoLocation de Google.
  • Está diseñado para actualizar los campos personalizados de NinjaOne con datos de ubicación.
  • El script requiere una conexión activa a Internet y está optimizado para dispositivos Windows 10.
  • La API de GeoLocation de Google ofrece precisión y una cobertura más amplia en comparación con otros métodos.
  • El uso del script para rastrear la ubicación de un dispositivo plantea problemas éticos y de privacidad.
  • Es esencial contar con permisos explícitos antes de desplegar esta herramienta para evitar violaciones de la privacidad.
  • Es fundamental conocer los límites de las tarifas y los costes asociados a la API de Google.
  • NinjaOne, combinado con dichos scripts, ofrece sólidas capacidades para las operaciones de TI y la gestión de activos.

En el interconectado ecosistema informático actual, uno de los datos más valiosos es la «ubicación». La capacidad de rastrear la ubicación de un dispositivo puede resultar crucial en muchas operaciones informáticas, desde la gestión de activos hasta la supervisión de la seguridad. Este post analiza un script de PowerShell que permite a los profesionales de TI y MSP (proveedores de servicios gestionados) rastrear la ubicación de un dispositivo Windows y almacenarla utilizando los campos personalizados de NinjaOne.

Antecedentes

El script en cuestión actualiza los campos personalizados con las coordenadas geográficas y la dirección de un dispositivo utilizando la API de GeoLocation de Google. Para los profesionales de TI y los MSP, conocer la ubicación física de un dispositivo es fundamental. Ya se trate de rastrear equipos robados, auditar dispositivos o verificar la dispersión geográfica de los activos informáticos, su aplicación puede ser diversa y profunda.

El script para rastrear la ubicación de un dispositivo a través de la API de GeoLocation de Google

#Requires -Version 5.1

<#
.SYNOPSIS
    Updates Custom Fields with the location of a device based on the Google GeoLocation API.
.DESCRIPTION
    Updates Custom Fields with the location of a device based on the Google GeoLocation API.

    The CustomFieldName parameter can be used to specify which custom field to save the Latitude and Longitude coordinates to.
    The AddressCustomFieldName parameter can be used to specify which custom field to save the address to.

    This script requires a custom field to save location data in NinjaRMM.
    The default for CustomFieldName is "Location".
    The default for AddressCustomFieldName is "Address".
    You can use any text custom field that you wish.
.EXAMPLE
    -GoogleApiKey "<GeoLocation API key here>"
    Saves the Latitude and Longitude coordinates to the custom field named Location.
.EXAMPLE
    -GoogleApiKey "<GeoLocation API key here>" -CustomFieldName "Location" -AddressCustomFieldName "Address"
    Saves the Latitude and Longitude coordinates to the custom field named Location as well as the address to Address.
.INPUTS
    None
.OUTPUTS
    None
.NOTES
    Minimum OS Architecture Supported: Windows 10
    Release Notes:
    Updated to work with either Parameters or Script Variables
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()]
    [String]
    $GoogleApiKey,
    [Parameter()]
    [String]
    $CustomFieldName = "Location",
    [Parameter()]
    [String]
    $AddressCustomFieldName = "Address"
)

begin {
    function Test-StringEmpty {
        param([string]$Text)
        # Returns true if string is empty, null, or whitespace
        process { [string]::IsNullOrEmpty($Text) -or [string]::IsNullOrWhiteSpace($Text) }
    }
    function Get-NearestCity {
        param (
            [double]$lat,
            [double]$lon,
            [string]$GoogleApi
        )
        try {
            $Response = Invoke-RestMethod -Uri "http://maps.googleapis.com/maps/api/geocode/json?latlng=$lat,$lon&key=$GoogleApi"
        }
        catch {
            throw $Error[0]
        }
        return $Response.results[0].formatted_address
    }
    function Get-WifiNetwork {
        end {
            try {
                netsh.exe wlan sh net mode=bssid | ForEach-Object -Process {
                    if ($_ -match '^SSID (d+) : (.*)$') {
                        $current = @{}
                        $networks += $current
                        $current.Index = $matches[1].trim()
                        $current.SSID = $matches[2].trim()
                    }
                    else {
                        if ($_ -match '^s+(.*)s+:s+(.*)s*$') {
                            $current[$matches[1].trim()] = $matches[2].trim()
                        }
                    }
                } -Begin { $networks = @() } -End { $networks | ForEach-Object { New-Object -TypeName "PSObject" -Property $_ } }    
            }
            catch {
                # return nothing
            }
        }
    }

    # Check if Script Variables are being used
    if (-not $(Test-StringEmpty -Text $env:GoogleApiKey)) {
        $GoogleApiKey = $env:GoogleApiKey
    }
    if (-not $(Test-StringEmpty -Text $env:CustomFieldName)) {
        $CustomFieldName = $env:CustomFieldName
    }
    if (-not $(Test-StringEmpty -Text $env:AddressCustomFieldName)) {
        $AddressCustomFieldName = $env:AddressCustomFieldName
    }
    # Check if api key is set, error if not set
    if ($(Test-StringEmpty -Text $GoogleApiKey)) {
        # Both Parameter and Script Variable are empty
        # Can not combine Parameter "[Parameter(Mandatory)]" and Script Variable Required
        Write-Error "GoogleApiKey is required."
        exit 1
    }

    # Use the system's new line
    $NewLine = $([System.Environment]::NewLine)

    # Build URL with API key
    $Url = "https://www.googleapis.com/geolocation/v1/geolocate?key=$GoogleApiKey"
}
process {
    # Get WIFI network data nearby
    $WiFiData = Get-WifiNetwork |
        Select-Object @{name = 'age'; expression = { 0 } },
        @{name = 'macAddress'; expression = { $_.'BSSID 1' } },
        @{name = 'channel'; expression = { $_.Channel } },
        @{name = 'signalStrength'; expression = { (($_.Signal -replace "%") / 2) - 100 } }

    # Check if we got any number access points
    $Body = if ($WiFiData -and $WiFiData.Count -gt 0) {
        @{
            considerIp       = $true
            wifiAccessPoints = $WiFiData
        } | ConvertTo-Json
    }
    else {
        @{
            considerIp = $true
        } | ConvertTo-Json
    }

    # Get our lat,lng position
    try {
        $Response = Invoke-RestMethod -Method Post -Uri $Url -Body $Body -ContentType "application/json" -ErrorVariable Err
    }
    catch {
        Write-Error $_
        exit 1
    }

    # Save the relevant results to variable that have shorter names
    $Lat = $Response.location.lat
    $Lon = $Response.location.lng

    try {
        # Save Latitude, Longitude to the custom field from the CustomFieldName parameter
        Ninja-Property-Set -Name $CustomFieldName -Value "$Lat,$Lon"
    }
    catch {
        Write-Error "Failed to save to CustomFieldName($CustomFieldName)"
        exit 1
    }

    if ( $(Test-StringEmpty -Text $AddressCustomFieldName) -and $(Test-StringEmpty -Text $env:AddressCustomFieldName)) {
        # Both Parameter and Variable are empty
        Write-Output "$($NewLine)Location: $Lat,$Lon"
    }
    else {
        if ($(Test-StringEmpty -Text $AddressCustomFieldName)) {
            # Parameter was not used
            $AddressCustomFieldName = $env:AddressCustomFieldName
        }

        try {
            # Get City from Google API's
            # Google API: https://developers.google.com/maps/documentation/geocoding/requests-reverse-geocoding
            $Address = Get-NearestCity -lat $Lat -lon $Lon -GoogleApi $GoogleApiKey
        }
        catch {
            Write-Error "Failed to save to get nearest city."
            exit 1
        }

        try {
            # Save Lat and Lon to custom field
            Ninja-Property-Set -Name $AddressCustomFieldName -Value "$Address"
            Write-Output "$($NewLine)Location: $Address`: $Lat,$Lon"
        }
        catch {
            Write-Error "Failed to save to AddressCustomFieldName($AddressCustomFieldName)"
            exit 1
        }
    }
    exit 0
}
end {
    $ScriptVariables = @(
        [PSCustomObject]@{
            name           = "GoogleApiKey"
            calculatedName = "GoogleApiKey"
            required       = $true
            defaultValue   = $null
            valueType      = "TEXT"
            valueList      = $null
            description    = ""
        }
        [PSCustomObject]@{
            name           = "CustomFieldName"
            calculatedName = "CustomFieldName"
            required       = $false
            defaultValue   = [PSCustomObject]@{
                type  = "TEXT"
                value = "Location"
            }
            valueType      = "TEXT"
            valueList      = $null
            description    = ""
        }
    )
}

 

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

Obtén acceso

Análisis detallado

El script para rastrear la ubicación de un dispositivo puede dividirse en tres partes principales:

  • Inicialización: el script comienza definiendo parámetros como GoogleApiKey, CustomFieldName y AddressCustomFieldName. Estos parámetros actúan como inputs para personalizar el comportamiento del script.
  • Operaciones principales: la parte principal del script consiste en:
  • Buscar redes WiFi disponibles alrededor del dispositivo.
  • Construir una carga útil con datos WiFi y enviarla al servicio de geolocalización de Google para obtener la latitud y la longitud.
  • Encontrar la ciudad o dirección más cercana utilizando las coordenadas obtenidas.
  • Actualizar los campos personalizados en NinjaOne con los datos de ubicación.
  • Operaciones finales: las variables del script se inicializan para almacenar datos y ayudar en operaciones posteriores.

Posibles casos de uso

Pensemos en un profesional de TI, Alex, que trabaja para una empresa. Se le ha asignado la auditoría de todos los ordenadores portátiles de las distintas sucursales. Con este script para rastrear la ubicación de un dispositivo, Alex puede obtener rápidamente la ubicación geográfica de cada portátil y asegurarse de que se encuentran en las oficinas indicadas.

Comparaciones

El enfoque de este script para rastrear la ubicación de un dispositivo aprovecha la API de Google GeoLocation, que ofrece detalles precisos sobre la ubicación. Las alternativas pueden consistir en utilizar los servicios de localización nativos de Windows u otras API de terceros. Sin embargo, la gran cantidad de datos y la sólida infraestructura de Google lo convierten en la opción preferida para este tipo de aplicaciones, ya que ofrece una mayor precisión y una cobertura más amplia.

FAQ

  • ¿Este script funciona sin conexión?
    No, el script requiere una conexión activa a Internet para comunicarse con los servicios de Google.
  • ¿Hay un límite para el número de solicitudes de localización?
    La API de GeoLocation de Google tiene límites en función del tipo de cuenta y del estado de facturación.
  • ¿El script sólo funciona en Windows 10?
    El requisito mínimo del sistema operativo del script es Windows 10.

Implicaciones

Aunque la capacidad de rastrear la ubicación de un dispositivo es una gran herramienta para la gestión de activos y la seguridad, también plantea problemas de privacidad. Es crucial que los equipos informáticos se aseguren de que esta herramienta se utiliza de forma ética, con los debidos permisos y divulgaciones. El rastreo no autorizado puede dar lugar a infracciones de las leyes y normativas sobre privacidad.

Recomendaciones

  • Obtén siempre permiso explícito antes de ejecutar este script en cualquier dispositivo.
  • Asegúrate de que conoces los límites de tarifas y los costes asociados a la API de GeoLocation de Google.
  • Revisa y audita periódicamente los registros para evitar cualquier uso indebido.

Reflexiones finales

Para los MSP y los profesionales de TI, NinjaOne proporciona una plataforma inestimable para centralizar y agilizar las operaciones de TI. La integración de estos scripts para obtener las ubicaciones de los dispositivos amplía aún más las capacidades de NinjaOne, convirtiéndolo en una herramienta indispensable para los entornos de TI modernos. Los scripts PowerShell, especialmente el que hemos analizado anteriormente para rastrear la ubicación de un dispositivo, ofrecen una capa adicional de flexibilidad y poder a los usuarios de NinjaOne, ayudándoles a mantener el ritmo en el dinámico mundo de las TI.

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 Endpoint Management, echa un vistazo a un tour en vivoo tu prueba gratuita de la plataforma NinjaOne.

Categorías:

Quizá también te interese…

×

¡Vean a NinjaOne en acción!

Al enviar este formulario, acepto la política de privacidad de NinjaOne.

Términos y condiciones de NinjaOne

Al hacer clic en el botón «Acepto» que aparece a continuación, estás aceptando los siguientes términos legales, así como nuestras Condiciones de uso:

  • Derechos de propiedad: NinjaOne posee y seguirá poseyendo todos los derechos, títulos e intereses sobre el script (incluidos los derechos de autor). NinjaOne concede al usuario una licencia limitada para utilizar el script de acuerdo con estos términos legales.
  • Limitación de uso: solo podrás utilizar el script para tus legítimos fines personales o comerciales internos, y no podrás compartirlo con terceros.
  • Prohibición de republicación: bajo ninguna circunstancia está permitido volver a publicar el script en ninguna biblioteca de scripts que pertenezca o esté bajo el control de cualquier otro proveedor de software.
  • Exclusión de garantía: el script se proporciona «tal cual» y «según disponibilidad», sin garantía de ningún tipo. NinjaOne no promete ni garantiza que el script esté libre de defectos o que satisfaga las necesidades o expectativas específicas del usuario.
  • Asunción de riesgos: el uso que el usuario haga del script corre por su cuenta y riesgo. El usuario reconoce que existen ciertos riesgos inherentes al uso del script, y entiende y asume cada uno de esos riesgos.
  • Renuncia y exención: el usuario no hará responsable a NinjaOne de cualquier consecuencia adversa o no deseada que resulte del uso del script y renuncia a cualquier derecho o recurso legal o equitativo que pueda tener contra NinjaOne en relación con su uso del script.
  • CLUF: si el usuario es cliente de NinjaOne, su uso del script está sujeto al Contrato de Licencia para el Usuario Final (CLUF).