# 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]
# Monday, June 29, 2009

The process of creating a Windows PE 3.0 disk has changed slightly from the previous version. Luckily the Windows PE User’s Guide that ships with the WAIK has all the information you’ll ever need. To get started download the WAIK for Windows 7 RC here. Then follow the steps in the section “Windows PE Walkthroughs”. I’ve provided the batch file I use to create a generic WinPE 3.0 ISO below.

@Echo off"
REM ********************************************************************************
REM head block

REM Setup
SET PETOOLS=C:\Program Files\Windows AIK\Tools\PETools
SET ARCH=x86
SET WORKINGDIR=%~dp0windowspe-%ARCH%


IF NOT EXIST "%WORKINGDIR%" Goto :COPYPE
Echo "%WORKINGDIR%" exists, Removing....
rmdir "%WORKINGDIR%" /S /Q


:COPYPE
cd /d "%PETOOLS%"

call copype.cmd %ARCH% "%WORKINGDIR%"

REM Copy Base WIM to boot.wim
copy "%WORKINGDIR%\winpe.wim" "%WORKINGDIR%\ISO\sources\boot.wim"

REM Mount boot.wim
Dism /Mount-Wim /WimFile:"%WORKINGDIR%\ISO\sources\boot.wim" /index:1 /MountDir:"%WORKINGDIR%\mount"

REM Add Optional Components
Dism /image:"%WORKINGDIR%\mount" /Add-Package /PackagePath:"%PETOOLS%\%ARCH%\WinPE_FPs\winpe-wmi.cab"
Dism /image:"%WORKINGDIR%\mount" /Add-Package /PackagePath:"%PETOOLS%\%ARCH%\WinPE_FPs\en-us\winpe-wmi_en-us.cab"

Dism /image:"%WORKINGDIR%\mount" /Add-Package /PackagePath:"%PETOOLS%\%ARCH%\WinPE_FPs\winpe-hta.cab"
Dism /image:"%WORKINGDIR%\mount" /Add-Package /PackagePath:"%PETOOLS%\%ARCH%\WinPE_FPs\en-us\winpe-hta_en-us.cab"

Dism /image:"%WORKINGDIR%\mount" /Add-Package /PackagePath:"%PETOOLS%\%ARCH%\WinPE_FPs\winpe-mdac.cab"
Dism /image:"%WORKINGDIR%\mount" /Add-Package /PackagePath:"%PETOOLS%\%ARCH%\WinPE_FPs\en-us\winpe-mdac_en-us.cab"

Dism /image:"%WORKINGDIR%\mount" /Add-Package /PackagePath:"%PETOOLS%\%ARCH%\WinPE_FPs\winpe-scripting.cab"
Dism /image:"%WORKINGDIR%\mount" /Add-Package /PackagePath:"%PETOOLS%\%ARCH%\WinPE_FPs\en-us\winpe-scripting_en-us.cab"

Dism /image:"%WORKINGDIR%\mount" /Add-Package /PackagePath:"%PETOOLS%\%ARCH%\WinPE_FPs\winpe-wmi.cab"
Dism /image:"%WORKINGDIR%\mount" /Add-Package /PackagePath:"%PETOOLS%\%ARCH%\WinPE_FPs\en-us\winpe-wmi_en-us.cab"

REM Copy Imagex into the Windows Dir
copy "C:\Program Files\Windows AIK\Tools\%ARCH%\imagex.exe" "%WORKINGDIR%\mount\Windows"

REM COpy Tools
xcopy %~dp0Tools %WORKINGDIR%\ISO /E /S

REM Unmount the WIM
Dism /unmount-Wim /MountDir:"%WORKINGDIR%\mount" /Commit


REM Create the ISO
oscdimg -n -b"%WORKINGDIR%\etfsboot.com" "%WORKINGDIR%\ISO" "%WORKINGDIR%\winpe_x86.iso"

You may want to comment out the line with “xcopy %~dp0Tools” at the beginning. I usually copy a bunch of tools onto my WinPE disk using this tools directory.

posted on Monday, June 29, 2009 2:14:16 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]
# Tuesday, December 16, 2008

