You are currently offline, waiting for your internet to reconnect

How to manually update scan engines in Microsoft Forefront Protection for Exchange Server or Microsoft Forefront Protection for SharePoint

Summary
This article describes how to manually update the scan engines in Microsoft Forefront Protection for Exchange Server or Microsoft Forefront Protection for SharePoint. You may have to do this if you experience issues with the updates.

This article also describes how to update the scan engines from a computer that does not have the Microsoft Forefront Protection server security products installed.


More information
To manually update the scan engines in Forefront Protection products and to update the scan engines from a computer that does not have these products installed, follow these steps.

Note These steps apply to both scenarios. However, in the first scenario, you can follow the steps on the Forefront server or on a remote server for a Universal Naming Convention (UNC) update. For more information about how to configure and perform UNC updates, see the Forefront Protection for Exchange Server User Guide, or the Forefront Protection for SharePoint User Guide.

  1. The Update-Engines.ps1 Powershell script can be found below. The script can be changed according to your needs. The update path, list of engines, and list of platforms can be changed in the script, or passed as parameters when the script is executed.

    Please note that when defining a specific engine(s), adhere to the following naming conventions:

    X86: Microsoft, Command, VBuster, Kaspersky, Norman, Wormlist

    AMD64: Microsoft, Command, VBuster, Kaspersky, Norman, Wormlist, Cloudmark

    Note The script defaults the engine update path to http://forefrontdl.microsoft.com/server/scanengineupdate/. By default, all engines will be downloaded for both the 32-bit and 64-bit platforms.
  2. Create a local directory structure on the computer on which you want to download the scan engine updates. To do this, follow these steps:
    1. Create a directory. For example, create a directory that is named "ScanEngineUpdates."

      Note
      This directory must be passed as a parameter to the script.
    2. Set the NTFS file system and share permissions on the directory so that the target Forefront servers have access to the directory.
  3. Open Notepad. Paste the following script into the file. Choose File and Save As. Under Save as type, select All Files (*.*) and save it as Update-Engines.ps1.
    #--------------------------------------------------------------------------------------- # The UpdateEngines script demonstrates how to download engine packages for use# by the Forefront Protection for Exchange and Sharepoint products.## What the script does:#        #        * Downloads copies of the UniversalManifest, EngineInfo.#        * Downloads and extracts the full update package for the#          specified engines for each specified platforms. This script #          automatically creates directories under this root (metadata, x86, amd64) #          and a script specific temp directory used during the processing.#--------------------------------------------------------------------------------------- param(  [string]$EngineDirPath,  [string]$UpdatePathUrl = "http://forefrontdl.microsoft.com/server/scanengineupdate/",  [string[]]$Engines = ("Microsoft", "Norman", "Command", "VBuster", "Kaspersky", "WormList", "Cloudmark"),  [string[]]$Platforms = ("x86", "amd64"))# Display Helpif (($Args[0] -eq "-?") -or ($Args[0] -eq "-help")) {	""	"Usage: Update-Engines.ps1 [-EngineDirPath <string>] [[-UpdatePathUrl] <update url>] [[-Engines] <engine names>] [[-Platforms] <platform names> "	"       [-EngineDirPath <string>]           The directory to serve as the root engines directory"	"       [-UpdatePathUrl <update url]        The update path used to pull the updates from"	"       [[-Engines] <engine names>[]]       The list of names of engines to update"	"       [[-Platforms] <platform names>[]]   The list of names of platforms to update"	""	"Examples: "    "     Update-Engines.ps1 -EngineDirPath C:\Engines\"    "     Update-Engines.ps1 -EngineDirPath C:\Engines\ -UpdatePathUrl http://forefrontdl.microsoft.com/server/scanengineupdate/ -Engines Microsoft -Platforms amd64, x86"	""	exit}if ($EngineDirPath.Length -eq 0){    $(throw "The EngineDirPath is not set. Please set the EngineDirPath parameter to a valid directory.")}# The directory to store the engines with needs to contain# a trailing slash.if (!$EngineDirPath.EndsWith("\")){    $EngineDirPath += "\"}# Constants used in the script$ShellProgId = "Shell.Application"$DoNotDisplayProgress = 4$YesAll = 16$NoConfirmDirectory = 512$NoUI = 1024$UmFileName = "UniversalManifest.cab"$EliFileName = "EngineInfo.cab"# Checks if the specified path exists.# If not the directory is created.function CreatePath($path){    if ((Test-Path $path) -ne $true)    {        New-Item -type Directory $path        Write-Host "Created: " $path    }}# Use the Shell.Application COM object to extract the# contents of the sourceCabPath and put the contents into# the destinationDirectory. Support is included for cab# files with sub directory hierarchies.function ExtractCab($sourceCabPath, $destinationDirectory){    # Determine if we can call the expand.exe utility    # if so use it, otherwise, use the Shell.Application    # COM object to perform the expansion of the CAB       & "expand.exe"        if($?)    {                & "expand.exe" "-R" $sourceCabPath "-F:*" $destinationDirectory    }    else    {            $shell = new-object -comobject $ShellProgId        if(!$?)        {            $(throw "unable to create $ShellProgId object")        }        $source = $shell.Namespace($sourceCabPath).items()        $destination = $shell.Namespace($destinationDirectory)        $flags = $DoNotDisplayProgress + $YesAll + $NoConfirmDirectory + $NoUI        $itemCount = $source.Count        $cabNameLength = $sourceCabPath.Length                $cachedDestDir = ""            $relativeDest = ""                # Process each item in the cab. Determine if the destination        # is a sub directory and create if necessary.        for($i=0; $i -lt $itemCount; $i++)        {            $lastPathIndex = $source.item($i).Path.LastIndexOf("\");                        # If the file inside the zip file should be extracted            # to a subfolder, then we need to reset the destination            if ($lastPathIndex -gt $cabNameLength)            {                $relativePath = $source.item($i).Path.SubString(($cabNameLength + 1), ($lastPathIndex - $cabNameLength))                $relativeDestDir = $destinationDirectory + $relativePath                                if ($relativeDestDir -ne $cachedDestDir)                {                    $relativeDest = $shell.Namespace($relativeDestDir)                    $cachedDestDir = $relativeDestDir                }                                $relativeDest.CopyHere($source.item($i), $flags)            }            else            {                $destination.CopyHere($source.item($i), $flags)            }        }    }}#--------------------------------------------------------------------------------------- # Main Script#--------------------------------------------------------------------------------------- Write-Host "Update Path: " $UpdatePathUrlWrite-Host "Engine Directory: " $EngineDirPathWrite-Host "Engines: " $EnginesWrite-Host "Platforms: " $Platformsif ((Test-Path $EngineDirPath) -ne $true){    $(throw "The directory specified to store the engines does not exist or the user this script is running as does not have permissions to access it. " + $EngineDirPath)         }$tempFilePath = $EngineDirPath + "temp\"$wc = new-object System.Net.WebClient# Download the Universal Manifest file$url = ($UpdatePathUrl + "metadata/UniversalManifest.cab")$umFilePath = $EngineDirPath + "metadata\UniversalManifest.cab"$metaDataDir = $EngineDirPath + "metadata\"CreatePath $metaDataDir$wc.DownloadFile($url, $umFilePath)CreatePath $tempFilePath# Delete any temporary files left over from# any previous runs of the scriptRemove-Item ($tempFilePath + "*.*")# Extract the xml file from the cab# so we can parse and read the dataExtractCab $umFilePath $tempFilePath# Read in and process the contents of the # Universal Manifest file. [xml]$umFile = Get-Content($tempFilePath + "UniversalManifest.xml")# Check if we need to download a new Engine License Info file$engineInfoVersion = $umFile.UniversalManifest.licenseInfoVersionWrite-Host "The current Engine License Info version: " $engineInfoVersion$engineInfoFilePath = $EngineDirPath + "metadata\" + $engineInfoVersionCreatePath $engineInfoFilePath$engineInfoFilePath += "\" + $EliFileName# If the versioned directory does not exists# download the new version of the Engine License Infoif ((Test-Path $engineInfoFilePath) -ne $true){    Write-Host "The current version of the Engine License Info needs to be downloaded."    $engineInfoURL = ($UpdatePathUrl + "\metadata\" + $engineInfoVersion + "/" + $EliFileName)    $wc.DownloadFile($engineInfoURL, $engineInfoFilePath)        Write-Host "The Engine License Info download is complete."}Write-Host "Begin Processing Engine Updates"# Process each engine in the Universal Manifest# and download all applicable enginesforeach ($p in $Platforms){    $platform = $umFile.UniversalManifest.EngineVersions.SelectSingleNode(("Platform[@id='" + $p + "']"))        if ($platform -isnot [System.Xml.XmlElement])    {       $(throw "The Platform '" + $p + "' is not valid.")     }        Write-Host "Platform: " $platform.id            foreach ($e in $Engines)    {        $engine = $platform.SelectSingleNode(("Category/Engine[@name='" + $e + "']"))                if ($engine -isnot [System.Xml.XmlElement])        {            $errMsg = "The engine name '" + $e + "' is not valid."             Write-Error $errMsg -Category InvalidArgument        }        else        {                   Write-Host "Engine: " $engine.Name "UpdateVersion: " $engine.Package.version                           $manifestFileNameRoot = "manifest." + $engine.Default            $manifestFileName = $manifestFileNameRoot + ".cab"            $engineUrl = $UpdatePathUrl + $platform.id + "/" + $engine.Name + "/" + "Package/"            $manifestUrl =  ($engineUrl + $manifestFileName)            $enginePath = $EngineDirPath + $platform.id + "\" + $engine.Name + "\Package\"                    Write-Host "Begin download: " $engine.Name " Url: " $manifestUrl                    CreatePath $enginePath                    $manifestPath = $enginePath + $manifestFileName                    $wc.DownloadFile($manifestUrl, $manifestPath)                                    # Delete any temporary files left over from            # any previous runs of the script            Remove-Item ($tempFilePath + "*.*")            ExtractCab $manifestPath $tempFilePath                    [xml]$manifest = Get-Content($tempFilePath + "manifest.xml")                    $fullPkgDir = $enginePath + $manifest.ManifestFile.Package.version + "\"                    CreatePath $fullPkgDir                    $fullPkgUrl = $engineUrl + $manifest.ManifestFile.Package.version + "/" + $manifest.ManifestFile.Package.FullPackage.name            $fullPkgPath = ($fullPkgDir + $manifest.ManifestFile.Package.FullPackage.name)                        $wc.DownloadFile($fullPkgUrl, $fullPkgPath)                        # Detect if there are any subdirectories            # needed for this engine            $subDirCount = $manifest.ManifestFile.Package.Files.Dir.Count                        for($i=0; $i -lt $subDirCount; $i++)            {                CreatePath ($fullPkgDir + $manifest.ManifestFile.Package.Files.Dir[$i].name)            }                        ExtractCab $fullPkgPath $fullPkgDir                        # Copy the downloaded manifest to the package directory            Copy-Item $manifestPath -Destination $fullPkgDir                        Write-Host "Download Complete: " $engine.Name        }                }}Write-Host "Engine Update processing completed."# Clean up the temporary directory# that is used during the updateRemove-Item $tempFilePath -recurse
  4. Execute the Update-Engines.ps1 Powershell script, providing any necessary parameters. The format of the command is as follows:
    Update-Engines.ps1 -EngineDirPath <string> -UpdatePathUrl <update url> -Engines <engine names> -Platforms <platform names>
    • EngineDirPath <string> The directory to serve as the root engines directory, created in step 2. This is a required parameter
    • UpdatePathUrl <update url> The update path used to pull the updates from
    • Engines <engine names> The list of names of engines to update

      Note Multiple engine names should be seperated by commas, with or without spaces.
    • Platforms <platform names> The list of names of platforms to update
    Examples:
    Update-Engines.ps1 -EngineDirPath C:\ScanEngineUpdates\
    Update-Engines.ps1 -EngineDirPath C:\ScanEngineUpdates\ -UpdatePathUrl http://forefrontdl.microsoft.com/server/scanengineupdate/ -Engines Microsoft -Platforms amd64, x86
    Update-Engines.ps1 -EngineDirPath C:\ScanEngineUpdates\ -UpdatePathUrl http://forefrontdl.microsoft.com/server/scanengineupdate/ -Engines Microsoft -Platforms amd64, x86
  5. You can now configure Forefront servers to download updates from the directory created in step 2 by using a UNC path of a share name, such as \\server_name\share_name.


Properties

Article ID: 2292741 - Last Review: 09/18/2012 06:39:00 - Revision: 3.0

Microsoft Forefront Protection 2010 for Exchange Server, Microsoft Forefront Protection 2010 for SharePoint

  • KB2292741
Feedback
"display:none;" onerror="var m=document.createElement('meta');m.name='ms.dqp0';m.content='true';document.getElementsByTagName('head')[0].appendChild(m);" onload="var m=document.createElement('meta');m.name='ms.dqp0';m.content='false';document.getElementsByTagName('head')[0].appendChild(m);" src="http://c1.microsoft.com/c.gif?"> s track by $index" class="col-sm-6 col-xs-24 ng-scope"> Paraguay - Español
Venezuela - Español
://c1.microsoft.com/c.gif?DI=4050&did=1&t=">0&did=1&t=">andom() * 16).toString(16); })).replace("R", (8 | Math.floor(Math.random() * 3)).toString(16)); var m = document.createElement("meta"); m.content = guid; m.name = "ms.dqid"; document.getElementsByTagName("head")[0].appendChild(m); >