1. WSUS or SUP (Software Update Point in ConfigMan)
2. UNC shares
3. Windows Update
4. Microsoft Security Portal (http://www.microsoft.com/security/encyclopedia/adlpackages.aspx)
5. Manual method (such as ConfigMan, scheduled scripts or similar solution)
While we have a lot of options, some customers really want to use the Distribution Points and Advertisement in ConfigMan, as they have an existing investment in this and want the most control of the network bandwidth.
Step 1 and 2: We execute a scheduled script that:
1. Determines the current engine version.
2. Determines the current signature version.
3. Downloads either a delta update (if engine and signature have not passed the rebase period) or a full update.
4. Copies the downloaded file to a location for ConfigMan.
Step 1. Create the directories C:\FEPUpdates, C:\FEPUpdates\script and C:\FEPUpdates\defs on the Primary Site Server.
Step 2. In the C:\FEPUpdates\script directory, create the VBS Script in appendix A.
Step 3. Schedule the script to run every 6 hours by using the Windows Task Scheduler as shown below: Note: Because this will be a scheduled task, you will need a service account with a non-expiring password.
Step 4. Manually run the scheduled task, so that your directory structure and files will be populated before you setup the program and advertisement in ConfigMan.
Step 5. Create a package in ConfigMan to where the package updates from the source every 7 hours as shown below:
Step 6. Create a program in the above package that runs the command cmd.exe /c "%PROCESSOR_ARCHITECTURE%\mpam-d.exe" as shown below:
Step 7. Schedule a reoccurring advertisement in ConfigMan that runs every 8 hours, as shown below:
' FEP Download delta definitions
'Customer needs to modify these for local environment '================================================================================================ strRootLocation = "C:\FEPUpdates\Defs" ' this need to be modified to local path for root of the folder structures for updates strLogFile = "C:\FEPUpdates\script\DefDownloadv5.log" ' set this to where you want to save the log file at if not placing in strRootLocation then will need to insure that folder structure exists and specify full path strLogData = "" '================================================================================================ 'Constants to not modify value in this area '================================================================================================ Const ForReading = 1, ForWriting = 2, ForAppending = 8, WindowsFolder = 0 Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0 '================================================================================================
LogToEventLog = True strSigNameDelta = "mpam-d.exe" AVDelta = reduceByOne(ReadReg("HKLM\SOFTWARE\Microsoft\Microsoft Antimalware\Signature Updates\AVSignatureVersion")) ASDelta = reduceByOne(ReadReg("HKLM\SOFTWARE\Microsoft\Microsoft Antimalware\Signature Updates\ASSignatureVersion")) Engine = ReadReg("HKLM\SOFTWARE\Microsoft\Microsoft Antimalware\Signature Updates\EngineVersion") strMSEx86URLDelta = "http://go.microsoft.com/fwlink/?LinkID=121721&clcid=0x409&arch=x86&eng=" & Engine & "&avdelta=" & AVDelta & "&asdelta=" & ASDelta strMSEx64URLDelta = "http://go.microsoft.com/fwlink/?LinkID=121721&clcid=0x409&arch=x64&eng=" & Engine & "&avdelta=" & AVDelta & "&asdelta=" & ASDelta
'=============== Logging Function =======================================
Set objFSO = Createobject("Scripting.FileSystemObject") if (not objFSO.FileExists(strLogFile)) then objFSO.CreateTextfile strLogFile set fileObj = objFSO.GetFile(strLogFile) set logStream = FileObj.OpenAsTextStream(ForAppending, TristateUseDefault) logstream.writeline now & " " & "Log file created and opened" else set fileObj = objFSO.GetFile(strLogFile) set logStream = FileObj.OpenAsTextStream(ForAppending, TristateUseDefault) end if
'====================================================== '= Sub to downlaod and save the files '= __in objConnection winhttprequest object '= __in strURL the url of the fiel to download '= __in strPAth the path to save the file to '= __ FileName name of the file to be saved sub DownloadDefs(objConnection, strURL, Path, FileName, logfile) 'turn on error handeling on error resume next 'copy PAth to temp variable to manipulate strPath = Path 'check to see if the URL for x86 or x64 was passed set regEx = new RegExp regEx.Pattern = "x86" regEx.IgnoreCase = True regEx.Global = False
if (regEx.Test(strUrl)) then strPath = strPath + "\" + "x86" Else strPath = strPath + "\" + "x64" end if
LogData " > Download of " & strURL & " started at: " & now objConnection.open "GET", strURL, false if (err.Number <> 0) then LogData now & " " & "Error # " & CStr(err.number) & " " & Err.Description & " Source: " & Err.Source Err.Clear exit sub end if objConnection.send() if (err.Number <> 0) then LogData now & " " & "Error # " & CStr(err.number) & " " & Err.Description & " Source: " & Err.Source Err.Clear exit sub end if
'check to see if download was successful before moving on If objConnection.Status = 200 Then Set objADOStream = CreateObject("ADODB.Stream") objADOStream.Open objADOStream.Type = 1 'adTypeBinary
objADOStream.Write objConnection.ResponseBody objADOStream.Position = 0 'Set the stream position to the start
Set m_objFSO = Createobject("Scripting.FileSystemObject") 'check if folder structure exists if (m_objFSO.FolderExists(strPath)) then 'create complete path strCompletePath = strPath + "\" + FileName 'check if file exists if so delete If m_objFSO.FileExists(strCompletePath) Then m_objFSO.DeleteFile(strCompletePath) end if if (err.Number <> 0) then LogData now & " " & "Error # " & CStr(err.number) & " " & Err.Description & " Source: " & Err.Source Err.Clear exit sub end if else m_objFSO.CreateFolder(strPath) strCompletePath = strPath + "\" + FileName If m_objFSO.FileExists(strCompletePath) Then m_objFSO.DeleteFile(strCompletePath) end if if (err.Number <> 0) then LogData now & " " & "Error # " & CStr(err.number) & " " & Err.Description & " Source: " & Err.Source Err.Clear exit sub end if end if objADOStream.SaveToFile(strCompletePath) if (err.Number <> 0) then LogData now & " " & "Error # " & CStr(err.number) & " " & Err.Description & " Source: " & Err.Source Err.Clear end if objADOStream.Close LogData " >> " & strCompletePath & " Successfuly downloaded at: " & now end if 'Cleanup strCompletePath = "" strPath = "" Set objADOStream = Nothing Set m_objFSO = Nothing end sub
function reduceByOne(versionnumber) versionnumberSplit= Split(versionnumber,".") reduceByOne = versionnumberSplit(0) & "." & versionnumberSplit(1) & "." & versionnumberSplit(2)-1 & "." & versionnumberSplit(3) end function
sub LogData(mydata) logStream.writeline mydata if LogToEventLog then strLogData = strLogData & vbcrlf & mydata end sub
sub WriteToEventLog() Set WshShell = WScript.CreateObject("WScript.Shell") WshShell.LogEvent 0, strLogData end sub
Function ReadReg(RegPath) Dim objRegistry, Key Set objRegistry = CreateObject("Wscript.shell") Key = objRegistry.RegRead(RegPath) ReadReg = Key End Function
'======================================================================================= '=== Main program body '=======================================================================================
'Turn on error handeling for Main program body on error resume next ' create WINHTTP object used to retrieve the file Set objWINHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
LogData " " LogData "==================== " & now & " Download Session started ===================="
DownloadDefs objWinHTTP, strMSEx86URLDelta, strRootLocation, strSigNameDelta, logstream DownloadDefs objWinHTTP, strMSEx64URLDelta, strRootLocation, strSigNameDelta, logstream
LogData "===================== " & now & " Download Session ended ====================="
if LogToEventLog then WriteToEventLog()
'Clean UP set objFSO = nothing Set objWINHTTP = Nothing
Great documention on a workaround to what seems to be a lacking feature.
Having tested this out though, it seems like the expectation is that the version of FEP is consistent across all machines. Isn't this script checking the definition version on the SCCM server and then downloading the deltas accordingly? If so, what happens to clients that are not at the same version? In my testing it seems like the update fails. Perhaps this is due to the clients having the original engine version or will issues exist if the versions are not the same as the SCCM server?
jpalarchio, you need to have the FEP client get the latest definitions before using the directions above. It needs a full update before it can do deltas.
gadgetadam is correct, you need the full engine update first, as this is just a delta update.
If you look at the script, we use the function "reduceByOne" which rolls back the definition date. In my testing, the update worked pretty well and even caught up if the machine was a revision or two behind. the secret is the URL. As of right now, my engine is 1.1.6603.0 and my AV and AS definitions are: 1.99.1311.0. So you would use the URL: go.microsoft.com/fwlink to get the update. If you change this URL to be an earlier AV and AS, say: 1.99.1211.0 (go.microsoft.com/fwlink) you will see that it downloads the same ~3.27 MB file. This being the case, I don't imaging we will have an issue with a machine falling behind a day or so. On the monthly rebase, when the engine version changes, the URL will pull down the needed update. Try the URL: go.microsoft.com/fwlink and you will see what I mean (notice the engine version is -1.
The customer who really prompted me to write this was also using a UNC location where they would place full engine updates, but those were much larger (~60 mb) and they would only update these once a week or so.
Here's an alternative method for accomplishing the same thing using code from the SDK. This was put together by Kim Oppalfens.
www.myitforum.com/.../Articles.aspx
I'm new to SCCM/FEP and I will attempt to use this method to deploy updates to our remote DPs. In the guide it doesn't mention which collection I should advertise to...I was a little confused - do I advertise this to a collection that contains my DPs, my clients or both? I guess I'm not clear as to how the remote DPs get these updates and then distribute them.
Thanks!
Hello:
You should advertise the "Deployment Succeeded" collection and sub collections.
Regards,
Great stuff. In our environment, we have amd64 processors being detected.
Is there any way to add it to the script?
Right now I have created a batch file (not that good at scripting) that calls the script, then copies the files from the 'x64' folder to an 'amd64' folder.
The program command line in Step 6 was causing this error (Although the updates were installing)
"A failure exit code of -15 was returned. "
Changing it to "%PROCESSOR_ARCHITECTURE%\mpam-d.exe" fixed the error and now advertisement shows as successfully completing.
This method will definitely be used in our production environment when we switch over to FEP.
Thanks.