Comment automatiser la désinstallation d’une application sur Windows avec PowerShell ?

Dans le monde de l’informatique, la gestion des logiciels sur plusieurs machines est une tâche complexe et essentielle. L’un des défis les plus courants auxquels sont confrontés les administrateurs informatiques est la désinstallation des applications d’une manière efficace et standardisée.

La désinstallation manuelle, en particulier sur plusieurs terminaux, prend du temps et est également sujette à des erreurs. C’est là que les scripts PowerShell, comme celui dont nous allons parler, entrent en jeu.

Ce script particulier automatise la désinstallation d’une application à l’aide de UninstallString et d’arguments personnalisés, offrant ainsi une approche rationalisée de la gestion des suppressions de logiciels.

Nécessité d’un script de désinstallation automatisé

La désinstallation de logiciels, en particulier dans les grandes entreprises, n’est pas une tâche facile. Les professionnels de l’informatique et les fournisseurs de services gérés (MSP) ont souvent affaire à un ensemble varié d’applications installées sur diverses machines. Chaque application peut nécessiter des commandes de désinstallation différentes ou suivre des protocoles différents.

Le script que nous analysons est conçu pour gérer ces nuances, en ajoutant automatiquement les arguments nécessaires tels que /qn /norestart ou /S, qui sont essentiels pour une désinstallation silencieuse et sans redémarrage. Cette automatisation est essentielle pour maintenir la cohérence et l’efficacité des environnements informatiques à grande échelle.

Le script :

#Requires -Version 5.1

<#
.SYNOPSIS
    Uninstall an application using the UninstallString and custom arguments. This script will auto-add /qn /norestart or /S arguments.

    This script will only uninstall apps that follow typical uninstall patterns such as msiexec /X{GUID} /qn /norestart.
.DESCRIPTION
    Uninstall an application using the UninstallString and custom arguments. This script will auto-add /qn /norestart or /S arguments.

    This script will only uninstall apps that follow typical uninstall patterns such as msiexec /X{GUID} /qn /norestart.
.EXAMPLE
    -Name "VLC media Player"
    
    Beginning uninstall of VLC media player using MsiExec.exe /X{9675011C-2395-4AD7-B1CC-92910F991F58} /qn /norestart...
    Exit Code for VLC media player: 0
    Successfully uninstalled your requested apps!

PARAMETER: -Name "ReplaceMeWithNameOfApp"
    Exact name of the application to uninstall, separated by commas. E.g., 'VLC media player, Everything 1.4.1.1024 (x64)'.

PARAMETER: -Arguments "/SILENT, /NOREBOOT"
    Additional arguments to use when uninstalling the app, separated by commas. E.g., '/SILENT, /NOREBOOT'.

PARAMETER: -Reboot
    Schedules a reboot for 1 minute after the uninstall process succeeds.

PARAMETER: -Timeout "ReplaceMeWithTheNumberOfMinutesToWait"
    Specify the amount of time in minutes to wait for the uninstall process to complete. 
    If the process exceeds this time, the script and uninstall process will be terminated.

.NOTES
    Minimum OS Architecture Supported: Windows 10, Windows Server 2016
    Release Notes: Initial Release
.COMPONENT
    Misc
#>

[CmdletBinding()]
param (
    [Parameter()]
    [String]$Name,
    [Parameter()]
    [String]$Arguments,
    [Parameter()]
    [switch]$Reboot = [System.Convert]::ToBoolean($env:reboot),
    [Parameter()]
    [int]$Timeout = 10
)

