About Pre-Actions and Post-Actions
You can add actions you want to execute on the assets for the Windows, Linux, and Mac deployment job types. Using the pre-actions and post-actions, you can run scripts or install software on assets before or after the patches are installed. You can add actions to determine the software version, install the software before the latest patch can be applied, install a patch that is not supported out-of-the-box by Qualys Patch Management, remediate a vulnerability that might require a configuration change, and so on. You can run a job to execute only one or more actions without adding any patches.
You can add the following actions:
- Pre-Action: Action that you want to execute before the job starts.
- Post-Action: Action you want to execute after the job completes.
For detailed information, refer to the following sections:
Types of Actions
Types of pre-actions:
Pre-action Name |
Supported for Windows (Y/N) |
Supported for Linux (Y/N)
|
Supported for Mac (Y/N)
|
---|---|---|---|
Y |
Y |
Y |
|
Y |
N |
N |
|
Y |
N |
N |
|
Y |
N |
N |
|
Y |
N |
N |
Types of post-actions:
Post-action Name |
Supported for Windows (Y/N) |
Supported for Linux (Y/N)
|
Supported for Mac (Y/N) |
---|---|---|---|
Y |
Y |
Y |
|
Y |
N |
N |
|
Y |
N |
N |
|
Y |
N |
N |
Allows you to use a custom script to execute actions.
Field |
Description |
Available for (Windows, Linux, or Mac Deployment Job) |
---|---|---|
Action Name |
Enter the action name. You can choose to enable or disable the Bypass Execution Policy while adding the Run Script pre-action or post-action to a Windows deployment job. |
Windows, Linux, and Mac. |
Script Type |
Select the required script type. The supported script types are Shell Script and Apple Script. |
Mac |
Custom Script |
You can enter a custom script that you want to execute on the assets.
You can use the Write-Host command in the Powershell script to provide a custom message that is returned in case the action fails.
|
Windows, Linux, and Mac. |
Example 1: Run a script to check loop failure.
The error codes and failure descriptions are reported on the Job Progress screen. If a reboot return code is returned by the script, the agent will reboot based on the reboot policy defined for the job.
Example 2: Mac pre-actions and post-actions
Install SoftwareInstall Software
Allows you to create a pre-action or post-action to install a specific software or update software that Qualys Patch Management does not support out-of-the-box.
You must provide the following information:
Field |
Description |
Action Name |
The name of the software that you want to install. |
Note: You can choose to enable or disable the Bypass Execution Policy while adding the Install Software pre-action or post-action to a Windows deployment job. When you click the Click here link, you are navigated to the Configuration > Setup tab and then you can enable or disable the Bypass Execution Policy. For more information, see Bypass Execution Policy. |
|
Protocol |
Select https://, http://, or Network Share from the Protocol list. Enter the download URL in the URL field from where the software installer will be downloaded. Note: When you select the Network Share protocol, you can download the installable software file from the Universal Naming Convention (UNC) path you provide in the UNC field. |
File Checksum/Hash |
The agent validates the integrity of the downloaded file by comparing it to the hash that you provide. You can use publicly available methods, such as certUtil, to generate SHA256 for a file. |
Detection Script (optional) |
The detection script is used to determine whether to install the software on a specific asset. The script checks the pre-conditions that must be met for the software to be installed or updated. - Success, to indicate that the software can be installed on the asset: 0 |
Install Script |
This script performs the installation. The installer file downloaded by our agent is stored at the following location: %ProgramData%\Qualys\QualysAgent\PatchManagement\PatchDownloads\ You can check details in the log to understand why an action failed. The script returns one of the following codes after execution: You can use the Write-Host command in the Powershell script to provide a custom message that is returned in case the action fails. Note that if the script indicates that a reboot is required, the agent uses the job reboot preferences to enforce a reboot. Only one reboot is enforced for a patch job. |
For example, install Notepad++.
Change Registry KeyChange Registry Key
Allows you to add or update the registry key for an application before or after installation.
Field |
Description |
Key PATH ending with Key name |
Enter the key path, including the key name. You can change the following registry keys: - HKEY_CURRENT_USER - HKEY_USERS - HKEY_LOCAL_MACHINE - HKEY_CLASSES_ROOT - HKEY_CURRENT_CONFIG Note the following important points: - You cannot use a forward slash (/). - The path should not end with a backslash (\). - The path must contain at least one directory after the root path. |
Registry Type |
Select the registry key type. - REG_BINARY - REG_DWORD - REG_EXPAND_SZ - REG_MULTI_SZ - REG_QWORD - REG_SZ Note: Only numerical values are accepted for the REG_BINARY, REG_DWORD, and REG_QWORD registry key type. |
Registry Value name |
Based on the registry type selected, enter the registry value name. |
Registry Value data |
Based on the registry type selected, enter the registry value data. |
Add New Key |
Select one of the following options: - True: if you want to add the registry key in case it doesn't exist. - False: if you don't want to take any action in case the registry key doesn't exist. |
For example, change the registry key for Internet Explorer.
Uninstall SoftwareUninstall Software
Allows you to uninstall a specified software. Uninstall software is supported only on Windows with PM-enabled assets, and software with msi exec-based installers.
Field |
Description |
Action Name |
Enter an action name. Example: Uninstall Notepad++ 8.5 |
Uninstall Registry Key |
Enter the registry key path containing the registry value name. For example, for putty, HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{1E0D5689-40F1-4E46-ABBB-EAAC68B5CD89}. |
Software Display Name |
Enter the value data for the value name DisplayName under the registry key path. The value data is the exact name of the software that you want to uninstall. |
Software Display Version |
Enter the exact value data for the value name Version under the Registry key path. The value data is the version of the software that you want to uninstall. Note: If you don't specify a version, then any installed version of the software will be uninstalled.
|
Uninstall Software Version Match |
The Uninstall Software Version Match field is shown only when you enter details in the Software Display Version field. Note: When the Equals operator is selected, the software is uninstalled only if the Software Display Version that you provided matches the value data for the value name Version under the registry key. |
For example, uninstall Notepad ++ version 8.5.
The System Reboot pre-action ensures a machine reboot. The reboot takes effect after all job activities, if configured, are done and honors all the reboot-related settings if configured.
Field |
Description |
Action Name |
Enter the action name. Example: System reboot pre-action. |
Note: Consider the following points while creating and scheduling the job to which you want to add a ‘System Reboot’ pre-action: - As a cloud agent can run only one job at a time, ensure that other jobs are completed before this job runs for the ‘System Reboot’ pre-action to get executed successfully. - When you add the 'System Reboot' pre-action, you cannot enable the 'Suppress Reboot' option from the 'Deployment and Reboot Communication Options'. - You can create a job with a System Reboot action only and without patches. If you configure a job with patches and a System Reboot pre-action, and if the patches need a reboot after installation, the system will reboot only once at the end of the job execution. |
Examples
The following examples help you understand the pre-actions and post-actions user scenarios.
Windows Pre-Actions and Post-Actions Examples
Linux Pre-Actions and Post-Actions Examples
Mac Pre-Actions and Post-Actions Examples
Windows Pre-Actions and Post-Actions Examples
Example 1: To detect if the Notepad++ version 8.1.2 can be installed
This sample script detects if the software is installed or not. If the code returned is 0, the software can be installed, and if the code returned is 1, installation is not required.
Return Code:
- Success: 0
- Failure: 1
*********************************************************************** # Sample pre-detection script for Qualys Patch Manager * # * # This sample script demonstrate detection of installed * # software. It returns 0 if software can be installed * # and returns 1 if installation is not required * # * # * # Return Code * # * # 0 - success * # 1 - failure * #************************************************************* # required parameter [string]$SoftwareName = "notepad++*" [string]$SoftwareVersion = "8.1.2" # Print OS info for asset information and troubleshooting Write-Host "Gathering OS Information..." $osInfo = Get-CimInstance Win32_OperatingSystem | Select-Object Caption, Version, ServicePackMajorVersion, OSArchitecture, CSName $properties = @{ Caption = $osInfo.Caption Version = $osInfo.Version ServicePackMajorVersion = $osInfo.ServicePackMajorVersion OSArchitecture = $osInfo.OSArchitecture HostName = $osInfo.CSNAme } $obj = New-Object -TypeName PSObject -Property $properties Write-Output $obj Write-Host "Looking for package installation...`n" # Check install key in both wow64 and normal path. Application can be either 32-bit or 64-bit. $32bit = Get-ItemProperty HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* $64bit = Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\* $programs = $32bit + $64bit $packageFound = $false foreach ($program in $programs) { $program = Write-Output $program | Where-Object Displayname -like $SoftwareName if ($null -ne $program.DisplayName) { $LastModified = (Get-Item $program.uninstallstring).lastwritetime $properties = @{ ProgramName = $program.DisplayName Publisher = $program.Publisher Version = $program.DisplayVersion UninstallString = $program.UninstallString LastModified = $LastModified } $package = New-Object -TypeName PSObject -Property $properties Write-Output $package $packageFound = $true break; } } if ($packageFound -eq $false) { Write-Host "No installed package found" # Package needs to be isntalled exit 0 } Write-Host "Checking installed software version..." [System.Version] $installedVersion = $package.Version [System.Version] $ExpectedVersion = $SoftwareVersion if ($installedVersion -lt $ExpectedVersion) { Write-Host "Installed software is older than required version. Patch upgrade needed." exit 0 } else { Write-Host "Installed software is up to date." exit 1 }> |
Example 2: To install the Notepad++ version 8.1.2
This sample script demonstrates the installation of software. If the code returned is 0, the software is installed successfully, and if the code returned is 1, the installation fails.
Return Code:
- Success: 0
- Failure: 1
#************************************************************* # Sample install script for Qualys Patch Manager * # This sample script demonstrate installation of * # software. It returns 0 if software is installed * # successfully and returns 1 if installation fails. * # Return Code * # 0 - success * # 1 - failure * #************************************************************* [string]$PackageName = "npp.8.1.2.Installer.x64.exe" [string]$InstallerLocation = $Env:ProgramData + "\Qualys\QualysAgent\PatchManagement\PatchDownloads\" [string]$Arguments = "/S" #set this 1 if reboot is required after package installation [int]$RebootFlag = 1 function Get-QualysScriptReturn { param ( [ValidateRange(0, 1)] [Int] $Success_Code, [ValidateRange(0, 1)] [Int] $RebootFlag ) return $Success_Code + ($RebootFlag * 10) } function Start-Program { param ( [ValidateNotNullOrEmpty()] [string] $ProgramFullPath, [Parameter(Mandatory = $false)] [string] $Arguments )
try { $pinfo = New-Object System.Diagnostics.ProcessStartInfo $pinfo.FileName = $ProgramFullPath $pinfo.RedirectStandardError = $true $pinfo.RedirectStandardOutput = $true $pinfo.UseShellExecute = $false
if ($null -ne $Arguments) { $pinfo.Arguments = $Arguments }
$pinfo.WorkingDirectory = Get-Location $p = New-Object System.Diagnostics.Process $p.StartInfo = $pinfo $p.Start() | Out-Null $p.WaitForExit() $stdout = $p.StandardOutput.ReadToEnd() $stderr = $p.StandardError.ReadToEnd()
Write-Host "Process Stdout:`n $stdout" Write-Host "Process Stderr:`n $stderr" Write-Host "exit code: "$p.ExitCode return $p.ExitCode } catch { Write-Host -ForegroundColor DarkRed "Failed to execute program" $_.Exception.Message return 1 } } Write-Host "Running install script to install -"$PackageName Write-Host "Looking package installer..." $InstallerFullPath = $InstallerLocation + $PackageName if (Test-Path $InstallerFullPath) { Write-Host "Found installer at "$InstallerFullPath } else { Write-Host "Installer does not exist at "$InstallerFullPath exit 1; } Write-Host "Launching installer..." $ReturnCode = Start-Program $InstallerFullPath $Arguments if ($ReturnCode -eq 0) { Write-Host -ForegroundColor Green "Installation successfull..." exit Get-QualysScriptReturn 0 $RebootFlag; } else { Write-Host -ForegroundColor DarkRed "Installation failed. See output for more details." exit 1 } |
Example 3: Custom script to create an array of text files
This sample script checks whether a specific file (pc.txt) already exists in a particular folder; if not, it generates a list of all AD computers and saves it to a new file named pc.txt. It returns 0 if the file does not exist and the latest AD computer list is saved and returns 1 if the file already exists.
Return Code:
- Success: 0
- Failure: 1
#************************************************************* # Sample custom script for Qualys Patch Manager * # * # This sample script checks whether a specific file * # (pc.txt) already exists in a particular folder; * # if not, it generates a list of all AD computers and * # saves it to a new file named pc.txt. It returns 0 if * # file does not exists and latest AD computer list is * # saved and returns 1 if file already exists. * # * # Return Code * # 0 - success * # 1 - failure * #************************************************************* #create array of text files $files=Get-ChildItem C:\data\*.txt | select -expand fullname #check if file exists inside the array $files -match "pc.txt" #if matching return “True” key then exit, if “False” then create a report if($files -eq 'False'){ Get-ADComputer -Filter * | Export-Csv -Path C:\data\pc.txt exit 0 } else{ exit 1 } |
Example 4: Sample run script to uninstall the software
The following sample run script that can be used to uninstall the software:
# Define the software name and registry key path $softwareName = "Notepad++ (64-bit x64)" # Replace with the exact name of the software # Function to uninstall software function Uninstall-Software { param ( [string]$softwareName ) # Search for the software in the uninstall registry keys $uninstallKeyPaths = @( "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*", "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" ) $uninstallString = $null foreach ($path in $uninstallKeyPaths) { $key = Get-ItemProperty -Path $path | Where-Object { $_.DisplayName -eq $softwareName } if ($key) { $uninstallString = $key.UninstallString break } } if ($uninstallString) { # Modify the uninstall string to add silent flags if ($uninstallString -match "msiexec") { $uninstallString += " /quiet /norestart" } elseif ($uninstallString -match "uninstall.exe") { $uninstallString += " /S" } elseif ($uninstallString -match "setup.exe") { $uninstallString += " /quiet" } else { $uninstallString += " /silent /quiet /norestart" } # Execute the uninstall command silently Start-Process -FilePath "cmd.exe" -ArgumentList "/c", $uninstallString -NoNewWindow -Wait Write-Host "Uninstalled $softwareName successfully." } else { Write-Host "$softwareName is not installed." } } # Function to remove registry key function Remove-RegistryKey { param ( [string]$registryKeyPath ) if (Test-Path $registryKeyPath) { Remove-Item -Path $registryKeyPath -Recurse -Force Write-Host "Removed registry key: $registryKeyPath successfully." } else { Write-Host "Registry key: $registryKeyPath does not exist." } } # Uninstall the software Uninstall-Software -softwareName $softwareName # Remove the registry key Remove-RegistryKey -registryKeyPath $registryKeyPath |
Linux Pre-Actions and Post-Actions Examples
Example 1: To copy the contents from one file to the other file.
This sample script detects if the contents from a source file are copied to the other file that is the destined file. If the code returned is 0, the content is successfully copied to the destined file, and if the code returned is 1, the content is not copied to the destined file.
Return Code:
- Success: 0
- Failure: 1
******************************************************************** #!/bin/bash # Specify the paths of the source file (the one you want to replace with) and the destination file (the one you want to replace).
# Check if the source file exists. # Copy the source file to the destination location. |
Example 2: To install the RPM package for a specific application
This sample script detects whether or not the RPM package for a specific application is installed. If the code returned is 0, the RPM package is installed successfully; if the code returned is 1, the installation fails.
Return Code:
- Success: 0
- Failure: 1
********************************************************** #!/bin/bash # Check if the script is being run as root
# Check if an RPM file is provided as an argument
rpm_file="$1" # Check if the RPM file exists
# Install the RPM package
# Check the installation status
|
Mac Pre-Actions and Post-Actions Examples
Mac Zsh script examples
You can execute the following sample scripts on Mac ARM Agent 5.3.0.x:
Script 1: With this script, you can create a backup of the text file.
Before You Begin, you need to grant the execute permission for the sample shell script file after creating it using the following command:
chmod +x <filename.sh> |
Execute the following script:
bash-3.2$ ./Filebackup.sh
Result: The backup file (backup.txt) is created.
Script 2: With this script, you can check the network connectivity of the website
./networkconnectivity.sh |
Execute the following script:
./ networkconnectivity.sh
Result: Website www.google.com is unreachable.
Mac Apple Script Examples
Script 1: Apple Script to target an app for user interface scripting
The following sample scripts are executed on Mac ARM Agent 5.3.0.x.
Prerequisite
To run a user interface script in Script Editor, you must enable accessibility for Script Editor. Admin credentials are required to enable user interface scripting.
tell application "System Events" |
Result: Refer to the following screenshot, which displays a list of menu names.
Script 2: Apple Script to display a simple dialog box that shows the current date and time.
Script:
set theDialogText to "The current date and time is " & (current date) & "."
display dialog theDialogText
Result: The following dialog box is displayed.
Consider this
- You can add pre-actions and post-actions to Windows, Linux, and Mac jobs.
- You can only add actions on assets with Windows Cloud Agent version 4.6.1.6 or later.
- You can add a maximum of five pre-actions and post-actions each for a job.
- If one action fails, the other actions continue to execute.
- The script size cannot exceed 20 KB, and the script length must not exceed 20480 characters, including spaces. The script beyond 20480 characters will be truncated.
- Success or failure of action execution does not impact the patches that are part of the job. Installation of all patches in a job is attempted.
- The run time for each action can be at most 180 minutes. If the action is not completed within 180 minutes, the subsequent action is executed.
- Only one reboot request is honored for one job. If the pre-actions require a reboot, the reboot will happen only after the patches are installed. Post-actions might be executed after the reboot.
- If a post-action requires a reboot, the job is considered complete only after a reboot.
- We strongly recommend not to use a force reboot in the script. Since Patch Management only allows one reboot for one job, this can cause the job to go into a reboot loop.
- You can view details for each action using the Job Progress option after the job is executed. For more information, see Viewing Action Details.
- You can include the pre-actions and post-actions results in the job progress report. For more information, refer to Reviewing Job Results.
- For the Install Software action type, ensure that you provide the SHA256 based checksum of the download file.
- The scripts you provide are sent in the base64 encoded format.
- Only PowerShell scripts are supported, and we recommend using signed scripts. The PowerShell scripts are executed based on the execution policy that you define. Patch Management will support all execution policies; however, we recommend using AllSigned or RemoteSigned execution policy for security reasons. For more information, see About Execution Policies.
To ensure scripts are executed on an asset, ensure that PowerShell scripts are not blocked on the device or, in case the execution policy only allows signed scripts to run, ensure that you provide a signed script and paste the script and its signature both in the script text box.
- You can use publicly available methods, such as certUtil, to generate SHA256 for a file. For example, you can run the following command in your command prompt: certUtil -hashfile "<<filename>>" SHA256.
- For the Install Software action type, ensure that the script you add contains the code to deploy the binary.
- The detection script acts as a pre-check for the Install Software action type. The detection script is not mandatory, and if you don't enter the detection script, the install script action will be executed directly. If the detection script fails, the install software. action will not be executed.
Patch Management performs no validation and executes any script you provide. We recommend that you exercise caution with the scripts that you run.
Related Links
Managing Patch Jobs for Windows Assets