installation_key="Product_key" #Must be in the format 1234-1234-1234-1234. ps_content=r''' # Actifile Powershell Download and Installation Script for Continuum (and other) RMM # First line in the script must be retrieving the command line parameters - in our case the install key. param ( [string]$key ) # Optional Replace __INSTALL_KEY__ with your tenant's install key. Must be in the format 1234-1234-1234-1234. # Each tenant has their own unique key (and thus their own script): DO NOT mix keys between tenants! $InstallKey = "%s" # Installation Locations and Names (usually don't need to change these....) $InstallerName = "Actifile Install.msi" $InstallerPath = Join-Path $Env:TMP $InstallerName $DownloadURL = "https://app.actifile.com/Home/DownloadAgentMsi" # Append messages and errors to installation top the following log file... $DebugLog = Join-Path $Env:TMP ActifileInstall.log $ActifileMSILog = Join-Path $Env:TMP ActifileMSI.log function Get-TimeStamp { return "[{0:yyyy/MM/dd} {0:HH:mm:ss}]" -f (Get-Date) } function LogMessage ($msg) { Add-Content $DebugLog "$(Get-TimeStamp) $msg" Write-Host "$(Get-TimeStamp) $msg" } function CheckAdmin { $oIdent= [Security.Principal.WindowsIdentity]::GetCurrent() $oPrincipal = New-Object Security.Principal.WindowsPrincipal($oIdent) if(!$oPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator )){ $err = "Please start script with Administrator rights - Quitting!" LogMessage $err throw $ScriptFailed + " " + $err exit 1 } } # Replace InstallKey with key from command line parameters (if exist) # and check for proper install Key (must be in form 1234-1234-1234-1234) function Check-InstallKey { if ( ! [string]::IsNullOrEmpty($key) ) { $InstallKey = $key.Trim() } if ($InstallKey -eq "__INSTALL_KEY__") { $err = "InstallKey not set - Quitting!" LogMessage $err LogMessage "Command Line Usage: `".\deployActifile.ps1 1234-1234-1234-1234`"" LogMessage "or Replace script macro __INSTALL_KEY__ with your tenant key." LogMessage "Replace 1234-1234-1234-1234 with the correct tenant install key" LogMessage " " throw $ScriptFailed + " " + $err exit 1 } elseif ($InstallKey.length -ne 19) { $err = "Invalid InstallKey specified (incorrect length - should be in format 1234-1234-1234-1234) - Quitting!" LogMessage $err throw $ScriptFailed + " " + $err exit 1 } LogMessage "InstallKey: '$InstallKey'" return $InstallKey } # Check if installer already installed - and if not download function Check-MSI { # if (! (Test-Path $InstallerPath)){ # we want to always download the latest installer. LogMessage "Downloading from: '$DownloadURL' to: '$InstallerPath'" $WebClient = New-Object System.Net.WebClient $WebClient.DownloadFile($DownloadURL, $InstallerPath) if (! (Test-Path $InstallerPath)) { $err = "Failed to Download Installer!" LogMessage $err throw $ScriptFailed + " " + $err exit 1 } # } else { LogMessage "Actifile Installer Downloaded - continuing..." # } } # Check if product already installed function Check-Actifile-Installed { $ProductRegKey = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\`{0D13F554-E542-4590-AACB-AA60CAE75A64`}" if (Test-Path $ProductRegKey){ $err = "Product Already Installed - Quitting!" LogMessage $err throw $ScriptFailed + " " + $err } else { LogMessage "Actifile not previously installed - continuing..." } } # Create the command line arguments and install Actifile function Install-Actifile { $MSIArguments = @( "/i" "`"$InstallerPath`"" "installkey=$InstallKey" "/quiet" "/l*v $ActifileMSILog" ) LogMessage "Now executing: MSIEXEC.EXE $MSIArguments" Start-Process msiexec.exe -Wait -ArgumentList $MSIArguments } try { LogMessage "Actifile Download and Installation Script" LogMessage "v0.15" CheckAdmin $InstallKey = Check-InstallKey Check-Actifile-Installed Check-MSI Install-Actifile } catch { $ErrorMessage = $_.Exception.Message LogMessage $ErrorMessage exit 1 } '''%installation_key import os def ecmd(command): import ctypes from subprocess import PIPE, Popen class disable_file_system_redirection: _disable = ctypes.windll.kernel32.Wow64DisableWow64FsRedirection _revert = ctypes.windll.kernel32.Wow64RevertWow64FsRedirection def __enter__(self): self.old_value = ctypes.c_long() self.success = self._disable(ctypes.byref(self.old_value)) def __exit__(self, type, value, traceback): if self.success: self._revert(self.old_value) with disable_file_system_redirection(): obj = Popen(command, shell = True, stdout = PIPE, stderr = PIPE) out, err = obj.communicate() ret=obj.returncode if ret==0: if out: return out.strip() else: return ret else: if err: return err.strip() else: return ret file_name='powershell_file.ps1' file_path=os.path.join(os.environ['TEMP'], file_name) with open(file_path, 'wb') as wr: wr.write(ps_content) ecmd('powershell "Set-ExecutionPolicy RemoteSigned"') print ecmd('powershell "%s"'%file_path) os.remove(file_path)