¿Ya eres cliente de NinjaOne? Inicia sesión para ver más guías y las últimas actualizaciones.

Script personalizado: Eliminación del agente NinjaOne (Windows)

Tema

Este script elimina el Agente NinjaOne en terminales Windows.

Entorno

Automatización NinjaOne

Descripción

Descargue el script de PowerShell adjunto al final de este artículo o pegue el siguiente script en un nuevo archivo de script de PowerShell y guárdelo. A continuación, cargue el archivo en su Biblioteca de automatizaciones. Una vez hecho esto, puede desplegarlo en su entorno. Para obtener más información sobre el uso de scripts con NinjaOne, consulte Introducción a la Biblioteca de automatizaciones (scripting) de NinjaOne.

function Write-LogEntry {
  param (
    [Parameter(Mandatory = $true)]
    [string]$Message
  )

  $LogPath = "$env:windirtempNinjaOneAgentRemoval.log"
  $TimeStamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
  Add-Content -Path $LogPath -Value "$TimeStamp - $Message"
  Write-Host "$TimeStamp - $Message"
}

function Uninstall-NinjaMSI {
  $Arguments = @(
    "/x$($UninstallString)"
    '/quiet'
    '/L*V'
    "$env:windirtempNinjaRMMAgent_uninstall.log"
    "WRAPPED_ARGUMENTS=`"--mode unattended`""
  )

  Start-Process "msiexec.exe" -ArgumentList $Arguments -Wait -NoNewWindow
  Write-LogEntry 'Finished running uninstaller. Continuing to clean up...'
  Start-Sleep 30
}

#Get current user context
$CurrentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent())
#Check user that is running the script is a member of Administrator Group
if (!($CurrentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator))) {
  #UAC Prompt will occur for the user to input Administrator credentials and relaunch the powershell session
  Write-LogEntry 'This script must be ran with administrative privileges. Script will relaunch and request elevation...'
  Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; Exit
}

$ErrorActionPreference = "SilentlyContinue"

Write-LogEntry 'Beginning NinjaRMM Agent removal...'
Write-LogEntry 'Path to log file: C:tempNinjaOneAgentRemoval.log'

$NinjaRegPath = 'HKLM:SOFTWAREWOW6432NodeNinjaRMM LLCNinjaRMMAgent'
$NinjaDataDirectory = "$($env:ProgramData)NinjaRMMAgent"
$UninstallRegPath = 'HKLM:SOFTWAREWOW6432NodeMicrosoftWindowsCurrentVersionUninstall*'
$NinjaModulePath = "$env:ProgramFilesWindowsPowerShellModulesNJCliPSh"

if (!([System.Environment]::Is64BitOperatingSystem)) {
  $NinjaRegPath = 'HKLM:SOFTWARENinjaRMM LLCNinjaRMMAgent'
  $UninstallRegPath = 'HKLM:SOFTWAREMicrosoftWindowsCurrentVersionUninstall*'
}

$NinjaInstallLocation = (Get-ItemPropertyValue $NinjaRegPath -Name Location).Replace('/', '')

if (!(Test-Path "$($NinjaInstallLocation)NinjaRMMAgent.exe")) {
  $NinjaServicePath = ((Get-WMIObject Win32_Service | Where-Object { $_.Name -eq 'NinjaRMMAgent' }).PathName).Trim('"')
  if (!(Test-Path $NinjaServicePath)) {
    Write-LogEntry 'Unable to locate Ninja installation path. Continuing with cleanup...'
  }
  else {
    $NinjaInstallLocation = $NinjaServicePath | Split-Path
  }
}

Start-Process "$NinjaInstallLocationNinjaRMMAgent.exe" -ArgumentList "-disableUninstallPrevention NOUI" -Wait -NoNewWindow
$UninstallString = (Get-ItemProperty $UninstallRegPath | Where-Object { ($_.DisplayName -eq 'NinjaRMMAgent') -and ($_.UninstallString -match 'msiexec') }).UninstallString

if (!($UninstallString)) {
  Write-LogEntry 'Unable to to determine uninstall string. Continuing with cleanup...' 
}
else {
  $UninstallString = $UninstallString.Split('X')[1]
  Uninstall-NinjaMSI
}

$NinjaServices = @('NinjaRMMAgent', 'nmsmanager', 'lockhart')
$Processes = @("NinjaRMMAgent", "NinjaRMMAgentPatcher", "njbar", "NinjaRMMProxyProcess64")

foreach ($Process in $Processes) {
  if ($GetP = Get-Process $Process) {
    try {
      Stop-Process $GetP -Force -ErrorAction Stop
      Write-LogEntry "Successfully stopped process: $($GetP.Name)"
    }
    catch {
      Write-LogEntry "Unable to stop $($GetP.Name) for the following reason:"
      Write-LogEntry "$($_.Exception.Message). Continuing..."
    }
  }
}

foreach ($NS in $NinjaServices) {
  if ($NS -eq 'lockhart' -and !(Test-Path "$NinjaInstallLocationlockhartbinlockhart.exe")) {
    continue
  }
  if (Get-Service $NS) {
    try {
      Write-LogEntry "Stopping service $($NS)..."
      Stop-Service $NS -Force -ErrorAction Stop
    }
    catch {
      Write-LogEntry "Unable to stop $($NS) service..."
      Write-LogEntry "$($_.Exception.Message)"
      Write-LogEntry 'Attempting to remove service...'
    }
  
    & sc.exe DELETE $NS
    Start-Sleep 5
    if (Get-Service $NS) {
      Write-LogEntry "Failed to remove $($NS) service. Continuing with remaining removal steps..."
    }
    else {
      Write-LogEntry "Successfully removed $($NS) service."
    }
  }
}

if (Test-Path $NinjaInstallLocation) {
  Write-LogEntry 'Removing Ninja installation directory:'
  Write-LogEntry "$($NinjaInstallLocation)"
  try {
    Remove-Item $NinjaInstallLocation -Recurse -Force -ErrorAction Stop
    Write-LogEntry 'Successfully removed.'
  }
  catch {
    Write-LogEntry 'Failed to remove Ninja installation directory.'
    Write-LogEntry "$($_.Exception.Message)"
    Write-LogEntry 'Continuing with removal attempt...'
  }
}

if (Test-Path $NinjaDataDirectory) {
  Write-LogEntry 'Removing Ninja data directory:'
  Write-LogEntry "$($NinjaDataDirectory)"
  try {
    Remove-Item $NinjaDataDirectory -Recurse -Force -ErrorAction Stop
    Write-LogEntry 'Successfully removed.'
  }
  catch {
    Write-LogEntry 'Failed to remove Ninja data directory.'
    Write-LogEntry "$($_.Exception.Message)"
    Write-LogEntry 'Continuing with removal attempt...'
  }
}

if (Test-Path $NinjaModulePath) {
  Write-LogEntry 'Removing Ninja data directory:'
  Write-LogEntry "$($NinjaModulePath)"
  try {
    Remove-Item $NinjaModulePath -Recurse -Force -ErrorAction Stop
    Write-LogEntry 'Successfully removed.'
  }
  catch {
    Write-LogEntry 'Failed to remove Ninja PowerShell module directory.'
    Write-LogEntry "$($_.Exception.Message)"
    Write-LogEntry 'Continuing with removal attempt...'
  }
}

$MSIWrapperReg = 'HKLM:SOFTWAREWOW6432NodeEXEMSI.COMMSI WrapperInstalled'
$ProductInstallerReg = 'HKLM:SOFTWAREMicrosoftWindowsCurrentVersionInstallerUserDataS-1-5-18Products'
$HKCRInstallerReg = 'Registry::HKEY_CLASSES_ROOTInstallerProducts'

$RegKeysToRemove = [System.Collections.Generic.List[object]]::New()

(Get-ItemProperty $UninstallRegPath | Where-Object { $_.DisplayName -eq 'NinjaRMMAgent' }).PSPath | ForEach-Object { $RegKeysToRemove.Add($_) }
(Get-ItemProperty $ProductInstallerReg | Where-Object { $_.ProductName -eq 'NinjaRMMAgent' }).PSPath | ForEach-Object { $RegKeysToRemove.Add($_) }
(Get-ChildItem $MSIWrapperReg | Where-Object { $_.Name -match 'NinjaRMMAgent' }).PSPath | ForEach-Object { $RegKeysToRemove.Add($_) }
Get-ChildItem $HKCRInstallerReg | ForEach-Object { if ((Get-ItemPropertyValue $_.PSPath -Name 'ProductName') -eq 'NinjaRMMAgent') { $RegKeysToRemove.Add($_.PSPath) } }

$ProductInstallerKeys = Get-ChildItem $ProductInstallerReg | Select-Object *
foreach ($Key in $ProductInstallerKeys) {
  $KeyName = $($Key.Name).Replace('HKEY_LOCAL_MACHINE', 'HKLM:') + "InstallProperties"
  if (Get-ItemProperty $KeyName | Where-Object { $_.DisplayName -eq 'NinjaRMMAgent' }) {
    $RegKeysToRemove.Add($Key.PSPath)
  }
}

Write-LogEntry 'Removing registry items if found...'
if (($RegKeysToRemove | Measure-Object).Count -gt 0 ) {
  foreach ($RegKey in $RegKeysToRemove) {
    if (!([string]::IsNullOrWhiteSpace($RegKey))) {
      Write-LogEntry "Attempting to remove: $($RegKey)"
      try { 
        Remove-Item $RegKey -Recurse -Force -ErrorAction Stop
        Write-LogEntry 'Successfully removed.'
      }
      catch {
        Write-LogEntry 'Failed to remove registry key.'
        Write-LogEntry "$($_.Exception.Message)"
        Write-LogEntry "Continuing with removal..."
      }
    }
  }
}

if (Test-Path $NinjaRegPath) {
  try {
    Write-LogEntry "Removing: $($NinjaRegPath)"
    Get-Item ($NinjaRegPath | Split-Path -ErrorAction Stop) | Remove-Item -Recurse -Force -ErrorAction Stop
    Write-LogEntry 'Successfully removed.'
  }
  catch {
    Write-LogEntry 'Failed to remove key.'
    Write-LogEntry "$($_.Exception.Message)"
    Write-LogEntry "Continuing with removal..."
  }
}

#Checks for rogue reg entry from older installations where ProductName was missing
#Filters out a Windows Common GUID that doesn't have a ProductName
$Child = Get-ChildItem 'HKLM:SoftwareClassesInstallerProducts'
$MissingPNs = [System.Collections.Generic.List[object]]::New()

foreach ($C in $Child) {
  if ($C.Name -match '99E80CA9B0328e74791254777B1F42AE') {
    continue
  }
  try {
    Get-ItemPropertyValue $C.PSPath -Name 'ProductName' -ErrorAction Stop | Out-Null
  }
  catch {
    $MissingPNs.Add($($C.Name))
  } 
}

##Begin Ninja Remote Removal##
$NR = 'ncstreamer'

if (Get-Process $NR) {
  Write-LogEntry 'Stopping Ninja Remote process...'
  try {
    Get-Process $NR | Stop-Process -Force
  }
  catch {
    Write-LogEntry 'Unable to stop the Ninja Remote process...'
    Write-LogEntry "$($_.Exception.Message)"
    Write-LogEntry 'Continuing to Ninja Remote service...'
  }
}

if (Get-Service $NR) {
  try {
    Stop-Service $NR -Force
  }
  catch {
    Write-LogEntry 'Unable to stop the Ninja Remote service...'
    Write-LogEntry "$($_.Exception.Message)"
    Write-LogEntry 'Attempting to remove service...'
  }

  & sc.exe DELETE $NR
  Start-Sleep 5
  if (Get-Service $NR) {
    Write-LogEntry 'Failed to remove Ninja Remote service. Continuing with remaining removal steps...'
  }
}

$NRDriver = 'nrvirtualdisplay.inf'
$DriverCheck = pnputil /enum-drivers | Where-Object { $_ -match "$NRDriver" }
if ($DriverCheck) {
  Write-LogEntry 'Ninja Remote Virtual Driver found. Removing...'
  $DriverBreakdown = pnputil /enum-drivers | Where-Object { $_ -ne 'Microsoft PnP Utility' }

  $DriversArray = [System.Collections.Generic.List[object]]::New()
  $CurrentDriver = @{}
    
  foreach ($Line in $DriverBreakdown) {
    if ($Line -ne "") {
      $ObjectName = $Line.Split(':').Trim()[0]
      $ObjectValue = $Line.Split(':').Trim()[1]
      $CurrentDriver[$ObjectName] = $ObjectValue
    }
    else {
      if ($CurrentDriver.Count -gt 0) {
        $DriversArray.Add([PSCustomObject]$CurrentDriver)
        $CurrentDriver = @{}
      }
    }
  }

  $DriverToRemove = ($DriversArray | Where-Object { $_.'Provider Name' -eq 'NinjaOne' }).'Published Name'
  pnputil /delete-driver "$DriverToRemove" /force
}

$NRDirectory = "$($env:ProgramFiles)NinjaRemote"
if (Test-Path $NRDirectory) {
  Write-LogEntry "Removing directory: $NRDirectory"
  Remove-Item $NRDirectory -Recurse -Force
  if (Test-Path $NRDirectory) {
    Write-LogEntry 'Failed to completely remove Ninja Remote directory at:'
    Write-LogEntry "$NRDirectory"
    Write-LogEntry 'Continuing to registry removal...'
  }
}

$NRHKUReg = 'Registry::HKEY_USERSS-1-5-18SoftwareNinjaRMM LLC'
if (Test-Path $NRHKUReg) {
  Remove-Item $NRHKUReg -Recurse -Force
}

function Remove-NRRegistryItems {
  param (
    [Parameter(Mandatory = $true)]
    [string]$SID
  )
  $NRRunReg = "Registry::HKEY_USERS$SIDSOFTWAREMicrosoftWindowsCurrentVersionRun"
  $NRRegLocation = "Registry::HKEY_USERS$SIDSoftwareNinjaRMM LLC"
  if (Test-Path $NRRunReg) {
    $RunRegValues = Get-ItemProperty -Path $NRRunReg
    $PropertyNames = $RunRegValues.PSObject.Properties | Where-Object { $_.Name -match "NinjaRMM|NinjaOne" } 
    foreach ($PName in $PropertyNames) {    
      Write-LogEntry "Removing item..."
      Write-LogEntry "$($PName.Name): $($PName.Value)"
      Remove-ItemProperty $NRRunReg -Name $PName.Name -Force
    }
  }
  if (Test-Path $NRRegLocation) {
    Write-LogEntry "Removing $NRRegLocation..."
    Remove-Item $NRRegLocation -Recurse -Force
  }
  Write-LogEntry 'Registry removal completed.'
}

$AllProfiles = Get-CimInstance Win32_UserProfile | Select-Object LocalPath, SID, Loaded, Special | 
Where-Object { $_.SID -like "S-1-5-21-*" }
$Mounted = $AllProfiles | Where-Object { $_.Loaded -eq $true }
$Unmounted = $AllProfiles | Where-Object { $_.Loaded -eq $false }

$Mounted | Foreach-Object {
  Write-LogEntry "Removing registry items for $($_.LocalPath)"
  Remove-NRRegistryItems -SID "$($_.SID)"
}

$Unmounted | ForEach-Object {
  $Hive = "$($_.LocalPath)NTUSER.DAT"
  if (Test-Path $Hive) {      
    Write-LogEntry "Loading hive and removing Ninja Remote registry items for $($_.LocalPath)..."

    REG LOAD HKU$($_.SID) $Hive 2>&1>$null

    Remove-NRRegistryItems -SID "$($_.SID)"
        
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
          
    REG UNLOAD HKU$($_.SID) 2>&1>$null
  } 
}

$NRPrinter = Get-Printer | Where-Object { $_.Name -eq 'NinjaRemote' }

if ($NRPrinter) {
  Write-LogEntry 'Removing Ninja Remote printer...'
  Remove-Printer -InputObject $NRPrinter
}

$NRPrintDriverPath = "$env:SystemDriveUsersPublicDocumentsNrSpoolNrPdfPrint"
if (Test-Path $NRPrintDriverPath) {
  Write-LogEntry 'Removing Ninja Remote printer driver...'
  Remove-Item $NRPrintDriverPath -Force
}

Write-LogEntry 'Removal of Ninja Remote complete.'
##End Ninja Remote Removal##

if ($MissingPNs) {
  Write-LogEntry '############################# !!! WARNING !!! ####################################'
  Write-LogEntry 'Some registry keys are missing the Product Name.'
  Write-LogEntry 'This could be an indicator of a corrupt Ninja install key.'
  Write-LogEntry 'If you are still unable to install the NinjaOne Agent after running this script...'
  Write-LogEntry 'Please make a backup of the following keys and then remove them from the registry:'
  Write-LogEntry ( $MissingPNs | Out-String )
  Write-LogEntry '##################################################################################'
}

Write-LogEntry 'Removal script completed. Please review if any errors displayed.'

FAQ

Próximos pasos