From f81fc674115d68e56c8d18a344a3e88f38bae71a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Miranda?= <143180482+sergiomiranda-outsystems@users.noreply.github.com> Date: Mon, 28 Jul 2025 02:21:06 +0100 Subject: [PATCH 1/2] Initial commit of function to set Windows Defender exceptions --- .../Functions/Set-OSServerWindowsDefender.ps1 | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 src/Outsystems.SetupTools/Functions/Set-OSServerWindowsDefender.ps1 diff --git a/src/Outsystems.SetupTools/Functions/Set-OSServerWindowsDefender.ps1 b/src/Outsystems.SetupTools/Functions/Set-OSServerWindowsDefender.ps1 new file mode 100644 index 0000000..5868fbd --- /dev/null +++ b/src/Outsystems.SetupTools/Functions/Set-OSServerWindowsDefender.ps1 @@ -0,0 +1,140 @@ +function Set-OSServerWindowsDefender { + + <# + + .SYNOPSIS + Creates exclusions in Windows Defender for directories and processes according to OutSystems and Microsoft recommendations. + + .DESCRIPTION + This will create exclusions in Windows Defender for critical directories and processes used by IIS, .NET Framework and OutSystems services, according to OutSystems and Microsoft recommendations. + https://success.outsystems.com/documentation/11/setup_outsystems_infrastructure_and_platform/setting_up_outsystems/performance_best_practices_for_your_outsystems_infrastructure/ + + + .PARAMETER SkipSystemTempExclusion + If specified, the exclusion for the System TEMP folder (usually C:\Windows\Temp) will not be added + This can be useful for cases where the security team doesn't agree with applying this exclusion. + + .EXAMPLE + Set-OSServerWindowsDefender -SkipSystemTempExclusion + + #> + + [CmdletBinding()] + param( + [Parameter()] + [switch]$SkipSystemTempExclusion + ) + + begin { + LogMessage -Function $($MyInvocation.Mycommand) -Phase 0 -Stream 0 -Message "Starting" + SendFunctionStartEvent -InvocationInfo $MyInvocation + + #region Check status of Windows Defender + + $WinDefenderStatus = Get-MpComputerStatus + if ( ($null -eq $WinDefenderStatus) -or + ($WinDefenderStatus.AntivirusEnabled -eq $false) -or + ($WinDefenderStatus.AMRunningMode -eq 'Not running') ) { + Write-Error 'Windows Defender is either not installed, not running or has AntiVirus features disabled.' -ErrorAction Stop + } + + #endregion + } + + process { + + #region Get variables + + # Get platform installation path variables + $PSInstallDir = Get-OSServerInstallDir -ErrorAction Stop + + # Get path to the profile of the account running the OutSystems Deployment Controller Service + $CntrllrSvcAccountName = (Get-CimInstance -ClassName CIM_Service -Filter "name='OutSystems Deployment Controller Service'").StartName + $CntrllrSvcAccount = New-Object System.Security.Principal.NTAccount($CntrllrSvcAccountName) + $CntrllrSvcAccountSID = $CntrllrSvcAccount.Translate([System.Security.Principal.SecurityIdentifier]).Value + $CntrllrSvcAccountProfilePath = (Get-CimInstance -ClassName Win32_UserProfile -Filter "SID='$CntrllrSvcAccountSID'").LocalPath + + # Get path to Temporary .NET Files directory + $TempDotNETFilesPath = (Get-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT' -Filter 'system.web/compilation' -Name 'tempDirectory').Value + if ($TempDotNETFilesPath -eq '') { + $TempDotNETFilesPath = "$env:SystemRoot\Microsoft.Net\Framework64\v4.0.30319\Temporary ASP.NET Files" + } + + # Get path to IIS Temporary Compression Files directory + $IISTempCompFilesPath = [System.Environment]::ExpandEnvironmentVariables((Get-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' ` + -Filter 'system.webServer/httpCompression' ` + -Name 'directory').Value) + + + # Get path to IIS Logs directory + $IISLogFilesPath = [System.Environment]::ExpandEnvironmentVariables((Get-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' ` + -Filter 'system.applicationHost/log/centralW3CLogFile' ` + -Name 'directory').Value) + + #endregion + + #region Add OutSystems recommended exclusions to Windows Defender + + LogMessage -Function $($MyInvocation.Mycommand) -Phase 1 -Stream 0 -Message "Adding OutSystems recomended exclusions to Windows Defender" + try { + # Platform installation directory + Add-MpPreference -ExclusionPath $PSInstallDir + + # .NET Framework config directory + Add-MpPreference -ExclusionPath "$env:SystemRoot\Microsoft.Net\Framework64\v4.0.30319\Config" + + # Temporary .NET Files directory + Add-MpPreference -ExclusionPath $TempDotNETFilesPath + + # OutSystems Services processes + Add-MpPreference -ExclusionProcess "$PSInstallDir\CompilerService\CompilerService.exe" + Add-MpPreference -ExclusionProcess "$PSInstallDir\DeployService\DeployService.exe" + Add-MpPreference -ExclusionProcess "$PSInstallDir\Scheduler\Scheduler.exe" + + # Controller service account Temp directory + Add-MpPreference -ExclusionPath "$CntrllrSvcAccountProfilePath\AppData\Local\Temp" + + # System Temp directory + if ($SkipSystemTempExclusion -ne $true) { + Add-MpPreference -ExclusionPath "$env:SystemRoot\Temp" + } + } + catch { + Write-Error 'Failed to add the OutSystems recommended exclusions to Windows Defender' + } + LogMessage -Function $($MyInvocation.Mycommand) -Phase 1 -Stream 0 -Message "Windows Defender exclusions added successfully" + + #endregion + + #region Add Microsoft recomended exclusions to Windows Defender + + LogMessage -Function $($MyInvocation.Mycommand) -Phase 1 -Stream 0 -Message "Adding Microsoft recomended exclusions to Windows Defender" + try { + # IIS Config directory + Add-MpPreference -ExclusionPath "$env:SystemRoot\System32\inetsrv\config" + + # IIS temp files directory + Add-MpPreference -ExclusionPath "$env:SystemDrive\inetpub\temp" + + # IIS Temporary Compressed Files (by defaut inthe above dir, but can be changed) + Add-MpPreference -ExclusionPath $IISTempCompFilesPath + + # IIS Logs directory + Add-MpPreference -ExclusionPath $IISLogFilesPath + + } + catch { + Write-Error 'Failed to add the Microsoft recommended exclusions to Windows Defender' + } + LogMessage -Function $($MyInvocation.Mycommand) -Phase 1 -Stream 0 -Message "Windows Defender exclusions added successfully" + + #endregion + + } + + end { + SendFunctionEndEvent -InvocationInfo $MyInvocation + LogMessage -Function $($MyInvocation.Mycommand) -Phase 2 -Stream 0 -Message "Ending" + } + +} \ No newline at end of file From e8e7c66ba8d98ed11df04b1b8210e3a5c30f1e14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Miranda?= <143180482+sergiomiranda-outsystems@users.noreply.github.com> Date: Thu, 7 Aug 2025 09:35:58 +0100 Subject: [PATCH 2/2] Add to the list of functions to export --- src/Outsystems.SetupTools/OutSystems.SetupTools.psd1 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Outsystems.SetupTools/OutSystems.SetupTools.psd1 b/src/Outsystems.SetupTools/OutSystems.SetupTools.psd1 index 9e5bbdb..860c9f6 100644 --- a/src/Outsystems.SetupTools/OutSystems.SetupTools.psd1 +++ b/src/Outsystems.SetupTools/OutSystems.SetupTools.psd1 @@ -106,6 +106,7 @@ FunctionsToExport = @( 'Set-OSServerPerformanceTunning', 'Set-OSServerPerformanceTunning2', 'Set-OSServerSecuritySettings', + 'Set-OSServerWindowsDefender', 'Set-OSServerWindowsFirewall', 'Start-OSServerServices', 'Stop-OSServerServices',