Archive for the ‘SCCM’ Category

h1

VBScript: Run Optional SCCM Advertisements

October 13, 2009

Here’s a fairly simple script that will check for and execute all optional advertisments on a client machine. This could be modified to include checks for adverts that have already ran and not rerun or put a GUI around it to choose which adverts to run selectively.
If the code has not been downloaded to the client yet a content retrieval will be made automatically prior to running.

CAREFUL OF WORD WRAPPING

'==========================================================================
'
' VBScript Source File -- Created with SAPIEN Technologies PrimalScript 2009
'
' NAME: RunOptionalAdvertisements.vbs
'
' AUTHOR: William Bracken
' DATE : 10/12/2009
'
' COMMENT: Run optional advertisments
'
'==========================================================================
Dim oUIResource, programArray(), fs, f
Dim oPrograms, x, i, strLogFile, strFileName, UserTempPath, WindowsTempPath
Dim oProgram, programId, packageId, myProgram, WinTempLog, UsrTempLog
Const ForReading = 1, TemporaryFolder = 2, ForAppending = 8
Set fs = CreateObject("Scripting.FileSystemObject")
Set WSHShell = CreateObject("WScript.Shell")
windir = WSHShell.ExpandEnvironmentStrings("%WINDIR%")
UserTempPath = WSHShell.ExpandEnvironmentStrings("%TEMP%")
WindowsTempPath = windir & "\temp"
strFileName = "RunOptionalAdverts.log"
WinTempLog = WindowsTempPath & "\" & strFileName
UsrTempLog = UserTempPath & "\"& strFileName
strLogFile = UsrTempLog

CLEANLOG strLogFile
COLLECTMSG "Begin Logging", ""

' Validate connection to SCCM Client
Set oUIResource = CreateObject ("UIResource.UIResourceMgr")
If oUIResource Is Nothing Then
COLLECTMSG "CONNECT TO SCCM CLIENT", "Could not create Resource Object - quitting"
wscript.echo "Could not create Resource Object - quitting"
WScript.Quit
End If

'==========================================================================
' Begin Process
'==========================================================================
' Call ShowPrograms routine to get array of programs available
ShowPrograms

' Split Array And Call Sub to install
For Each program In programArray
strStrings = Split (program,";")
programId = strStrings(0)
packageId = strStrings(1)
' Call RunProgam routine to invoke installation
'RunProgram programId,packageId
Next

' Cleanup
Set oProgram=Nothing
Set oUIResource=Nothing

'==========================================================================
' Routines
'==========================================================================
Sub ShowPrograms
On Error Resume Next

Set oPrograms = oUIResource.GetAvailableApplications

If oPrograms Is Nothing Then
COLLECTMSG "SHOWPROGRAMS", "Failed to get programs object - quitting"
wscript.echo "Failed to get programs object - quitting"
Set oUIResource=Nothing
Exit Sub
End If
strCount = oPrograms.Count
COLLECTMSG "SHOWPROGRAMS", "There are " & strCount & " programs"
wscript.echo "There are " & strCount & " programs"
wscript.echo
strCount = strCount - 1

ReDim programArray(strCount)
x = 0
For Each oProgram In oPrograms
COLLECTMSG "SHOWPROGRAMS", "ProgramName:" & oProgram.Name & ";" & "PackageID:" & oProgram.PackageId
WScript.Echo "Program Name: " & oProgram.Name
WScript.Echo " Package ID: " & oProgram.PackageId
' build array
programArray(x) = oProgram.Name & ";" & oProgram.packageId
x = x + 1
Next
End Sub

Sub RunProgram(programId,packageId)
On Error Resume Next
' #region Disabled code
' if oUIResourceMgr.IsMandatoryProgramPending = 1 Then
' Wscript.Echo "Mandatory program pending. Try again later."
' Set oUIResource=Nothing
' Exit Sub
' End If
' #endregion

' Get Program object
Set oProgram = oUIResource.GetProgram(programId,packageId)
'WScript.Echo "oProgram: " & oProgram.Name
if oProgram is Nothing Then
COLLECTMSG "RUNPROGRAMS", "Couldn't get the program"
WScript.Echo "Couldn't get the program"
Set oUIResource=Nothing
Exit Sub
End If

'When was the program last ran?
Set myProgram = oUIResource.GetProgram(programId, packageId)
oldTime = myProgram.LastRunTime
COLLECTMSG "RUNPROGRAMS", "Last Run Time: " & oldTime
WScript.Echo oldTime

' Execute program
COLLECTMSG "RUNPROGRAMS", "Running program: " & programId & " " & packageId
Wscript.Echo "Running program: " & programId & " " & packageId
oUIResource.ExecuteProgram programId, packageId, True

