Skip to content

Instantly share code, notes, and snippets.

@chrisisbeef
Last active April 5, 2024 20:35
Show Gist options
  • Save chrisisbeef/ac701d471282f8588e969b90887da857 to your computer and use it in GitHub Desktop.
Save chrisisbeef/ac701d471282f8588e969b90887da857 to your computer and use it in GitHub Desktop.
Bitdefender GravityZone Remote Installation Scripts (Works with JumpCloud Command-Runner Agent)
# Insert your company-hash here. When you get the download link, this is the long alpha-numeric scring
# that comes after setupdownloader_ in the filename.
# Do not include the square brackets (but do include the = if there is one).
$CompanyHash = ""
### Modify below this line at your own risk!
# If it's already installed, just do nothing
$Installed = Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" |
Where-Object { $_.DisplayName -eq "Bitdefender Endpoint Security Tools" }
if ($Installed) {
Write-Output "Bitdefender already installed. Exiting."
Exit 0
}
$BitdefenderURL = "setupdownloader_[$CompanyHash].exe"
$BaseURL = "https://cloud.gravityzone.bitdefender.com/Packages/BSTWIN/0/"
$URL = $BaseURL + $BitdefenderURL
$Destination = 'C:\Windows\Temp\setupdownloader.exe'
try
{
Write-Output "Beginning download of Bitdefender to $Destination"
Invoke-WebRequest -Uri $URL -OutFile $Destination
}
catch
{
Write-Output "Error Downloading - $_.Exception.Response.StatusCode.value_"
Write-Output $_
Exit 1
}
# Check if a previous attempt failed, leaving the installer in the temp directory and breaking the script
$FullDestination = "$DestinationPath\setupdownloader_[$CompanyHash].exe"
if (Test-Path $FullDestination) {
Remove-Item $FullDestination
Write-Out "Removed $FullDestination..."
}
Rename-Item -Path $Destination -NewName "setupdownloader_[$CompanyHash].exe"
Write-Output "Download succeeded, beginning install..."
Start-Process -FilePath "C:\Windows\Temp\$BitdefenderURL" -ArgumentList "/bdparams /silent silent" -Wait -NoNewWindow
# Wait an additional 30 seconds after the installer process completes to verify installation
Start-Sleep -Seconds 30
$Installed = Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" |
Where-Object { $_.DisplayName -eq "Bitdefender Endpoint Security Tools" }
if ($Installed) {
Write-Output "Bitdefender successfully installed."
Exit 0
}
else {
Write-Output "ERROR: Failed to install Bitdefender"
Exit 1
}
# Get the download url for the Mac installer from your GravityZone server and put it here
DownloadUrl=""
### Modify below this line at your own risk!
# Check if BDLDaemon is already running
PROCESS=BDLDaemon
count=$(ps aux | grep -v grep | grep -ci $PROCESS)
if [ $count -gt 0 ]; then
echo "Bitdefender is already installed..."
exit 0
fi
# Verify JumpCloud MDM
verify_jc_mdm (){
# Check the system for the following profileIdentifier
mdmID="com.jumpcloud.mdm"
check=$(profiles -Lv | grep "name: $4" -4 | awk -F": " '/attribute: profileIdentifier/{print $NF}')
if [[ $check == *$mdmID* ]] ; then
echo "ProfileIdentifier: ${mdmID} found on system. MDM Verified"
return
else
echo "JumpCloud MDM profile not found on system."
false
fi
}
if ! verify_jc_mdm "$":; then
echo "Device is not yet supervised..."
exit 0
fi
# Locate DMG Download Link From URL
regex='^https.*.dmg$'
if [[ $DownloadUrl =~ $regex ]]; then
echo "URL points to direct DMG download"
validLink="True"
else
echo "Searching headers for download links"
urlHead=$(curl -s --head $DownloadUrl)
locationSearch=$(echo "$urlHead" | grep https:)
if [ -n "$locationSearch" ]; then
locationRaw=$(echo "$locationSearch" | cut -d' ' -f2)
locationFormatted="$(echo "${locationRaw}" | tr -d '[:space:]')"
regex='^https.*'
if [[ $locationFormatted =~ $regex ]]; then
echo "Download link found"
DownloadUrl=$(echo "$locationFormatted")
else
echo "No https location download link found in headers"
exit 1
fi
else
echo "No location download link found in headers"
exit 1
fi
fi
#Create Temp Folder
DATE=$(date '+%Y-%m-%d-%H-%M-%S')
TempFolder="Download-$DATE"
mkdir /tmp/$TempFolder
# Navigate to Temp Folder
cd /tmp/$TempFolder
# Download File into Temp Folder
curl -s -O "$DownloadUrl"
# Capture name of Download File
DownloadFile="$(ls)"
echo "Downloaded $DownloadFile to /tmp/$TempFolder"
# Verifies DMG File
regex='\.dmg$'
if [[ $DownloadFile =~ $regex ]]; then
DMGFile="$(echo "$DownloadFile")"
echo "DMG File Found: $DMGFile"
else
echo "File: $DownloadFile is not a DMG"
rm -r /tmp/$TempFolder
echo "Deleted /tmp/$TempFolder"
exit 1
fi
# Mount DMG File -nobrowse prevents the volume from popping up in Finder
hdiutilAttach=$(hdiutil attach /tmp/$TempFolder/$DMGFile -nobrowse)
echo "Used hdiutil to mount $DMGFile "
err=$?
if [ ${err} -ne 0 ]; then
echo "Could not mount $DMGFile Error: ${err}"
rm -r /tmp/$TempFolder
echo "Deleted /tmp/$TempFolder"
exit 1
fi
regex='\/Volumes\/.*'
if [[ $hdiutilAttach =~ $regex ]]; then
DMGVolume="${BASH_REMATCH[@]}"
echo "Located DMG Volume: $DMGVolume"
else
echo "DMG Volume not found"
rm -r /tmp/$TempFolder
echo "Deleted /tmp/$TempFolder"
exit 1
fi
# Identify the mount point for the DMG file
DMGMountPoint="$(hdiutil info | grep "$DMGVolume" | awk '{ print $1 }')"
echo "Located DMG Mount Point: $DMGMountPoint"
# Capture name of App file
cd "$DMGVolume/SetupDownloader.app/Contents/MacOS/"
./SetupDownloader
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>AllowUserOverrides</key>
<true/>
<key>AllowedSystemExtensions</key>
<dict>
<key>GUNFMW623Y</key>
<array>
<string>com.bitdefender.cst.net.dci.dci-network-extension</string>
</array>
</dict>
<key>PayloadDescription</key>
<string></string>
<key>PayloadDisplayName</key>
<string>System Extensions</string>
<key>PayloadIdentifier</key>
<string>C4CC343D-B6B3-42AA-BDBE-17A87938BE42</string>
<key>PayloadOrganization</key>
<string>Bitdefender Vendor Payload</string>
<key>PayloadType</key>
<string>com.apple.system-extension-policy</string>
<key>PayloadUUID</key>
<string>C4CC343D-B6B3-42AA-BDBE-17A87938BE42</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
<dict>
<key>PayloadDescription</key>
<string></string>
<key>PayloadDisplayName</key>
<string>Privacy Preferences Policy Control</string>
<key>PayloadIdentifier</key>
<string>A8D2FB69-FE19-4F76-8E9E-E0FD82F4F08F</string>
<key>PayloadOrganization</key>
<string>Bitdefender Vendor Payload</string>
<key>PayloadType</key>
<string>com.apple.TCC.configuration-profile-policy</string>
<key>PayloadUUID</key>
<string>A8D2FB69-FE19-4F76-8E9E-E0FD82F4F08F</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>Services</key>
<dict>
<key>SystemPolicyAllFiles</key>
<array>
<dict>
<key>Allowed</key>
<integer>1</integer>
<key>CodeRequirement</key>
<string>anchor apple generic and identifier "com.bitdefender.epsecurity.BDLDaemonApp" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = GUNFMW623Y)</string>
<key>Identifier</key>
<string>com.bitdefender.epsecurity.BDLDaemonApp</string>
<key>IdentifierType</key>
<string>bundleID</string>
<key>StaticCode</key>
<integer>0</integer>
</dict>
<dict>
<key>Allowed</key>
<integer>1</integer>
<key>CodeRequirement</key>
<string>identifier "com.bitdefender.EndpointSecurityforMac" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = GUNFMW623Y</string>
<key>Identifier</key>
<string>com.bitdefender.EndpointSecurityforMac</string>
<key>IdentifierType</key>
<string>bundleID</string>
<key>StaticCode</key>
<integer>0</integer>
</dict>
</array>
</dict>
</dict>
<dict>
<key>FilterPacketProviderBundleIdentifier</key>
<string>com.bitdefender.cst.net.dci.dci-network-extension</string>
<key>FilterPacketProviderDesignatedRequirement</key>
<string>anchor apple generic and identifier "com.bitdefender.cst.net.dci.dci-network-extension" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = GUNFMW623Y)</string>
<key>FilterPackets</key>
<true/>
<key>FilterSockets</key>
<false/>
<key>FilterType</key>
<string>Plugin</string>
<key>PayloadDisplayName</key>
<string>Web Content Filter Payload</string>
<key>PayloadIdentifier</key>
<string>CDB57D2F-44EF-4386-A2BE-530E1EAB71AE</string>
<key>PayloadOrganization</key>
<string>JAMF Software</string>
<key>PayloadType</key>
<string>com.apple.webcontent-filter</string>
<key>PayloadUUID</key>
<string>CDB57D2F-44EF-4386-A2BE-530E1EAB71AE</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PluginBundleID</key>
<string>com.bitdefender.epsecurity.BDLDaemonApp</string>
<key>UserDefinedName</key>
<string>Bitdefender</string>
<key>VendorConfig</key>
<dict/>
</dict>
</array>
<key>PayloadDescription</key>
<string></string>
<key>PayloadDisplayName</key>
<string>BitDefender</string>
<key>PayloadIdentifier</key>
<string>8758FD71-64D2-4739-8836-7838BE671CCE</string>
<key>PayloadOrganization</key>
<string>Bitdefender GravityZone.</string>
<key>PayloadRemovalDisallowed</key>
<true/>
<key>PayloadScope</key>
<string>System</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>B3EB5B54-D81F-4670-B586-53E8D1944AC2</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>
@chrisisbeef
Copy link
Author