begin {
    # Replace parameters with dynamic script variables
    if ($env:nameOfAppToUninstall -and $env:nameOfAppToUninstall -notlike "null") { $Name = $env:nameOfAppToUninstall }
    if ($env:arguments -and $env:arguments -notlike "null") { $Arguments = $env:arguments }
    if ($env:timeoutInMinutes -and $env:timeoutInMinutes -notlike "null") { $Timeout = $env:timeoutInMinutes }

    # Check if application name is provided
    if (-not $Name) {
        Write-Host -Object "[Error] No name given, please enter in the name of an app to uninstall!"
        exit 1
    }

    # Check if timeout is provided
    if (-not $Timeout) {
        Write-Host -Object "[Error] No timeout given!"
        Write-Host -Object "[Error] Please enter in a timeout that's greater than or equal to 1 minute or less than or equal to 60 minutes."
        exit 1
    }

    # Validate the timeout is within the acceptable range
    if ($Timeout -lt 1 -or $Timeout -gt 60) {
        Write-Host -Object "[Error] An invalid timeout was given of $Timeout minutes."
        Write-Host -Object "[Error] Please enter in a timeout that's greater than or equal to 1 minute or less than or equal to 60 minutes."
        exit 1
    }

    # Create a list to hold application names after splitting
    $AppNames = New-Object System.Collections.Generic.List[String]
    $Name -split ',' | ForEach-Object {
        $AppNames.Add($_.Trim())
    }

    # Function to check if the script is run with elevated permissions
    function Test-IsElevated {
        $id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
        $p = New-Object System.Security.Principal.WindowsPrincipal($id)
        $p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
    }

    # Get all users registry hive locations
    function Get-UserHives {
        param (
            [Parameter()]
            [ValidateSet('AzureAD', 'DomainAndLocal', 'All')]
            [String]$Type = "All",
            [Parameter()]
            [String[]]$ExcludedUsers,
            [Parameter()]
            [switch]$IncludeDefault
        )
    
        # User account SID's follow a particular pattern depending on if they're Azure AD, a Domain account, or a local "workgroup" account.
        $Patterns = switch ($Type) {
            "AzureAD" { "S-1-12-1-(\d+-?){4}$" }
            "DomainAndLocal" { "S-1-5-21-(\d+-?){4}$" }
            "All" { "S-1-12-1-(\d+-?){4}$" ; "S-1-5-21-(\d+-?){4}$" } 
        }
    
        # We'll need the NTUSER.DAT file to load each user's registry hive. So we grab it if their account SID matches the above pattern. 
        $UserProfiles = Foreach ($Pattern in $Patterns) { 
            Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*" |
                Where-Object { $_.PSChildName -match $Pattern } | 
                Select-Object @{Name = "SID"; Expression = { $_.PSChildName } },
                @{Name = "UserName"; Expression = { "$($_.ProfileImagePath | Split-Path -Leaf)" } }, 
                @{Name = "UserHive"; Expression = { "$($_.ProfileImagePath)\NTuser.dat" } }, 
                @{Name = "Path"; Expression = { $_.ProfileImagePath } }
        }
    
        # There are some situations where grabbing the .Default user's info is needed.
        switch ($IncludeDefault) {
            $True {
                $DefaultProfile = "" | Select-Object UserName, SID, UserHive, Path
                $DefaultProfile.UserName = "Default"
                $DefaultProfile.SID = "DefaultProfile"
                $DefaultProfile.Userhive = "$env:SystemDrive\Users\Default\NTUSER.DAT"
                $DefaultProfile.Path = "C:\Users\Default"
    
                $DefaultProfile | Where-Object { $ExcludedUsers -notcontains $_.UserName }
            }
        }
    
        $UserProfiles | Where-Object { $ExcludedUsers -notcontains $_.UserName }
    }

    # Function to find the uninstallation key of an application
    function Find-UninstallKey {
        [CmdletBinding()]
        param (
            [Parameter(ValueFromPipeline = $True)]
            [String]$DisplayName,
            [Parameter()]
            [Switch]$UninstallString
        )
        process {
            $UninstallList = New-Object System.Collections.Generic.List[Object]

            # Search for uninstall key in 32-bit registry location
            $Result = Get-ChildItem "Registry::HKEY_USERS\*\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" | Get-ItemProperty | Where-Object { $_.DisplayName -match "$([regex]::Escape($DisplayName))" }
            if ($Result) { $UninstallList.Add($Result) }

            # Search for uninstall key in 32-bit user locations
            $Result = Get-ChildItem HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Get-ItemProperty | Where-Object { $_.DisplayName -match "$([regex]::Escape($DisplayName))" }
            if ($Result) { $UninstallList.Add($Result) }

            # Search for uninstall key in 64-bit registry location
            $Result = Get-ChildItem HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Get-ItemProperty | Where-Object { $_.DisplayName -match "$([regex]::Escape($DisplayName))" }
            if ($Result) { $UninstallList.Add($Result) }

            # Search for uninstall key in 64-bit user locations
            $Result = Get-ChildItem "Registry::HKEY_USERS\*\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" | Get-ItemProperty | Where-Object { $_.DisplayName -match "$([regex]::Escape($DisplayName))" }
            if ($Result) { $UninstallList.Add($Result) }
    
            # Optionally return the DisplayName and UninstallString
            if ($UninstallString) {
                $UninstallList | ForEach-Object { $_ | Select-Object DisplayName, UninstallString -ErrorAction SilentlyContinue }
            }
            else {
                $UninstallList
            }
        }
    }

    # Initialize the exit code variable
    $ExitCode = 0
}
process {
    # Check for administrative privileges
    if (-not (Test-IsElevated)) {
        Write-Host -Object "[Error] Access Denied. Please run with Administrator privileges."
        exit 1
    }

    # Load unloaded profiles
    $UserProfiles = Get-UserHives -Type "All"
    $ProfileWasLoaded = New-Object System.Collections.Generic.List[string]

    # Loop through each profile on the machine.
    Foreach ($UserProfile in $UserProfiles) {
        # Load user's NTUSER.DAT if it's not already loaded.
        If ((Test-Path Registry::HKEY_USERS\$($UserProfile.SID)) -eq $false) {
            Start-Process -FilePath "cmd.exe" -ArgumentList "/C reg.exe LOAD HKU\$($UserProfile.SID) `"$($UserProfile.UserHive)`"" -Wait -WindowStyle Hidden
            $ProfileWasLoaded.Add("$($UserProfile.SID)")
        }
    }

    # Retrieve similar applications based on names provided
    $SimilarAppsToName = $AppNames | ForEach-Object { Find-UninstallKey -DisplayName $_ -UninstallString }
    if (-not $SimilarAppsToName) {
        Write-Host "[Error] The requested app(s) was not found and none were found that are similar!"
        exit 1
    }

    # Unload all hives that were loaded for this script.
    ForEach ($UserHive in $ProfileWasLoaded) {
        If ($ProfileWasLoaded -eq $false) {
            [gc]::Collect()
            Start-Sleep 1
            Start-Process -FilePath "cmd.exe" -ArgumentList "/C reg.exe UNLOAD HKU\$($UserHive)" -Wait -WindowStyle Hidden | Out-Null
        }
    }

    # Create a list to store apps that are confirmed for uninstallation
    $AppsToUninstall = New-Object System.Collections.Generic.List[Object]
    $SimilarAppsToName | ForEach-Object {
        foreach ($AppName in $AppNames) {
            if ($AppName -eq $_.DisplayName) {
                # A matching app has been found
                $ExactMatch = $True
    
                if ($_.UninstallString) {
                    # Uninstall string is available
                    $UninstallStringFound = $True
                    # Add app to uninstall list
                    $AppsToUninstall.Add($_)
                }
            }
        }
    }

    # Check if any exact matches were found
    if (-not $ExactMatch) {
        Write-Host "[Error] Your requested apps were not found. Please see the below list and try again."
        $SimilarAppsToName | Format-Table DisplayName | Out-String | Write-Host
        exit 1
    }

    # Check if uninstall strings were found for the apps
    if (-not $UninstallStringFound) {
        Write-Host "[Error] No uninstall string found for any of your requested apps!"
        exit 1
    }

    # Check if there are apps without uninstall strings or not found at all
    $AppNames | ForEach-Object {
        if ($AppsToUninstall.DisplayName -notcontains $_) {
            Write-Host "[Error] Either the uninstall string was not present or the app itself was not found for one of your selected apps! See the below list of similar apps and try again."
            $SimilarAppsToName | Format-Table DisplayName | Out-String | Write-Host
            $ExitCode = 1
        }
    }

    # Convert timeout from minutes to seconds
    $TimeoutInSeconds = $Timeout * 60
    $StartTime = Get-Date

    # Process each app to uninstall
    $AppsToUninstall | ForEach-Object {
        $AdditionalArguments = New-Object System.Collections.Generic.List[String]

        # If the uninstall string contains msiexec that's what our executable will be.
        if($_.UninstallString -match "msiexec"){
            $Executable = "msiexec.exe"
        }

        # If it contains a filepath we'll use that as our executable.
        if($_.UninstallString -notmatch "msiexec" -and $_.UninstallString -match '[a-zA-Z]:\\(?:[^\\\/:*?"<>|\r\n]+\\)*[^\\\/:*?"<>|\r\n]*'){
            $Executable = $Matches[0]
        }

        # Confirm we have an executable.
        if(-not $Executable){
            Write-Host -Object "[Error] Unable to find uninstall executable!"
            exit 1
        }

        # Split uninstall string into executable and possible arguments
        $PossibleArguments = $_.UninstallString -split ' ' | ForEach-Object { $_.Trim() } | Where-Object { $_ -match "^/"}

        # Decide executable and additional arguments based on uninstall string analysis
        $i = 0
        foreach ($PossibleArgument in $PossibleArguments) {
            if (-not ($PossibleArgument -match "^/I{") -and $PossibleArgument) {
                $AdditionalArguments.Add($PossibleArgument)
            }

            if ($PossibleArgument -match "^/I{") {
                $AdditionalArguments.Add("$($PossibleArgument -replace '/I', '/X')")
            }

            $i++
        }

        # Add custom arguments from the user
        if ($Arguments) {
            $Arguments.Split(',') | ForEach-Object {
                $AdditionalArguments.Add($_.Trim())
            }
        }

        # Add the usual silent uninstall arguments if not present
        if($Executable -match "Msiexec"){
            if($AdditionalArguments -notcontains "/qn"){
                $AdditionalArguments.Add("/qn")
            }

            if($AdditionalArguments -notcontains "/norestart"){
                $AdditionalArguments.Add("/norestart")
            }
        }elseif($Executable -match "\.exe"){
            if($AdditionalArguments -notcontains "/S"){
                $AdditionalArguments.Add("/S")
            }

            if($AdditionalArguments -notcontains "/norestart"){
                $AdditionalArguments.Add("/norestart")
            }
        }

        # Verify that executable for uninstallation is found
        if (-not $Executable) {
            Write-Host "[Error] Could not find the executable from the uninstall string!"
            exit 1
        }

        # Start the uninstallation process
        Write-Host -Object "Beginning uninstall of $($_.DisplayName) using $Executable $AdditionalArguments..."
        try{
            if ($AdditionalArguments) {
                $Uninstall = Start-Process $Executable -ArgumentList $AdditionalArguments -NoNewWindow -PassThru
            }
            else {
                $Uninstall = Start-Process $Executable -NoNewWindow -PassThru
            }
        }catch{
            Write-Host "[Error] $($_.Exception.Message)"
            return
        }

        # Calculate the remaining time for the uninstall process and enforce timeout
        $TimeElapsed = (Get-Date) - $StartTime
        $RemainingTime = $TimeoutInSeconds - $TimeElapsed.TotalSeconds

        # Wait for the uninstall process to complete within the remaining time
        try {
            $Uninstall | Wait-Process -Timeout $RemainingTime -ErrorAction Stop
        }
        catch {
            Write-Host -Object "[Alert] The uninstall process for $($_.DisplayName) has exceeded the specified timeout of $Timeout minutes."
            Write-Host -Object "[Alert] The script is now terminating."
            $Uninstall | Stop-Process -Force
            $ExitCode = 1
        }

        # Check and report the exit code of the uninstallation process
        Write-Host -Object "Exit code for $($_.DisplayName): $($Uninstall.ExitCode)"
        if ($Uninstall.ExitCode -ne 0) {
            Write-Host -Object "[Error] Exit code does not indicate success!"
            $ExitCode = 1
        }
    }

    # Pause for 30 seconds before final checks
    Start-Sleep -Seconds 30

    $UserProfiles = Get-UserHives -Type "All"
    $ProfileWasLoaded = New-Object System.Collections.Generic.List[string]

    # Loop through each profile on the machine.
    Foreach ($UserProfile in $UserProfiles) {
        # Load user's NTUSER.DAT if it's not already loaded.
        If ((Test-Path Registry::HKEY_USERS\$($UserProfile.SID)) -eq $false) {
            Start-Process -FilePath "cmd.exe" -ArgumentList "/C reg.exe LOAD HKU\$($UserProfile.SID) `"$($UserProfile.UserHive)`"" -Wait -WindowStyle Hidden
            $ProfileWasLoaded.Add("$($UserProfile.SID)")
        }
    }

    # Re-check for any remaining apps to confirm they were uninstalled
    $SimilarAppsToName = $AppNames | ForEach-Object { Find-UninstallKey -DisplayName $_ }
    $SimilarAppsToName | ForEach-Object {
        foreach ($AppName in $AppNames) {
            if ($_.DisplayName -eq $AppName) {
                Write-Host -Object "[Error] Failed to uninstall $($_.DisplayName)."
                $UninstallFailure = $True
                $ExitCode = 1
            }
        }
    }

    # Unload all hives that were loaded for this script.
    ForEach ($UserHive in $ProfileWasLoaded) {
        If ($ProfileWasLoaded -eq $false) {
            [gc]::Collect()
            Start-Sleep 1
            Start-Process -FilePath "cmd.exe" -ArgumentList "/C reg.exe UNLOAD HKU\$($UserHive)" -Wait -WindowStyle Hidden | Out-Null
        }
    }

    # Confirm successful uninstallation if no failures detected
    if (-not $UninstallFailure) {
        Write-Host "Successfully uninstalled your requested apps!"
    }

    # Handle reboot if requested and there were no uninstall failures
    if ($Reboot -and -not $UninstallFailure) {
        Write-Host -Object "[Alert] a reboot was requested. Scheduling restart for 60 seconds from now..."
        Start-Process shutdown.exe -ArgumentList "/r /t 60" -Wait -NoNewWindow
    }

    # Exit script with the final exit code
    exit $ExitCode
}
end {
    
    
    
}

 

