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