When working with the Microsoft Deployment Toolkit (MDT) I spend a lot of time in VMWare Workstation as it makes the job of developing and testing a workstation image much simpler. However there is one big gottcha that you should be aware of. Make sure you edit your .VMX file and modify the following:

scsi0.present = "TRUE" should be changed to scsi0.present = "FALSE"

If you don't do this then after deploying a Syspreped image to VMWare Workstation you'll end up with a Stop 0x7B error and much less hair than when you started.

Thanks Chris for reminding me of something I supposedly knew. :)

posted on Tuesday, December 16, 2008 3:20:49 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]
# Tuesday, October 07, 2008

If you've ever had anything to do with maintaining or migrating a fileserver you will probably have experienced issues with MAX_PATH. In Windows the maximum length for a path is MAX_PATH, which is defined as 260 characters. One of the most common errors for MAX_PATH is "Can't access this folder. Path is too long." This usually happens when users (those pesky users!) map a drive half way down a directory structure and started creating new files and folders.

You can find more information about MAX_PATH at the following locations:

I've seen a number of different ways of finding paths that are too long but my favourite at the moment is using the Microsoft Log Parser. Details:

Once you've downloaded LogParser you can run the following command to output a CSV file of paths greater than 250 characters:

LogParser "SELECT Path, Size FROM C:\*.* WHERE STRLEN(Path) > 250" -i:FS -preserveLastAccTime:ON -o:CSV > Results.csv

Just change the "C:\*.*" to the location you want to check for long paths and Bob's your uncle.

posted on Tuesday, October 07, 2008 10:50:24 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0]
# Monday, October 06, 2008

I booted an SCCM Task Sequence boot image this morning in VMWare Workstation and received the following error: "This application has failed to start because wdi.dll was not found. Re-installing the application may fix this problem".

Error

Oh of course that makes perfect sense......arhhh actually no. After a bit of searching it appears as thought this is an issue with the VMWare Workstation Drivers. Earlier I'd added the entire drivers directory from the VMWare Tools directory to SCCM. Bad move! All you need is the the vmxnet and scsi directories. Remove all the others, re-generate the Boot Image and you're away!

posted on Monday, October 06, 2008 3:09:29 PM (E. Australia Standard Time, UTC+10:00)  #    Comments [0]
# Thursday, October 02, 2008

Today I was attempting to create a sysprep.xml file for Windows 2008. After opening my WIM file in Windows SIM I got the prompt to generate a Catalog file, clicked Yes and then......Error!! What?? Lets try that again....Error!! Whatever, lets try again, Error!! Ok this time I read the error. "System.Reflection.TargetParameterCountException: Parameter count mismatch." Ummm, what??

After wasting almost 2 hours chasing this error I found this post on the TechNet Forums: http://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=3066853&SiteID=17.

The key information is:

Because of the changes in the servicing stack in Windows Vista with Service Pack 1 (SP1) and Windows Server 2008, Windows System Image Manager (Windows SIM) cannot create catalog files for some Windows images of different architecture types. The following list describes the Image Manager architecture types and catalogs that can be created for each one.

x86 Windows SIM:
Can create catalogs for x86, x64, and Itanium-based Windows images.

x64 Windows SIM:
Can create catalogs only for x64 Windows images.

Itanium-based Windows SIM:
Can create catalogs only for Itanium-based Windows images. 

Please confirm if what version of Windows SIM you are using. I recommend installing x86 Windows SIM.

Hope it helps.

Tim Quan - MSFT

Update: Michael Niehaus pointed out that this information is available in the updated version of the WAIK 1.1 release notes available at http://www.microsoft.com/downloads/details.aspx?FamilyID=051091e8-51ea-4d2c-96b3-dc9863edebd9&displaylang=en.

posted on Thursday, October 02, 2008 11:12:33 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [3]
# Wednesday, October 01, 2008

I just notice there is a new version of my favourite comparison tool Beyond Compare. In my mind Beyond Compare is one of the best file and folder comparison tools available. Go to Scooter Software to get Beyond Compare 3!

posted on Wednesday, October 01, 2008 10:02:29 AM (E. Australia Standard Time, UTC+10:00)  #    Comments [0]