Comment fonctionne le script

Ce script est conçu pour désinstaller des applications sur la base de leur nom et gère une variété de scénarios qui peuvent survenir au cours du processus de désinstallation. Vous trouverez ci-dessous une description étape par étape du fonctionnement du script :

1. Définition des paramètres et traitement des entrées :

  • Le script commence par définir plusieurs paramètres, tels que -Name pour le nom de l’application, -Arguments pour les arguments de désinstallation supplémentaires, -Reboot pour planifier un redémarrage et -Timeout pour spécifier la durée pendant laquelle le script doit attendre le processus de désinstallation.
  • Le script vérifie ensuite si ces paramètres sont fournis et les valide, en s’assurant qu’ils répondent à des critères spécifiques, par exemple que la valeur du délai d’attente est comprise entre 1 et 60 minutes.

2. Gestion des profils et des ruches d’utilisateurs :

  • Il comprend une fonction permettant de charger et de gérer les profils d’utilisateur et les ruches de registre, nécessaires pour accéder aux chaînes de désinstallation de chaque application. Ceci est crucial car la désinstallation d’une application nécessite souvent d’accéder au registre pour localiser le chemin de désinstallation correct.

3. Identification des applications et récupération des clés de désinstallation :

  • Le script utilise une fonction appelée Find-UninstallKey pour rechercher dans le registre la clé de désinstallation associée au nom de l’application fourni. Cette opération s’effectue à différents endroits du registre, à la fois en 32 bits et en 64 bits, afin d’assurer une couverture complète.

