Wichtigste Erkenntnisse
- Automatisierte Effizienz: Das PowerShell-Skript für die Installation von ConnectWise ScreenConnect automatisiert und vereinfacht den Bereitstellungsprozess und steigert die betriebliche Effizienz.
- Anpassbare Installation: Es unterstützt die dynamische URL-Erstellung für benutzerdefinierte Installationen auf der Grundlage von Parametern wie Organisationsname, Standort und Gerätetyp.
- Breite Anwendbarkeit: Ideal für MSPs und IT-Expert:innen, die mehrere Geräte an verschiedenen Standorten verwalten.
- Erweiterte Funktionen: Bietet Funktionen wie Überprüfung des Installationsstatus und Fehlerprotokollierung und übertrifft damit herkömmliche manuelle oder Batch-Skript-Methoden.
- Kompatibilität und Beschränkungen: Funktioniert am besten mit Windows 8, Server 2012 und neueren Versionen, mit möglichen Einschränkungen bei älteren Versionen.
- Sicherheitserwägungen: Benutzer:innen müssen das Skript überprüfen und verstehen, um die Sicherheit zu gewährleisten, insbesondere in MSP-Umgebungen.
- NinjaOne-Integration: Dieses Skript passt gut zu NinjaOnes einheitlichem IT-Management-Ansatz und bietet eine zentralisierte Lösung für IT-Expert:innen.
- Kontinuierliche Anpassung: Regelmäßige Updates und Änderungen des Skripts können erforderlich sein, um es an die neuesten Versionen von ConnectWise ScreenConnect anzupassen.
In der dynamischen Welt der IT sind Effizienz und Automatisierung der Schlüssel zur Erhaltung eines Wettbewerbsvorteils. Die Skripterstellung hat sich zu einem wichtigen Werkzeug entwickelt, mit dem IT-Expert:innen komplexe Prozesse rationalisieren können. Das PowerShell-Skript zur Installation von ConnectWise ScreenConnect ist ein Beispiel dafür und bietet eine ausgefeilte Lösung für die Fernverwaltung und den Support.
Kontext
ConnectWise ScreenConnect, ein beliebtes Tool für Remote-Support und -Management, wird häufig von IT-Expert:innen und Managed Service Providern (MSPs) eingesetzt. Seine Fähigkeit, den Fernzugriff auf Geräte zu erleichtern, ist in den zunehmend dezentralisierten Arbeitsumgebungen von heute unerlässlich. Dieses PowerShell-Skript vereinfacht den Bereitstellungsprozess von ScreenConnect und löst damit eine häufige Herausforderung für IT-Teams – eine effiziente, skalierbare und automatisierte Softwareinstallation.
Das Skript zur Automatisierung der ConnectWise ScreenConnect-Bereitstellung
<# .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 { }
Greifen Sie auf über 300 Skripte im NinjaOne Dojo zu.
Detailansicht
Das Skript funktioniert auf unkomplizierte Weise:
- Initialisierung der Parameter: Zu Beginn werden Parameter wie MSI-Dateiname, Zielordner und ScreenConnect-Domain festgelegt.
- Prüfungen vor der Ausführung: Es wird geprüft, ob Sie über Administratorrechte verfügen und ob der Zielordner vorhanden ist.
- Dynamische URL-Erstellung: Eine wichtige Funktion ist die Fähigkeit, eine Download-URL auf der Grundlage von Parametern wie Unternehmensnamen, Standort und Gerätetyp dynamisch zu erstellen.
- Download-Prozess: Das Skript lädt dann das ScreenConnect-Installationsprogramm von der erstellten URL herunter.
- Installation: Nach dem Herunterladen wird geprüft, ob ScreenConnect bereits installiert ist. Ist dies nicht der Fall oder wird der Force-Parameter verwendet, wird mit der Installation fortgefahren.
- Protokollierung: Während des gesamten Prozesses werden Protokolle zur Fehlerbehebung geführt.
Potenzielle Anwendungsfälle
Stellen Sie sich einen MSP vor, der für die Verwaltung der IT-Infrastruktur an mehreren Kundenstandorten verantwortlich ist. Die manuelle Installation von ScreenConnect auf jedem Gerät wäre sehr zeitaufwändig. Mit diesem Skript kann der MSP Installationen automatisieren und Einstellungen wie Standort und Gerätetyp für jeden Kunden anpassen, was Zeit spart und Fehler reduziert.
Vergleiche
Traditionell kann die Softwareinstallation das manuelle Herunterladen und Einrichten auf jedem Gerät oder die Verwendung einfacher Batch-Skripte ohne Anpassungsmöglichkeiten beinhalten. Dieses PowerShell-Skript übertrifft solche Methoden, indem es erweiterte Funktionen wie dynamische URL-Erstellung und Installationsstatusprüfungen bietet, was zu effizienteren und fehlerfreien Bereitstellungen führt.
FAQs
F: Ist das Skript mit allen Windows-Versionen kompatibel?
A: Es unterstützt Windows 8, Server 2012 und neuere Versionen, obwohl ältere Versionen mit einigen Einschränkungen funktionieren können.
F: Kann es Installationen in großem Maßstab bewältigen?
A: Ja, es ist skalierbar und kann auf zahlreichen Geräten installiert werden.
F: Ist es sicher, dieses Skript zu verwenden?
A: Das Skript ist sicher, aber Sie sollten jedes Skript überprüfen und verstehen, bevor Sie es in Ihrer Umgebung einsetzen.
Folgen
Dieses Skript vereinfacht zwar den Installationsprozess erheblich, aber die Benutzer:innen müssen sich der Sicherheitsaspekte bewusst sein. Eine unsachgemäße Verwendung oder Änderung kann zu Schwachstellen führen, insbesondere in MSP-Umgebungen, wo sich eine einzige Sicherheitsverletzung auf mehrere Kunden auswirken kann.
Empfehlungen
- Überprüfen und testen Sie: Prüfen und testen Sie das Skript immer gründlich in einer kontrollierten Umgebung.
- Passen Sie das Skript sorgfältig an: Ändern Sie die Skriptparameter entsprechend Ihren spezifischen Anforderungen.
- Bleiben Sie auf dem Laufenden: Halten Sie sich über Updates von ConnectWise ScreenConnect auf dem Laufenden und passen Sie das Skript bei Bedarf an.
Abschließende Überlegungen
NinjaOne, mit seinem Fokus auf einen einheitlichen IT-Betrieb, ergänzt solche Skripting-Lösungen. Es bietet eine Plattform, auf der solche Skripte integriert und effizient verwaltet werden können, was die IT-Managementfähigkeiten von Expert:innen weiter verbessert. Dieses PowerShell-Skript zusammen mit Tools wie NinjaOne zeigt, dass Automatisierung und intelligente Tools im modernen IT-Management unverzichtbar sind.