' Wait for last ran to change...
Set myProgram = oUIResource.GetProgram(programId, packageId)
Do While myProgram.LastRunTime = oldTime
Wscript.Sleep(2500)
Set myProgram = oUIResource.GetProgram(programId, packageId)
Loop
COLLECTMSG "RUNPROGRAMS", "Return Code: " & Err
WScript.Echo "Return Code: " & Err
End Sub

'*************************************************************
'*** Method: COLLECTMSG
'*** Description: Collections Errors for logging to log file
'*************************************************************
Sub COLLECTMSG(szLocation, errmsg)
'on error resume next
'Dim f
strmsg=errmsg
Set f = fs.OpenTextFile(strLogFile, ForAppending, True)
strmsg = Now & " | " & szLocation & " | "& errmsg
if err0 then
strmsg=strmsg & vbCrLf _
& "Error | " & Hex(Err.Number) & " h (" & CStr(Err.Number) & ") | Description |" & Err.Description
end if
f.Writeline strmsg
f.Close
strmsg=""
Err.Clear
End Sub

Sub CLEANLOG(strLogFile)
If fs.FileExists(strLogFile) Then
fs.DeleteFile strLogFile
End If
End Sub

h1

Adding Duplicate Drivers to SCCM SP1

September 26, 2009

Another one of the most glaring deficiencies in my opinion with OS deployment using SCCM is the inability to import the same drivers for different models.  I personally prefer to import ALL drivers for every model of machine I have versus trying to dig through other imported drivers and piece together what each model actually needs.  It can be quite frustrating to say the least.  I break up my drivers by model and would love to out of the box (I believe this may addresses in SP2) simply import the entire driver set in each subfolder, then create a package per model and assign the drivers from the subfolders to their respective package.  Well the good news is you CAN!  You simply have to trick SCCM into allowing you to do this.  Its quite simple actually. SCCM bases whether drivers are the “same” based on the calculated hash value of the driver files.  By simply adding a unique text file to the driver folder it creates a different hash value and allows you to import them even if the actual drivers have already been imported.  How I do it:

Break your drivers down by model in their own subfolders:
Example:
\\Server\share$\Drivers\Latitude E6500\Audio
\\Server\share$\Drivers\Latitude E6500\Video
Etc..

\\Server\share$\Drivers\Latitude E4300\Audio
\\Server\share$\Drivers\Latitude E4300\Chipset
etc..

Now open the root folder and create a new txt file based on the model.
Example:
\\Server\share$\Drivers\Latitude E4300\Latitude E4300.txt

Now copy this file to your clipboard, then do a windows search within the root directory for “*”.  Sort by type to gather all the folders at the top of the search.  Right click on EACH folder within the search and past the model specific txt file.

Do this for each of your driver sets and when you import them into their own sub-folder under the drivers node they will import even if the actual driver has already been imported.  :-)   you can now make corresponding packages for each model all with their OWN version of their drivers.

I know this has made my life SO much better with managing drivers in SCCM.  I hope it helps someone else.

h1

How to prevent optional PXE Adv from popping on clients

January 27, 2009

Once of the glaring deficiencies of SCCM OSD deployment (in my opinion of course) is the default behavior of an optional PXE advertisement.  Effectively if you want to have more than one pxe advertised task sequence the one that you DIDN’T execute will eventually pop up on every machine that has not run it before as an optional advertisement.  If the user clicks it and tries to run it (assuming your task sequence is set to do so) it will fail as it should be designed to only run within Windows PE.  Not a concern from a user accidentally rebuilding their own pc however not a viable option to have this popup on everyone and thus freak out the organization.  Well fortunately I have discovered a workaround for this issue.  It’s quite simple actually.  ;)

This is assuming you have your “PXE” TS adverts and your “Push” TS Adverts separated.
*ALWAYS test any new changes in a lab environment prior to production implementation*
Right-Click your PXE advertisement and go to Properties.
Click the Advanced tab.
Select the radio button “This task sequence can only run on the specified client platforms”
Now find a platform that you will not have in your environment.  In my case I have selected “x64 Windows XP Professional SP1”.  I should not have this OS version on my network.  If I do it’s unsupported and the machine needs to be rebuilt as we currently do not support ANY x64 OS’s.  ;)
Give that several minutes to propagate the changes.
You can then turn off the mandatory advertisement.  Your client will receive the advertisement however they will reject it based on the platform restriction.  This has no effect on your PXE building since the platform is not evaluated as part of the PXE build process.

You can now have multiple PXE adverts.  This is invaluable for testing build updates, etc.

One thing to keep in mind is that when you make your adverts optional the auto PXE boot (after selecting the network card as your boot device) goes away and you must press F12 (again) to initiate the connection.

I have found a workaround for this in my environment however the big disclaimer here is that this is NOT a supported solution from Microsoft.

