Showing posts with label SCCM. Show all posts
Showing posts with label SCCM. Show all posts

Wednesday, April 29, 2009

ConfigMgr.next revealed at MMS09

The MMS09 State of the Union session revealed what the next version of SCCM will look like.  The MMC is gone in favor of the Outlook-esqe toolbar (wonder-bar) as seen in SCOM 2007.  It also requires Server 2008 64-bit as well as SQL 2008 64-bit.  The other big piece of news is the elimination of ASP web reports in favor of SQL Server reporting services only.  See all the screen shots and read more about it on Kenneth van Surksum's blog:

http://www.techlog.org/archive/2009/04/29/mms_2009_information_about_mic

Thursday, January 15, 2009

wsutil to change your wsus server's ports

Following up on my recovery of a sccm site.  My original recovery doc did not specify that during the wsus install, wsus needs to be setup to use its own custom website on ports 8530 (for http) and 8531 (for https).  I later found that if you miss this step  (When you notice your site fails to sync with its wsus database) then there is a simple utility installed with wsus that will allow you to change it.  From the command line:

wsusutil.exe usecustomwebsite true

Also, if your site just isn't syncing for no apparent reason, I've found that a wsus reset may help:

wsusutil.exe reset

You can find wsutil on the wsus server in the program files\Update Services\Tools folder.

Friday, January 9, 2009

Recovery of SCCM Site Failure