4. Processus de désinstallation :

  • Une fois la chaîne de désinstallation identifiée, le script la traite pour en extraire le chemin d’accès à l’exécutable et les arguments nécessaires à la désinstallation.
  • Il garantit que les arguments de désinstallation silencieuse nécessaires tels que /qn, /norestart ou /S sont ajoutés s’ils ne sont pas déjà présents. Cela garantit que la désinstallation est effectuée sans interaction de l’utilisateur et sans forcer le redémarrage du système, sauf indication contraire.

5. Traitement des erreurs et contrôles finaux :

  • Le script comprend une gestion robuste des erreurs, garantissant que si quelque chose se passe mal pendant la désinstallation, l’administrateur en est informé et le script se termine avec un code d’erreur approprié.
  • Après la désinstallation, le script vérifie à nouveau que l’application a bien été supprimée, en s’assurant qu’aucun composant résiduel n’est laissé sur place.

Application dans le monde réel: Une étude de cas

Imaginons un scénario dans lequel un administrateur informatique doit désinstaller une version obsolète de VLC Media Player sur 200 ordinateurs d’une entreprise. Le faire manuellement prendrait énormément de temps. Au lieu de cela, l’administrateur pourrait déployer ce script PowerShell sur toutes les machines, en spécifiant « VLC Media Player » comme nom d’application.

