Automatiser le déploiement de ConnectWise ScreenConnect avec PowerShell

Principaux points à retenir

  • Efficacité automatisée: Le script PowerShell pour l’installation de ConnectWise ScreenConnect automatise et simplifie le processus de déploiement, améliorant ainsi l’efficacité opérationnelle.
  • Installation personnalisable: Il prend en charge la création d’URL dynamiques pour des installations personnalisées basées sur des paramètres tels que le nom de l’organisation, le lieu et le type d’appareil.
  • Grande applicabilité: Idéal pour les MSP et les professionnels de l’informatique qui gèrent plusieurs appareils sur différents sites.
  • Fonctionnalités avancées: Il offre des fonctionnalités telles que la vérification de l’état de l’installation et la journalisation des erreurs, surpassant ainsi les méthodes manuelles traditionnelles ou les scripts batch.
  • Compatibilité et limites: Fonctionne au mieux avec Windows 8 et Server 2012, avec des limitations potentielles sur les versions plus anciennes.
  • Questions relatives à la sécurité : Les utilisateurs doivent examiner et comprendre le script pour garantir la sécurité, en particulier dans les environnements MSP.
  • Intégration de NinjaOne: Ce script s’aligne bien avec l’approche de gestion informatique unifiée de NinjaOne, offrant une solution fiable pour les professionnels de l’informatique.
  • Adaptation continue: Des mises à jour régulières et des modifications du script peuvent être nécessaires pour s’aligner sur les dernières versions de ConnectWise ScreenConnect.

Dans le monde dynamique de l’informatique, l’efficacité et l’automatisation sont essentielles pour conserver un avantage concurrentiel. Les scripts sont devenus un outil essentiel, permettant aux professionnels de l’informatique de rationaliser des processus complexes. Le script PowerShell pour l’installation de ConnectWise ScreenConnect en est un exemple, offrant une solution sophistiquée pour la gestion et l’assistance à distance.

Contexte

ConnectWise ScreenConnect, un outil d’assistance et de gestion à distance très populaire, est largement utilisé par les professionnels de l’informatique et les fournisseurs de services gérés (MSP). Sa capacité à faciliter l’accès à distance aux appareils est essentielle dans les environnements de travail, étant de plus en plus décentralisés de nos jours. Ce script PowerShell simplifie le processus de déploiement de ScreenConnect, en répondant à un challenge classique auquel sont confrontées les équipes informatiques : l’installation efficace, évolutive et automatisée de logiciels.

Le script PowerShell :

<#
.SYNOPSIS
Download and Install ConnectWise ScreenConnect from the domain used for ScreenConnect. Supports automatic customization of the device type, location and other ScreenConnect Fields.

.DESCRIPTION
Download and Install ConnectWise ScreenConnect from the domain used for ScreenConnect. Supports automatic customization of the device type, location and other ScreenConnect Fields.

.EXAMPLE
-ScreenConnectDomain "testscreen.screenconnect.com" -UseOrgName -UseLocation -UseDeviceType

Installer Log File location will be: C:WindowsTEMPtmp9A50.tmp
ScreenConnect Client (abcd123456) is not installed and will be installed.
Attempting to build from domain...
URL Built: https://testscreen.screenconnect.com/Bin/Test Company.ClientSetup.msi?e=Access&y=Guest&c=Kyle - OOB&c=Main Office&c=&c=Workstation&c=&c=&c=&c=
URL Given, Downloading the file...
Download Attempt 1
Exit Code: 0
Success

PRESET PARAMETER: -ScreenConnectDomain "your.domain.com"
Your ScreenConnect instance's domain name. The script will use this to construct a download URL from scratch with the options you selected.

PRESET PARAMETER: -UseOrgName
Modifies your URL to use the organization name in the Company Name Field in ScreenConnect.

PRESET PARAMETER: -UseLocation
Modifies your URL to use the Location Name in the Site Name Field in ScreenConnect.

PRESET PARAMETER: -UseDeviceType
Modifies your URL to include the type of device in ScreenConnect. (Server, Workstation, Laptop etc.)