Despite the fact that Microsoft has recovery information posted in their online support docs ( http://technet.microsoft.com/en-us/library/bb680474.aspx), site recovery is still a confusing task.  I've gone through several site recoveries and here are the notes from my last one, where the central site happened to fail.  An important note that I don't think is explained very well is that you have to have a functioning site setup the same way as the old site before you can recover the old site.

So before starting the site recovery review the original site setup procedure.  If you don't have one documented, then see the excellent write up by Ying Li: http://myitforum.com/cs2/blogs/yli628/archive/2008/06/25/setup-configmgr-2007-sp1-from-start-to-finish.aspx

Notes from recovery of Central site on 12/17/08.

1. OS, Server name, Site Code, and Drive layout (OS on C: and program files on drive d: ) should match original hardware.  (Do not move from 64-bit to 32-bit OS).

2. Install the OS and configure as normal

3. Give the machine account admin rights on the SQL server

4. Install WSUS 3.0 with SP1.  Do not use the default website.  Use custom website.  During install point it to the remote SQL server (if you use a remote sql server to host wsus metadata).  Do not overwrite the contents of the database.  Do not use the configuration wizard to setup wsus.  Simply exit when the configuration wizard starts.

5. Start copying the backup files to the local machine since it can take 1/2 hour.

6. Install the correct version of SCCM

a. Make sure to reuse the same program path (d:\sms for our Primary sites since they were upgrades from sms.  d:\sccm for our Secondary sites, since they were fresh installs when we set them up).  This part is critical.  When you do the recovery step, your site will to use the original setup paths that were in use prior to the site failure.  Changing the paths will cause a significant headache!

b. On a new fully patched system you will not pass the prereq check.  Double click on each item to see how to resolve the issue.  You should be able to resolve every error.

c. After resolving the MMC sp3 issue, it will still show up as an warning in prereq check, that is fine if you are sure you have applied sp3 for MMC.  The setup routine does not correctly query the registry to see that lastest version of the hotfix that Microsoft issued.

d. You can ignore the warning about SQL server authentication mode if you typically run SQL under the system account (without hardening SQL).

e. If you are attempting to restore a site that has a remote provider and point it back to the correct remote provider machine, the installer will complain that machine already has a provider.

1. On the provider machine, the registry key is blocking the install of the new remote provider, so remove the HKLM\SOFTWARE\Microsoft\SMS\Providers key.

2. On the provider machine, connect to root\sms with WBEMTEST and press the 'Enum Classes button'. No input is necessary, just press 'OK' to do an 'Immediate only' search. In the Query Results dialog window, click on the 'SMS_ProviderLocation' and press the 'Delete' key. Close out of all of these dialogs.

3. Delete the SMSPROV folder on the root.

4. Add the new site server machine as a local administrator and remove the old site server (if applicable).

Note: Provider fix, pasted from http://social.technet.microsoft.com/forums/en-US/configmgrsetup/thread/bb307748-7638-404d-a6a4-982827a051c8/

f. All other site servers will install the provider on themselves.

g. On the SQL DB server detach the old DB.  Create a new DB with the same name and file locations.  Give the smssite server db_owner on the db.

7. After the install has completed successfully run the site recovery wizard.

a. Close the console if open

b. Start>all programs>Microsoft System Center>Config Mgr 2007>Config Mgr Site Repair Wizard

c. Redsite and ROSsite do not have local DP's installed.  Choose the option to skip package verification.

8. Reset permissions for site in AD.

a. Open AD users and Computers> System> System Management

b. Open properties and give site server full control on Systems Management container.

c. Open advance properties and change permissions so that they apply to "This object and all descendant objects"  (this is not the default so be sure to do it).

9. Restore the site control file

a. Copy  site_control_files sitectrl_<SiteCode>.ct0 to D:\sms\inboxes\sitectrl.box

b. Rename file from sitectrl_<SiteCode>.ct0 to sitectrl.ct0

10. After recovery perform a site reset

a. Rerun setup from Start>all programs>Microsoft System Center>Config Mgr 2007>

b. Choose site reset

11. Set user group permissions for recovered site and related site servers

a. Computer mgmt>local users and groups>Groups

b. Sms_sitetositeconnection_<sitecode>  should contain the parent server and any child servers that need to connect to the site.

c. Sms_siteSystemtoSiteServer_<sitecode> should contain any parent or child site that needs to write to the site's DB.

d. Sms Reporting Users should contain any domain accounts that have reporting rights.

e. Sms admins should contain your sms administrators domain accounts.

12. If this was the central site with the wsus updates, then the wsus updates folders need to be reshared with the same share names.  Check the software updates deployment packages nodes.  On each package open the package properties.  The general tab will show the share name that the packages is expected to be found on.  The central site's machine account will need full control of this share.

13. Reset the wsus db:

a. From the cmd prompt:  c:\program files\Update Services\tools\wsusutil.exe reset

b. Wait 1 hour

c. Force a Synchronization on the Update Repository

d. Verify wsus is syncing properly: wsyncmgr.log for errors.

14. Verify backup share permissions for newly restored site.  Our backups are set for a share on another server, which is then backed up to tape.  This can be verified in the site maintenance node and by reviewing the smsbkup.log located in the backup share.

15. If this was the central site, recreate the backup schedule for the site control file.  A scheduled task that runs every 15 mins to dump the site control file and copy them to another machine:

a. site_control_file_backup.bat

D:\sms\bin\i386\00000409\preinst.exe /Dump

xcopy d:\*.ct0 backup_location\site_control_files /C /Y

16. Check and review system logs for errors for the next several days.

17. Monitor Site Status for errors.  The only errors should be on the central site and be related to unapproved clients trying to get policy.  Recheck in 24 hours.

18. Verify successful backups by reviewing the smsbkup.log located in the backup share.

Friday, November 7, 2008

Interactive Services Detection Service

Yesterday another admin notified me that his Vista machine prompted him before showing a message from a program I had distributed via SCCM.  The name of the prompt was "Interactive Services Dialog Detection", and it was requesting to show him a message.

image001

Selecting "Show me the message" hides the desktop and allows the user to see the message.  After viewing the message, the user had to click on "Return Now" to get back to the desktop.

This event was a surprise to me.  I've been running Vista since it came out and the program we advertised has been advertised for the last 3 years, and we run it every month.  After researching this service, I discovered that it is a new security feature in Vista.  Designed to protect users by intercepting messages run under another security context.  In this case, the program is advertised to run whether or not a user is logged on, but allow users to interact with the program.  When these options are chosen in SCCM, the program runs under the machine account as a service.  Since this program pops up a message, we chose the option to allow users to interact so they can see the message and click okay on it.  Vista may see this as a security risk if the Interactive Services Detection service is running.  We checked 4 different Vista machines, and it appears the default behavior is the service is Stopped and set to Manual.   UAC did not appear to have any affect on this service.  Apparently this admin had done something else to set this service to Running.  There are several available ways to resolve this issue:

  • Choose the option to run the program only when a user is logged on, and run it as the user.
  • Don't make the program interactive (user will not see the program).
  • Stop the Interactive Services Detection service.

Ignore it.  Vista is doing it's job of being safer.  Users may have to click an extra prompt.

I don't really recommend stopping or disabling the service since that is a built in security feature of Vista.  But it will prevent the prompt from appearing if desired.

Wednesday, November 5, 2008

Organize Collections with Drag and Drop

One of the plans we've had since I took over the administration of Configuration Manager is to organize the objects in the admin console.  SCCM makes it easier than SMS since it supports drag and drop.  The catch is that it only supports it with certain types of objects.  Collections is one of the object types that doesn't support drag and drop.  The only way I found to reorganize collection objects was to make a link of a collection to a second collection.  Making this link actually makes a 2nd instance of the collection appear in the hierarchy.  Then you can go back and safely delete the original collection.  The other option is to use a Microsoft provided SMS tool called CollTree.  Yes, the program does work with SCCM.  After downloading the SMS 2003 SDK you can compile the executable from \Program Files\Microsoft Systems Management Server 2003 SDK V3\Samples\VB\CollTree\CollTree.vbp  It's not as great as if Microsoft had built this functionality into the Admin Console, but at least it works!  Download a compiled version of CollTree here: http://myitforum.com/cs2/blogs/bleary/attachment/68439.ashx

Credits to Brian Leary for pointing out this useful tool: http://myitforum.com/cs2/blogs/bleary/archive/2006/12/01/colltree-drag-and-drop-collections-for-sms-2003.aspx

Thursday, October 23, 2008

Upgrade BITS

As companies move from SMS 2003 to SCCM one of the items frequently mentioned is the desire to predeploy the latest version of BITS (Background Intelligent Transfer Service).  This makes it possible to deploy the client without requiring a reboot.  However, Microsoft didn't really provide a method for doing the BITS deployment.  So I wrote my own.  Download the latest versions of BITS from: 2000, XP, 2003, x64- XP and 2003

They will need to be in a subdirectory named bin of this script.  The script will require a drive letter to run, so when you create the program be sure to specify that option.  The nice thing about this script is that you can deploy to everybody, and it will only upgrade those that need it.

'==========================================================================
' VBScript Source File -- Created with SAPIEN Technologies PrimalScript 4.0
'
' NAME: Install_Bits.vbs
' AUTHOR: Bill Phillips , ESRI
' DATE : 10/22/2008
'
' COMMENT:
'==========================================================================
On Error Resume Next
Dim strOSName, strSPName, strComputerType, systemroot, detectfile
Dim objFile, strFileVersion, strInstallFile


Set objShell = CreateObject ("Wscript.Shell")
set objEnv = objShell.Environment("Process")
systemroot = objEnv("SYSTEMROOT")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objExp = new regexp 'Create the RegExp object


detectOS()
detectFileversion(systemroot & "\system32\QMgr.dll")
compareBITSVersion(strFileVersion)
installBITS()

' ********************************************************************************
'Detect OS Function
'********************************************************************************
Function detectOS()
For Each objOS In GetObject("winmgmts:").InstancesOf ("Win32_OperatingSystem")
strOSName = objOS.Caption
strSPName = "SP" & objOS.ServicePackMajorVersion
Next

For Each objComputer In GetObject("winmgmts:").InstancesOf ("Win32_ComputerSystem")
strComputerType = objComputer.systemtype
Next

'need to normalize data (too many different versions of windows)
objExp.Pattern = "2000"
If objEXP.Test (strOSName) Then
strOSName = "win2k"
End If

objExp.Pattern = "XP"
If objEXP.Test (strOSName) Then
strOSName = "winXP"
End If

objExp.Pattern = "2003"
If objEXP.Test (strOSName) Then
strOSName = "w2k3"
End If

objExp.Pattern = "Vista"
If objEXP.Test (strOSName) Then
strOSName = "Vista"
End If

objExp.Pattern = "2008"
If objEXP.Test (strOSName) Then
strOSName = "w2k8"
End If
End Function

Function detectFileversion(detectfile)
If objFSO.FileExists(detectfile) Then
Set objFile = objFSO.GetFile(detectfile)
strFileVersion = objFSO.GetFileVersion(detectfile)
End If

End Function

Function compareBITSVersion(strFileVersion)
Select Case strFileVersion
' Case for Windows 2000 Server and Pro
Case "6.6.2600.1596"
'wscript.echo "BitsVersion Passed"
WScript.quit
WScript.Sleep 1

' Case for Windows XP SP2
'Case "6.7.2600.3143"
Case "Fake"
'wscript.echo "BitsVersion Passed"
WScript.quit
WScript.Sleep 1

' Case for Windows XP SP3
Case "6.7.2600.5512"
'wscript.echo "BitsVersion Passed"
WScript.quit
WScript.Sleep 1

' Case for Server 2003 SP1
Case "6.6.3790.1830"
'wscript.echo "BitsVersion Passed"
WScript.quit
WScript.Sleep 1

' Case for Server 2003 SP2
Case "6.6.3790.3959"
'wscript.echo "BitsVersion Passed"
WScript.quit
WScript.Sleep 1

' Case for Vista RTM
Case "7.0.6000.16386"
'wscript.echo "BitsVersion Passed"
WScript.quit
WScript.Sleep 1

' Case for Vista and Server 2008 SP1 x32 & x64
'Case "7.0.6001.18000"
Case "fake"
'wscript.echo "BitsVersion Passed"
WScript.quit
WScript.Sleep 1
' Case for failure
Case Else
'WScript.Echo "Bits Failed"
selectBITSinstall()
End Select
End Function

Function selectBITSinstall()
Select Case strComputerType
Case "x64-based PC"
Select Case strOSName
Case "w2k3"
strInstallFile = "WindowsServer2003.WindowsXP-KB923845-x64-ENU.exe"
Case "winXP"
strInstallFile = "WindowsServer2003.WindowsXP-KB923845-x64-ENU.exe"
End Select
Case "X86-based PC"
Select Case strOSName
Case "win2k"
strInstallFile = "Windows2000-KB842773-x86-ENU.exe"
Case "winXP"
strInstallFile = "WindowsXP-KB923845-x86-ENU.exe"
Case "w2k3"
strInstallFile = "WindowsServer2003-KB923845-x86-ENU.exe"
End Select
End Select

' no match found so quitting
If strInstallFile = "" Then
WScript.Quit
End If

End Function

Function installBITS()
'Turn off prompt for unknown locations
objEnv("SEE_MASK_NOZONECHECKS") = 1


objShell.Run ("bin\" & strInstallFile & " /passive /norestart /overwriteoem")', 1, True

'Turn prompt back On
objEnv.Remove("SEE_MASK_NOZONECHECKS")
End Function

Wednesday, October 22, 2008

Client Health Check Script

See updated post: http://smsimpossible.blogspot.com/2008/12/client-health-check-script-take-2.html

1e used to have a client health check script for sms 2003. The script would reinstall the client or force a repair depending on what part of the check it failed. Since the release of SCCM they have not updated the script. I believe the old script will probably still work just by changing the install directory, but I have a rewritten version of the script that we use so I'm providing it below. I don't think there is anything wrong with posting this, but I will remove it if 1e asks me to do so. To use the script you must specify the siteserver. Also the sccm/client directory must be shared out and the script will need to be modified to reflect the share directory. After meeting these 2 requirements the script is usable. You may also specify an smtp email server in the email section and who the email should be sent to. The siteserver and email recipient may be passed as arguments or hard coded into the script.

'==========================================================================
' VBScript Source File -- Created with SAPIEN Technologies PrimalScript 4.0
' NAME: SCCM_Client_Health_Check.vbs
' AUTHOR: Bill Phillips , ESRI
' DATE : 10/20/2008
'
' COMMENT: Code rewrite for SCCM client taken from 1E ClientHealth Script for SMS client
'==========================================================================
On Error Resume Next

Dim smsserver, platform, email
Dim domainrole, ComSpec, diffdate, enddate, fso, filedate, SmsClient, returncode, Results
Dim ISmsClient, DiscoveredSite, AssignedSite
Dim servicename, startdate, strMessage, strSMSPolEval, windir, wmi, colItems, wShShell, Compname, present, objShare
Dim BitsVersion, tempdir, logfile, logsize

Set WshShell = WScript.CreateObject("WScript.Shell")
WinDir = WshShell.ExpandEnvironmentStrings("%windir%")
Compname = WshShell.ExpandEnvironmentStrings("%COMPUTERNAME%")
ComSpec = WshShell.ExpandEnvironmentStrings("%COMSPEC%")
tempdir = WshShell.ExpandEnvironmentStrings("%temp%")

'Set up the loggong
Set fso = CreateObject("Scripting.FileSystemObject")
Set logfile = fso.OpenTextFile(tempdir & "\SCCM_Client_Health_Check.Log",2,True)


logfile.writeline "####################################"
logfile.writeline "Begining SCCM Client Health Check Script"
logfile.writeline "####################################"

'Either uncomment variables below or pass arguments to script:
'sccm_client_health_check.vbs /smsserver:smststserver /email:recepient@company.com
'********************************************************HARD CODED COMMAND LINE OVERRIDES********************************************************
'***********************************************************UNCOMMENT ONLY IF NECESSARY***********************************************************
'smsserver = "smststserver" 'Should reflect the PMP/PDP for each office
'platform = "" 'No need to modify
'Email = "recepient@company.com" 'Should be set to go to an alias that includes the needed peoeple.
'********************************************************HARD CODED COMMAND LINE OVERRIDES********************************************************
'***********************************************************UNCOMMENT ONLY IF NECESSARY***********************************************************
checkSCCMserverCMD()
checkPlatformCMD()
checkEmailCMD()
checkAdminShare()
checkCCMSetupRunning()
checkClient()
checkLogsUpdate()
checkBITSversion()
checkServices()
checkAssignment()
logfile.writeline "Cleaning Up"
Call Cleanup
logfile.writeline "Ending Processing"
WScript.Quit


'Check to see if SCCM server is specifed as an argument or hardcoded into script
Function checkSCCMserverCMD()
If smsserver = "" Then
If Wscript.Arguments.Named.Exists("smsserver") Then
If Wscript.Arguments.Named("smsserver") <> "" Then
logfile.writeline "smsserver specified in command line is " & WScript.Arguments.Named("smsserver")
Else
logfile.writeline "/smsserver parameter is the incorrect format. Please see documentation"
WScript.Quit
End If
Else
logfile.writeline "Missing /smsserver: in command line"
WScript.Quit
End If
Else
logfile.WriteLine "The SCCMserver hardcoded command line override specified as = " & smsserver
End If
End Function

Function checkPlatformCMD()
If platform = "" Then
domainrole = GetDomainRole()
If Wscript.Arguments.Named.Exists("platform") Then
If Wscript.Arguments.Named("platform") <> "" Then
platform = Wscript.Arguments.Named("platform")
logfile.WriteLine "platform = " & platform
If Not CInt(platform) = CInt(domainrole) Then
logfile.WriteLine "System running is not the correct platform as specified"
WScript.Quit
End If
End If
End If
Else
logfile.WriteLine "platform hardcoded command line override specified as = " & platform
domainrole = GetDomainRole()
If Not CInt(Platform) = CInt(domainrole) Then
logfile.WriteLine "System running is not the correct platform as specified"
WScript.Quit
End If
End If
End Function

Function checkEmailCMD()
If email = "" Then
If WScript.Arguments.Named.Exists("email") Then
email = True
End If
Else
logfile.WriteLine ("Email hardcoded command line override specified as = " & email)
'email = True 'uncomment if you use hardcoded email in script
End If
End Function

Function checkAdminShare()
'Check for Admin$ - If not present then log
Set wmi = getobject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colItems = wmi.ExecQuery("Select * From Win32_Share",,48)
present = "FALSE"
For Each objShare In colItems
If LCASE(objShare.Name) = "admin$" Then
present = "TRUE"
End If
Next
If present <> "TRUE" Then
If Email = True Then
logfile.writeline "Sending email that Admin$ is missing"
Call EmailMessage("Admin$ Missing", Compname & " does not have an Admin$.")
Else
logfile.writeline "Admin$ is missing."
End If
End If
End Function

Function checkCCMSetupRunning()
'Abort if ccmsetup running
Results = ServiceState("ccmsetup")
If LCase(Results) = LCase("Running")Then
logfile.writeline "Sending email that ccmsetup service is running and script is aborting"
Call EmailMessage("Aborting Client Installation", "ccmsetup is running on " & CompName)
WScript.Quit

logfile.writeline "Exiting script processing because ccmsetup service is running"
WScript.Quit

Elseif LCase(Results) = LCase("Stopped")Then
logfile.WriteLine "ccmsetup service is in a stopped state, attempting to start"
KickService("ccmsetup")
End If
End Function

Function checkClient()
' SMS Client COM object available, Version Installed, & WMI Namespace available
Set SmsClient = GetObject("winmgmts:ROOT/CCM:SMS_Client=@")
If Err Then
'Advanced client not installed
logfile.writeline "Advanced Client not installed, calling AdvCliInst to install the client"
Call AdvCliInst(ComSpec)
WScript.Sleep 10000
Call Cleanup
WScript.Quit
Else
logfile.writeline SmsClient.ClientVersion
Select Case SmsClient.ClientVersion
'IMPORTANT! >>>>>>>>> Adjust CASE as necessary, but do *not* remove it! <<<<<<<<IMPORTANT!
'Alter this by adding an additional CASE statement followed by the version in quotes for each SMS client
'version which is allowed in the hierarchy. This can also be used as an additional cleanup method after
'upgrading clients for those that might have missed this via software distribution
'Case "2.50.3174.1018"
'Case "2.50.4160.2000" 'SP2 Version
Case "4.00.6221.1000" 'configMGR sp1 client
logfile.writeline "SMS Client Version Passed"
WScript.Sleep 1
Case Else
logfile.writeline "Calling AdvCliInst routine to install SMS Advanced client"
Call AdvCliInst(ComSpec)
WScript.Sleep 10000
Call Cleanup
WScript.Quit
End Select
End If
End Function

Function checkLogsUpdate()
Set SmsClient = GetObject("winmgmts://./root/ccm:SMS_Client")
' SMS Logs recently updated
logfile.writeline "Begining to evaluate " & windir & "\system32\CCM\Logs\PolicyEvaluator.log"
strSMSPolEval = windir & "\system32\CCM\Logs\PolicyEvaluator.log"
startdate = ShowFileAccessInfo(strSMSPolEval, Compname)
logfile.writeline "startdate = " & startdate
enddate = date()
logfile.writeline "enddate = " & enddate

If isDate(startdate) Then
diffdate = DateDiff("d", startdate, enddate)
logfile.writeline "diffdate = " & diffdate
End If

If diffdate > 21 Then
If Email = True Then
logfile.writeline "diffdate is greater than 21 days, sending email"
Call EmailMessage(CompName & " is out of date", Compname & " has not updated is logs in 21 days or more - attempting client repair")
End If
logfile.writeline "diffdate is greater than 21 days, attempting to repair SMS Client"
smsClient.RepairClient
wscript.quit
End If
End Function

Function checkBITSversion()

'Check BITS version, email if out of date
logfile.writeline "Checking BITS version by looking at " & windir & "\system32\QMgr.dll"
If fso.FileExists(windir & "\system32\QMgr.dll") Then
BitsVersion = fso.GetFileVersion(windir & "\system32\QMgr.dll")
logfile.writeline "BitsVersion is " & BitsVersion
Select Case BitsVersion

' Case for Windows 2000 Server and Pro
Case "6.6.2600.1596"
logfile.writeline "BitsVersion Passed"
WScript.Sleep 1

' Case for Windows XP SP2
Case "6.7.2600.3143"
logfile.writeline "BitsVersion Passed"
WScript.Sleep 1

' Case for Windows XP SP3
Case "6.7.2600.5512"
logfile.writeline "BitsVersion Passed"
WScript.Sleep 1

' Case for Server 2003 SP1
Case "6.6.3790.1830"
logfile.writeline "BitsVersion Passed"
WScript.Sleep 1

' Case for Server 2003 SP2
Case "6.6.3790.3959"
logfile.writeline "BitsVersion Passed"
WScript.Sleep 1

' Case for Vista
Case "7.0.6000.16386"
logfile.writeline "BitsVersion Passed"
WScript.Sleep 1

' Case for Server 2008 SP1
Case "7.0.6001.18000"
logfile.writeline "BitsVersion Passed"
WScript.Sleep 1


' Case for failure
Case Else
If Email = True Then
logfile.writeline "BITS is out of date, sending email"
Call EmailMessage("BITS out of date", Compname & " - BITS version is at " & BitsVersion)
Else
logfile.writeline "BITS is out of date, exiting script processing"
WScript.Quit
End If
End Select
Else
If Email = True Then
logfile.writeline "Unable to process BITS version because " & windir & "\system32\QMgr.dll is missing. Sending email."
Call EmailMessage("File Missing", "%system32%\QMgr.dll" & " is missing on " & Compname)
Else
logfile.writeline "Unable to process BITS version because " & windir & "\system32\QMgr.dll is missing. Exiting Script processing."
WScript.Quit
End If
End If
End Function

Function checkServices()

' SMS Agent Host Service started
logfile.writeline "Calling KickService"
Call KickService("CcmExec")

' Remote Registry Service started
logfile.writeline "Calling RemoteRegistry"
Call KickService("RemoteRegistry")
End Function

Function checkAssignment()
'Ensure that the client is assigned to a site if its not assigned to any
logfile.writeline "Checking to make sure SMS Client has site assignment"
Set ISmsClient = CreateObject ("Microsoft.SMS.Client")
AssignedSite = ISmsClient.GetAssignedSite
If NOT Len(AssignedSite & "")>0 Then
logfile.writeline "Client is not assigned, attempting to AutoDiscover and set"
ISmsClient.EnableAutoAssignment 1
DiscoveredSite = ISmsClient.AutoDiscoverSite
ISmsClient.SetAssignedSite DiscoveredSite,0
logfile.writeline "Client is now assigned to " & ISmsClient.GetAssignedSite
End If
logfile.writeline "Client is now assigned to " & ISmsClient.GetAssignedSite
End Function




' =====================================================
' KickService function
' =====================================================
Function KickService(servicename)
On Error Resume Next
logfile.writeline "Inside KickService"
Dim Results, wmi, Service, returncode, Service2, Started
Results = ServiceState(servicename)
logfile.writeline "servicename = " & servicename
logfile.writeline "Results = " & Results
set wmi = getobject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")

If NOT LCase(Results) = LCase("Running")Then
set Results = wmi.execquery("select state from win32_service where name='" & servicename & "'")
For Each Service In Results
' Start service
returncode = Service.StartService
logfile.writeline "returncode = " & returncode
if returncode <> 0 Then
If Email = True Then
logfile.writeline "SMS Client Service Failure " & servicename & " failed to start on " & CompName
Call EmailMessage("Start Service Error", "SMS Client Service Failure " & servicename & " failed to start on " & CompName)
Call Cleanup
logfile.writeline "Quiting Script"
WScript.Quit
Else
logfile.writeline "Displaying message to user - Error starting service your Windows Management Service (" & servicename & ") - Call The Help Desk immediately"
msgbox "Error starting service your Windows Management Service (" & servicename & ") - Call The Help Desk immediately"
Call Cleanup
logfile.writeline "Quiting Script"
WScript.Quit
End If
end If
Do Until Started = True
'IMPORTANT! >>>>>>>>> Adjust sleep as necessary, but do *not* remove it! <<<<<<<<IMPORTANT!
logfile.writeline "Sleeping for 2 seconds..."
logfile.writeline "Use the below text to see how many times the script looped to start the Service"
WScript.Sleep 2000 'Sleep for 2 Seconds
set Results = wmi.execquery("select state from win32_service where name='" & servicename & "'")
for each Service2 In Results
if lcase(Service2.State) = lcase("Running") Then
logfile.writeline "Started = " & Started
Started = True
end If
Next
Loop
Next
End If
End Function
' =====================================================
' ServiceState subprocedure
' =====================================================
Function ServiceState(servicename)
On Error Resume Next
logfile.writeline "Inside ServiceState"
logfile.WriteLine "Checking " & servicename & " service"
Dim wmi, Results, Service, StateResults, StartMode
set wmi = getobject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
set Results = wmi.execquery("select state from win32_service where name='" & servicename & "'")
For Each Service In Results
StateResults = Service.State
logfile.writeline "StateResults = " & StateResults
Next
ServiceState = StateResults
End Function
' =====================================================
' AdvCliInst subprocedure
' =====================================================
Sub AdvCliInst(ComSpec)
On Error Resume Next
logfile.writeline "Inside AdvCliInst"
Dim smsinstall, WshShell, InstallArgs

Set WshShell = WScript.CreateObject("WScript.Shell")
ComSpec = WshShell.ExpandEnvironmentStrings("%COMSPEC%")
If ComSpec = "" Then
If Email = True Then
logfile.writeline "SMS Client Installation Failure", "The SMS Client failed to Install On " & CompName
Call EmailMessage("SMS Client Installation Failure", "The SMS Client failed to Install On " & CompName)
Call Cleanup
logfile.writeline "Exiting Script Processing"
WScript.Quit
Else
logfile.writeline "Displaying Message to user - Windows Management Service Installation Failed. Please contact The Help Desk"
MsgBox "Windows Management Service Installation Failed. Please contact The Help Desk"
Call Cleanup
logfile.writeline "Exiting Script Processing"
WScript.Quit
End If
Else
InstallArgs = ""
If Wscript.Arguments.Named.Exists("params") Then
If Wscript.Arguments.Named("params") <> "" Then
InstallArgs = Wscript.Arguments.Named("params")
logfile.writeline = "InstallArgs = " & InstallArgs
End If
End If
smsinstall = ComSpec & " /c \\" & Wscript.Arguments.Named("smsserver") & "\SMSClient\ccmsetup.exe SMSSLP=smststserver Disablesiteopt=true FSP=smststserver SMSSITECODE=tst" & InstallArgs
logfile.writeline "Calling SCCM Client installation with below command line:"
logfile.writeline "smsinstall = " & smsinstall
' Run SMS Client Installation
WshShell.Run smsinstall,0,False
End If
End Sub
' =====================================================
' GetDomainRole function
' =====================================================
Function GetDomainRole
On Error Resume Next
logfile.writeline "Inside GetDomainRole"
Dim domainroles, wmi, domainrole
Set wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set domainroles = wmi.ExecQuery("SELECT DomainRole FROM Win32_ComputerSystem")
For Each domainrole in domainroles
GetDomainRole = domainrole.DomainRole
logfile.writeline "GetDomainRole = " & GetDomainRole
Next
Set domainroles = Nothing
Set wmi = Nothing
End Function
' =====================================================
' EmailMessage subprocedure
' =====================================================
Function EmailMessage(Subject, Body)
On Error Resume Next
logfile.writeline "Inside EmailMessage"
logfile.writeline "Email Subject: " & Subject
logfile.writeline "Email Body: " & Body
Dim objEmail, objemailfrom
' email using a generic user account as system is being booted up and user may not have logged on yet
Set objEmail = CreateObject("CDO.Message")
objemailfrom = WScript.Arguments.Named("smsserver") & "@company.com"
objEmail.From = objemailfrom
objEmail.To = WScript.Arguments.Named("email")
' objEmail.To = "receipants@company.com"
objEmail.Subject = Subject
objEmail.Textbody = Body
objEmail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
objEmail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserver") = _
"smtp.company.com"
objEmail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
objEmail.Configuration.Fields.Update
logfile.writeline "Sending Email"
objEmail.Send
Set objEmail = Nothing
End Function
' =====================================================
' ShowFileAccessInfo function
' =====================================================
Function ShowFileAccessInfo(filespec, Compname)
On Error Resume Next
logfile.writeline "Inside ShowFileAccessInfo"
Dim fso, f, filespec_date, FSpace
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists(filespec) Then
Set f = fso.GetFile(filespec)
logfile.writeline "f = " & f
filespec_date = f.DateLastModified
logfile.writeline "filespec_date = " & filespec_date
FSpace = Instr(filespec_date," ") - 1
logfile.writeline "FSpace = " & FSpace
ShowFileAccessInfo = Left(filespec_date,FSpace)
logfile.writeline "ShowFileAccessInfo = " & ShowFileAccessInfo
Else
If Email = True Then
logfile.writeline "File Missing - " & filespec & " is missing On " & Compname
Call EmailMessage("File Missing", filespec & " is missing On " & Compname)
logfile.writeline "Exiting Script Processing"
WScript.Quit
End If
End If
End Function
' =====================================================
' Destroy any objects
' =====================================================
Sub Cleanup
On Error Resume Next
logfile.writeline "Inside Cleanup"
Set WshShell = Nothing
Set ComSpec = Nothing
Set windir = Nothing
Set strCompName = Nothing
Set SmsClient = Nothing
End Sub
' =====================================================

Thursday, October 16, 2008

open file - security warning

In our SCCM environment we frequently use the option to run from server instead of download and run.  One of the issues we've seen from time to time is if our script calls another program that was downloaded from the internet it may have had the untrusted source bit set during the download.  In our scripts we get around the Open File - Security warning dialog box by temporarily turning off zone checking.  At the end of the script we turn zone checking back on.  No need to add servers to trusted sites via group policy!  More info on this problem here:

set objShell = CreateObject("Wscript.shell")
Set objEnv = objShell.Environment("PROCESS")

' ********************************************************************************
'Main Routine
'*********************************************************************************
objEnv("SEE_MASK_NOZONECHECKS") = 1
objShell.Run("taskkill.exe /F /IM foo.exe"),,False
Install_Application()
objEnv.Remove("SEE_MASK_NOZONECHECKS")
WSCRIPT.QUIT

' ********************************************************************************
'Install Application
'*********************************************************************************
Function Install_Application()
'setup program
objShell.run("fooInstall.exe /silent"),1,true
Wscript.Sleep(5000)
End Function

Thursday, October 9, 2008

configmgr right click tools

If your familiar with the sms 2003 right click tools, then your probably already know that there are new console extenstions available for SCCM. My favorite is Rick Houchin's SCCM Right Click tools: http://myitforum.com/cs2/blogs/rhouchins/archive/2008/04/09/sccm-right-click-tools.aspx Download version 1.7 directly from: http://myitforum.com/cs2/blogs/rhouchins/0613ConfigMgrTools.zip For those of you who haven't tried them, I highly recommend that you do since they make life so much easier.

Wednesday, October 8, 2008

Update Package versus Refresh Package

You may have noticed that if you right click on the distribution point node of a Package you will get an option to Update Distribution points. If you open the node and right click on an individual DP you will get an option to refresh the package on that distribution point. There is no option to refresh a package on all DP's and there is no option to Update a package on just one DP. What's going on here? Well, each function is slightly different. When you create a package and assign a source location to it, that package is actually stored on the site server in the SMSPKG folder as a compressed file in the form of PackageID.pck extension. This folder is shared out from the site server as \\server\SMS_CPSx$, where x represents the drive letter it is located on. When choosing the option to Update a package a delta file of the changes is created from the specified source location and the version number is incremented for both the source and client policy. The delta file is what gets sent out to the DP's. Choosing the option to refresh a package will actually repair a package at a DP by recopying the entire compressed package from the local site server to the DP. There is no update of any changes that may have occured at the package source.

More info: http://technet.microsoft.com/en-us/library/bb892806.aspx
and here: http://www.serverwatch.com/tutorials/article.php/1474011

Monday, October 6, 2008

Script to Force Client Inventory on 64-Bit OS

In my previous post I posted the script to force HW and SW inventory on a client. However if you run the script on 64-bit vista or '08, you will get a 800a01ad error code (I'm guessing this will also happen of 64-bit XP, but didnt' test it). The specific error is: ActiveX component can't create object: 'CPAPPLET.CPAppletMgr' . The issue is that configmgr's applet's are 32-bit only. On a 64-bit system, Open control panel and you will not see the configmgr cpl, unless you open the "View 32-bit Control Panel" applet. By default, 64-bit versions of windows call the 64-bit version of the scripting host (wscript or cscript), which will only talk to the 64-bit part of the control panel. So the solution is to call the 32-bit scripting host that will talk to the 32-bit control panel items. A simple batch file to run from either verison of the OS to launch your vbs using the correct scripting host will do the trick:

if exist %systemroot%\SysWOW64\cscript.exe goto run64
\\server\share\swinventory.vbs
exit
:run64
%systemroot%\SysWOW64\cscript.exe \\server\share\swinventory.vbs
exit

Friday, October 3, 2008

Script to Force Hardware or Software Inventory

In my previous post I stated that we were allowing users to opt in to a collection on their own by putting a dummy exe on their computers.  The collection is setup to update its membership nightly.  However, clients need to run software inventory to report the new exe back to the Management Point.  Here's a VB script that clients can run to kick this process off.  Credit to Chris Stauffer at myitforum for the original code ( http://myitforum.com/cs2/blogs/cstauffer/archive/2007/04/04/script-to-perform-a-full-sms-inventory.aspx).  Also, I added in the Hardware Inventory version in case your adding registry keys, wmi classes, other HWinv type items.  If you want to verify that it's running check the inventoryagent.log file on the client.

On Error Resume Next

ForceSoftwareInventory()
ForceHardwareInventory()

'*********************************************************************************************************
'Force Software Inventory on the Client
'*********************************************************************************************************

Function ForceSoftwareInventory()
Set sho = CreateObject("WScript.Shell")
strSystemRoot = sho.expandenvironmentstrings("%SystemRoot%")
strCurrentDir = Left(Wscript.ScriptFullName, (InstrRev(Wscript.ScriptFullName, "\") -1))
'Run a SMS Software Inventory

Set cpApplet = CreateObject("CPAPPLET.CPAppletMgr")
Set actions = cpApplet.GetClientActions
For Each action In actions
    If Instr(action.Name,"Software Inventory Collection Cycle") > 0 Then
        action.PerformAction  
'        WScript.Echo action.name
End If
Next
End Function

'*********************************************************************************************************
'Force Hardware Inventory on the Client
'*********************************************************************************************************

Function ForceHardwareInventory()
Set sho = CreateObject("WScript.Shell")
strSystemRoot = sho.expandenvironmentstrings("%SystemRoot%")
strCurrentDir = Left(Wscript.ScriptFullName, (InstrRev(Wscript.ScriptFullName, "\") -1))
'Run a SMS Hardware Inventory

Set cpApplet = CreateObject("CPAPPLET.CPAppletMgr")
Set actions = cpApplet.GetClientActions
For Each action In actions
    If Instr(action.Name,"Hardware Inventory Collection Cycle") > 0 Then
        action.PerformAction  
'        WScript.Echo action.name
End If
Next
End Function

Tuesday, September 30, 2008

query collection based on file existing on machine

At my company we wanted to create a system where developers could opt in to receive a copy of the nightly build of the software they were working on. In the first part of this project we create a collection based on the software inventory of a particular file. By default SCCM looks for any *.exe's on client systems. Rather than add another file type, we created a dummy exe as the criteria for our collection:
Criterion Type: Simple Value
Where: Software Files – File Name
Operator: is equal to
Value: Filename.exe

Equilivent in wql:

select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_SoftwareFile on SMS_G_System_SoftwareFile.ResourceID = SMS_R_System.ResourceId where SMS_G_System_SoftwareFile.FileName = "Filename.exe"

Sunday, September 28, 2008

SCCM MindMap

I've been very busy this past week updating or SCCM environment to SP1.  We want to be at SP1 before we start updating clients from SMS 2003.  During the process I've been helping another admin learn some of the in's and out's of SCCM.  To help I put together a quick mindmap that will help people new to SCCM wrap their heads around it.  You can create your own mindmap at http://www.text2mindmap.com/ .












If you like my list and want to add to it:
SCCM
Software Distribution
Packages
Source
Refresh Distribution Point
Programs
Advertisments
Available
Mandatory
Expires
Collections
Static
Dynamic
Software Updates
Updates lists
Deployment Templates
Deployment Management
Deployment Packages
OSD
Tasks
Drivers

Friday, September 19, 2008

Clients Do Not Run Mandatory Advertisements and They Return Status Message 10052

Yesterday I created a program for a package and advertised it to some test machines.  The package was pretty small so I decided to use the download and run option instead of my normal run from Distribution Point.  Everything else I did the same way I normally do.  To my surprise the program refused to run on the clients.  Checking the Advertisment Status logs I found the error being returned by the clients:  10052 The program for the advertisement "advertisementID" ("packageID" - "program_name") could not be run because the policy contains an invalid combination of requirements: site_code. Possible causes: The program is set to run when no user is logged on, but is being advertised to a user. The program is set to require user input, but does not require that a user be logged on in order to run. Solution: Examine the properties of the program to resolve the conflicting requirements.  I found out that setting the client to download and run, and requires a mapped drive letter will trigger this error message.  No need to map a drive letter if the content is already on the machine!  Anyway here is Microsofts KB on the same issue (written for SMS 2003): http://support.microsoft.com/kb/829858

Wednesday, September 17, 2008

Script to Modify SCCM Advertisement

Below is a script I wrote to echo out all the proprieties from an SCCM advertisement.  Then I modified the comment property and saved it back.  You can modify any property you want, but the Mandatory Assignments will be tricker since they are in an Array.

' --- Set Variables
siteName = "tst"
serverName = "SMSSITESERVER"
SMS_AdvertisementID = "tst20408"
Dim replacementScheduleArray()
Dim SMS_ScheduleToken

' --- Create Objects
Set loc = CreateObject("WbemScripting.SWbemLocator")
Set WbemServices = loc.ConnectServer(servername , "root\SMS\site_" & siteName)


smsAdvertisement()

' --- Refresh Package
Function smsAdvertisement()
Set colAdvertisements = WbemServices.ExecQuery("Select * From SMS_Advertisement where AdvertisementID='" & SMS_AdvertisementID & "'")
Set objAdvertisement = WbemServices.Get("SMS_Advertisement.AdvertisementID='" & SMS_AdvertisementID & "'")
Set Advertisement_Properties = objAdvertisement.Properties_ 'get property Set
set AssignedScheduleArray = Advertisement_Properties.Item("AssignedSchedule")

For each Advertisement In colAdvertisements
'Get Info
Wscript.Echo "adname " & Advertisement.AdvertisementName
wscript.echo "ad ID " & Advertisement.AdvertisementID
wscript.echo "ad Flag " & Advertisement.AdvertFlags
wscript.echo "Present Time " & Advertisement.PresentTime
wscript.echo "Present Time enforced? " & Advertisement.PresentTimeEnabled
wscript.echo "TimeFlags Property " & Advertisement.TimeFlags
wscript.echo "Is Assigned Schedule Enabled/active? Must be true for Mandatory True/false " & Advertisement.AssignedScheduleEnabled
wscript.echo "Expiration Time " & Advertisement.ExpirationTime
wscript.echo "Expiration Time Enabled? " & Advertisement.ExpirationTimeEnabled
wscript.echo "Collection ID " & Advertisement.collectionID
wscript.echo "Package ID " & Advertisement.PackageID
wscript.echo "Program Name " & Advertisement.ProgramName


For i = 0 to UBound(AssignedScheduleArray)
Set SMS_ScheduleToken = AssignedScheduleArray(i)
WScript.Echo AssignedScheduleArray.Name & " " & i & ":" & SMS_ScheduleToken.GetObjectText_()
WScript.Echo "Assignment:" & SMS_ScheduleToken.StartTime

Next

'begin modifying:

strNewComment = "Updated by vbs"
Advertisement.Comment = strNewComment

'This next line will modify the Advertisment with settings set in variables above.
Advertisement.Put_

Next 
End Function

Tuesday, September 16, 2008

Scripting SCCM to refresh a package source directory

My company has a need to have a particular package's distribution points update automatically when a file in the package source directory changes. We looked at the package's built in option to automatically update DP's on a schedule. Ultimately, we decided this would not work. We have a very short window to obtain a 4GB updated package source and then distribute that content to clients. If we set the window too small (every 20 minutes), then clients would be mostly locked out from getting content from the DP, since the DP would be constantly updating. If we set it too large, we don't get the content within the targeted time window. Using the SCCM SDK ( http://www.microsoft.com/downloads/details.aspx?FamilyId=064A995F-EF13-4200-81AD-E3AF6218EDCC&displaylang=en ) and information from a post by aparrott on myitforum: http://www.myitforum.com/forums/m_180582/mpage_1/key_/tm.htm#180582 we were able to create our own script that will detect the change and then update the DP. I have a scheduled task that runs every 20 minutes. If the last modified stamp on the text file is different, then the DP's will update. This happens once a day, but I get new content onto the DP's within 25 minutes. Now I just need to delete the old mandatory assignment and create a new one.

Careful of the wordwrap!  I suggest you copy and paste into notepad.
'==========================================================================
'
' VBScript Source File -- Created with PrimalScript.
'
' NAME: SCCM_Refresh_DP_Nightly_Build.vbs
'
' Created by: Bill Phillips, ESRI
' Date: 09/15/2008
'
' COMMENT:
' Run this as a scheduled task under the System account.
' Machine's account must have rights to the shares.
' Example code from: http://www.myitforum.com/forums/m_180582/mpage_1/key_/tm.htm#180582
'==========================================================================

On Error Resume Next

' --- Set Variables
siteName = "tst"
serverName = "SMSSERVER"
SMS_PackageID = "tst00158"

' --- Create Objects
Set loc = CreateObject("WbemScripting.SWbemLocator")
Set WbemServices = loc.ConnectServer(servername , "root\SMS\site_" & siteName)
set FSO=CreateObject("Scripting.FileSystemObject")

CompareFiles()

' --- Compare Files
Function CompareFiles()
Set objSourceBuildNumTextDate = FSO.GetFile ("\\smsserver\source\foo.txt")
Set objDestBuildNumTextDate = FSO.GetFile ("\\dpserver\SMSPKGE$\tst00158\foo.txt")
If not objSourceBuildNumTextDate.DateLastModified = objDestBuildNumTextDate.DateLastModified Then RefreshPKG
End Function

' --- Refresh Package
Function RefreshPKG()
Set packages = WbemServices.ExecQuery("Select * From SMS_Package where PackageID = '" & SMS_PackageID & "'")
For Each package In packages

Package.RefreshPkgSource( )

Next

End Function

Thursday, September 11, 2008

Searching Config Manager Docs on Technet

As many of you know, searching Config Manager documentation on Technet is a PITA! Fortunetly Jeff Gilbert has figured out how to narrow your Technet search down to just the Config Manager docs. http://blogs.technet.com/wemd_ua_-_sms_writing_team/archive/2007/11/07/how-to-more-easily-search-the-configuration-manager-documentation-library-online.aspx
This should make life significantly better. Can't believe I haven't seen this before now.

Tuesday, September 9, 2008

Deployment of Group Policy Preferences Client Side Extensions

Yesterday my Group Policy Admin asked about deploying the Client Side Extensions (CSE's) for Group Policy Preferences (GPP) to all the machines in our network.  So I started looking into it and must say I'm very dissappointed with Microsofts support for the deployment of CSE's.  Sure CSE's are available in WSUS and therefore available in SCCM.  However, they haven't released CSE's for XP SP3 yet.  Additionally, the CSE's have a prerequisite of XMLLite.  Unbelievably, XMLLite is not available via WSUS.  The work around is to deploy IE7 which includes XMLLite.  All of this is a little confusing so I made a chart:



Basically I'll create 2 seperate collections for XMLLite to deploy it to the machines that require it.  Then I'll use Software Updates to deploy the CSE's.  XP SP3 will just have to wait until Microsoft gets it done.  Hopefully they're working on CSE deployment with XMLlite bundled in.