These scripts will install Bitdefender Endpoint Security Tools (BEST) on both Mac and Windows machines. For Mac, it will check to make sure that MDM is enabled prior to installing - this will allow you to push the attached .mobileconfig profile to endpoints prior to installing so that your end-users don't need to manually allow access to the resources required by the endpoint agent.

@seattletheatregroup
Copy link

Greetings!
I am attempting to use your script to deploy GZ to my mac endpoints through NinjaOne rmm and have removed the section for Jumpcloud MDM but when I run the script it returns an unexpected "end of file" error message.
I assume it's something simple, what and I missing here?
The terminal is root and bash btw.
I am am willing to pay you to rework your script so it works with NinjaOne rmm :)
-Michael vK

@SuyogAdhikari
Copy link

SuyogAdhikari commented Nov 6, 2022

On windows installation, I had exception on Invoke-WebRequest
The request was aborted: Could not create SSL/TLS secure channel

By default powershell uses TLS 1.0 the site security requires TLS 1.2

The fix was, i added
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

above
Invoke-WebRequest -Uri $URL -OutFile $Destination
this line and the installation was a success

@aimaq2020
Copy link

aimaq2020 commented Jan 5, 2023

Hi @chrisisbeef,
Thanks for the script it is very helpful. I used for remote deployment of Bitdefender through JumpCloud which nicely worked on Mac devices but on windows machines, the download part is success but failing install and I am getting the following error message:
ERROR: Failed to install Bitdefender
Rename-Item : Cannot create a file when that file already exists.
At line:35 char:1

  • Rename-Item -Path $Destination -NewName "setupdownloader_[$CompanyHas ...

