Files
Veeam/Veeam Security & Compliance Analyzer 1.8.ps1

517 lines
27 KiB
PowerShell

<#--
=====================================
Veeam Security & Compliance Analyzer
Enforcement Script
=====================================
This script provides reporting on the current
status and enforces recommended security settings
on a backup server. It is designed to be executed
locally on the backup server.
Version: 1.8 (Updated on 8/21/2024)
--#>
# Making sure Veeam PowerCLI is working
Write-Output "Importing VBR Powershell module..."
$path = [Environment]::GetEnvironmentVariable('PSModulePath', 'Machine')
$env:PSModulePath +="$([System.IO.Path]::PathSeparator)$path"
$veeamPSModule = Get-Module -ListAvailable | Where-Object{$_.Name -match "Veeam.Backup.PowerShell"}
Import-Module $veeamPSModule.Path -DisableNameChecking
# This function collects current status and prints out a compliance report
function Get-VBRComplianceReport
{
Write-host "Initiating Analyzer and collecting compliance status..."
# Checking Veeam Backup Service status
if ((Get-Service VeeamBackupSvc -ErrorAction SilentlyContinue).Status -ne "Running") {Write-Host "Veeam Backup Service is not running. Check service status and try again."; break}
# Trigger S&CA session
Start-VBRSecurityComplianceAnalyzer
Start-Sleep 10
# Collect results into array
$AnalyzerResult = ([Veeam.Backup.DBManager.CDBManager]::Instance.BestPractices.GetAll())
$Recommendations = @()
$Recommendations = @(
[Ordered]@{
Id = 1
Name = "Remote Desktop Services (TermService) should be disabled"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "RemoteDesktopServiceDisabled"}).Status
Remediation = "Script"
}
[Ordered]@{
Id = 2
Name = "Remote Registry service (RemoteRegistry) should be disabled"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "RemoteRegistryDisabled"}).Status
Remediation = "Script"
}
[Ordered]@{
Id = 3
Name = "Windows Remote Management (WinRM) service should be disabled"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "WinRmServiceDisabled"}).Status
Remediation = "Script"
}
[Ordered]@{
Id = 4
Name = "Windows Firewall should be enabled"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "WindowsFirewallEnabled"}).Status
Remediation = "Script"
}
[Ordered]@{
Id = 5
Name = "WDigest credentials caching should be disabled"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "WDigestNotStorePasswordsInMemory"}).Status
Remediation = "Script"
}
[Ordered]@{
Id = 6
Name = "Web Proxy Auto-Discovery service (WinHttpAutoProxySvc) should be disabled"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "WebProxyAutoDiscoveryDisabled"}).Status
Remediation = "Script"
}
[Ordered]@{
Id = 7
Name = "Deprecated versions of SSL and TLS should be disabled"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "OutdatedSslAndTlsDisabled"}).Status
Remediation = "Script"
}
[Ordered]@{
Id = 8
Name = "Windows Script Host should be disabled"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "WindowsScriptHostDisabled"}).Status
Remediation = "Script"
}
[Ordered]@{
Id = 9
Name = "SMBv1 protocol should be disabled"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "SMB1ProtocolDisabled"}).Status
Remediation = "Script"
}
[Ordered]@{
Id = 10
Name = "Link-Local Multicast Name Resolution (LLMNR) should be disabled"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "LLMNRDisabled"}).Status
Remediation = "Script"
}
[Ordered]@{
Id = 11
Name = "SMBv3 signing and encryption should be enabled"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "CSmbSigningAndEncryptionEnabled"}).Status
Remediation = "Script"
}
[Ordered]@{
Id = 12
Name = "MFA for the backup console should be enabled"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "MfaEnabledInBackupConsole"}).Status
Remediation = "Manual"
}
[Ordered]@{
Id = 13
Name = "Immutable or offline (air gapped) media should be used"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "ImmutableOrOfflineMediaPresence"}).Status
Remediation = "Manual"
}
[Ordered]@{
Id = 14
Name = "Password loss protection should be enabled"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "LossProtectionEnabled"}).Status
Remediation = "Manual"
}
[Ordered]@{
Id = 15
Name = "Backup server should not be a part of the production domain"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "BackupServerInProductionDomain"}).Status
Remediation = "Manual"
}
[Ordered]@{
Id = 16
Name = "Email notifications should be enabled"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "EmailNotificationsEnabled"}).Status
Remediation = "Manual"
}
[Ordered]@{
Id = 17
Name = "All backups should have at least one copy (the 3-2-1 backup rule)"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "ContainBackupCopies"}).Status
Remediation = "Manual"
}
[Ordered]@{
Id = 18
Name = "Reverse incremental backup mode is deprecated and should be avoided"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "ReverseIncrementalInUse"}).Status
Remediation = "Manual"
}
[Ordered]@{
Id = 19
Name = "Unknown Linux servers should not be trusted automatically"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "ManualLinuxHostAuthentication"}).Status
Remediation = "Script"
}
[Ordered]@{
Id = 20
Name = "The configuration backup must not be stored on the backup server"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "ConfigurationBackupRepositoryNotLocal"}).Status
Remediation = "Manual"
}
[Ordered]@{
Id = 21
Name = "Host to proxy traffic encryption should be enabled for the Network transport mode"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "ViProxyTrafficEncrypted"}).Status
Remediation = "Script"
}
[Ordered]@{
Id = 22
Name = "Hardened repositories should not be hosted in virtual machines"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "HardenedRepositoryNotVirtual"}).Status
Remediation = "Manual"
}
[Ordered]@{
Id = 23
Name = "Network traffic encryption should be enabled in the backup network"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "TrafficEncryptionEnabled"}).Status
Remediation = "Manual"
}
[Ordered]@{
Id = 24
Name = "Linux servers should have password-based authentication disabled"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "LinuxServersUsingSSHKeys"}).Status
Remediation = "Manual"
}
[Ordered]@{
Id = 25
Name = "Backup services should be running under the LocalSystem account"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "BackupServicesUnderLocalSystem"}).Status
Remediation = "Manual"
}
[Ordered]@{
Id = 26
Name = "Configuration backup should be enabled and use encryption"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "ConfigurationBackupEnabledAndEncrypted"}).Status
Remediation = "Manual"
}
[Ordered]@{
Id = 27
Name = "Credentials and encryption passwords should be rotated at least annually"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "PasswordsRotation"}).Status
Remediation = "Manual"
}
[Ordered]@{
Id = 28
Name = "Hardened repositories should have the SSH Server disabled"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "HardenedRepositorySshDisabled"}).Status
Remediation = "Manual"
}
[Ordered]@{
Id = 29
Name = "S3 Object Lock in the Governance mode does not provide true immutability"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "OsBucketsInComplianceMode"}).Status
Remediation = "Manual"
}
[Ordered]@{
Id = 30
Name = "Backup jobs to cloud repositories should use encryption"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "JobsTargetingCloudRepositoriesEncrypted"}).Status
Remediation = "Manual"
}
[Ordered]@{
Id = 31
Name = "Latest product updates should be installed"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "BackupServerUpToDate"}).Status
Remediation = "Manual"
}
[Ordered]@{
Id = 32
Name = "PostgreSQL server should be configured with recommended settings"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "PostgreSqlUseRecommendedSettings"}).Status
Remediation = "Script"
}
[Ordered]@{
Id = 33
Name = "Hardened repositories should not be used as backup proxy servers"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "HardenedRepositoryNotContainsNBDProxies"}).Status
Remediation = "Manual"
}
[Ordered]@{
Id = 34
Name = "Local Security Authority Server Service (LSASS) should be set to run as a protected process"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "LsassProtectedProcess"}).Status
Remediation = "Script"
}
[Ordered]@{
Id = 35
Name = "NetBIOS protocol should be disabled on all network interfaces"
Status = ($AnalyzerResult | Where-Object {$_.Type -eq "NetBiosDisabled"}).Status
Remediation = "Script"
}
)
# Formatting and better structure for future updates
$Summary = $Recommendations | ForEach-Object {
if ($_.Id -lt 10) { $CleanID = "0"+$_.Id } else { $CleanID = $_.Id }
[PSCustomObject]@{
Id = $CleanID
Name = $_.Name
Status = $_.Status
Remediation = $_.Remediation
}
}
# Print out current status report
Clear-Host
Write-Host "Report:" -ForegroundColor Green
Write-Host ""
foreach ($Recommendation in $Summary)
{
switch ($Recommendation.Status)
{
"UnableToCheck"
{ Write-Host $Recommendation.Id "-" $Recommendation.Name ": " -NoNewline; Write-Host "Unable to detect" -ForegroundColor Yellow }
{$Recommendation.Status -eq "Ok"}
{ Write-Host $Recommendation.Id "-" $Recommendation.Name ": " -NoNewline; Write-Host "Passed" -ForegroundColor Green }
"Suppressed"
{ Write-Host $Recommendation.Id "-" $Recommendation.Name ": " -NoNewline; Write-Host "Suppressed" -ForegroundColor DarkGray }
default
{ Write-Host $Recommendation.Id "-" $Recommendation.Name ": " -NoNewline; if($Recommendation.Remediation -eq "Script") {Write-Host "Not implemented" -ForegroundColor Red -NoNewline; Write-Host " (Use 'Apply configurations' option to fix)" -ForegroundColor Yellow} else {Write-Host "Not implemented" -ForegroundColor Red;} }
}
}
return $Summary
}
# This function sets defined practice ID configuration on a server into a recommended state
function Set-VBRComplianceRecommendations($id)
{
switch ([int]$id){
1 {
Write-host "Disabling Remote Desktop Services (TermService)..." -NoNewline
Try {
# This action locks server from RDP access!
Set-Service "TermService" -StartupType "Disabled" -ErrorAction SilentlyContinue
Write-host "OK (Reboot required)" -ForegroundColor Green
}
Catch {Write-host "Failed" -ForegroundColor Red}
}
2 {
Write-host "Disabling Remote Registry service (RemoteRegistry)..." -NoNewline
Try {
Stop-Service "RemoteRegistry" -Force -ErrorAction SilentlyContinue
Set-Service "RemoteRegistry" -StartupType "Disabled" -ErrorAction SilentlyContinue
Write-host "OK" -ForegroundColor Green
}
Catch {Write-host "Failed" -ForegroundColor Red}
}
3 {
Write-host "Disabling Windows Remote Management (WinRM) service..." -NoNewline
Try {
Set-Service "WinRM" -StartupType "Disabled" -ErrorAction SilentlyContinue
Write-host "OK (Reboot required)" -ForegroundColor Green
}
Catch {Write-host "Failed" -ForegroundColor Red}
}
4 {
Write-host "Enabling Windows Firewall..." -NoNewline
Try {
Set-NetFirewallProfile -All -Enabled "True" -ErrorAction SilentlyContinue
Write-host "OK" -ForegroundColor Green
}
Catch {Write-host "Failed" -ForegroundColor Red}
}
5 {
Write-host "Disabling WDigest credentials caching..." -NoNewline
Try {
Remove-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" -Name "UseLogonCredential" -ErrorAction Ignore
Write-host "OK (Reboot required)" -ForegroundColor Green
}
Catch {Write-host "Failed" -ForegroundColor Red}
}
6 {
Write-host "Disabling Web Proxy Auto-Discovery service (WinHttpAutoProxySvc)..." -NoNewline
Try {
Set-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\WinHttpAutoProxySvc -Name Start -Value 4
Write-host "OK (Reboot required)" -ForegroundColor Green
}
Catch {Write-host "Failed" -ForegroundColor Red}
}
7 {
Write-host "Disabling deprecated versions of SSL and TLS..." -NoNewline
Try {
# Write-host "SSL 2.0"
New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server' -Force -ErrorAction SilentlyContinue | Out-Null
New-ItemProperty -path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server' -name 'Enabled' -value '0' -PropertyType 'DWORD' -Force -ErrorAction SilentlyContinue | Out-Null
New-ItemProperty -path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server' -name 'DisabledByDefault' -value 1 -PropertyType 'DWORD' -Force -ErrorAction SilentlyContinue | Out-Null
New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client' -Force | Out-Null
New-ItemProperty -path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client' -name 'Enabled' -value '0' -PropertyType 'DWORD' -Force -ErrorAction SilentlyContinue | Out-Null
New-ItemProperty -path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client' -name 'DisabledByDefault' -value 1 -PropertyType 'DWORD' -Force -ErrorAction SilentlyContinue | Out-Null
# Write-host "SSL 3.0"
New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server' -Force -ErrorAction SilentlyContinue | Out-Null
New-ItemProperty -path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server' -name 'Enabled' -value '0' -PropertyType 'DWORD' -Force -ErrorAction SilentlyContinue | Out-Null
New-ItemProperty -path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server' -name 'DisabledByDefault' -value 1 -PropertyType 'DWORD' -Force -ErrorAction SilentlyContinue| Out-Null
New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client' -Force -ErrorAction SilentlyContinue | Out-Null
New-ItemProperty -path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client' -name 'Enabled' -value '0' -PropertyType 'DWORD' -Force -ErrorAction SilentlyContinue | Out-Null
New-ItemProperty -path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client' -name 'DisabledByDefault' -value 1 -PropertyType 'DWORD' -Force -ErrorAction SilentlyContinue | Out-Null
# Write-host "TLS 1.0"
New-Item -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server' -Force -ErrorAction SilentlyContinue | Out-Null
New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server' -Force -ErrorAction SilentlyContinue | Out-Null
New-ItemProperty -path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server' -name 'Enabled' -value '0' -PropertyType 'DWORD' -Force -ErrorAction SilentlyContinue | Out-Null
New-ItemProperty -path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server' -name 'DisabledByDefault' -value 1 -PropertyType 'DWORD' -Force -ErrorAction SilentlyContinue | Out-Null
New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client' -Force -ErrorAction SilentlyContinue | Out-Null
New-ItemProperty -path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client' -name 'Enabled' -value '0' -PropertyType 'DWORD' -Force -ErrorAction SilentlyContinue | Out-Null
New-ItemProperty -path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client' -name 'DisabledByDefault' -value 1 -PropertyType 'DWORD' -Force -ErrorAction SilentlyContinue | Out-Null
# Write-host "TLS 1.1"
New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server' -Force -ErrorAction SilentlyContinue | Out-Null
New-ItemProperty -path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server' -name 'Enabled' -value '0' -PropertyType 'DWORD' -Force -ErrorAction SilentlyContinue | Out-Null
New-ItemProperty -path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server' -name 'DisabledByDefault' -value 1 -PropertyType 'DWORD' -Force -ErrorAction SilentlyContinue | Out-Null
New-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client' -Force -ErrorAction SilentlyContinue | Out-Null
New-ItemProperty -path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client' -name 'Enabled' -value '0' -PropertyType 'DWORD' -Force -ErrorAction SilentlyContinue | Out-Null
New-ItemProperty -path 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client' -name 'DisabledByDefault' -value 1 -PropertyType 'DWORD' -Force -ErrorAction SilentlyContinue | Out-Null
Write-host "OK (Reboot required)" -ForegroundColor Green
}
Catch {Write-host "Failed" -ForegroundColor Red}
}
8 {
Write-host "Disabling Windows Script Host..." -NoNewline
Try {
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows Script Host\Settings" -Name "Enabled" -PropertyType "DWORD" -Value "0" -Force -ErrorAction SilentlyContinue | Out-Null
Write-host "OK" -ForegroundColor Green
}
Catch {Write-host "Failed" -ForegroundColor Red}
}
9 {
Write-host "Disabling SMBv1 protocol..." -NoNewline
Try {
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force -ErrorAction SilentlyContinue | Out-Null
Disable-WindowsOptionalFeature -Online -FeatureName "SMB1Protocol" -NoRestart -ErrorAction SilentlyContinue | Out-Null
Write-host "OK (Reboot required)" -ForegroundColor Green
}
Catch {Write-host "Failed" -ForegroundColor Red}
}
10 {
Write-host "Disabling Link-Local Multicast Name Resolution (LLMNR)..." -NoNewline
Try {
New-Item "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT" -Name "DNSClient" -Force -ErrorAction SilentlyContinue | Out-Null
New-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" -Name "EnableMultiCast" -Value "0" -PropertyType "DWORD" -Force -ErrorAction SilentlyContinue | Out-Null
Write-host "OK (Reboot required)" -ForegroundColor Green
}
Catch {Write-host "Failed" -ForegroundColor Red}
}
11 {
Write-host "Enabling SMBv3 signing and encryption..." -NoNewline
Try {
Set-SmbServerConfiguration -EncryptData $true -Force -ErrorAction SilentlyContinue
Set-SmbServerConfiguration -EnableSecuritySignature $true -Force -ErrorAction SilentlyContinue
Set-SmbServerConfiguration -RequireSecuritySignature $true -Force -ErrorAction SilentlyContinue
Write-host "OK" -ForegroundColor Green
}
Catch {Write-host "Failed" -ForegroundColor Red}
}
19 {
Write-host "Setting unknown Linux servers trust settings..." -NoNewline
Try {
Set-VBRLinuxTrustedHostPolicy -Type "KnownHosts"
Write-host "OK" -ForegroundColor Green
}
Catch {Write-host "Failed" -ForegroundColor Red}
}
21 {
Write-host "Setting host to proxy traffic encryption in Network transport mode..." -NoNewline
Try {
Get-VBRViProxy | Where-Object {$_.UseSSL -ne $True} | Set-VBRViProxy -EnableHostToProxyEncryption -ErrorAction SilentlyContinue
Write-host "OK" -ForegroundColor Green
}
Catch {Write-host "Failed" -ForegroundColor Red}
}
32 {
Write-host "Setting recommended PostgreSQL settings (applies to local instances only)..." -NoNewline
Try {
Set-VBRPSQLDatabaseServerLimits -WA 0
Write-host "OK (Reboot required)" -ForegroundColor Green
}
Catch {Write-host "Failed" -ForegroundColor Red}
}
34 {
Write-host "Making LSASS to run as a protected process..." -NoNewline
Try {
if ($env:firmware_type -eq "UEFI") { Set-ItemProperty -Path "HKLM:SYSTEM\CurrentControlSet\Control\Lsa" -Name "RunAsPPL" -Value 1 }
else { Set-ItemProperty -Path "HKLM:SYSTEM\CurrentControlSet\Control\Lsa" -Name "RunAsPPL" -Value 2 }
Write-host "OK" -ForegroundColor Green
}
Catch {Write-host "Failed" -ForegroundColor Red}
}
35 {
Write-host "Disabling NETBIOS on all network interfaces..." -NoNewline
Try {
$interfaces = Get-ChildItem "HKLM:SYSTEM\CurrentControlSet\Services\NetBT\Parameters\Interfaces" | Select -ExpandProperty PSChildName
Foreach($interface in $interfaces) { Set-ItemProperty -Path "HKLM:SYSTEM\CurrentControlSet\Services\NetBT\Parameters\Interfaces\$interface" -Name "NetbiosOptions" -Value 2 }
Write-host "OK" -ForegroundColor Green
}
Catch {Write-host "Failed" -ForegroundColor Red}
}
default {Write-host "Unknown recommendation ID"}
}
}
# This function draws main menu
function Get-VeeamMenu
{
Write-host ""
Write-host "Available actions:" -ForegroundColor Green
Write-host ""
Write-host "1 : Refresh compliance report"
if ($RemediationCount -gt 0) {Write-host "2 : Apply ALL recommended configurations " -NoNewline; Write-host "(total:$RemediationCount)" -ForegroundColor Yellow } else {Write-host "2 : Apply all recommended security & compliance configurations"}
Write-host "3 : Apply selected configuration only..."
Write-host "0 : Exit"
Write-host ""
}
# Trigger execution
Clear-Host
# Validating MFA settings
Write-Host "Validating user permissions..."
try {
Start-VBRSecurityComplianceAnalyzer
}
catch {
if ($Error[0].Exception.Message.Contains("Unable to connect to the server with MFA-enabled user account.")) {
Write-Host "Unable to connect to the server with MFA-enabled user account. Consider KB4535 (https://www.veeam.com/kb4535)." -ForegroundColor Red
Exit
}
else {
Write-Host "Failed to start Security & Compliance Analyzer" -ForegroundColor Red
Exit
}
}
$Report = Get-VBRComplianceReport
do
{
# Things we can fix with the script
$RemediationActions = $Report | Where-Object {$_.Remediation -eq "Script" -and $_.Status -eq "Violation"}
$RemediationCount = ($RemediationActions | Measure-Object).count
Get-VeeamMenu
$choice = Read-host "Select action to perform"
Write-host ""
# Menu action list
switch ($choice)
{
0 { break }
1 { $Report = Get-VBRComplianceReport }
2 { foreach ($Action in $RemediationActions) {Set-VBRComplianceRecommendations $Action.ID} }
3 { $ActionID = Read-Host "Enter recommendation ID"; if ($Remediationactions.id -contains $ActionID) {Set-VBRComplianceRecommendations $ActionID} else { Write-host "Selected configuration ID does not need to be applied." -ForegroundColor Red } }
default { Write-host "Error: select correct action." -ForegroundColor Red}
}
} until ($choice -eq 0)