-
Notifications
You must be signed in to change notification settings - Fork 6
/
Win_Sophos_EndpointProtection_Install.ps1
201 lines (162 loc) · 7.4 KB
/
Win_Sophos_EndpointProtection_Install.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
<#
.SYNOPSIS
Installs Sophos Endpoint via the Sophos API https://developer.sophos.com/apis
.REQUIREMENTS
You will need API credentials to use this script. The instructions are slightly different depending who you are.
(Only Step 1 Required For API Credentials)
For Partners : https://developer.sophos.com/getting-started
For Organizations: https://developer.sophos.com/getting-started-organization
For Tenants : https://developer.sophos.com/getting-started-tenant
.INSTRUCTIONS
1. Get your API Credentials (Client Id, Client Secret) using the steps in the Requirements section
2. In Tactical RMM, Go to Settings >> Global Settings >> Custom Fields and under Clients, create the following custom fields:
a) SophosTenantName as type text
b) SophosClientId as type text
c) SophosClientSecret as type text
3. In Tactical RMM, Right-click on each client and select Edit. Fill in the SophosTenantName, SophosClientId, and SophosClientSecret.
Make sure the SophosTenantName is EXACTLY how it is displayed in your Sophos Partner / Central Dashboard. A partner can find the list of tenants on the left menu under Sophos Central Customers
4. Create the follow script arguments
a) -ClientId {{client.SophosClientId}}
b) -ClientSecret {{client.SophosClientSecret}}
c) -TenantName {{client.SophosTenantName}}
d) -Products (Optional Parameter) - A list of products to install, comma-separated. Available options are: antivirus, intercept, mdr, deviceEncryption or all. Example - To install Antivirus, Intercept, and Device encryption you would pass "antivirus,intercept,deviceEncryption".
.NOTES
V1.0 Initial Release by https://github.com/bc24fl/tacticalrmm-scripts/
V1.1 Added error handling for each Invoke-Rest Call for easier troubleshooting and graceful exit.
V1.2 Added support for more than 100 tenants.
V1.3 Removed Chocolately dependency
#>
param(
$ClientId,
$ClientSecret,
$TenantName,
$Products
)
if ([string]::IsNullOrEmpty($ClientId)) {
throw "ClientId must be defined. Use -ClientId <value> to pass it."
}
if ([string]::IsNullOrEmpty($ClientSecret)) {
throw "ClientSecret must be defined. Use -ClientSecret <value> to pass it."
}
if ([string]::IsNullOrEmpty($TenantName)) {
throw "TenantName must be defined. Use -TenantName <value> to pass it."
}
if ([string]::IsNullOrEmpty($Products)) {
Write-Output "No product options specified installing default antivirus and intercept."
$Products = "antivirus,intercept"
}
Write-Host "Running Sophos Endpoint Installation Script On: $env:COMPUTERNAME"
# Set TLS Version for web requests
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# Find if workstation or server. osInfo.ProductType returns 1 = workstation, 2 = domain controller, 3 = server
$osInfo = Get-CimInstance -ClassName Win32_OperatingSystem
$urlAuth = "https://id.sophos.com/api/v2/oauth2/token"
$urlWhoami = "https://api.central.sophos.com/whoami/v1"
$urlTenant = "https://api.central.sophos.com/partner/v1/tenants?pageTotal=true"
$authBody = @{
"grant_type"="client_credentials"
"client_id"=$ClientId
"client_secret"=$ClientSecret
"scope"="token"
}
$authResponse = (Invoke-RestMethod -Method 'post' -Uri $urlAuth -Body $authBody)
$authToken = $authResponse.access_token
$authHeaders = @{Authorization = "Bearer $authToken"}
if ($authToken.length -eq 0){
throw "Error, no authentication token received. Please check your api credentials. Exiting script."
}
$whoAmIResponse = (Invoke-RestMethod -Method 'Get' -headers $authHeaders -Uri $urlWhoami)
$myId = $whoAmIResponse.Id
$myIdType = $whoAmIResponse.idType
if ($myIdType.length -eq 0){
throw "Error, no Whoami Id Type received. Please check your api credentials or network connections. Exiting script."
}
if($myIdType -eq 'partner'){
$requestHeaders =@{
'Authorization'="Bearer $authToken"
'X-Partner-ID'=$myId
}
}
elseif($myIdType -eq 'organization') {
$requestHeaders =@{
'Authorization' = "Bearer $authToken"
'X-Organization-ID' = $myId
}
}
elseif($myIdType -eq 'tenant'){
$requestHeaders =@{
'Authorization' = "Bearer $authToken"
'X-Tenant-ID' = $myId
}
}
else {
throw "Error finding id type. This script only supports Partner, Organization, and Tenant API's."
}
# Cycle through all tenants until a tenant match, or all pages have exhausted.
$currentPage = 1
do {
Write-Output "Looking for tenant on page $currentPage. Please wait..."
if ($currentPage -ge 2){
Start-Sleep -s 5
$urlTenant = "https://api.central.sophos.com/partner/v1/tenants?page=$currentPage"
}
$tenantResponse = (Invoke-RestMethod -Method 'Get' -headers $requestHeaders -Uri $urlTenant)
$tenants = $tenantResponse.items
$totalPages = [int]$tenantResponse.pages.total
foreach ($tenant in $tenants) {
if ($tenant.name -eq $TenantName){
$tenantRegion = $tenant.dataRegion
$tenantId = $tenant.id
}
}
$currentPage += 1
} until( $currentPage -gt $totalPages -Or ($tenantId.length -gt 1 ) )
if ($tenantId.length -eq 0){
throw "Error, no tenant found with the provided name. Please check the name and try again. Exiting script."
}
$requestHeaders =@{
'Authorization' = "Bearer $authToken"
'X-Tenant-ID' = $tenantId
}
$urlEndpoint = "https://api-" + $tenantRegion + ".central.sophos.com/endpoint/v1/downloads"
$endpointDownloadResponse = (Invoke-RestMethod -Method 'Get' -headers $requestHeaders -Uri $urlEndpoint)
$endpointInstallers = $endpointDownloadResponse.installers
if ($endpointInstallers.length -eq 0){
throw "Error, no installers received. Please check your api credentials or network connections. Exiting script."
}
foreach ($installer in $endpointInstallers){
if ( ($installer.platform -eq "windows") -And ($installer.productName = "Sophos Endpoint Protection") ){
if ( ($osInfo.ProductType -eq 1) -And ($installer.type = "computer") ){
# Workstation Install
$installUrl = $installer.downloadUrl
}
elseif ( ( ($osInfo.ProductType -eq 2) -Or ($osInfo.ProductType -eq 3) ) -And ($installer.type = "server") ){
# Server Install
$installUrl = $installer.downloadUrl
}
else{
throw "Error, this script only supports producttype of 1) Work Station, 2) Domain Controller, or 3) Server."
}
}
}
try{
Write-Host "Checking if Sophos Endpoint installed. Please wait..."
$software = "Sophos Endpoint Agent";
$installed = ((Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*).DisplayName -Match $software).Length -gt 0
if(-Not $installed) {
Write-Host "Sophos Endpoint is NOT installed. Installing now..."
Write-Host "Downloading Sophos from " + $installUrl + " Please wait..."
$tmpDir = [System.IO.Path]::GetTempPath()
$outpath = $tmpDir + "SophosSetup.exe"
Write-Host "Saving file to " + $outpath
Invoke-WebRequest -Uri $installUrl -OutFile $outpath
Write-Host "Running Sophos Setup... Please wait up to 20 minutes for install to complete."
$appArgs = @("--products=" + $Products + " --quiet ")
Start-Process -Filepath $outpath -ArgumentList $appArgs
} else {
Write-Host "Sophos Endpoint is installed. Skipping installation."
}
}
catch{
throw "Installation failed with error message: $($PSItem.ToString())"
}