Le script trouverait automatiquement la chaîne de désinstallation appropriée, exécuterait la désinstallation en silence et programmerait même un redémarrage si nécessaire. L’ensemble du processus, qui aurait pu prendre des jours, est achevé en quelques minutes.

Comparaison avec d’autres méthodes

Traditionnellement, les administrateurs peuvent utiliser le panneau de configuration ou un outil de désinstallation tiers pour supprimer des applications. Toutefois, ces méthodes nécessitent une intervention manuelle, ne sont pas extensibles et manquent souvent de souplesse pour ajouter des arguments personnalisés ou gérer efficacement les désinstallations silencieuses.

Ce script, en revanche, offre une approche hautement automatisée et personnalisable, permettant aux professionnels de l’informatique de gérer les désinstallations sur plusieurs machines de manière efficace et avec un minimum d’intervention manuelle.

Questions fréquemment posées

  1. Que se passe-t-il si le nom de l’application n’est pas trouvé ? Si le script ne trouve pas d’application avec le nom exact fourni, il recherche des noms similaires et fournit une liste de correspondances possibles. Cela permet à l’administrateur d’ajuster l’entrée et de réessayer.
  2. Le script peut-il gérer plusieurs applications à la fois ? Oui, le paramètre -Name peut accepter une liste d’applications séparées par des virgules, ce qui permet au script de désinstaller plusieurs applications en une seule fois.
  3. Que se passe-t-il si le processus de désinstallation dépasse le délai d’attente ? Le script mettra fin au processus de désinstallation et sortira avec un code d’erreur, garantissant ainsi qu’aucun processus ne s’exécute indéfiniment.