PRESET PARAMETER: -Department "Your Department Name Here"
Modifies your URL to include your desired department name in ScreenConnect.

PRESET PARAMETER: -SkipSleep
By default the script sleeps for a random interval between 3 and 60 seconds prior to downloading the file. This parameter skips the sleep.

PRESET PARAMETER: -Force
If ScreenConnect is already installed attempt to install it anyways.

.NOTES
Minimum OS Architecture Supported: Windows 8, Windows Server 2012
Can work on lower versions of Windows, provided that the OS/.NET is able to download the file. PowerShell 2.0 might face issues due to its lack of TLS support in .NET 2.0.

Adapted from Chris White's script: https://ninjarmm.zendesk.com/hc/en-us/community/posts/7549797399821-Connectwise-Control-Installer

Release Notes: Initial Release
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 (
    # Change the defaults if you don't wish to use parameters when running this script
    [Parameter()]
    [String]$MSI = "ClientSetup.msi",
    [Parameter()]
    [String]$DestinationFolder = "$env:TEMP",
    [Parameter()]
    [String]$ScreenConnectDomain,
    [Parameter()]
    [String]$InstanceID,
    [Parameter()]
    [Switch]$UseOrgName = [System.Convert]::ToBoolean($env:useNinjaOrganizationName),
    [Parameter()]
    [Switch]$UseLocation = [System.Convert]::ToBoolean($env:useNinjaLocationName),
    [Parameter()]
    [Switch]$UseDeviceType = [System.Convert]::ToBoolean($env:addDeviceType),
    [Parameter()]
    [String]$Department,
    [Parameter()]
    [Switch]$SkipSleep = [System.Convert]::ToBoolean($env:skipSleep),
    [Parameter()]
    [Switch]$Force = [System.Convert]::ToBoolean($env:force)
)
begin {
    # If Script Form is used replace the parameters with what was filled in.
    if ($env:screenconnectDomainName -and $env:screenconnectDomainName -notlike "null") { $ScreenConnectDomain = $env:screenconnectDomainName }
    if ($env:department -and $env:department -notlike "null") { $Department = $env:department }

    # Some means of installing the file is required.
    if (-not ($ScreenConnectDomain)) { Write-Error "A domain is required to install control."; exit 1 }

    if ($ScreenConnectDomain -match "^http(s)?://") {
        Write-Warning "http(s):// is not part of the domain name. Removing http(s):// from your input...."
        $ScreenConnectDomain = $ScreenConnectDomain -replace "^http(s)?://"
        Write-Warning "New Domain Name $ScreenConnectDomain."
    }

    if ($ScreenConnectDomain -match "^C:/") {
        Write-Error "It looks like you entered in a file path by mistake. We actually need the domain name used to reach your ScreenConnect website for example 'companyname.screenconnect.com'"
        exit 1
    }
    
    #### Helper functions used throughout the script ####

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

    # Extract the ProductName from the msi
    function Get-ControlPanelName {
        [CmdletBinding()]
        param (
            [Parameter()]
            [string]$msiPath
        )
        $windowsInstaller = New-Object -ComObject WindowsInstaller.Installer
        $database = $windowsInstaller.GetType().InvokeMember("OpenDatabase", "InvokeMethod", $null, $windowsInstaller, @($msiPath, 0))
        $query = "SELECT `Value` FROM `Property` WHERE `Property` = 'ProductName'"

        $view = $database.GetType().InvokeMember("OpenView", "InvokeMethod", $null, $database, $query)
        $view.GetType().InvokeMember("Execute", "InvokeMethod", $null, $view, $null)

        $record = $view.GetType().InvokeMember("Fetch", "InvokeMethod", $null, $view, $null)
        if ($record) {
            return $record.GetType().InvokeMember("StringData", "GetProperty", $null, $record, 1)
        }

        [System.Runtime.InteropServices.Marshal]::ReleaseComObject($windowsInstaller) | Out-Null
        [System.GC]::Collect()
    }

    # Is it a Server or Desktop OS?
    function Get-ProductType {
        if ($PSVersionTable.PSVersion.Major -ge 5) {
            $OS = Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object ProductType -ExpandProperty ProductType
        }
        else {
            $OS = Get-WmiObject -Class Win32_OperatingSystem | Select-Object ProductType -ExpandProperty ProductType
        }
        
        return $OS
    }

    # Check the Chassis type to find out if it's a laptop or not.
    function Test-IsLaptop {
        if ($PSVersionTable.PSVersion.Major -ge 5) {
            $Chassis = Get-CimInstance -ClassName win32_systemenclosure | Select-Object ChassisTypes -ExpandProperty ChassisTypes
        }
        else {
            $Chassis = Get-WmiObject -Class win32_systemenclosure | Select-Object ChassisTypes -ExpandProperty ChassisTypes
        }

        switch ($Chassis) {
            9 { return $True }
            10 { return $True }
            14 { return $True }
            default { return $False }
        }
    }

    # Check's the two uninstall registry keys to see if the app is installed. Needs the name as it would appear in Control Panel.
    function Find-UninstallKey {
        [CmdletBinding()]
        param (
            [Parameter(ValueFromPipeline = $True)]
            [String]$DisplayName,
            [Parameter()]
            [Switch]$UninstallString
        )
        process {
            $UninstallList = New-Object System.Collections.Generic.List[Object]

            $Result = Get-ChildItem HKLM:SoftwareWow6432NodeMicrosoftWindowsCurrentVersionUninstall* | Get-ItemProperty | Where-Object { $_.DisplayName -like "*$DisplayName*" }
            if ($Result) { $UninstallList.Add($Result) }

            $Result = Get-ChildItem HKLM:SoftwareMicrosoftWindowsCurrentVersionUninstall* | Get-ItemProperty | Where-Object { $_.DisplayName -like "*$DisplayName*" }
            if ($Result) { $UninstallList.Add($Result) }

            # Programs don't always have an uninstall string listed here so to account for that I made this optional.
            if ($UninstallString) {
                $UninstallList | Select-Object -ExpandProperty UninstallString -ErrorAction SilentlyContinue
            }
            else {
                $UninstallList
            }
        }
    }

    # Handy download function
    function Invoke-Download {
        param(
            [Parameter()]
            [String]$URL,
            [Parameter()]
            [String]$Path,
            [Parameter()]
            [Switch]$SkipSleep
        )
        Write-Host "URL given; downloading the file..."

        $SupportedTLSversions = [enum]::GetValues('Net.SecurityProtocolType')
        if ( ($SupportedTLSversions -contains 'Tls13') -and ($SupportedTLSversions -contains 'Tls12') ) {
            [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol::Tls13 -bor [System.Net.SecurityProtocolType]::Tls12
        }
        elseif ( $SupportedTLSversions -contains 'Tls12' ) {
            [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
        }
        else {
            # Not everything requires TLS 1.2, but we'll try anyways.
            Write-Warning "TLS 1.2 and or TLS 1.3 isn't supported on this system. This download may fail!"
            if ($PSVersionTable.PSVersion.Major -lt 3) {
                Write-Warning "PowerShell 2 / .NET 2.0 doesn't support TLS 1.2."
            }
        }

        $i = 1
        While ($i -lt 4) {
            if (-not ($SkipSleep)) {
                $SleepTime = Get-Random -Minimum 3 -Maximum 30
                Start-Sleep -Seconds $SleepTime
            }

            Write-Host "Download Attempt $i"

            try {
                $WebClient = New-Object System.Net.WebClient
                $WebClient.DownloadFile($URL, $Path)
                $File = Test-Path -Path $Path -ErrorAction SilentlyContinue
            }
            catch {
                Write-Warning "An error has occurred while downloading!"
                Write-Warning $_.Exception.Message
            }

            if ($File) {
                $i = 4
            }
            else {
                $i++
            }
        }

        if (-not (Test-Path $Path)) {
            Write-Error "Failed to download file!"
            Exit 1
        }
    }

    # This will build our screenconnect download url if only given a domain name or if modification is needed to include the device type, location, org name etc.
    function Build-URL {
        param(
            [Parameter()]
            [String]$BaseURL,
            [Parameter()]
            [String]$Domain,
            [Parameter()]
            [String]$MSI,
            [Parameter()]
            [String]$Department,
            [Parameter()]
            [Switch]$UseOrgName,
            [Parameter()]
            [Switch]$UseLocation,
            [Parameter()]
            [Switch]$UseDeviceType
        )

        Write-Host "Attempting to build from domain..."
        $URL = "https://$Domain/Bin/$env:NINJA_COMPANY_NAME.ClientSetup.msi`?e=Access&y=Guest"

        if ($UseOrgName) { $URL = $URL + "&c=$env:NINJA_ORGANIZATION_NAME" }else { $URL = $URL + "&c=" }
        if ($UseLocation) { $URL = $URL + "&c=$env:NINJA_LOCATION_NAME" }else { $URL = $URL + "&c=" }
        if ($Department) { $URL = $URL + "&c=$Department" }else { $URL = $URL + "&c=" }
        if ($UseDeviceType) {
            switch (Get-ProductType) {
                1 { if (Test-IsLaptop) { $URL = $URL + "&c=Laptop&c=&c=&c=&c=" }else { $URL = $URL + "&c=Workstation&c=&c=&c=&c=" } }
                2 { $URL = $URL + "&c=Domain Controller&c=&c=&c=&c=" }
                3 { $URL = $URL + "&c=Server&c=&c=&c=&c=" }
            }
        }
        else {
            $URL = $URL + "&c=&c=&c=&c=&c="
        }

        Write-Host "URL Built: $URL"

        return $URL
    }

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

    if (-not (Test-Path $DestinationFolder -ErrorAction SilentlyContinue)) {
        Write-Host "Destination Folder does not exist! Creating directory..."
        New-Item $DestinationFolder -ItemType Directory
    }

    #Set the log file as a temporary file, it will be created in the temp folder of the context the script runs in (c:windowstemp or c:usersusernameappdatatemp)
    $InstallerLogFile = [IO.Path]::GetTempFileName()
    Write-Host "Installer Log File location will be: $InstallerLogFile"
}
process {
    # Arguments required to download the file
    $DownloadArgs = @{ Path = "$DestinationFolder$MSI" }
    if ($SkipSleep) { $DownloadArgs["SkipSleep"] = $True }

    # Build the arguments needed to create the url
    $ArgumentList = @{ Domain = $ScreenConnectDomain }
    if ($UseOrgName) { $ArgumentList["UseOrgName"] = $True }
    if ($UseLocation) { $ArgumentList["UseLocation"] = $True }
    if ($UseDeviceType) { $ArgumentList["UseDeviceType"] = $True }
    if ($Department) { $ArgumentList["Department"] = $Department }

    # Build the URL and get it ready for download
    $DownloadArgs["URL"] = Build-Url @ArgumentList

    # Download the installer
    Invoke-Download @DownloadArgs

    # Grab the installer file
    $InstallerFile = Join-Path -Path $DestinationFolder -ChildPath $MSI -Resolve

    # Define the name of the software we are searching for and look for it in both the 64 bit and 32 bit registry nodes
    $ProductName = "$(Get-ControlPanelName -msiPath $InstallerFile)".Trim()
    if (-not $ProductName) { 
        Write-Error "Failed to fetch the product name from the MSI at path '$InstallerFile'. Ensure the MSI path is correct and the MSI contains the necessary product information."
        exit 1
    }

    # If already installed, exit.
    $IsInstalled = Find-UninstallKey -DisplayName $ProductName
    if ($IsInstalled -and -not ($Force)) {
        Write-Host "$ProductName is already installed; exiting..."
        exit 0
    }

    # ScreenConnect install arguments
    $Arguments = "/c msiexec /i ""$InstallerFile"" /qn /norestart /l ""$InstallerLogFile"" REBOOT=REALLYSUPPRESS"

    # Install and let the user know the exit code
    $Process = Start-Process -Wait cmd -ArgumentList $Arguments -PassThru
    Write-Host "Exit Code: $($Process.ExitCode)";

    # Interpret the exit code
    switch ($Process.ExitCode) {
        0 { Write-Host "Success" }
        3010 { Write-Host "Success. Reboot required to complete installation" }
        1641 { Write-Host "Success. Installer has initiated a reboot" }
        default {
            Write-Error "Exit code does not indicate success"
            Get-Content $InstallerLogFile -ErrorAction SilentlyContinue | Select-Object -Last 50 | Write-Host
        }
    }

    exit $Process.ExitCode
    
}
end {
    
    
    
}

 

Accédez à plus de 700 scripts dans le Dojo NinjaOne

Obtenir l’accès

Description détaillée

Le script fonctionne de manière simple :

  • Initialisation des paramètres : Il commence par définir des paramètres tels que le nom du fichier MSI, le dossier de destination et le domaine ScreenConnect.
  • Vérifications avant exécution : Il vérifie les privilèges d’administrateur et l’existence du dossier de destination.
  • Création d’URL dynamiques: Une caractéristique importante est sa capacité à créer dynamiquement une URL de téléchargement basée sur des paramètres tels que le nom de l’organisation, le lieu et le type d’appareil.
  • Processus de téléchargement: Le script télécharge ensuite le programme d’installation de ScreenConnect à partir de l’URL conçue.
  • Installation: Après le téléchargement, il vérifie si ScreenConnect est déjà installé. Si ce n’est pas le cas, ou si le paramètre “Force” est utilisé, l’installation se poursuit.
  • Enregistrement: Tout au long du processus, les journaux sont tenus à jour pour le dépannage.

Cas d’utilisation potentiels

Imaginez une entreprise MSP chargée de gérer l’infrastructure informatique de plusieurs sites clients. L’installation manuelle de ScreenConnect sur chaque appareil prendrait beaucoup de temps. Grâce à ce script, le MSP peut automatiser les installations, en personnalisant les paramètres tels que l’emplacement et le type d’appareil pour chaque client, ce qui permet de gagner du temps et de réduire les erreurs.

Comparaisons

Traditionnellement, l’installation d’un logiciel implique un téléchargement manuel et une configuration sur chaque appareil ou l’utilisation de scripts batch basiques, sans possibilité de personnalisation. Ce script PowerShell dépasse ces méthodes en offrant des fonctionnalités avancées telles que la construction d’URL dynamiques et la vérification de l’état de l’installation, ce qui permet des déploiements plus efficaces et sans erreur.

FAQ

Q : Le script est-il compatible avec toutes les versions de Windows ? 
R : Il prend en charge Windows 8 et Server 2012, bien que les versions plus anciennes puissent fonctionner avec certaines limitations.

Q : Peut-il gérer des installations à grande échelle ? 
R : Oui, il est conçu pour être évolutif et peut gérer des installations sur de nombreux appareils.

Q : L’utilisation de ce script est-elle sûre ? 
R : Le script est sécurisé, mais il faut toujours examiner et comprendre un script avant de l’exécuter dans votre environnement.

Implications

Bien que ce script simplifie considérablement le processus d’installation, les utilisateurs doivent être conscients des implications en matière de sécurité. Une utilisation ou une modification incorrecte peut entraîner des vulnérabilités, en particulier dans les environnements de MSP où une seule violation peut avoir un impact sur plusieurs clients.

Recommandations

  • Révision et test: Examinez et testez toujours soigneusement le script dans un environnement contrôlé.
  • Personnaliser avec soin: Modifiez les paramètres du script en fonction de vos besoins spécifiques.
  • Rester informé: Tenez-vous au courant des mises à jour de ConnectWise ScreenConnect et adaptez le script si nécessaire.

Conclusion

NinjaOne, qui met l’accent sur les opérations informatiques unifiées, complète ce type de script. Il offre une plateforme où ces scripts peuvent être intégrés et gérés efficacement, améliorant ainsi les capacités de gestion informatique des professionnels. Ce script PowerShell, ainsi que des outils tels que NinjaOne, démontrent que l’automatisation et les outils intelligents sont indispensables à la gestion moderne de l’informatique.

Pour aller plus loin

Pour créer une équipe informatique efficace et performante, il est essentiel d'avoir une solution centralisée qui joue le rôle de nœud principal pour 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 profitez d'un 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)).