F12 workaround:
On your WDS server(s) navigate to
D:\RemoteInstall\SMSBoot\x86
Make a copy of your pxeboot.com (the version that prompts you to press F12)
Delete the original pxeboot.com
Make a copy of pxeboot.n12 (the version that bypasses the additional F12 prompt)
Rename this copy to pxeboot.com
Flag this file as READ-ONLY.  If you do not do this the next reboot of your server will revert this file back.
Restart your WDS service and away you go.

Hope this helps someone else out there!!

h1

Image Capture: VPC vs VMWare

October 20, 2008

Just thought I may be able to save someone else out there a headache..

Although I am typically a much bigger proponent of VMWare products in terms of performance I found out the hard way that building and capturing an image from VMWare (Server 2.0) works great in most cases for newer hardware. I also discovered that the “IDE” mass storage driver in VMWare Server 2.0 would not allow the image to boot on older hardware (think Latitude D800, 600, etc). I spent a couple of days trying to find a set of driver that I could inject to get the machines working but to no avail. I had used Virtual PC 2007 in the past to build and capture but the performance is so lacking compared to VMWare I figured I would start there first. Well a long story short, after I went back to using Virtual PC 2007 (SP1) as my base machine for build and capture my “older” hardware is now back to booting properly and my newer hardware continues to function by injecting their mass storage drives as needed.

The moral of the story? Use Virtual PC 2007 to build and capture your image! Then you can turn it off and use VMWare for everything else. ;)

h1

PXEFilter.vbs update to auto clear last PXE Advert

September 27, 2008

** This script has been deprecated with the release of SCCM 2007 R2.  It supports “Unknown Machines” inherently

I have modified the PXEFilter.vbs that ships with MDT 2008 to automatically clear the last PXE advertisement of the machine that is PXE booting. This allows me to set a mandatory assignment for my OS Deployment and removes the requirement for field techs to have to open the admin console to re-image a machine via PXE.

The section I added was:

‘//————————————————————-
‘// Clear Last PXE Advertisement
‘//————————————————————-
On Error Resume Next
Dim resources
Dim InParams

‘ Set up the Resource array parameter.
resources = Array(1)
resources(0) = iResourceID

Set InParams = oSMS.Get(“SMS_Collection”).Methods_(“ClearLastNBSAdvForMachines”).InParameters.SpawnInstance_
InParams.ResourceIDs = resources

oSMS.ExecMethod “SMS_Collection”,”ClearLastNBSAdvForMachines”, InParams

if Err.number <> 0 Then
PXE.LogTrace “Failed to clear PXE advertisement for resource: ” & iResourceID
Else
PXE.LogTrace “Clear PXE Advertisement Completed successfully for resource: ” & iResourceID
End If

h1

SMS_SQL_MONITOR Service Fails after upgrade to SCCM

September 27, 2008

After upgrading my SMS 2003 SP2 site to SCCM 2007 SP1 the “SMS_SQL_MONITOR” service would fail to start stating Error 2: Cannot find the specified file.

I finally figured out (by stumbling across the website below) that this service is an SMS 2003 service only and is not required for SCCM. Apparently this is a bug in the Setup that doesn’t remove this service for you..

*I should also note that I verified that this service does not exists in my clean install of SCCM in my Lab.

Instructions on removing this service here:
http://blogs.technet.com/alipka/archive/2008/07/22/sccm-sp1-slipstream-setup-on-sms-2003-sp2-sp3-site-fails-to-remove-sms-sql-monitor-service.aspx

h1

Windows PE 2.0 AD Scripting requirements

September 27, 2008

 From the Vista install.wim or from a Vista machine retrieve the following files (located in the System32 directory):

adsldp.dll
adsnt.dll
mscoree.dll
mscorier.dll
mscories.dll

Mount your Windows PE boot image using imagex.
Example:
imagex /mountrw c:\PathToPEWim\WinPE.wim 1 c:\Mounted_Images

Copy the dll files above to c:\Mounted_Images\Windows\System32

Using regedit, load the SOFTWARE hive from your PE 2.0 Boot WIM and call it PE_Software.
(Location of the Software hive:
c:\Mounted_Images\Windows\System32\config\SOFTWARE)

Save the text below as a reg file. With the PE_Software hive loaded, import the registry key. UNLOAD the hive when finished to save the changes.
Unmount and commit changes to your PE wim image. Read the rest of this entry ?

h1

SCCM: Interactive Software install during Task Sequence

September 27, 2008

When building my base OS for capturing there always seems to something that cant be automated or is a royal pain to automate. Using the SCCM TS “Software Install” it has to be completely non interactive. This present a challenge for something you may want to install by hand. Here’s a trick to get around that:

Turn on the command shell capability in the Boot Image and when your in your “State Restore” phase press F8 to open a command window. Viola! you can now map a drive to a network share and execute (interactively) anything you like.