Implications pour la sécurité et la gestion des technologies de l’information

L’automatisation du processus de désinstallation à l’aide de scripts de ce type a des implications importantes pour la sécurité et la gestion informatiques. En s’assurant que les logiciels obsolètes ou vulnérables sont supprimés rapidement et de manière cohérente sur toutes les machines, les entreprises peuvent réduire le risque de failles de sécurité. En outre, l’automatisation réduit les erreurs humaines, garantissant qu’aucune application n’est désinstallée par inadvertance.

Meilleures pratiques pour l’utilisation de ce script

  • Toujours tester dans un environnement contrôlé : Avant de déployer le script sur plusieurs machines, testez-le dans un environnement contrôlé pour vous assurer qu’il fonctionne comme prévu.
  • Conserver les journaux : Conserver les journaux des processus de désinstallation à des fins d’audit et de dépannage.
  • Sauvegarde avant désinstallation : Assurez-vous que les données importantes sont sauvegardées avant d’exécuter les scripts de désinstallation, en particulier pour les applications susceptibles de stocker des données localement.
  • Mettez régulièrement le script à jour : Au fur et à mesure de la sortie de nouvelles applications et mises à jour, mettez le script à jour pour gérer les nouvelles chaînes et méthodes de désinstallation.

Conclusion