I'm not good at scripting, can you help me please to troubleshoot this error? Much appreciated

@chrisisbeef
Copy link
Author

Hi @chrisisbeef, Thanks for the script it is very helpful. I used for remote deployment of Bitdefender through JumpCloud which nicely worked on Mac devices but on windows machines, the download part is success but failing install and I am getting the following error message: ERROR: Failed to install Bitdefender Rename-Item : Cannot create a file when that file already exists. At line:35 char:1

  • Rename-Item -Path $Destination -NewName "setupdownloader_[$CompanyHas ...

I'm not good at scripting, can you help me please to troubleshoot this error? Much appreciated

Hi @aimaq2020 - I unfortunately don't have a way to test this script anymore as I am no longer with the company I was working with and thus no access to a BitDefender account to test with, however I'd guess that it is most likely a permissions issue, check which user is running the script in the command on the jumpcloud side if you're running it using JumpCloud commands and make sure that user has rights to write to C:\Windows\Temp directory. You can also check on one of the workstations you're deploying to and see if the files are being written in that directory to help debug a bit

@aimaq2020
Copy link

Hi @chrisisbeef appreciate that you replied back. I figured out, the issue was with the Bitdefender URL hash, in my case replaced Invoke-WebRequest with Start-BitsTransfer which worked to download the file, now I am struggling with the second part, installing the downloaded file which isn't working and neither giving any error log details. Thanks

@davidshbroussard
Copy link

davidshbroussard commented May 3, 2023

Hi @chrisisbeef, Thanks for the script it is very helpful. I used for remote deployment of Bitdefender through JumpCloud which nicely worked on Mac devices but on windows machines, the download part is success but failing install and I am getting the following error message: ERROR: Failed to install Bitdefender Rename-Item : Cannot create a file when that file already exists. At line:35 char:1

  • Rename-Item -Path $Destination -NewName "setupdownloader_[$CompanyHas ...

I'm not good at scripting, can you help me please to troubleshoot this error? Much appreciated

