# Wednesday, December 16, 2009

I was wondering today if it would be possible to create an Update Search Folder in Powershell. Turns out you can but it isn’t as straight forward as you might think. According to the SCCM SDK Search Folders are an instance of the SMS_ObjectContainerNode class. You can find the details about this class here.

I’m using the SCCM.psm1 file by Michael Niehaus with a few modifications. I’ve added code to force asking for credentials and also added a function to create new SCCM object. My version is available at the end of this post. The additional function looks like:

function New-SCCMObject {

    [CmdletBinding()] 
    PARAM 
    ( 
        [Parameter(Position=1)] $class 
    ) 
	
	$staticClass = get-wmiobject -query "SELECT * FROM Meta_Class WHERE __Class = '$class'" -computername $sccmServer -namespace $sccmNamespace -Credential $sccmCredentials
	
	$staticClass.CreateInstance()

}

SMS_ObjectContainerNode has a property called SearchString that controls what the search filters are. I figured the easiest way to understand what should go in the SearchString property would be create a search folder manually and then view the property. Here is my Search Folder:
Screenshot

Here is the code to view the contents of the SearchString Property:

#Get the Update Search Folder and Return the XML.
$searchFolder = Get-SCCMObject -class SMS_ObjectContainerNode -filter "Name='All Current Workstation Updates'"
$searchFolder.Get()

#list the XML
$searchFolder.SearchString

The XML looks like:

	
		
			
				'Product:041e4f9f-3a3d-4f58-8b2f-5e6fe95c4591'
				'Product:558f4bc3-4827-49e1-accf-ea79fd72d4c9'
			
		
		
			
				MS
			
		
		
			
				 = 0
			
		
		
			
				 = 0
			
		
	
Pretty straight forward right?? Well no not really but anyway, here is how to create a search folder:

$server = "server"
$siteCode = "ABCa"

$scriptDir = Split-Path -Path $MyInvocation.MyCommand.Path -Parent
Import-Module $scriptDir\SCCM.psm1

Connect-SCCMServer -serverName $server -siteCode $siteCode

$xml=[xml] @'

	
		
			
				'Product:041e4f9f-3a3d-4f58-8b2f-5e6fe95c4591'
				'Product:558f4bc3-4827-49e1-accf-ea79fd72d4c9'
			
		
		
			
				MS
			
		
		
			
				 = 0
			
		
		
			
				 = 0
			
		
	

'@

#create a new instance of a search folder
$newFolder = New-SCCMObject -class SMS_ObjectContainerNode

#Set the Properties
$newFolder.Name = "Workstation Updates"
$newFolder.ObjectType = 1011 #1011 = SMS_SoftwareUpdate
$newFolder.ParentContainerNodeID = 0
$newFolder.SearchFolder = $true
$newFolder.SearchString = $xml.InnerXML
$newFolder.FolderFlags = 1

#Save the folder
$newFolder.Put()

posted on Wednesday, December 16, 2009 2:00:30 PM (E. Australia Standard Time, UTC+10:00)  #    Comments [0]
# Friday, May 08, 2009

I had a situation last week where a server that had the source shares for my Packages and Drivers had to be decommissioned. This initially seemed like an simple task of updating the source location in each package to the new server. However after realising that there were a lot of packages and about 400 drivers I sought a better way. Powershell to the rescue!

The following block of Powershell gets all the drivers and does a search and replace on the server name.

$drivers = Get-WmiObject SMS_Driver -Namespace root\SMS\site_LNK

$drivers | ?{$_.ContentSourcePath -like "\\creekserver\*"} | `
%{$_.ContentSourcePath = $_.ContentSourcePath -replace "creekserver", "PRI-SCCM-V01"; $_.Put()}

I did the same for packages:

$packages = Get-WmiObject SMS_Package -Namespace root\SMS\site_LNK

$packages | ?{$_.PkgSourcePath -like "*creekserver*"} | `
%{$_.PkgSourcePath = $_.PkgSourcePath -replace "creekserver","PRI-SCCM-V01"; $_.Put()}

$packages | %{$_.RefreshPkgSource}


Enjoy!

posted on Friday, May 08, 2009 10:38:08 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0]
# Friday, March 06, 2009

If you've ever tried to install the Lenovo Hotkey utility as part of an SCCM Task Sequence you'll have noticed that no matter how big a tantrum you through it won't work. Lenovo's documentation states that you can install the Hotkey utility in an unattended fasion using "Setup.exe /S". For whatever reason this doesn't work in a Task Sequence using a standard Package and Program. To get around this do the follow:

  1. Extract the Hotkey utility.
  2. Create a batch file InstallHotkey.cmd with a single line: %~dp0SETUP.EXE /S
  3. Create a standard SCCM package with the source pointing to your extracted hotkey files.
  4. Make sure that InstallHotkey.cmd is in the same dir as Setup.exe
  5. In you Task Sequence add a new "Run Command Line" task.
  6. Set the Package to the Hotkey Package you created in step 4.
  7. In the command line put InstallHotkey.cmd

posted on Friday, March 06, 2009 4:20:48 PM (E. Australia Standard Time, UTC+10:00)  #    Comments [0]
# Thursday, October 16, 2008

The answer is yes! Incidentally, is there really any limit to what you can do with ConfigMgr?? Well I suppose that is like asking, "How much wood could a woodchuck chuck if a woodchuck could chuck wood?", but anyway let's move on.

My first clue for solving this came from deployvista.com, "Using the $OEM$ folder with SCCM 2007 OS Deployments". To summarize you need to place your $OEM$ files into C:\_SMSTaskSequence\OSD\$OEM$ in order for Windows Setup to use the files. Here is what I did:

  1. Added my $OEM$ Files to my MDT Settings Package. (The one with unattend.txt, sysprep.inf and customsettings.ini)
  2. Add Z-CONFIG-CopyOEM.wsf to your MDT Source Files package. I've provided it below. (Remember to update DP)
  3. In your Task Sequence right before "Setup Windows and ConfigMgr" add a new "Run Command Line" task.
  4. Set the Name to "Copy OEM Files".
  5. Set the Command Line to "cscript.exe "%deployroot%\scripts\Z-CONFIG-CopyOEM.wsf".
  6. Click the "Package" checkbox and select your MDT Settings Package.
  7. All Done!

The guts of the script is pretty simple stuff and it works because when you set a Package in a Run Command Line Task the current directory is the path to whatever package you've select. In this case the current directory is the MDT Settings package containing our $OEM$ files.

'//----------------------------------------------------------------------------
'//  See if we can find the $OEM$ Directory
'//----------------------------------------------------------------------------
sDest = OEnvironment.GetOSDV4("_SMSTSMDATAPATH") & "\OSD\$OEM$"
oLogging.CreateEntry "$OEM$ Files will be copied to " & sDest, LogTypeInfo 

'//----------------------------------------------------------------------------
'//  Make sure the Destination exists
'//----------------------------------------------------------------------------
MKDir sDest 

'//----------------------------------------------------------------------------
'//  Get the Source Location and Copy the files
'//----------------------------------------------------------------------------
sSource = oShell.CurrentDirectory & "\$OEM$"
oLogging.CreateEntry "$OEM$ Files will be copied from " & sSource, LogTypeInfo 

'Copy the folder
oFSO.CopyFolder sSource, sDest 

posted on Thursday, October 16, 2008 3:30:23 PM (E. Australia Standard Time, UTC+10:00)  #    Comments [0]