Les scripts PowerShell tels que celui présenté ici sont des outils indispensables pour les professionnels de l’informatique qui gèrent de grands réseaux. En automatisant la désinstallation des applications, ils gagnent du temps, réduisent les erreurs et renforcent la sécurité. NinjaOne peut compléter ces scripts avec ses outils de gestion informatique complets, fournissant des couches supplémentaires d’automatisation, de surveillance et de contrôle, garantissant que votre infrastructure informatique reste robuste, sécurisée et à jour.

Pour aller plus loin

Créer une équipe informatique efficace et performante nécessite une solution centralisée qui soit l’outil principal pour fournir vos services. NinjaOne permet aux équipes informatiques de surveiller, gérer, sécuriser et prendre en charge tous les appareils, où qu’ils soient, sans avoir besoin d’une infrastructure complexe sur site.

Pour en savoir plus sur NinjaOne Endpoint Management, participez à une visite guidée ou commencez votre essai gratuit de la plateforme NinjaOne.

Catégories :

Vous pourriez aussi aimer

×

Voir NinjaOne en action !

En soumettant ce formulaire, j'accepte la politique de confidentialité de NinjaOne.

Termes et conditions NinjaOne

En cliquant sur le bouton « J’accepte » ci-dessous, vous indiquez que vous acceptez les termes juridiques suivants ainsi que nos conditions d’utilisation:

  • Droits de propriété: NinjaOne possède et continuera de posséder tous les droits, titres et intérêts relatifs au script (y compris les droits d’auteur). NinjaOne vous accorde une licence limitée pour l’utilisation du script conformément à ces conditions légales.
  • Limitation de l’utilisation: Les scripts ne peuvent être utilisés qu’à des fins personnelles ou professionnelles internes légitimes et ne peuvent être partagés avec d’autres entités.
  • Interdiction de publication: Vous n’êtes en aucun cas autorisé à publier le script dans une bibliothèque de scripts appartenant à, ou sous le contrôle d’un autre fournisseur de logiciels.
  • Clause de non-responsabilité: Le texte est fourni « tel quel » et « tel que disponible », sans garantie d’aucune sorte. NinjaOne ne promet ni ne garantit que le script sera exempt de défauts ou qu’il répondra à vos besoins ou attentes particulières.
  • Acceptation des risques: L’utilisation du script est sous votre propre responsabilité. Vous reconnaissez qu’il existe certains risques inhérents à l’utilisation du script, et vous comprenez et assumez chacun de ces risques.
  • Renonciation et exonération de responsabilité: Vous ne tiendrez pas NinjaOne pour responsable des conséquences négatives ou involontaires résultant de votre utilisation du script, et vous renoncez à tout droit ou recours légal ou équitable que vous pourriez avoir contre NinjaOne en rapport avec votre utilisation du script.
  • EULA: Si vous êtes un client de NinjaOne, votre utilisation du script est soumise au contrat de licence d’utilisateur final qui vous est applicable (End User License Agreement (EULA)).