@aimaq2020 What did you do to get it to install on the Macs? I was able to get it working for PC, but am having trouble with the Mac install. I put the part labeled best.sh in the command, but not sure what to do with best_unsigned.mobileconfig. When I run the command, I can see it on the dock and it shows SetupDownloader, but it never installs and I can hear the fan running making me think that it is trying to do the silent install, but is needing security settings to be accepted. I am assuming that the .mobileconfig has something to do with that, but not sure what to do with it.

@chrisisbeef
Copy link
Author

Hi @chrisisbeef, Thanks for the script it is very helpful. I used for remote deployment of Bitdefender through JumpCloud which nicely worked on Mac devices but on windows machines, the download part is success but failing install and I am getting the following error message: ERROR: Failed to install Bitdefender Rename-Item : Cannot create a file when that file already exists. At line:35 char:1

  • Rename-Item -Path $Destination -NewName "setupdownloader_[$CompanyHas ...

I'm not good at scripting, can you help me please to troubleshoot this error? Much appreciated

@aimaq2020 What did you do to get it to install on the Macs? I was able to get it working for PC, but am having trouble with the Mac install. I put the part labeled best.sh in the command, but not sure what to do with best_unsigned.mobileconfig. When I run the command, I can see it on the dock and it shows SetupDownloader, but it never installs and I can hear the fan running making me think that it is trying to do the silent install, but is needing security settings to be accepted. I am assuming that the .mobileconfig has something to do with that, but not sure what to do with it.

Hi @davidshbroussard - you have to push the .mobileconfig as a policy to your macs before the command will work. You can add the custom policy by going to Policy Management in the admin console, and searching for "Mac - MDM Custom Configuration Profile Policy" then attach the .mobileconfig file to that policy and select the devices or device groups to push the policy to.

@davidshbroussard
Copy link

Hi @chrisisbeef, Thanks for the script it is very helpful. I used for remote deployment of Bitdefender through JumpCloud which nicely worked on Mac devices but on windows machines, the download part is success but failing install and I am getting the following error message: ERROR: Failed to install Bitdefender Rename-Item : Cannot create a file when that file already exists. At line:35 char:1

  • Rename-Item -Path $Destination -NewName "setupdownloader_[$CompanyHas ...

I'm not good at scripting, can you help me please to troubleshoot this error? Much appreciated

@aimaq2020 What did you do to get it to install on the Macs? I was able to get it working for PC, but am having trouble with the Mac install. I put the part labeled best.sh in the command, but not sure what to do with best_unsigned.mobileconfig. When I run the command, I can see it on the dock and it shows SetupDownloader, but it never installs and I can hear the fan running making me think that it is trying to do the silent install, but is needing security settings to be accepted. I am assuming that the .mobileconfig has something to do with that, but not sure what to do with it.

Hi @davidshbroussard - you have to push the .mobileconfig as a policy to your macs before the command will work. You can add the custom policy by going to Policy Management in the admin console, and searching for "Mac - MDM Custom Configuration Profile Policy" then attach the .mobileconfig file to that policy and select the devices or device groups to push the policy to.

@chrisisbeef Thanks for that reply. I was not sure how it got pushed as I am newly getting into JumpCloud with policies. I appreciate it. Once it was on, it installed. This will make it much easier for installation! I appreciate it.

@ezjurgen
Copy link

If I am not mistaken at line 35 $DestinationPath is never filled so it will not find that file. I guess it needs to be $Destination

@42leaks
Copy link

42leaks commented Nov 2, 2023

hello
thank you for the script.
How did you générate a mobilconfigfile ?
how did you find <key>PayloadIdentifier</key> <string>8758FD71-64D2-4739-8836-7838BE671CCE</string> and <key>GUNFMW623Y</key> all all others id ?
?

@carallel
Copy link

Do you know if the GZ silent installation process can remove previous antivirus installs? We have a number of Windows systems that either have a small office install of BitDefender or Mcafee, and I’m trying to figure out if I can do the whole process remotely via JumpCloud.

@carallel
Copy link

I'm trying this script with Windows Powershell and getting the following error without any real details as to what is failing:

Beginning download of Bitdefender to C:\Windows\Temp\setupdownloader.exe
Download succeeded, beginning install...
ERROR: Failed to install Bitdefender

So it looks like it's downloaded the file successfully but not installing. Any troubleshooting suggestions?

@kklang774
Copy link

I'm trying this script with Windows Powershell and getting the following error without any real details as to what is failing:

Beginning download of Bitdefender to C:\Windows\Temp\setupdownloader.exe
Download succeeded, beginning install...
ERROR: Failed to install Bitdefender

So it looks like it's downloaded the file successfully but not installing. Any troubleshooting suggestions?

I'd guess its because you are not running it elevated. I have a machine that has a local admin account, i'm kicking off the script with my rmm software, however i don't have the local admin account creds yet, and I get the same thing. Are you pushing it out or running it locally? If you are running it locally, click powershell, and run as administrator, then try it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment